From d342a1befa88cb3f23c7e3fccfd1edaeea968fed Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 22 May 2014 14:57:56 +0100 Subject: [PATCH] Add ContentTimePeriod class. --- src/lib/content_subtitle.cc | 17 ++++++----------- src/lib/content_subtitle.h | 22 +++++++--------------- src/lib/dcpomatic_time.h | 13 +++++++++++++ src/lib/ffmpeg_decoder.cc | 14 +++++++------- src/lib/player.cc | 4 ++-- src/lib/subtitle_decoder.cc | 22 +++++++++++----------- src/lib/subtitle_decoder.h | 8 ++++---- src/wx/subtitle_view.cc | 2 +- test/subrip_test.cc | 6 +++++- 9 files changed, 56 insertions(+), 52 deletions(-) diff --git a/src/lib/content_subtitle.cc b/src/lib/content_subtitle.cc index 11873afee..93e0677bb 100644 --- a/src/lib/content_subtitle.cc +++ b/src/lib/content_subtitle.cc @@ -19,18 +19,13 @@ #include "content_subtitle.h" -ContentTime -ContentTextSubtitle::from () const +ContentTimePeriod +ContentTextSubtitle::period () const { /* XXX: assuming we have some subs and they are all at the same time */ assert (!subs.empty ()); - return ContentTime::from_seconds (double (subs.front().in().to_ticks()) / 250); -} - -ContentTime -ContentTextSubtitle::to () const -{ - /* XXX: assuming we have some subs and they are all at the same time */ - assert (!subs.empty ()); - return ContentTime::from_seconds (double (subs.front().out().to_ticks()) / 250); + return ContentTimePeriod ( + ContentTime::from_seconds (double (subs.front().in().to_ticks()) / 250), + ContentTime::from_seconds (double (subs.front().out().to_ticks()) / 250) + ); } diff --git a/src/lib/content_subtitle.h b/src/lib/content_subtitle.h index 8c266f483..6a28c37bf 100644 --- a/src/lib/content_subtitle.h +++ b/src/lib/content_subtitle.h @@ -30,34 +30,27 @@ class Image; class ContentSubtitle { public: - virtual ContentTime from () const = 0; - virtual ContentTime to () const = 0; + virtual ContentTimePeriod period () const = 0; }; class ContentImageSubtitle : public ContentSubtitle { public: - ContentImageSubtitle (ContentTime f, ContentTime t, boost::shared_ptr im, dcpomatic::Rect r) + ContentImageSubtitle (ContentTimePeriod p, boost::shared_ptr im, dcpomatic::Rect r) : image (im) , rectangle (r) - , _from (f) - , _to (t) + , _period (p) {} - ContentTime from () const { - return _from; + ContentTimePeriod period () const { + return _period; } - ContentTime to () const { - return _to; - } - boost::shared_ptr image; dcpomatic::Rect rectangle; private: - ContentTime _from; - ContentTime _to; + ContentTimePeriod _period; }; class ContentTextSubtitle : public ContentSubtitle @@ -67,8 +60,7 @@ public: : subs (s) {} - ContentTime from () const; - ContentTime to () const; + ContentTimePeriod period () const; std::list subs; }; diff --git a/src/lib/dcpomatic_time.h b/src/lib/dcpomatic_time.h index 109dc9b7f..e56f58c4b 100644 --- a/src/lib/dcpomatic_time.h +++ b/src/lib/dcpomatic_time.h @@ -146,6 +146,19 @@ public: std::ostream& operator<< (std::ostream& s, ContentTime t); +class ContentTimePeriod +{ +public: + ContentTimePeriod () {} + ContentTimePeriod (ContentTime f, ContentTime t) + : from (f) + , to (t) + {} + + ContentTime from; + ContentTime to; +}; + class DCPTime : public Time { public: diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 9548eaae9..eec70501a 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -535,7 +535,7 @@ FFmpegDecoder::decode_subtitle_packet () indicate that the previous subtitle should stop. */ if (sub.num_rects <= 0) { - image_subtitle (ContentTime (), ContentTime (), shared_ptr (), dcpomatic::Rect ()); + image_subtitle (ContentTimePeriod (), shared_ptr (), dcpomatic::Rect ()); return; } else if (sub.num_rects > 1) { throw DecodeError (_("multi-part subtitles not yet supported")); @@ -545,10 +545,11 @@ FFmpegDecoder::decode_subtitle_packet () source that we may have chopped off for the DCP) */ ContentTime packet_time = ContentTime::from_seconds (static_cast (sub.pts) / AV_TIME_BASE) + _pts_offset; - - /* hence start time for this sub */ - ContentTime const from = packet_time + ContentTime::from_seconds (sub.start_display_time / 1e3); - ContentTime const to = packet_time + ContentTime::from_seconds (sub.end_display_time / 1e3); + + ContentTimePeriod period ( + packet_time + ContentTime::from_seconds (sub.start_display_time / 1e3), + packet_time + ContentTime::from_seconds (sub.end_display_time / 1e3) + ); AVSubtitleRect const * rect = sub.rects[0]; @@ -586,8 +587,7 @@ FFmpegDecoder::decode_subtitle_packet () dcp::Size const vs = _ffmpeg_content->video_size (); image_subtitle ( - from, - to, + period, image, dcpomatic::Rect ( static_cast (rect->x) / vs.width, diff --git a/src/lib/player.cc b/src/lib/player.cc index 4865073d7..b60dd8467 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -337,7 +337,7 @@ Player::content_to_player_video_frame ( ContentTime const from = dcp_to_content_subtitle (*i, time); ContentTime const to = from + ContentTime::from_frames (1, content->video_frame_rate ()); - list > image_subtitles = subtitle_decoder->get_image_subtitles (from, to); + list > image_subtitles = subtitle_decoder->get_image_subtitles (ContentTimePeriod (from, to)); if (!image_subtitles.empty ()) { list im = process_content_image_subtitles ( subtitle_content, @@ -348,7 +348,7 @@ Player::content_to_player_video_frame ( } if (_burn_subtitles) { - list > text_subtitles = subtitle_decoder->get_text_subtitles (from, to); + list > text_subtitles = subtitle_decoder->get_text_subtitles (ContentTimePeriod (from, to)); if (!text_subtitles.empty ()) { list im = process_content_text_subtitles (text_subtitles); copy (im.begin(), im.end(), back_inserter (sub_images)); diff --git a/src/lib/subtitle_decoder.cc b/src/lib/subtitle_decoder.cc index 0f5a1992c..d114df979 100644 --- a/src/lib/subtitle_decoder.cc +++ b/src/lib/subtitle_decoder.cc @@ -34,9 +34,9 @@ SubtitleDecoder::SubtitleDecoder () * Image may be 0 to say that there is no current subtitle. */ void -SubtitleDecoder::image_subtitle (ContentTime from, ContentTime to, shared_ptr image, dcpomatic::Rect rect) +SubtitleDecoder::image_subtitle (ContentTimePeriod period, shared_ptr image, dcpomatic::Rect rect) { - _decoded_image_subtitles.push_back (shared_ptr (new ContentImageSubtitle (from, to, image, rect))); + _decoded_image_subtitles.push_back (shared_ptr (new ContentImageSubtitle (period, image, rect))); } void @@ -47,11 +47,11 @@ SubtitleDecoder::text_subtitle (list s) template list > -SubtitleDecoder::get (list > const & subs, ContentTime from, ContentTime to) +SubtitleDecoder::get (list > const & subs, ContentTimePeriod period) { - if (subs.empty() || from < subs.front()->from() || to > (subs.back()->to() + ContentTime::from_seconds (10))) { + if (subs.empty() || period.from < subs.front()->period().from || period.to > (subs.back()->period().to + ContentTime::from_seconds (10))) { /* Either we have no decoded data, or what we do have is a long way from what we want: seek */ - seek (from, true); + seek (period.from, true); } /* Now enough pass() calls will either: @@ -60,14 +60,14 @@ SubtitleDecoder::get (list > const & subs, ContentTime from, Conte * * XXX: with subs being sparse, this may need more care... */ - while (!pass() && (subs.empty() || (subs.front()->from() > from || to < subs.back()->to()))) {} + while (!pass() && (subs.empty() || (subs.front()->period().from > period.from || period.to < subs.back()->period().to))) {} /* Now look for what we wanted in the data we have collected */ /* XXX: inefficient */ list > out; for (typename list >::const_iterator i = subs.begin(); i != subs.end(); ++i) { - if ((*i)->from() <= to && (*i)->to() >= from) { + if ((*i)->period().from <= period.to && (*i)->period().to >= period.from) { out.push_back (*i); } } @@ -76,15 +76,15 @@ SubtitleDecoder::get (list > const & subs, ContentTime from, Conte } list > -SubtitleDecoder::get_text_subtitles (ContentTime from, ContentTime to) +SubtitleDecoder::get_text_subtitles (ContentTimePeriod period) { - return get (_decoded_text_subtitles, from, to); + return get (_decoded_text_subtitles, period); } list > -SubtitleDecoder::get_image_subtitles (ContentTime from, ContentTime to) +SubtitleDecoder::get_image_subtitles (ContentTimePeriod period) { - return get (_decoded_image_subtitles, from, to); + return get (_decoded_image_subtitles, period); } void diff --git a/src/lib/subtitle_decoder.h b/src/lib/subtitle_decoder.h index a26348ee6..fea4ab973 100644 --- a/src/lib/subtitle_decoder.h +++ b/src/lib/subtitle_decoder.h @@ -35,13 +35,13 @@ class SubtitleDecoder : public virtual Decoder public: SubtitleDecoder (); - std::list > get_image_subtitles (ContentTime from, ContentTime to); - std::list > get_text_subtitles (ContentTime from, ContentTime to); + std::list > get_image_subtitles (ContentTimePeriod period); + std::list > get_text_subtitles (ContentTimePeriod period); protected: void seek (ContentTime, bool); - void image_subtitle (ContentTime from, ContentTime to, boost::shared_ptr, dcpomatic::Rect); + void image_subtitle (ContentTimePeriod period, boost::shared_ptr, dcpomatic::Rect); void text_subtitle (std::list); std::list > _decoded_image_subtitles; @@ -49,7 +49,7 @@ protected: private: template - std::list > get (std::list > const & subs, ContentTime from, ContentTime to); + std::list > get (std::list > const & subs, ContentTimePeriod period); }; #endif diff --git a/src/wx/subtitle_view.cc b/src/wx/subtitle_view.cc index adbc4a625..d14f260c9 100644 --- a/src/wx/subtitle_view.cc +++ b/src/wx/subtitle_view.cc @@ -63,7 +63,7 @@ SubtitleView::SubtitleView (wxWindow* parent, shared_ptr content) } shared_ptr decoder (new SubRipDecoder (content)); - list > subs = decoder->get_text_subtitles (ContentTime(), ContentTime::max ()); + list > subs = decoder->get_text_subtitles (ContentTimePeriod (ContentTime(), ContentTime::max ())); int n = 0; for (list >::const_iterator i = subs.begin(); i != subs.end(); ++i) { for (list::const_iterator j = (*i)->subs.begin(); j != (*i)->subs.end(); ++j) { diff --git a/test/subrip_test.cc b/test/subrip_test.cc index de102369f..19caca592 100644 --- a/test/subrip_test.cc +++ b/test/subrip_test.cc @@ -190,7 +190,11 @@ BOOST_AUTO_TEST_CASE (subrip_render_test) BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds ((3 * 60) + 56.471)); shared_ptr decoder (new SubRipDecoder (content)); - list > cts = decoder->get_text_subtitles (ContentTime::from_seconds (109), ContentTime::from_seconds (110)); + list > cts = decoder->get_text_subtitles ( + ContentTimePeriod ( + ContentTime::from_seconds (109), ContentTime::from_seconds (110) + ) + ); BOOST_CHECK_EQUAL (cts.size(), 1); PositionImage image = render_subtitles (cts.front()->subs, dcp::Size (1998, 1080)); -- 2.30.2