diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/audio_mapping.cc | 32 | ||||
| -rw-r--r-- | src/lib/film.cc | 30 | ||||
| -rw-r--r-- | src/lib/film.h | 2 | ||||
| -rw-r--r-- | src/lib/image.cc | 20 | ||||
| -rw-r--r-- | src/lib/memory_util.cc | 46 | ||||
| -rw-r--r-- | src/lib/memory_util.h | 7 | ||||
| -rw-r--r-- | src/lib/po/zh_CN.po | 63 | ||||
| -rw-r--r-- | src/lib/reel_writer.cc | 30 |
8 files changed, 153 insertions, 77 deletions
diff --git a/src/lib/audio_mapping.cc b/src/lib/audio_mapping.cc index 4e13d1adb..c926437ea 100644 --- a/src/lib/audio_mapping.cc +++ b/src/lib/audio_mapping.cc @@ -85,13 +85,13 @@ AudioMapping::make_zero() struct ChannelRegex { - ChannelRegex(string regex_, int channel_) + ChannelRegex(string regex_, dcp::Channel channel_) : regex(regex_) , channel(channel_) {} string regex; - int channel; + dcp::Channel channel; }; @@ -99,19 +99,19 @@ void AudioMapping::make_default(AudioProcessor const * processor, optional<boost::filesystem::path> filename) { static ChannelRegex const regex[] = { - ChannelRegex(".*[\\._-]L[\\._-].*", 0), - ChannelRegex(".*[\\._-]R[\\._-].*", 1), - ChannelRegex(".*[\\._-]C[\\._-].*", 2), - ChannelRegex(".*[\\._-]Lfe[\\._-].*", 3), - ChannelRegex(".*[\\._-]LFE[\\._-].*", 3), - ChannelRegex(".*[\\._-]Lss[\\._-].*", 4), - ChannelRegex(".*[\\._-]Lsr[\\._-].*", 6), - ChannelRegex(".*[\\._-]Lrs[\\._-].*", 6), - ChannelRegex(".*[\\._-]Ls[\\._-].*", 4), - ChannelRegex(".*[\\._-]Rss[\\._-].*", 5), - ChannelRegex(".*[\\._-]Rsr[\\._-].*", 7), - ChannelRegex(".*[\\._-]Rrs[\\._-].*", 7), - ChannelRegex(".*[\\._-]Rs[\\._-].*", 5), + ChannelRegex(".*[\\._-]L[\\._-].*", dcp::Channel::LEFT), + ChannelRegex(".*[\\._-]R[\\._-].*", dcp::Channel::RIGHT), + ChannelRegex(".*[\\._-]C[\\._-].*", dcp::Channel::CENTRE), + ChannelRegex(".*[\\._-]Lfe[\\._-].*", dcp::Channel::LFE), + ChannelRegex(".*[\\._-]LFE[\\._-].*", dcp::Channel::LFE), + ChannelRegex(".*[\\._-]Lss[\\._-].*", dcp::Channel::LS), + ChannelRegex(".*[\\._-]Lsr[\\._-].*", dcp::Channel::BSL), + ChannelRegex(".*[\\._-]Lrs[\\._-].*", dcp::Channel::BSL), + ChannelRegex(".*[\\._-]Ls[\\._-].*", dcp::Channel::LS), + ChannelRegex(".*[\\._-]Rss[\\._-].*", dcp::Channel::RS), + ChannelRegex(".*[\\._-]Rsr[\\._-].*", dcp::Channel::BSR), + ChannelRegex(".*[\\._-]Rrs[\\._-].*", dcp::Channel::BSR), + ChannelRegex(".*[\\._-]Rs[\\._-].*", dcp::Channel::RS), }; static int const regexes = sizeof(regex) / sizeof(*regex); @@ -127,7 +127,7 @@ AudioMapping::make_default(AudioProcessor const * processor, optional<boost::fil if (filename) { for (int i = 0; i < regexes; ++i) { boost::regex e(regex[i].regex, boost::regex::icase); - if (boost::regex_match(filename->filename().string(), e) && regex[i].channel < output_channels()) { + if (boost::regex_match(filename->filename().string(), e) && static_cast<int>(regex[i].channel) < output_channels()) { set(0, regex[i].channel, 1); guessed = true; } diff --git a/src/lib/film.cc b/src/lib/film.cc index b0276086a..de6343b9c 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -113,6 +113,7 @@ using namespace dcpomatic; static constexpr char metadata_file[] = "metadata.xml"; static constexpr char ui_state_file[] = "ui.xml"; static constexpr char assets_file[] = "assets.xml"; +static constexpr char info_dir[] = "info"; /* 5 -> 6 @@ -289,7 +290,7 @@ boost::filesystem::path Film::info_file(DCPTimePeriod period) const { boost::filesystem::path p; - p /= "info"; + p /= info_dir; p /= video_identifier() + "_" + fmt::to_string(period.from.get()) + "_" + fmt::to_string(period.to.get()); return file(p); } @@ -1440,7 +1441,7 @@ Film::cpls() const for (auto const& item: dcp::filesystem::directory_iterator(dir)) { if ( dcp::filesystem::is_directory(item) && - item.path().filename() != "j2c" && item.path().filename() != "video" && item.path().filename() != "info" && item.path().filename() != "analysis" + item.path().filename() != "j2c" && item.path().filename() != "video" && item.path().filename() != info_dir && item.path().filename() != "analysis" ) { try { @@ -2204,12 +2205,35 @@ Film::speed_up_range(int dcp_frame_rate) const return _playlist->speed_up_range(dcp_frame_rate); } + void -Film::copy_from(shared_ptr<const Film> film) +Film::copy_from(shared_ptr<const Film> film, std::function<void (float)> set_progress) { read_metadata(film->file(metadata_file)); + + auto old_assets = film->read_remembered_assets(); + auto new_assets = std::vector<RememberedAsset>{}; + + /* Find source film's remembered assets that still exist and copy them to our new film */ + for (auto path: dcp::filesystem::recursive_directory_iterator(*film->directory())) { + auto iter = std::find_if(old_assets.begin(), old_assets.end(), [path](RememberedAsset const& asset) { + return asset.filename() == path.path().filename(); + }); + if (iter != old_assets.end()) { + copy_in_bits(path, assets_path() / path.path().filename(), set_progress); + new_assets.push_back({path.path().filename(), iter->period(), iter->identifier()}); + } + } + + write_remembered_assets(new_assets); + + /* To use the assets we also need the info files */ + for (auto path: dcp::filesystem::directory_iterator(film->dir(info_dir))) { + dcp::filesystem::copy_file(path.path(), dir(info_dir) / path.path().filename()); + } } + bool Film::references_dcp_video() const { diff --git a/src/lib/film.h b/src/lib/film.h index ae812f6d4..09b51202c 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -122,7 +122,7 @@ public: void write_template(boost::filesystem::path path) const; std::shared_ptr<xmlpp::Document> metadata(bool with_content_paths = true) const; - void copy_from(std::shared_ptr<const Film> film); + void copy_from(std::shared_ptr<const Film> film, std::function<void (float)> set_progress); std::string isdcf_name(bool if_created_now) const; std::string dcp_name(bool if_created_now = false) const; diff --git a/src/lib/image.cc b/src/lib/image.cc index 4a07dcdca..3a2e99c23 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -612,17 +612,15 @@ Image::make_black() case AV_PIX_FMT_UYVY422: { - int const Y = sample_size(0).height; - int const X = line_size()[0]; - uint8_t* p = data()[0]; - for (int y = 0; y < Y; ++y) { - for (int x = 0; x < X / 4; ++x) { - *p++ = eight_bit_uv; // Cb - *p++ = 0; // Y0 - *p++ = eight_bit_uv; // Cr - *p++ = 0; // Y1 - } - } + fill_memory( + data()[0], + sample_size(0).height * line_size()[0], + /* Cb/Cr is eight_bit_uv, Y0/Y1 is 0 */ + static_cast<uint64_t>(eight_bit_uv) | + (static_cast<uint64_t>(eight_bit_uv) << 16) | + (static_cast<uint64_t>(eight_bit_uv) << 32) | + (static_cast<uint64_t>(eight_bit_uv) << 48) + ); break; } diff --git a/src/lib/memory_util.cc b/src/lib/memory_util.cc index 00117855d..cf8842615 100644 --- a/src/lib/memory_util.cc +++ b/src/lib/memory_util.cc @@ -30,12 +30,52 @@ LIBDCP_ENABLE_WARNINGS void * -wrapped_av_malloc (size_t s) +wrapped_av_malloc(size_t s) { - auto p = av_malloc (s); + auto p = av_malloc(s); if (!p) { - throw std::bad_alloc (); + throw std::bad_alloc(); } return p; } + +void +fill_memory(void* ptr, size_t bytes, uint64_t value) +{ + if (bytes == 0) { + return; + } + + auto const start = std::min(bytes, sizeof(value) - reinterpret_cast<uintptr_t>(ptr) % sizeof(value)); + auto start_ptr = reinterpret_cast<uint8_t*>(ptr); + if (start < 8) { + for (auto i = 0UL; i < start; ++i) { + *start_ptr++ = value & 0xff; + value = (value >> 8) | ((value & 0xff) << 56); + } + + bytes -= start; + if (bytes == 0) { + return; + } + } + + auto const main = (bytes - (bytes % sizeof(value))) / 8; + auto main_ptr = reinterpret_cast<uint64_t*>(start_ptr); + for (auto i = 0UL; i < main; ++i) { + *main_ptr++ = value; + } + + bytes -= main * 8; + if (bytes == 0) { + return; + } + + auto end_ptr = reinterpret_cast<uint8_t*>(main_ptr); + for (auto i = 0UL; i < bytes; ++i) { + *end_ptr++ = value & 0xff; + value = (value >> 8) | ((value & 0xff) << 56); + } +} + diff --git a/src/lib/memory_util.h b/src/lib/memory_util.h index eccc4a857..f6bbe0621 100644 --- a/src/lib/memory_util.h +++ b/src/lib/memory_util.h @@ -19,4 +19,9 @@ */ -extern void* wrapped_av_malloc (size_t); +#include <cstddef> +#include <cstdint> + + +extern void* wrapped_av_malloc(size_t); +extern void fill_memory(void* ptr, size_t bytes, uint64_t value); diff --git a/src/lib/po/zh_CN.po b/src/lib/po/zh_CN.po index a575f752b..db2ab4731 100644 --- a/src/lib/po/zh_CN.po +++ b/src/lib/po/zh_CN.po @@ -13,15 +13,15 @@ msgstr "" "Project-Id-Version: LIBDCPOMATIC\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2026-04-19 23:03+0200\n" -"PO-Revision-Date: 2025-10-05 13:31+0800\n" +"PO-Revision-Date: 2026-05-17 10:45+0800\n" "Last-Translator: Dian Li <xslidian@gmail.com>\n" -"Language-Team: Chinese Simplified (Rov8 branch)\n" +"Language-Team: Chinese Simplified (Hanyuan branch)\n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 3.7\n" +"X-Generator: Poedit 3.9\n" "X-Poedit-SourceCharset: UTF-8\n" #: src/lib/video_content.cc:515 @@ -207,7 +207,7 @@ msgid "; {} remaining; finishing at {}{}" msgstr "; 剩余 {} ; 完成于 {}{}" #: src/lib/analytics.cc:58 -#, fuzzy, c++-format +#, c++-format msgid "" "<h2>You have made {} DCPs with {}!</h2><img width=\"150\" height=\"193\" " "src=\"memory:me.jpg\" align=\"center\"><font size=\"+1\"><p>Hello. I'm Carl " @@ -429,7 +429,7 @@ msgstr "中置" #: src/lib/exceptions.cc:196 #, c++-format msgid "CPL {} not found" -msgstr "" +msgstr "未找到CPL {}" #: src/lib/job.cc:657 msgid "Cancelled" @@ -461,6 +461,8 @@ msgid "" "Check the server settings in the TMS tab of preferences, or un-tick \"Upload " "DCP to TMS after creation\" if you do not want to upload your DCP." msgstr "" +"在首选项的TMS页面中检查服务器设置,或者您不想要上传DCP的话,则取消选中“制作" +"DCP后上传到TMS)复选框" #: src/lib/transcode_job.cc:106 msgid "Check their new settings, then try again." @@ -682,9 +684,8 @@ msgid "Copying DCPs to {}" msgstr "复制DCP到 {}" #: src/lib/reel_writer.cc:194 -#, fuzzy msgid "Copying existing asset" -msgstr "检查现有的图像数据" +msgstr "正在拷贝已经存在的资产" #: src/lib/copy_to_drive_job.cc:58 #, c++-format @@ -811,9 +812,9 @@ msgid "DCP sample rate" msgstr "DCP 采样率" #: src/lib/frame_rate_change.cc:93 -#, fuzzy, c++-format +#, c++-format msgid "DCP will contain 1 out of every {} frames of the content.\n" -msgstr "将使用隔帧打包DCP。\n" +msgstr "DCP 将包含内容中每 {} 帧中的 1 帧。\n" #: src/lib/frame_rate_change.cc:103 #, c-format @@ -904,9 +905,8 @@ msgstr "下载失败 ({} error {})" #. TRANSLATORS: this is an abbreviation for "end credits", shown next to the pair of markers #. "FFEC" and "LFEC" ({First, Last} Frame of End Credits) #: src/lib/layout_markers.cc:145 -#, fuzzy msgid "EC" -msgstr "中置" +msgstr "片尾字幕" #: src/lib/frame_rate_change.cc:95 msgid "Each content frame will be doubled in the DCP.\n" @@ -1128,7 +1128,7 @@ msgstr "IEC61966-2-4" #. "FFOI" and "LFOI" ({First, Last} Frame of Intermission) #: src/lib/layout_markers.cc:142 msgid "IN" -msgstr "" +msgstr "幕间休息" #: src/lib/hints.cc:198 msgid "If you do use 25fps you should change your DCP standard to SMPTE." @@ -1231,9 +1231,8 @@ msgstr "左环绕" #. TRANSLATORS: this is an abbreviation for "moving credits", shown next to the pair of markers #. "FFMC" and "LFMC" ({First, Last} Frame of Moving Credits) #: src/lib/layout_markers.cc:148 -#, fuzzy msgid "MC" -msgstr "中置" +msgstr "滚动字幕" #: src/lib/mid_side_decoder.cc:39 msgid "Mid-side decoder" @@ -1279,12 +1278,11 @@ msgstr "动态隔行补偿" #: src/lib/dcp_content.cc:212 msgid "No ASSETMAP or ASSETMAP.xml file found: is this a DCP?" -msgstr "" +msgstr "未找到ASSETMAP或ASSETMAP.xml文件,这是一个DCP吗?" #: src/lib/dcp_examiner.cc:115 -#, fuzzy msgid "No CPLs found in DCP" -msgstr "DCP中没有找到CPL文件。" +msgstr "DCP中没有找到CPL文件" #: src/lib/dcp_decoder.cc:114 msgid "No CPLs found in DCP." @@ -1362,15 +1360,15 @@ msgstr "小波降噪" #: src/lib/colour_conversion.cc:293 msgid "P3 D60 (~6000K)" -msgstr "" +msgstr "P3 D60 (~6000K)" #: src/lib/colour_conversion.cc:292 msgid "P3 D65 (~6500K)" -msgstr "" +msgstr "P3 D65 (~6500K)" #: src/lib/colour_conversion.cc:291 msgid "P3 DCI (~6300K)" -msgstr "" +msgstr "P3 DCI (~6300K)" #: src/lib/util.cc:1111 #, c++-format @@ -1412,9 +1410,8 @@ msgstr "右声道" #. TRANSLATORS: this is an abbreviation for "ratings band", shown next to the pair of markers #. "FFOB" and "LFOB" ({First, Last} Frame of Band) #: src/lib/layout_markers.cc:136 -#, fuzzy msgid "RB" -msgstr "右声道" +msgstr "评级" #: src/lib/ffmpeg_content.cc:644 msgid "RGB / sRGB (IEC61966-2-1)" @@ -1503,9 +1500,8 @@ msgid "SMPTE ST 2084 for 10, 12, 14 and 16 bit systems" msgstr "SMPTE ST 2084 10, 12, 14和16 bit" #: src/lib/ffmpeg_content.cc:660 -#, fuzzy msgid "SMPTE ST 2128, IPT-C2" -msgstr "SMPTE ST 428-1" +msgstr "SMPTE ST 2128, IPT-C2" #: src/lib/ffmpeg_content.cc:636 msgid "SMPTE ST 428-1" @@ -1589,14 +1585,12 @@ msgstr "" "这些文件现在将被重新检查,因此您可能需要检查它们的设置。" #: src/lib/check_content_job.cc:94 -#, fuzzy msgid "" "Some files must be re-examined due to a bug fix in DCP-o-matic. You may " "need to check their settings." msgstr "" -"有些文件在添加到项目后发生了更改\n" -"\n" -"这些文件现在将被重新检查,因此您可能需要检查它们的设置。" +"由于 DCP-o-matic 中的一个漏洞修复,某些文件必须重新检查。您可能需要检查它们的" +"设置。" #: src/lib/hints.cc:622 #, c++-format @@ -1622,6 +1616,9 @@ msgid "" "in doubt, set everything (picture, sound and text) to be either encrypted or " "not." msgstr "" +"你的一些内容是加密的,而有些则不是。虽然一些分销商(例如 Netflix)要求字幕不" +"能加密(即使画面和声音可以加密),但其他分销商会对由此项目生成的 DCP 标记错" +"误。如果不确定,请将所有内容(画面、声音和文字)设置为加密或不加密。" #: src/lib/make_dcp.cc:69 msgid "Some of your content is missing" @@ -1670,9 +1667,8 @@ msgstr "星期日" #. TRANSLATORS: this is an abbreviation for "title credits", shown next to the pair of markers #. "FFTC" and "LFTC" ({First, Last} Frame of Title Credits) #: src/lib/layout_markers.cc:139 -#, fuzzy msgid "TC" -msgstr "中置" +msgstr "标题字幕" #: src/lib/dcp_content_type.cc:60 msgid "Teaser" @@ -1987,11 +1983,11 @@ msgstr "YCOCG" #: src/lib/ffmpeg_content.cc:661 msgid "YCgCo-R, even addition" -msgstr "" +msgstr "YCgCo-R,偶数叠加编码" #: src/lib/ffmpeg_content.cc:662 msgid "YCgCo-R, odd addition" -msgstr "" +msgstr "YCgCo-R,奇数叠加编码" #: src/lib/filter.cc:98 msgid "Yet Another Deinterlacing Filter" @@ -2313,11 +2309,10 @@ msgstr "名字" #. TRANSLATORS: this string will follow "Cannot reference this DCP: " #: src/lib/dcp_content.cc:829 -#, fuzzy msgid "" "one of its closed caption reels has a non-zero entry point so it must be re-" "written." -msgstr "它的一个隐藏字幕有一个非零的时间点,因此必须重写。" +msgstr "它的一个隐藏字幕卷有一个非零的起始点,因此必须重写。" #. TRANSLATORS: this string will follow "Cannot reference this DCP: " #: src/lib/dcp_content.cc:823 diff --git a/src/lib/reel_writer.cc b/src/lib/reel_writer.cc index b85b53305..76c1f8124 100644 --- a/src/lib/reel_writer.cc +++ b/src/lib/reel_writer.cc @@ -591,6 +591,7 @@ ReelWriter::create_reel_sound(shared_ptr<dcp::Reel> reel, list<ReferencedReelAss } +/** @param ensure_closed_captions List of DCPTextTracks that we need to make sure exist in this reel */ void ReelWriter::create_reel_text( shared_ptr<dcp::Reel> reel, @@ -630,17 +631,30 @@ ReelWriter::create_reel_text( } } - for (auto const& i: _closed_caption_assets) { - auto a = maybe_add_text<dcp::ReelInteropTextAsset, dcp::ReelSMPTETextAsset, dcp::ReelTextAsset>( - i.second, dcp::TextType::CLOSED_CAPTION, duration, reel, _reel_index, _reel_count, _content_summary, refs, film(), _period, output_dcp, _text_only + for (auto iter = ensure_closed_captions.begin(); iter != ensure_closed_captions.end(); ) { + /* Find any asset we wrote for this track */ + auto written_asset = _closed_caption_assets.find(*iter); + + /* Try to make a reel asset out of either written_asset or one of the referenced assets */ + auto asset = maybe_add_text<dcp::ReelInteropTextAsset, dcp::ReelSMPTETextAsset, dcp::ReelTextAsset>( + written_asset == _closed_caption_assets.end() ? shared_ptr<dcp::TextAsset>() : written_asset->second, + dcp::TextType::CLOSED_CAPTION, duration, reel, _reel_index, _reel_count, _content_summary, refs, film(), _period, output_dcp, _text_only ); - DCPOMATIC_ASSERT(a); - a->set_annotation_text(i.first.name); - if (i.first.language) { - a->set_language(i.first.language.get()); + + /* Fill in some details for the reel asset if we know them */ + if (asset && written_asset != _closed_caption_assets.end()) { + asset->set_annotation_text(written_asset->first.name); + if (written_asset->first.language) { + asset->set_language(written_asset->first.language.get()); + } } - ensure_closed_captions.erase(i.first); + if (asset) { + /* We made a reel asset for this track, so we don't need to worry about it any more */ + iter = ensure_closed_captions.erase(iter); + } else { + ++iter; + } } /* Make empty tracks for anything we've been asked to ensure but that we haven't added */ |
