Merge branch '1.0' into 1.0-seek
[dcpomatic.git] / src / lib / ffmpeg_decoder.cc
index e8489f5f6cbd1ea9e2fcbbabaf58faa279e51c13..298284512371b87c53ba21edee018434f218d009 100644 (file)
@@ -296,12 +296,11 @@ FFmpegDecoder::bytes_per_audio_sample () const
 }
 
 int
-FFmpegDecoder::minimal_run (boost::function<bool (ContentTime, ContentTime, int)> finished)
+FFmpegDecoder::minimal_run (boost::function<bool (optional<ContentTime>, optional<ContentTime>, int)> finished)
 {
        int frames_read = 0;
-       ContentTime last_video = 0;
-       ContentTime last_audio = 0;
-       bool flushing = false;
+       optional<ContentTime> last_video;
+       optional<ContentTime> last_audio;
 
        while (!finished (last_video, last_audio, frames_read)) {
                int r = av_read_frame (_format_context, &_packet);
@@ -354,9 +353,9 @@ FFmpegDecoder::minimal_run (boost::function<bool (ContentTime, ContentTime, int)
 }
 
 bool
-FFmpegDecoder::seek_overrun_finished (ContentTime seek, ContentTime last_video, ContentTime last_audio) const
+FFmpegDecoder::seek_overrun_finished (ContentTime seek, optional<ContentTime> last_video, optional<ContentTime> last_audio) const
 {
-       return last_video >= seek || last_audio >= seek;
+       return (last_video && last_video.get() >= seek) || (last_audio && last_audio.get() >= seek);
 }
 
 bool
@@ -368,19 +367,20 @@ FFmpegDecoder::seek_final_finished (int n, int done) const
 void
 FFmpegDecoder::seek_and_flush (ContentTime t)
 {
-       int64_t const initial_v = ((double (t) / TIME_HZ) - _video_pts_offset) /
+       int64_t s = ((double (t) / TIME_HZ) - _video_pts_offset) /
                av_q2d (_format_context->streams[_video_stream]->time_base);
-
-       av_seek_frame (_format_context, _video_stream, initial_v, AVSEEK_FLAG_BACKWARD);
-
-       shared_ptr<FFmpegAudioStream> as = _ffmpeg_content->audio_stream ();
-       if (as) {
-               int64_t initial_a = ((double (t) / TIME_HZ) - _audio_pts_offset) /
-                       av_q2d (as->stream(_format_context)->time_base);
-
-               av_seek_frame (_format_context, as->index (_format_context), initial_a, AVSEEK_FLAG_BACKWARD);
+       
+       if (_ffmpeg_content->audio_stream ()) {
+               s = min (
+                       s, int64_t (
+                               ((double (t) / TIME_HZ) - _audio_pts_offset) /
+                               av_q2d (_ffmpeg_content->audio_stream()->stream(_format_context)->time_base)
+                               )
+                       );
        }
 
+       av_seek_frame (_format_context, _video_stream, s, AVSEEK_FLAG_BACKWARD);
+
        avcodec_flush_buffers (video_codec_context());
        if (audio_codec_context ()) {
                avcodec_flush_buffers (audio_codec_context ());
@@ -410,8 +410,8 @@ FFmpegDecoder::seek (ContentTime time, bool accurate)
 
        seek_and_flush (initial_seek);
 
-       if (time == 0 || !accurate) {
-               /* We're already there, or we're as close as we need to be */
+       if (!accurate) {
+               /* That'll do */
                return;
        }
 
@@ -562,8 +562,8 @@ FFmpegDecoder::decode_subtitle_packet ()
        double const packet_time = static_cast<double> (sub.pts) / AV_TIME_BASE;
        
        /* hence start time for this sub */
-       DCPTime const from = (packet_time + (double (sub.start_display_time) / 1e3)) * TIME_HZ;
-       DCPTime const to = (packet_time + (double (sub.end_display_time) / 1e3)) * TIME_HZ;
+       ContentTime const from = (packet_time + (double (sub.start_display_time) / 1e3)) * TIME_HZ;
+       ContentTime const to = (packet_time + (double (sub.end_display_time) / 1e3)) * TIME_HZ;
 
        AVSubtitleRect const * rect = sub.rects[0];