Hopefully improve subtitle decoder seeking etc.
[dcpomatic.git] / src / lib / ffmpeg_decoder.cc
index dfd8786b37b833621b20d1767279e608ce5335d7..668cab88530d1b385821056aeb837d4b2a011ff0 100644 (file)
@@ -45,6 +45,7 @@ extern "C" {
 #include "ffmpeg_content.h"
 #include "image_proxy.h"
 #include "film.h"
+#include "timer.h"
 
 #include "i18n.h"
 
@@ -59,6 +60,7 @@ using std::stringstream;
 using std::list;
 using std::min;
 using std::pair;
+using std::make_pair;
 using boost::shared_ptr;
 using boost::optional;
 using boost::dynamic_pointer_cast;
@@ -140,7 +142,7 @@ FFmpegDecoder::pass ()
        }
 
        int const si = _packet.stream_index;
-       
+
        if (si == _video_stream) {
                decode_video_packet ();
        } else if (_ffmpeg_content->audio_stream() && _ffmpeg_content->audio_stream()->uses_index (_format_context, si)) {
@@ -283,9 +285,22 @@ FFmpegDecoder::bytes_per_audio_sample () const
 }
 
 void
-FFmpegDecoder::seek_and_flush (ContentTime t)
+FFmpegDecoder::seek (ContentTime time, bool accurate)
 {
-       ContentTime const u = t - _pts_offset;
+       VideoDecoder::seek (time, accurate);
+       AudioDecoder::seek (time, accurate);
+       
+       /* If we are doing an `accurate' seek, we need to use pre-roll, as
+          we don't really know what the seek will give us.
+       */
+
+       ContentTime pre_roll = accurate ? ContentTime::from_seconds (2) : ContentTime (0);
+       time -= pre_roll;
+       if (time < ContentTime (0)) {
+               time = ContentTime (0);
+       }
+
+       ContentTime const u = time - _pts_offset;
        int64_t s = u.seconds() / av_q2d (_format_context->streams[_video_stream]->time_base);
 
        if (_ffmpeg_content->audio_stream ()) {
@@ -311,26 +326,6 @@ FFmpegDecoder::seek_and_flush (ContentTime t)
        }
 }
 
-void
-FFmpegDecoder::seek (ContentTime time, bool accurate)
-{
-       VideoDecoder::seek (time, accurate);
-       AudioDecoder::seek (time, accurate);
-       
-       /* If we are doing an accurate seek, our initial shot will be 2s (2 being
-          a number plucked from the air) earlier than we want to end up.  The loop below
-          will hopefully then step through to where we want to be.
-       */
-
-       ContentTime pre_roll = accurate ? ContentTime::from_seconds (2) : ContentTime (0);
-       ContentTime initial_seek = time - pre_roll;
-       if (initial_seek < ContentTime (0)) {
-               initial_seek = ContentTime (0);
-       }
-
-       seek_and_flush (initial_seek);
-}
-
 void
 FFmpegDecoder::decode_audio_packet ()
 {
@@ -486,8 +481,8 @@ FFmpegDecoder::decode_subtitle_packet ()
        avsubtitle_free (&sub);
 }
 
-bool
-FFmpegDecoder::has_subtitle_during (ContentTimePeriod p) const
+list<ContentTimePeriod>
+FFmpegDecoder::subtitles_during (ContentTimePeriod p) const
 {
-       return _ffmpeg_content->has_subtitle_during (p);
+       return _ffmpeg_content->subtitles_during (p);
 }