Merge branch 'master' of ssh://git.carlh.net/home/carl/git/dcpomatic
authorCarl Hetherington <cth@carlh.net>
Tue, 28 Aug 2018 22:26:00 +0000 (23:26 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 28 Aug 2018 22:26:00 +0000 (23:26 +0100)
src/lib/content_text.h
src/lib/player.cc
src/lib/player.h
src/lib/reel_writer.cc
src/lib/reel_writer.h
src/lib/text_decoder.cc
src/lib/text_decoder.h
src/lib/writer.cc
src/lib/writer.h
src/wx/text_panel.cc
test/closed_caption_test.cc

index 3ef011f61173eefed1902a3a6fd7ae521016772a..2d8910577926c38bd259b1e10a7a7c82c90f356d 100644 (file)
@@ -33,29 +33,23 @@ class Image;
 class ContentText
 {
 public:
-       explicit ContentText (ContentTime f, TextType t)
+       explicit ContentText (ContentTime f)
                : _from (f)
-               , _type (t)
        {}
 
        ContentTime from () const {
                return _from;
        }
 
-       TextType type () const {
-               return _type;
-       }
-
 private:
        ContentTime _from;
-       TextType _type;
 };
 
 class ContentBitmapText : public ContentText
 {
 public:
-       ContentBitmapText (ContentTime f, TextType type, boost::shared_ptr<Image> im, dcpomatic::Rect<double> r)
-               : ContentText (f, type)
+       ContentBitmapText (ContentTime f, boost::shared_ptr<Image> im, dcpomatic::Rect<double> r)
+               : ContentText (f)
                , sub (im, r)
        {}
 
@@ -70,8 +64,8 @@ public:
 class ContentStringText : public ContentText
 {
 public:
-       ContentStringText (ContentTime f, TextType type, std::list<dcp::SubtitleString> s)
-               : ContentText (f, type)
+       ContentStringText (ContentTime f, std::list<dcp::SubtitleString> s)
+               : ContentText (f)
                , subs (s)
        {}
 
index 5dfc4e66dee46483a578d6a620144af1b24efd9f..cf9bc2e63dd61a43c4e64a28d398917e8c4594a3 100644 (file)
@@ -199,7 +199,7 @@ Player::setup_pieces_unlocked ()
                                bind(&Player::plain_text_start, this, weak_ptr<Piece>(piece), weak_ptr<const TextContent>((*j)->content()), _1)
                                );
                        (*j)->Stop.connect (
-                               bind(&Player::subtitle_stop, this, weak_ptr<Piece>(piece), weak_ptr<const TextContent>((*j)->content()), _1, _2)
+                               bind(&Player::subtitle_stop, this, weak_ptr<Piece>(piece), weak_ptr<const TextContent>((*j)->content()), _1)
                                );
 
                        ++j;
@@ -917,7 +917,7 @@ Player::bitmap_text_start (weak_ptr<Piece> wp, weak_ptr<const TextContent> wc, C
        ps.bitmap.push_back (subtitle.sub);
        DCPTime from (content_time_to_dcp (piece, subtitle.from()));
 
-       _active_texts[subtitle.type()].add_from (wc, ps, from);
+       _active_texts[text->type()].add_from (wc, ps, from);
 }
 
 void
@@ -961,19 +961,23 @@ Player::plain_text_start (weak_ptr<Piece> wp, weak_ptr<const TextContent> wc, Co
                ps.add_fonts (text->fonts ());
        }
 
-       _active_texts[subtitle.type()].add_from (wc, ps, from);
+       _active_texts[text->type()].add_from (wc, ps, from);
 }
 
 void
-Player::subtitle_stop (weak_ptr<Piece> wp, weak_ptr<const TextContent> wc, ContentTime to, TextType type)
+Player::subtitle_stop (weak_ptr<Piece> wp, weak_ptr<const TextContent> wc, ContentTime to)
 {
-       if (!_active_texts[type].have (wc)) {
+       shared_ptr<const TextContent> text = wc.lock ();
+       if (!text) {
+               return;
+       }
+
+       if (!_active_texts[text->type()].have(wc)) {
                return;
        }
 
        shared_ptr<Piece> piece = wp.lock ();
-       shared_ptr<const TextContent> text = wc.lock ();
-       if (!piece || !text) {
+       if (!piece) {
                return;
        }
 
@@ -983,11 +987,11 @@ Player::subtitle_stop (weak_ptr<Piece> wp, weak_ptr<const TextContent> wc, Conte
                return;
        }
 
-       pair<PlayerText, DCPTime> from = _active_texts[type].add_to (wc, dcp_to);
+       pair<PlayerText, DCPTime> from = _active_texts[text->type()].add_to (wc, dcp_to);
 
-       bool const always = (type == TEXT_OPEN_SUBTITLE && _always_burn_open_subtitles);
+       bool const always = (text->type() == TEXT_OPEN_SUBTITLE && _always_burn_open_subtitles);
        if (text->use() && !always && !text->burn()) {
-               Text (from.first, type, DCPTimePeriod (from.second, dcp_to));
+               Text (from.first, text->type(), DCPTimePeriod (from.second, dcp_to));
        }
 }
 
index e17456cf2d87838861404484822c523e2f47612b..b4f41f6da0348198130fcfdaa8d806decd38f773 100644 (file)
@@ -127,7 +127,7 @@ private:
        void audio (boost::weak_ptr<Piece>, AudioStreamPtr, ContentAudio);
        void bitmap_text_start (boost::weak_ptr<Piece>, boost::weak_ptr<const TextContent>, ContentBitmapText);
        void plain_text_start (boost::weak_ptr<Piece>, boost::weak_ptr<const TextContent>, ContentStringText);
-       void subtitle_stop (boost::weak_ptr<Piece>, boost::weak_ptr<const TextContent>, ContentTime, TextType);
+       void subtitle_stop (boost::weak_ptr<Piece>, boost::weak_ptr<const TextContent>, ContentTime);
        DCPTime one_video_frame () const;
        void fill_audio (DCPTimePeriod period);
        std::pair<boost::shared_ptr<AudioBuffers>, DCPTime> discard_audio (
index 12e45849bfc14e2076cdb8db776dc3da52614f44..3d5264060916f5e435420dc929dd050e485a3bbf 100644 (file)
@@ -335,7 +335,7 @@ ReelWriter::finish ()
 
 template <class T>
 void
-maybe_add_captions (
+maybe_add_text (
        shared_ptr<dcp::SubtitleAsset> asset,
        int64_t picture_duration,
        shared_ptr<dcp::Reel> reel,
@@ -508,8 +508,8 @@ ReelWriter::create_reel (list<ReferencedReelAsset> const & refs, list<shared_ptr
        }
        reel->add (reel_sound_asset);
 
-       maybe_add_captions<dcp::ReelSubtitleAsset>      (_caption_asset[TEXT_OPEN_SUBTITLE],  reel_picture_asset->duration(), reel, refs, fonts, _film, _period);
-       maybe_add_captions<dcp::ReelClosedCaptionAsset> (_caption_asset[TEXT_CLOSED_CAPTION], reel_picture_asset->duration(), reel, refs, fonts, _film, _period);
+       maybe_add_text<dcp::ReelSubtitleAsset>      (_text_asset[TEXT_OPEN_SUBTITLE],  reel_picture_asset->duration(), reel, refs, fonts, _film, _period);
+       maybe_add_text<dcp::ReelClosedCaptionAsset> (_text_asset[TEXT_CLOSED_CAPTION], reel_picture_asset->duration(), reel, refs, fonts, _film, _period);
 
        return reel;
 }
@@ -547,7 +547,7 @@ ReelWriter::write (shared_ptr<const AudioBuffers> audio)
 void
 ReelWriter::write (PlayerText subs, TextType type, DCPTimePeriod period)
 {
-       if (!_caption_asset[type]) {
+       if (!_text_asset[type]) {
                string lang = _film->subtitle_language ();
                if (lang.empty ()) {
                        lang = "Unknown";
@@ -557,7 +557,7 @@ ReelWriter::write (PlayerText subs, TextType type, DCPTimePeriod period)
                        s->set_movie_title (_film->name ());
                        s->set_language (lang);
                        s->set_reel_number (raw_convert<string> (_reel_index + 1));
-                       _caption_asset[type] = s;
+                       _text_asset[type] = s;
                } else {
                        shared_ptr<dcp::SMPTESubtitleAsset> s (new dcp::SMPTESubtitleAsset ());
                        s->set_content_title_text (_film->name ());
@@ -569,7 +569,7 @@ ReelWriter::write (PlayerText subs, TextType type, DCPTimePeriod period)
                        if (_film->encrypted ()) {
                                s->set_key (_film->key ());
                        }
-                       _caption_asset[type] = s;
+                       _text_asset[type] = s;
                }
        }
 
@@ -577,11 +577,11 @@ ReelWriter::write (PlayerText subs, TextType type, DCPTimePeriod period)
                /* XXX: couldn't / shouldn't we use period here rather than getting time from the subtitle? */
                i.set_in  (i.in()  - dcp::Time (_period.from.seconds(), i.in().tcr));
                i.set_out (i.out() - dcp::Time (_period.from.seconds(), i.out().tcr));
-               _caption_asset[type]->add (shared_ptr<dcp::Subtitle>(new dcp::SubtitleString(i)));
+               _text_asset[type]->add (shared_ptr<dcp::Subtitle>(new dcp::SubtitleString(i)));
        }
 
        BOOST_FOREACH (BitmapText i, subs.bitmap) {
-               _caption_asset[type]->add (
+               _text_asset[type]->add (
                        shared_ptr<dcp::Subtitle>(
                                new dcp::SubtitleImage(
                                        i.image->as_png(),
index a46c3efa7812d80692bbd58d745ecb8db46f9ac9..2e5ad8975f16e8a780245df7e453e64ead06d075 100644 (file)
@@ -113,7 +113,7 @@ private:
        boost::shared_ptr<dcp::PictureAssetWriter> _picture_asset_writer;
        boost::shared_ptr<dcp::SoundAsset> _sound_asset;
        boost::shared_ptr<dcp::SoundAssetWriter> _sound_asset_writer;
-       boost::shared_ptr<dcp::SubtitleAsset> _caption_asset[TEXT_COUNT];
+       boost::shared_ptr<dcp::SubtitleAsset> _text_asset[TEXT_COUNT];
 
        static int const _info_size;
 };
index 3b6a06ea1744a2a5a4b0763c251a0aff94fbba35..00d58af869f0135fa45d4d00388f02d734623453 100644 (file)
@@ -60,7 +60,7 @@ TextDecoder::TextDecoder (
 void
 TextDecoder::emit_bitmap_start (ContentTime from, shared_ptr<Image> image, dcpomatic::Rect<double> rect)
 {
-       BitmapStart (ContentBitmapText (from, _content->type(), image, rect));
+       BitmapStart (ContentBitmapText (from, image, rect));
        _position = from;
 }
 
@@ -94,7 +94,7 @@ TextDecoder::emit_plain_start (ContentTime from, list<dcp::SubtitleString> s)
                }
        }
 
-       PlainStart (ContentStringText (from, _content->type(), s));
+       PlainStart (ContentStringText (from, s));
        _position = from;
 }
 
@@ -233,7 +233,7 @@ TextDecoder::emit_plain_start (ContentTime from, sub::Subtitle const & subtitle)
 void
 TextDecoder::emit_stop (ContentTime to)
 {
-       Stop (to, _content->type());
+       Stop (to);
 }
 
 void
index 25125e701ae07d5365fbe1a444ae44f507e2311f..d8a64157e9f7f96ea48456312a6818ce34cff8f0 100644 (file)
@@ -64,7 +64,7 @@ public:
 
        boost::signals2::signal<void (ContentBitmapText)> BitmapStart;
        boost::signals2::signal<void (ContentStringText)> PlainStart;
-       boost::signals2::signal<void (ContentTime, TextType)> Stop;
+       boost::signals2::signal<void (ContentTime)> Stop;
 
 private:
        boost::shared_ptr<const TextContent> _content;
index a7e3218b5326396417faf7e7b63bb207456c2024..4b5c5a1023a6cc164c70bc8a8d791e68fe501e07 100644 (file)
@@ -96,7 +96,7 @@ Writer::Writer (shared_ptr<const Film> film, weak_ptr<Job> j)
        */
        _audio_reel = _reels.begin ();
        for (int i = 0; i < TEXT_COUNT; ++i) {
-               _caption_reel[i] = _reels.begin ();
+               _text_reel[i] = _reels.begin ();
        }
 
        /* Check that the signer is OK if we need one */
@@ -667,14 +667,14 @@ Writer::can_fake_write (Frame frame) const
 void
 Writer::write (PlayerText text, TextType type, DCPTimePeriod period)
 {
-       while (_caption_reel[type]->period().to <= period.from) {
-               ++_caption_reel[type];
-               DCPOMATIC_ASSERT (_caption_reel[type] != _reels.end());
+       while (_text_reel[type]->period().to <= period.from) {
+               ++_text_reel[type];
+               DCPOMATIC_ASSERT (_text_reel[type] != _reels.end());
        }
 
-       DCPOMATIC_ASSERT (_caption_reel[type] != _reels.end());
+       DCPOMATIC_ASSERT (_text_reel[type] != _reels.end());
 
-       _caption_reel[type]->write (text, type, period);
+       _text_reel[type]->write (text, type, period);
 }
 
 void
index 8fc0ce29ebb926ee2a8e5b8b6ebdc4afdb289bda..484ca1285043073f9f2a64af74fd2c91d10244c3 100644 (file)
@@ -124,7 +124,7 @@ private:
        boost::weak_ptr<Job> _job;
        std::vector<ReelWriter> _reels;
        std::vector<ReelWriter>::iterator _audio_reel;
-       std::vector<ReelWriter>::iterator _caption_reel[TEXT_COUNT];
+       std::vector<ReelWriter>::iterator _text_reel[TEXT_COUNT];
 
        /** our thread, or 0 */
        boost::thread* _thread;
index ef604f787579671e6a5853c40197b1ed7b1d636f..164b9dd7dccbe42d2780b95d2068577ff87d1bf8 100644 (file)
@@ -210,7 +210,7 @@ TextPanel::update_dcp_track_selection ()
                ++n;
        }
 
-       if (many) {
+       if (!selected || many) {
                _dcp_track->SetSelection (wxNOT_FOUND);
        }
 }
@@ -325,6 +325,7 @@ TextPanel::film_content_changed (int property)
                        _type->SetSelection (0);
                }
                setup_sensitivity ();
+               update_dcp_track_selection ();
        } else if (property == TextContentProperty::BURN) {
                checked_set (_burn, text ? text->burn() : false);
        } else if (property == TextContentProperty::X_OFFSET) {
@@ -442,7 +443,7 @@ TextPanel::setup_sensitivity ()
        _y_scale->Enable (!reference && any_subs > 0 && use && type == TEXT_OPEN_SUBTITLE);
        _line_spacing->Enable (!reference && use && type == TEXT_OPEN_SUBTITLE);
        _dcp_track->Enable (!reference && any_subs > 0 && use && type == TEXT_CLOSED_CAPTION);
-       _language->Enable (!reference && any_subs > 0 && use);
+       _language->Enable (!reference && any_subs > 0 && use && type == TEXT_OPEN_SUBTITLE);
        _stream->Enable (!reference && ffmpeg_subs == 1);
        _text_view_button->Enable (!reference);
        _fonts_dialog_button->Enable (!reference && type == TEXT_OPEN_SUBTITLE);
index b59e6990d03ec308cdeb297e0a2540f4a831df9e..4074f8371318d7fabdb31c9c1270c8fec017da7f 100644 (file)
@@ -53,3 +53,33 @@ BOOST_AUTO_TEST_CASE (closed_caption_test1)
        BOOST_REQUIRE_EQUAL (check.cpls().front()->reels().size(), 1);
        BOOST_REQUIRE (!check.cpls().front()->reels().front()->closed_captions().empty());
 }
+
+/** Test multiple closed captions */
+BOOST_AUTO_TEST_CASE (closed_caption_test2)
+{
+       shared_ptr<Film> film = new_test_film2 ("closed_caption_test2");
+       shared_ptr<StringTextFileContent> content1 (new StringTextFileContent (film, "test/data/subrip.srt"));
+       film->examine_and_add_content (content1);
+       shared_ptr<StringTextFileContent> content2 (new StringTextFileContent (film, "test/data/subrip2.srt"));
+       film->examine_and_add_content (content2);
+       shared_ptr<StringTextFileContent> content3 (new StringTextFileContent (film, "test/data/subrip3.srt"));
+       film->examine_and_add_content (content3);
+       BOOST_REQUIRE (!wait_for_jobs ());
+
+       content1->only_text()->set_type (TEXT_CLOSED_CAPTION);
+       content1->only_text()->set_dcp_track (DCPTextTrack("First track", "French"));
+       content2->only_text()->set_type (TEXT_CLOSED_CAPTION);
+       content2->only_text()->set_dcp_track (DCPTextTrack("Second track", "German"));
+       content3->only_text()->set_type (TEXT_CLOSED_CAPTION);
+       content3->only_text()->set_dcp_track (DCPTextTrack("Third track", "Italian"));
+
+       film->make_dcp ();
+       BOOST_REQUIRE (!wait_for_jobs ());
+
+       dcp::DCP check (film->dir(film->dcp_name()));
+       check.read ();
+
+       BOOST_REQUIRE_EQUAL (check.cpls().size(), 1);
+       BOOST_REQUIRE_EQUAL (check.cpls().front()->reels().size(), 1);
+       BOOST_REQUIRE_EQUAL (!check.cpls().front()->reels().front()->closed_captions().size(), 3);
+}