Ignore AVERROR_INVALIDDATA from av_read_frame() as it can apparently mean that there...
[dcpomatic.git] / src / lib / ffmpeg_decoder.cc
index d1b65cbc2846b56014f8dbc6a1bd108ab9408501..2d12ef0a007673d612babd8919f0cedb48d5ba0c 100644 (file)
@@ -97,6 +97,14 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr<const FFmpegContent> c, shared_ptr<Log>
                _pts_offset = - c->audio_stream()->first_audio.get();
        }
 
+       /* If _pts_offset is positive we would be pushing things from a -ve PTS to be played.
+          I don't think we ever want to do that, as it seems things at -ve PTS are not meant
+          to be seen (use for alignment bars etc.); see mantis #418.
+       */
+       if (_pts_offset > ContentTime ()) {
+               _pts_offset = ContentTime ();
+       }
+
        /* Now adjust both so that the video pts starts on a frame */
        if (have_video && have_audio) {
                ContentTime first_video = c->first_video().get() + _pts_offset;
@@ -128,14 +136,18 @@ FFmpegDecoder::pass ()
 {
        int r = av_read_frame (_format_context, &_packet);
 
-       if (r < 0) {
+       /* AVERROR_INVALIDDATA can apparently be returned sometimes even when av_read_frame
+          has pretty-much succeeded (and hence generated data which should be processed).
+          Hence it makes sense to continue here in that case.
+       */
+       if (r < 0 && r != AVERROR_INVALIDDATA) {
                if (r != AVERROR_EOF) {
                        /* Maybe we should fail here, but for now we'll just finish off instead */
                        char buf[256];
                        av_strerror (r, buf, sizeof(buf));
                        LOG_ERROR (N_("error on av_read_frame (%1) (%2)"), buf, r);
                }
-
+               
                flush ();
                return true;
        }
@@ -160,12 +172,12 @@ FFmpegDecoder::pass ()
 shared_ptr<AudioBuffers>
 FFmpegDecoder::deinterleave_audio (uint8_t** data, int size)
 {
-       assert (_ffmpeg_content->audio_channels());
-       assert (bytes_per_audio_sample());
+       DCPOMATIC_ASSERT (_ffmpeg_content->audio_channels());
+       DCPOMATIC_ASSERT (bytes_per_audio_sample());
 
        /* Deinterleave and convert to float */
 
-       assert ((size % (bytes_per_audio_sample() * _ffmpeg_content->audio_channels())) == 0);
+       DCPOMATIC_ASSERT ((size % (bytes_per_audio_sample() * _ffmpeg_content->audio_channels())) == 0);
 
        int const total_samples = size / bytes_per_audio_sample();
        int const frames = total_samples / _ffmpeg_content->audio_channels();
@@ -341,9 +353,6 @@ FFmpegDecoder::decode_audio_packet ()
 
                           Returning from the method here caused mantis #352.
                        */
-                       
-                       shared_ptr<const Film> film = _film.lock ();
-                       assert (film);
                        LOG_WARNING ("avcodec_decode_audio4 failed (%1)", decode_result);
 
                        /* Fudge decode_result so that we come out of the while loop when
@@ -404,7 +413,7 @@ FFmpegDecoder::decode_video_packet ()
                if (i->second != AV_NOPTS_VALUE) {
                        double const pts = i->second * av_q2d (_format_context->streams[_video_stream]->time_base) + _pts_offset.seconds ();
                        video (
-                               shared_ptr<ImageProxy> (new RawImageProxy (image, _video_content->film()->log())),
+                               shared_ptr<ImageProxy> (new RawImageProxy (image)),
                                rint (pts * _ffmpeg_content->video_frame_rate ())
                                );
                } else {