From: Carl Hetherington Date: Sun, 11 Dec 2022 23:51:56 +0000 (+0100) Subject: Support the 2014 version of SMPTE 428-7 in render_text.cc and use it X-Git-Tag: v2.16.45~18^2~17 X-Git-Url: https://git.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=5e7ec41119961114a9b4df90d1c9ced580667f54 Support the 2014 version of SMPTE 428-7 in render_text.cc and use it when placing subtitles (e.g. SRT). Also default to outputting 2014-era alignment. --- diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc index 0f4e1afa1..e82e9e958 100644 --- a/src/lib/dcp_decoder.cc +++ b/src/lib/dcp_decoder.cc @@ -304,7 +304,7 @@ DCPDecoder::pass_texts ( ContentTime::from_frames(_offset - entry_point, vfr) + ContentTime::from_seconds(b.out().as_seconds()) ), strings, - _dcp_content->standard() + asset->subtitle_standard() ); strings.clear (); } @@ -340,7 +340,7 @@ DCPDecoder::pass_texts ( ContentTime::from_frames(_offset - entry_point, vfr) + ContentTime::from_seconds(b.out().as_seconds()) ), strings, - _dcp_content->standard() + asset->subtitle_standard() ); strings.clear (); } diff --git a/src/lib/dcp_subtitle_decoder.cc b/src/lib/dcp_subtitle_decoder.cc index 617f7ec53..fa92193a5 100644 --- a/src/lib/dcp_subtitle_decoder.cc +++ b/src/lib/dcp_subtitle_decoder.cc @@ -47,11 +47,7 @@ DCPSubtitleDecoder::DCPSubtitleDecoder (shared_ptr film, shared_ptr< _subtitles = asset->subtitles (); _next = _subtitles.begin (); - if (dynamic_pointer_cast(asset)) { - _standard = dcp::Standard::INTEROP; - } else { - _standard = dcp::Standard::SMPTE; - } + _subtitle_standard = asset->subtitle_standard(); text.push_back (make_shared(this, content->only_text())); update_position(); @@ -109,7 +105,7 @@ DCPSubtitleDecoder::pass () } } - only_text()->emit_plain(p, s, _standard); + only_text()->emit_plain(p, s, _subtitle_standard); update_position(); diff --git a/src/lib/dcp_subtitle_decoder.h b/src/lib/dcp_subtitle_decoder.h index 3eed4ad24..45a4999dd 100644 --- a/src/lib/dcp_subtitle_decoder.h +++ b/src/lib/dcp_subtitle_decoder.h @@ -43,5 +43,5 @@ private: std::vector> _subtitles; std::vector>::const_iterator _next; - dcp::Standard _standard; + dcp::SubtitleStandard _subtitle_standard; }; diff --git a/src/lib/reel_writer.cc b/src/lib/reel_writer.cc index e0279725b..47df4feb1 100644 --- a/src/lib/reel_writer.cc +++ b/src/lib/reel_writer.cc @@ -892,9 +892,10 @@ ReelWriter::empty_text_asset (TextType type, optional track, bool float -ReelWriter::convert_vertical_position(StringText const& subtitle, dcp::Standard to) const +ReelWriter::convert_vertical_position(StringText const& subtitle, dcp::SubtitleStandard to) const { - if (subtitle.valign_standard == to) { + if (dcp::uses_baseline(subtitle.valign_standard) == dcp::uses_baseline(to)) { + /* The from and to standards use the same alignment reference */ return subtitle.v_position(); } @@ -914,7 +915,7 @@ ReelWriter::convert_vertical_position(StringText const& subtitle, dcp::Standard break; } - return subtitle.v_position() + ((subtitle.valign_standard == dcp::Standard::SMPTE) ? correction : -correction); + return subtitle.v_position() + (dcp::uses_bounding_box(subtitle.valign_standard) ? correction : -correction); } @@ -957,7 +958,7 @@ ReelWriter::write (PlayerText subs, TextType type, optional track, for (auto i: subs.string) { i.set_in (dcp::Time(period.from.seconds() - _period.from.seconds(), tcr)); i.set_out (dcp::Time(period.to.seconds() - _period.from.seconds(), tcr)); - i.set_v_position(convert_vertical_position(i, film()->interop() ? dcp::Standard::INTEROP : dcp::Standard::SMPTE)); + i.set_v_position(convert_vertical_position(i, film()->interop() ? dcp::SubtitleStandard::INTEROP : dcp::SubtitleStandard::SMPTE_2014)); auto sub = make_shared(i); if (type == TextType::OPEN_SUBTITLE) { sub->set_font(fonts.get(i.font)); diff --git a/src/lib/reel_writer.h b/src/lib/reel_writer.h index 8ceef9f51..892d803a5 100644 --- a/src/lib/reel_writer.h +++ b/src/lib/reel_writer.h @@ -121,7 +121,7 @@ private: std::set ensure_closed_captions ) const; void create_reel_markers (std::shared_ptr reel) const; - float convert_vertical_position(StringText const& subtitle, dcp::Standard to) const; + float convert_vertical_position(StringText const& subtitle, dcp::SubtitleStandard to) const; dcpomatic::DCPTimePeriod _period; /** the first picture frame index that does not already exist in our MXF */ diff --git a/src/lib/render_text.cc b/src/lib/render_text.cc index 702f848ac..99c4c06a8 100644 --- a/src/lib/render_text.cc +++ b/src/lib/render_text.cc @@ -253,7 +253,8 @@ y_position (StringText const& first, int target_height, int baseline_to_bottom, { int y = 0; switch (first.valign_standard) { - case dcp::Standard::INTEROP: + case dcp::SubtitleStandard::INTEROP: + case dcp::SubtitleStandard::SMPTE_2014: switch (first.v_align()) { case dcp::VAlign::TOP: /* v_position is distance from top of frame to subtitle baseline */ @@ -269,7 +270,8 @@ y_position (StringText const& first, int target_height, int baseline_to_bottom, break; } break; - case dcp::Standard::SMPTE: + case dcp::SubtitleStandard::SMPTE_2007: + case dcp::SubtitleStandard::SMPTE_2010: switch (first.v_align()) { case dcp::VAlign::TOP: /* v_position is distance from top of frame to top of subtitle */ diff --git a/src/lib/string_text.h b/src/lib/string_text.h index 4eef7da05..787231b8c 100644 --- a/src/lib/string_text.h +++ b/src/lib/string_text.h @@ -24,6 +24,7 @@ #include "font.h" +#include #include @@ -40,7 +41,7 @@ class StringText : public dcp::SubtitleString { public: - StringText(dcp::SubtitleString dcp_, int outline_width_, std::shared_ptr font_, dcp::Standard valign_standard_) + StringText(dcp::SubtitleString dcp_, int outline_width_, std::shared_ptr font_, dcp::SubtitleStandard valign_standard_) : dcp::SubtitleString (dcp_) , outline_width (outline_width_) , font (font_) @@ -49,18 +50,24 @@ public: int outline_width; std::shared_ptr font; + /** Interop and SMPTE use the same VAlign choices (top, center, bottom) but give them different - * meanings. This is the standard which should be used to interpret v_align() in this subtitle; - * valign_standard == SMPTE means: + * meanings. To add some extra confusion, it seems that SMPTE changed their minds on this topic + * between the 2010 and 2014 versions of standard 428-7, so there isn't even one answer for SMPTE. + * + * This is the standard which should be used to interpret v_align() in this subtitle. + * + * valign_standard == SMPTE_{2007,2010} means: * top - top of screen to top of subtitle * center - centre of screen to center of subtitle * bottom - bottom of screen to bottom of subtitle - * valign_standard == Interop means: + * + * valign_standard == {INTEROP,SMPTE_2014} means: * top - top of screen to baseline of subtitle * center - centre of screen to baseline of subtitle * bottom - bottom of screen to baseline of subtitle */ - dcp::Standard valign_standard; + dcp::SubtitleStandard valign_standard; }; diff --git a/src/lib/text_decoder.cc b/src/lib/text_decoder.cc index 6fd036ae1..2541bbc9b 100644 --- a/src/lib/text_decoder.cc +++ b/src/lib/text_decoder.cc @@ -88,7 +88,7 @@ set_forced_appearance(shared_ptr content, StringText& subtitl void -TextDecoder::emit_plain_start (ContentTime from, vector subtitles, dcp::Standard valign_standard) +TextDecoder::emit_plain_start(ContentTime from, vector subtitles, dcp::SubtitleStandard valign_standard) { vector string_texts; @@ -265,7 +265,7 @@ TextDecoder::emit_plain_start (ContentTime from, sub::Subtitle const & sub_subti dcp_subtitle, content()->outline_width(), content()->get_font(block.font.get_value_or("")), - dcp::Standard::SMPTE + dcp::SubtitleStandard::SMPTE_2014 ); set_forced_appearance(content(), string_text); string_texts.push_back(string_text); @@ -285,7 +285,7 @@ TextDecoder::emit_stop (ContentTime to) void -TextDecoder::emit_plain (ContentTimePeriod period, vector subtitles, dcp::Standard valign_standard) +TextDecoder::emit_plain(ContentTimePeriod period, vector subtitles, dcp::SubtitleStandard valign_standard) { emit_plain_start (period.from, subtitles, valign_standard); emit_stop (period.to); diff --git a/src/lib/text_decoder.h b/src/lib/text_decoder.h index 5362540c2..3b25e54cb 100644 --- a/src/lib/text_decoder.h +++ b/src/lib/text_decoder.h @@ -23,10 +23,13 @@ #define DCPOMATIC_CAPTION_DECODER_H +#include "content_text.h" #include "decoder.h" +#include "decoder_part.h" #include "rect.h" #include "content_text.h" -#include "decoder_part.h" +#include "types.h" +#include #include #include @@ -49,9 +52,9 @@ public: void emit_bitmap_start (ContentBitmapText const& bitmap); void emit_bitmap (dcpomatic::ContentTimePeriod period, std::shared_ptr image, dcpomatic::Rect rect); - void emit_plain_start (dcpomatic::ContentTime from, std::vector s, dcp::Standard valign_standard); + void emit_plain_start(dcpomatic::ContentTime from, std::vector s, dcp::SubtitleStandard valign_standard); void emit_plain_start (dcpomatic::ContentTime from, sub::Subtitle const & subtitle); - void emit_plain (dcpomatic::ContentTimePeriod period, std::vector s, dcp::Standard valign_standard); + void emit_plain(dcpomatic::ContentTimePeriod period, std::vector s, dcp::SubtitleStandard valign_standard); void emit_plain (dcpomatic::ContentTimePeriod period, sub::Subtitle const & subtitle); void emit_stop (dcpomatic::ContentTime to); diff --git a/src/lib/util.cc b/src/lib/util.cc index 086a99f24..82f31b8f1 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -412,7 +412,7 @@ LIBDCP_ENABLE_WARNINGS optional(), false, false, false, dcp::Colour(), 42, 1, dcp::Time(), dcp::Time(), 0, dcp::HAlign::CENTER, 0, dcp::VAlign::CENTER, 0, dcp::Direction::LTR, "Hello dolly", dcp::Effect::NONE, dcp::Colour(), dcp::Time(), dcp::Time(), 0 ); - subs.push_back (StringText(ss, 0, {}, dcp::Standard::SMPTE)); + subs.push_back(StringText(ss, 0, {}, dcp::SubtitleStandard::SMPTE_2014)); render_text (subs, dcp::Size(640, 480), DCPTime(), 24); #endif diff --git a/test/render_subtitles_test.cc b/test/render_subtitles_test.cc index e5de60c4e..d1c912602 100644 --- a/test/render_subtitles_test.cc +++ b/test/render_subtitles_test.cc @@ -66,7 +66,7 @@ add (std::list& s, std::string text, bool italic, bool bold, bool un ), 2, std::shared_ptr(), - dcp::Standard::SMPTE + dcp::SubtitleStandard::SMPTE_2014 ) ); }