summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/audio_mapping.cc32
-rw-r--r--src/lib/film.cc30
-rw-r--r--src/lib/film.h2
-rw-r--r--src/lib/image.cc20
-rw-r--r--src/lib/memory_util.cc46
-rw-r--r--src/lib/memory_util.h7
-rw-r--r--src/lib/po/zh_CN.po63
-rw-r--r--src/lib/reel_writer.cc30
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 */