Don't crash if the first packet in a stream has AV_NOPTS_VALUE;
[dcpomatic.git] / src / lib / ffmpeg_decoder.cc
index 0f39f7727348eadfd124689e5e1e858ab50c0ef6..69f366aade4e86f0e704a8041d4f781686823ed6 100644 (file)
@@ -42,6 +42,7 @@
 #include "compose.hpp"
 #include "text_content.h"
 #include "audio_content.h"
+#include "frame_interval_checker.h"
 #include <dcp/subtitle_string.h>
 #include <sub/ssa_reader.h>
 #include <sub/subtitle.h>
@@ -126,7 +127,7 @@ FFmpegDecoder::flush ()
        if (video) {
                double const vfr = _ffmpeg_content->video_frame_rate().get();
                Frame const f = full_length.frames_round (vfr);
-               Frame v = video->position(film()).frames_round(vfr) + 1;
+               Frame v = video->position(film()).get_value_or(ContentTime()).frames_round(vfr) + 1;
                while (v < f) {
                        video->emit (film(), shared_ptr<const ImageProxy> (new RawImageProxy (_black_image)), v);
                        ++v;
@@ -398,6 +399,10 @@ FFmpegDecoder::seek (ContentTime time, bool accurate)
        }
 
        _have_current_subtitle = false;
+
+       BOOST_FOREACH (optional<ContentTime>& i, _next_time) {
+               i = optional<ContentTime>();
+       }
 }
 
 void
@@ -446,12 +451,14 @@ FFmpegDecoder::decode_audio_packet ()
                        shared_ptr<AudioBuffers> data = deinterleave_audio (*stream);
 
                        ContentTime ct;
-                       if (_frame->pts == AV_NOPTS_VALUE && _next_time[stream_index]) {
+                       if (_frame->pts == AV_NOPTS_VALUE) {
                                /* In some streams we see not every frame coming through with a timestamp; for those
                                   that have AV_NOPTS_VALUE we need to work out the timestamp ourselves.  This is
                                   particularly noticeable with TrueHD streams (see #1111).
                                */
-                               ct = *_next_time[stream_index];
+                               if (_next_time[stream_index]) {
+                                       ct = *_next_time[stream_index];
+                               }
                        } else {
                                ct = ContentTime::from_seconds (
                                        av_frame_get_best_effort_timestamp (_frame) *