Basics of splitting CCAP streams into different assets.
authorCarl Hetherington <cth@carlh.net>
Tue, 28 Aug 2018 22:34:56 +0000 (23:34 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 29 Aug 2018 10:58:06 +0000 (11:58 +0100)
20 files changed:
src/lib/butler.cc
src/lib/butler.h
src/lib/dcp_encoder.cc
src/lib/dcp_encoder.h
src/lib/dcp_text_track.cc
src/lib/dcp_text_track.h
src/lib/hints.cc
src/lib/hints.h
src/lib/player.cc
src/lib/player.h
src/lib/reel_writer.cc
src/lib/reel_writer.h
src/lib/text_ring_buffers.cc
src/lib/text_ring_buffers.h
src/lib/writer.cc
src/lib/writer.h
src/wx/closed_captions_dialog.cc
src/wx/closed_captions_dialog.h
test/closed_caption_test.cc
test/player_test.cc

index de9ed4ed0d9e43f0a0de0a62a327d9d072e8f440..a127ee9bdeeff61428e19663d7a2c36f875f5288 100644 (file)
@@ -64,7 +64,7 @@ Butler::Butler (shared_ptr<Player> player, shared_ptr<Log> log, AudioMapping aud
 {
        _player_video_connection = _player->Video.connect (bind (&Butler::video, this, _1, _2));
        _player_audio_connection = _player->Audio.connect (bind (&Butler::audio, this, _1, _2));
-       _player_text_connection = _player->Text.connect (bind (&Butler::text, this, _1, _2, _3));
+       _player_text_connection = _player->Text.connect (bind (&Butler::text, this, _1, _2, _3, _4));
        /* The butler must here about things first, otherwise it might not sort out suspensions in time for
           get_video() to be called in response to this signal.
        */
@@ -208,7 +208,7 @@ Butler::get_video ()
        return r;
 }
 
-optional<pair<PlayerText, DCPTimePeriod> >
+optional<TextRingBuffers::Data>
 Butler::get_closed_caption ()
 {
        boost::mutex::scoped_lock lm (_mutex);
@@ -349,12 +349,14 @@ Butler::player_change (ChangeType type, bool frequent)
 }
 
 void
-Butler::text (PlayerText pt, TextType type, DCPTimePeriod period)
+Butler::text (PlayerText pt, TextType type, optional<DCPTextTrack> track, DCPTimePeriod period)
 {
        if (type != TEXT_CLOSED_CAPTION) {
                return;
        }
 
+       DCPOMATIC_ASSERT (track);
+
        boost::mutex::scoped_lock lm2 (_buffers_mutex);
-       _closed_caption.put (make_pair(pt, period));
+       _closed_caption.put (pt, *track, period);
 }
index b10c93e7984c5a581615d73ac6ab959a86074c1c..4322c401dc1b62824470c8a0d7df0aeaf35a3ecf 100644 (file)
@@ -43,7 +43,7 @@ public:
        void seek (DCPTime position, bool accurate);
        std::pair<boost::shared_ptr<PlayerVideo>, DCPTime> get_video ();
        boost::optional<DCPTime> get_audio (float* out, Frame frames);
-       boost::optional<std::pair<PlayerText, DCPTimePeriod> > get_closed_caption ();
+       boost::optional<TextRingBuffers::Data> get_closed_caption ();
 
        void disable_audio ();
 
@@ -53,7 +53,7 @@ private:
        void thread ();
        void video (boost::shared_ptr<PlayerVideo> video, DCPTime time);
        void audio (boost::shared_ptr<AudioBuffers> audio, DCPTime time);
-       void text (PlayerText pt, TextType type, DCPTimePeriod period);
+       void text (PlayerText pt, TextType type, boost::optional<DCPTextTrack> track, DCPTimePeriod period);
        bool should_run () const;
        void prepare (boost::weak_ptr<PlayerVideo> video) const;
        void player_change (ChangeType type, bool frequent);
index 7fbbb2c635f6935f196d283a68f292a6d8990050..50a8fd927264eecf385a0c208ab2171dc14ecaa3 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -49,6 +49,7 @@ using std::list;
 using boost::shared_ptr;
 using boost::weak_ptr;
 using boost::dynamic_pointer_cast;
+using boost::optional;
 
 /** Construct a DCP encoder.
  *  @param film Film that we are encoding.
@@ -61,7 +62,7 @@ DCPEncoder::DCPEncoder (shared_ptr<const Film> film, weak_ptr<Job> job)
 {
        _player_video_connection = _player->Video.connect (bind (&DCPEncoder::video, this, _1, _2));
        _player_audio_connection = _player->Audio.connect (bind (&DCPEncoder::audio, this, _1, _2));
-       _player_text_connection = _player->Text.connect (bind (&DCPEncoder::text, this, _1, _2, _3));
+       _player_text_connection = _player->Text.connect (bind (&DCPEncoder::text, this, _1, _2, _3, _4));
 
        BOOST_FOREACH (shared_ptr<const Content> c, film->content ()) {
                BOOST_FOREACH (shared_ptr<TextContent> i, c->text) {
@@ -143,10 +144,10 @@ DCPEncoder::audio (shared_ptr<AudioBuffers> data, DCPTime time)
 }
 
 void
-DCPEncoder::text (PlayerText data, TextType type, DCPTimePeriod period)
+DCPEncoder::text (PlayerText data, TextType type, optional<DCPTextTrack> track, DCPTimePeriod period)
 {
        if (type == TEXT_CLOSED_CAPTION || _non_burnt_subtitles) {
-               _writer->write (data, type, period);
+               _writer->write (data, type, track, period);
        }
 }
 
index 8a2ad947dcc95d3f391d878f7ef18cad0a9ed2e6..3ccd5695eea0c30ffe90cd9ff8e1641dc36b3362 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "types.h"
 #include "player_text.h"
+#include "dcp_text_track.h"
 #include "encoder.h"
 #include <boost/weak_ptr.hpp>
 
@@ -52,7 +53,7 @@ private:
 
        void video (boost::shared_ptr<PlayerVideo>, DCPTime);
        void audio (boost::shared_ptr<AudioBuffers>, DCPTime);
-       void text (PlayerText, TextType, DCPTimePeriod);
+       void text (PlayerText, TextType, boost::optional<DCPTextTrack>, DCPTimePeriod);
 
        boost::shared_ptr<Writer> _writer;
        boost::shared_ptr<J2KEncoder> _j2k_encoder;
index 2d3d9fe10d81539b74892787df333a41b9a6c74a..1c73870aa6c37ffd88b6ee00f8f3f8967d93e056 100644 (file)
@@ -61,3 +61,13 @@ operator!= (DCPTextTrack const & a, DCPTextTrack const & b)
 {
        return !(a == b);
 }
+
+bool
+operator< (DCPTextTrack const & a, DCPTextTrack const & b)
+{
+       if (a.name != b.name) {
+               return a.name < b.name;
+       }
+
+       return a.language < b.language;
+}
index d69e6dae9208d73d6b6504f8784f6931c31cefc0..913e77fa59cdb08f0500ebdf862a6dc2df8a4a88 100644 (file)
@@ -27,6 +27,7 @@
 class DCPTextTrack
 {
 public:
+       DCPTextTrack () {}
        DCPTextTrack (cxml::ConstNodePtr node);
        DCPTextTrack (std::string name_, std::string language_);
 
@@ -39,5 +40,6 @@ public:
 
 bool operator== (DCPTextTrack const & a, DCPTextTrack const & b);
 bool operator!= (DCPTextTrack const & a, DCPTextTrack const & b);
+bool operator< (DCPTextTrack const & a, DCPTextTrack const & b);
 
 #endif
index 8979b6b4ce3941a95f3e0ace2f69298866c6738b..f2e13f5033331a3a147817bdf89495adaf46b585 100644 (file)
@@ -266,7 +266,7 @@ Hints::thread ()
        shared_ptr<Player> player (new Player (film, film->playlist ()));
        player->set_ignore_video ();
        player->set_ignore_audio ();
-       player->Text.connect (bind(&Hints::text, this, _1, _2, _3));
+       player->Text.connect (bind(&Hints::text, this, _1, _2, _3, _4));
        while (!player->pass ()) {
                bind (boost::ref(Pulse));
        }
@@ -281,7 +281,7 @@ Hints::hint (string h)
 }
 
 void
-Hints::text (PlayerText text, TextType type, DCPTimePeriod period)
+Hints::text (PlayerText text, TextType type, optional<DCPTextTrack> track, DCPTimePeriod period)
 {
        if (type != TEXT_CLOSED_CAPTION) {
                return;
index 67cada89f49bee1e58b9489e5b032e64815eff2f..9da0612861a27ecd866a01491a2c2dcf5cce25e9 100644 (file)
@@ -21,6 +21,7 @@
 #include "signaller.h"
 #include "player_text.h"
 #include "types.h"
+#include "dcp_text_track.h"
 #include "dcpomatic_time.h"
 #include <boost/weak_ptr.hpp>
 #include <boost/signals2.hpp>
@@ -46,7 +47,7 @@ private:
        void thread ();
        void stop_thread ();
        void hint (std::string h);
-       void text (PlayerText text, TextType type, DCPTimePeriod period);
+       void text (PlayerText text, TextType type, boost::optional<DCPTextTrack> track, DCPTimePeriod period);
 
        boost::weak_ptr<const Film> _film;
        boost::thread* _thread;
index cf9bc2e63dd61a43c4e64a28d398917e8c4594a3..5202bbbe0ff190f6d0a8f4cf682eb1d522a8eb63 100644 (file)
@@ -991,7 +991,7 @@ Player::subtitle_stop (weak_ptr<Piece> wp, weak_ptr<const TextContent> wc, Conte
 
        bool const always = (text->type() == TEXT_OPEN_SUBTITLE && _always_burn_open_subtitles);
        if (text->use() && !always && !text->burn()) {
-               Text (from.first, text->type(), DCPTimePeriod (from.second, dcp_to));
+               Text (from.first, text->type(), text->dcp_track().get_value_or(DCPTextTrack()), DCPTimePeriod (from.second, dcp_to));
        }
 }
 
index b4f41f6da0348198130fcfdaa8d806decd38f773..70a2e4ae36614c8e42216fb0221735d7c0193ee1 100644 (file)
@@ -99,7 +99,7 @@ public:
        /** Emitted when a text is ready.  This signal may be emitted considerably
         *  after the corresponding Video.
         */
-       boost::signals2::signal<void (PlayerText, TextType, DCPTimePeriod)> Text;
+       boost::signals2::signal<void (PlayerText, TextType, boost::optional<DCPTextTrack>, DCPTimePeriod)> Text;
 
 private:
        friend class PlayerWrapper;
index 3d5264060916f5e435420dc929dd050e485a3bbf..7b0233d21e1a407ffe416231905a5bcb60cbbb9a 100644 (file)
@@ -57,6 +57,7 @@
 using std::list;
 using std::string;
 using std::cout;
+using std::map;
 using boost::shared_ptr;
 using boost::optional;
 using boost::dynamic_pointer_cast;
@@ -350,7 +351,6 @@ maybe_add_text (
        shared_ptr<T> reel_asset;
 
        if (asset) {
-
                boost::filesystem::path liberation_normal;
                try {
                        liberation_normal = shared_path() / "LiberationSans-Regular.ttf";
@@ -376,7 +376,6 @@ maybe_add_text (
                        boost::filesystem::create_directories (directory);
                        asset->write (directory / ("sub_" + asset->id() + ".xml"));
                } else {
-
                        /* All our assets should be the same length; use the picture asset length here
                           as a reference to set the subtitle one.  We'll use the duration rather than
                           the intrinsic duration; we don't care if the picture asset has been trimmed, we're
@@ -508,8 +507,10 @@ ReelWriter::create_reel (list<ReferencedReelAsset> const & refs, list<shared_ptr
        }
        reel->add (reel_sound_asset);
 
-       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);
+       maybe_add_text<dcp::ReelSubtitleAsset> (_subtitle_asset,  reel_picture_asset->duration(), reel, refs, fonts, _film, _period);
+       for (map<DCPTextTrack, shared_ptr<dcp::SubtitleAsset> >::const_iterator i = _closed_caption_assets.begin(); i != _closed_caption_assets.end(); ++i) {
+               maybe_add_text<dcp::ReelClosedCaptionAsset> (i->second, reel_picture_asset->duration(), reel, refs, fonts, _film, _period);
+       }
 
        return reel;
 }
@@ -545,9 +546,23 @@ ReelWriter::write (shared_ptr<const AudioBuffers> audio)
 }
 
 void
-ReelWriter::write (PlayerText subs, TextType type, DCPTimePeriod period)
+ReelWriter::write (PlayerText subs, TextType type, optional<DCPTextTrack> track, DCPTimePeriod period)
 {
-       if (!_text_asset[type]) {
+       shared_ptr<dcp::SubtitleAsset> asset;
+
+       switch (type) {
+       case TEXT_OPEN_SUBTITLE:
+               asset = _subtitle_asset;
+               break;
+       case TEXT_CLOSED_CAPTION:
+               DCPOMATIC_ASSERT (track);
+               asset = _closed_caption_assets[*track];
+               break;
+       default:
+               DCPOMATIC_ASSERT (false);
+       }
+
+       if (!asset) {
                string lang = _film->subtitle_language ();
                if (lang.empty ()) {
                        lang = "Unknown";
@@ -557,7 +572,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));
-                       _text_asset[type] = s;
+                       asset = s;
                } else {
                        shared_ptr<dcp::SMPTESubtitleAsset> s (new dcp::SMPTESubtitleAsset ());
                        s->set_content_title_text (_film->name ());
@@ -569,19 +584,31 @@ ReelWriter::write (PlayerText subs, TextType type, DCPTimePeriod period)
                        if (_film->encrypted ()) {
                                s->set_key (_film->key ());
                        }
-                       _text_asset[type] = s;
+                       asset = s;
                }
        }
 
+       switch (type) {
+       case TEXT_OPEN_SUBTITLE:
+               _subtitle_asset = asset;
+               break;
+       case TEXT_CLOSED_CAPTION:
+               DCPOMATIC_ASSERT (track);
+               _closed_caption_assets[*track] = asset;
+               break;
+       default:
+               DCPOMATIC_ASSERT (false);
+       }
+
        BOOST_FOREACH (StringText i, subs.string) {
                /* 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));
-               _text_asset[type]->add (shared_ptr<dcp::Subtitle>(new dcp::SubtitleString(i)));
+               asset->add (shared_ptr<dcp::Subtitle>(new dcp::SubtitleString(i)));
        }
 
        BOOST_FOREACH (BitmapText i, subs.bitmap) {
-               _text_asset[type]->add (
+               asset->add (
                        shared_ptr<dcp::Subtitle>(
                                new dcp::SubtitleImage(
                                        i.image->as_png(),
index 2e5ad8975f16e8a780245df7e453e64ead06d075..ae64c3ac77ed9c73bd6f4f6939c9f5c6710548cf 100644 (file)
@@ -22,6 +22,7 @@
 #include "dcpomatic_time.h"
 #include "referenced_reel_asset.h"
 #include "player_text.h"
+#include "dcp_text_track.h"
 #include <dcp/picture_asset_writer.h>
 #include <boost/shared_ptr.hpp>
 
@@ -60,7 +61,7 @@ public:
        void fake_write (Frame frame, Eyes eyes, int size);
        void repeat_write (Frame frame, Eyes eyes);
        void write (boost::shared_ptr<const AudioBuffers> audio);
-       void write (PlayerText text, TextType type, DCPTimePeriod period);
+       void write (PlayerText text, TextType type, boost::optional<DCPTextTrack> track, DCPTimePeriod period);
 
        void finish ();
        boost::shared_ptr<dcp::Reel> create_reel (std::list<ReferencedReelAsset> const & refs, std::list<boost::shared_ptr<Font> > const & fonts);
@@ -113,7 +114,8 @@ 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> _text_asset[TEXT_COUNT];
+       boost::shared_ptr<dcp::SubtitleAsset> _subtitle_asset;
+       std::map<DCPTextTrack, boost::shared_ptr<dcp::SubtitleAsset> > _closed_caption_assets;
 
        static int const _info_size;
 };
index 3586ab648db074a9f10ee1e91479667da478bd24..cc5357804bb0eccfccede815f9c8105f90bc4643 100644 (file)
@@ -24,21 +24,21 @@ using std::pair;
 using boost::optional;
 
 void
-TextRingBuffers::put (pair<PlayerText, DCPTimePeriod> text)
+TextRingBuffers::put (PlayerText text, DCPTextTrack track, DCPTimePeriod period)
 {
        boost::mutex::scoped_lock lm (_mutex);
-       _data.push_back (text);
+       _data.push_back (Data(text, track, period));
 }
 
-optional<pair<PlayerText, DCPTimePeriod> >
+optional<TextRingBuffers::Data>
 TextRingBuffers::get ()
 {
        boost::mutex::scoped_lock lm (_mutex);
        if (_data.empty ()) {
-               return pair<PlayerText, DCPTimePeriod>();
+               return optional<Data>();
        }
 
-       pair<PlayerText, DCPTimePeriod> r = _data.front ();
+       Data r = _data.front ();
        _data.pop_front ();
        return r;
 }
index e33d9be3b14fbbcd9ce14ce55555bf9b8de36ae6..289a38149146c2f27fae90f98f42e9980de41504 100644 (file)
 
 */
 
+#ifndef DCPOMATIC_TEXT_RING_BUFFERS_H
+#define DCPOMATIC_TEXT_RING_BUFFERS_H
+
 #include "player_text.h"
+#include "dcp_text_track.h"
 #include <boost/thread.hpp>
 #include <utility>
 
 class TextRingBuffers
 {
 public:
-       void put (std::pair<PlayerText, DCPTimePeriod> text);
-       boost::optional<std::pair<PlayerText, DCPTimePeriod> > get ();
+       void put (PlayerText text, DCPTextTrack track, DCPTimePeriod period);
+
+       struct Data {
+               Data (PlayerText text_, DCPTextTrack track_, DCPTimePeriod period_)
+                       : text (text_)
+                       , track (track_)
+                       , period (period_)
+               {}
+
+               PlayerText text;
+               DCPTextTrack track;
+               DCPTimePeriod period;
+       };
+
+       boost::optional<Data> get ();
        void clear ();
 
 private:
        boost::mutex _mutex;
-       std::list<std::pair<PlayerText, DCPTimePeriod> > _data;
+
+       std::list<Data> _data;
 };
+
+#endif
index 4b5c5a1023a6cc164c70bc8a8d791e68fe501e07..8e2079aebfdad8c17382ac1953ebf49985e72bd2 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -63,9 +63,11 @@ using std::cout;
 using std::map;
 using std::min;
 using std::max;
+using std::vector;
 using boost::shared_ptr;
 using boost::weak_ptr;
 using boost::dynamic_pointer_cast;
+using boost::optional;
 using dcp::Data;
 
 Writer::Writer (shared_ptr<const Film> film, weak_ptr<Job> j)
@@ -95,8 +97,9 @@ Writer::Writer (shared_ptr<const Film> film, weak_ptr<Job> j)
           and captions arrive to the Writer in sequence.  This is not so for video.
        */
        _audio_reel = _reels.begin ();
-       for (int i = 0; i < TEXT_COUNT; ++i) {
-               _text_reel[i] = _reels.begin ();
+       _subtitle_reel = _reels.begin ();
+       BOOST_FOREACH (DCPTextTrack i, _film->closed_caption_tracks()) {
+               _caption_reels[i] = _reels.begin ();
        }
 
        /* Check that the signer is OK if we need one */
@@ -664,17 +667,29 @@ Writer::can_fake_write (Frame frame) const
        return (frame != 0 && frame < reel.first_nonexistant_frame());
 }
 
+/** @param track Closed caption track if type == TEXT_CLOSED_CAPTION */
 void
-Writer::write (PlayerText text, TextType type, DCPTimePeriod period)
+Writer::write (PlayerText text, TextType type, optional<DCPTextTrack> track, DCPTimePeriod period)
 {
-       while (_text_reel[type]->period().to <= period.from) {
-               ++_text_reel[type];
-               DCPOMATIC_ASSERT (_text_reel[type] != _reels.end());
+       vector<ReelWriter>::iterator* reel = 0;
+
+       switch (type) {
+       case TEXT_OPEN_SUBTITLE:
+               reel = &_subtitle_reel;
+               break;
+       case TEXT_CLOSED_CAPTION:
+               reel = &_caption_reels[*track];
+               break;
+       default:
+               DCPOMATIC_ASSERT (false);
        }
 
-       DCPOMATIC_ASSERT (_text_reel[type] != _reels.end());
+       while ((*reel)->period().to <= period.from) {
+               ++(*reel);
+               DCPOMATIC_ASSERT (*reel != _reels.end());
+       }
 
-       _text_reel[type]->write (text, type, period);
+       (*reel)->write (text, type, track, period);
 }
 
 void
index 484ca1285043073f9f2a64af74fd2c91d10244c3..e08e9f28d0d19e06d51fcd1e2d2baab4203c68d8 100644 (file)
@@ -25,6 +25,7 @@
 #include "types.h"
 #include "player_text.h"
 #include "exception_store.h"
+#include "dcp_text_track.h"
 #include <boost/shared_ptr.hpp>
 #include <boost/weak_ptr.hpp>
 #include <boost/thread.hpp>
@@ -104,7 +105,7 @@ public:
        bool can_repeat (Frame) const;
        void repeat (Frame, Eyes);
        void write (boost::shared_ptr<const AudioBuffers>, DCPTime time);
-       void write (PlayerText text, TextType type, DCPTimePeriod period);
+       void write (PlayerText text, TextType type, boost::optional<DCPTextTrack>, DCPTimePeriod period);
        void write (std::list<boost::shared_ptr<Font> > fonts);
        void write (ReferencedReelAsset asset);
        void finish ();
@@ -124,7 +125,8 @@ private:
        boost::weak_ptr<Job> _job;
        std::vector<ReelWriter> _reels;
        std::vector<ReelWriter>::iterator _audio_reel;
-       std::vector<ReelWriter>::iterator _text_reel[TEXT_COUNT];
+       std::vector<ReelWriter>::iterator _subtitle_reel;
+       std::map<DCPTextTrack, std::vector<ReelWriter>::iterator> _caption_reels;
 
        /** our thread, or 0 */
        boost::thread* _thread;
index 3f444f9a4b14b5605fa9e51e41bb532ca093860a..b81414bed9f72b37a0e638cf6545a19440685fae 100644 (file)
@@ -104,18 +104,18 @@ private:
 void
 ClosedCaptionsDialog::update (DCPTime time)
 {
-       if (_current_in_lines && _current->second.to > time) {
+       if (_current_in_lines && _current->period.to > time) {
                /* Current one is fine */
                return;
        }
 
-       if (_current && _current->second.to < time) {
+       if (_current && _current->period.to < time) {
                /* Current one has finished; clear out */
                for (int j = 0; j < CLOSED_CAPTION_LINES; ++j) {
                        _lines[j] = "";
                }
                Refresh ();
-               _current = optional<pair<PlayerText, DCPTimePeriod> >();
+               _current = optional<TextRingBuffers::Data>();
        }
 
        if (!_current) {
@@ -126,10 +126,10 @@ ClosedCaptionsDialog::update (DCPTime time)
                _current_in_lines = false;
        }
 
-       if (_current && _current->second.contains(time)) {
+       if (_current && _current->period.contains(time)) {
                /* We need to set this new one up */
 
-               list<StringText> to_show = _current->first.string;
+               list<StringText> to_show = _current->text.string;
 
                for (int j = 0; j < CLOSED_CAPTION_LINES; ++j) {
                        _lines[j] = "";
@@ -153,7 +153,7 @@ ClosedCaptionsDialog::update (DCPTime time)
 void
 ClosedCaptionsDialog::clear ()
 {
-       _current = optional<pair<PlayerText, DCPTimePeriod> >();
+       _current = optional<TextRingBuffers::Data>();
        _current_in_lines = false;
        Refresh ();
 }
index 3da7f65225b7fc5330c928036c6bdbe9c8f387b3..3818e38124d9a583a6f7e51dc4ed73abd8b5557c 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "lib/dcpomatic_time.h"
 #include "lib/player.h"
+#include "lib/text_ring_buffers.h"
 #include <wx/wx.h>
 
 class Butler;
@@ -36,7 +37,7 @@ public:
 private:
        void paint ();
 
-       boost::optional<std::pair<PlayerText, DCPTimePeriod> > _current;
+       boost::optional<TextRingBuffers::Data> _current;
        bool _current_in_lines;
        std::vector<wxString> _lines;
        boost::weak_ptr<Butler> _butler;
index 4074f8371318d7fabdb31c9c1270c8fec017da7f..35abf1b02c5a14f5d80f8815329967f7588d1a0a 100644 (file)
@@ -81,5 +81,6 @@ BOOST_AUTO_TEST_CASE (closed_caption_test2)
 
        BOOST_REQUIRE_EQUAL (check.cpls().size(), 1);
        BOOST_REQUIRE_EQUAL (check.cpls().front()->reels().size(), 1);
+       std::cout << !check.cpls().front()->reels().front()->closed_captions().size() << "\n";
        BOOST_REQUIRE_EQUAL (!check.cpls().front()->reels().front()->closed_captions().size(), 3);
 }
index 605f3bddd1a0fc9207c24a7e5c0ef03064cfa316..0fe1d953bead375b410acebc4720b206565aca25 100644 (file)
@@ -286,15 +286,17 @@ BOOST_AUTO_TEST_CASE (player_trim_test)
 struct Sub {
        PlayerText text;
        TextType type;
+       optional<DCPTextTrack> track;
        DCPTimePeriod period;
 };
 
 static void
-store (list<Sub>* out, PlayerText text, TextType type, DCPTimePeriod period)
+store (list<Sub>* out, PlayerText text, TextType type, optional<DCPTextTrack> track, DCPTimePeriod period)
 {
        Sub s;
        s.text = text;
        s.type = type;
+       s.track = track;
        s.period = period;
        out->push_back (s);
 }
@@ -316,7 +318,7 @@ BOOST_AUTO_TEST_CASE (player_ignore_video_and_audio_test)
        player->set_ignore_audio ();
 
        list<Sub> out;
-       player->Text.connect (bind (&store, &out, _1, _2, _3));
+       player->Text.connect (bind (&store, &out, _1, _2, _3, _4));
        while (!player->pass ()) {}
 
        BOOST_CHECK_EQUAL (out.size(), 6);