X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fffmpeg_decoder.cc;h=b6b6e594d9f41055843220706c960dcb6f5756fd;hb=125377b86f3b2e7f47c1e884b833a39ea27ae519;hp=f7c435a7455a4ccb5993ce55da908749d5b468fe;hpb=2704fe5ce4ecfcb9214c032117be719079b93d89;p=dcpomatic.git diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index f7c435a74..b6b6e594d 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -98,6 +98,7 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr c, shared_ptr new SubtitleDecoder ( this, c->subtitle, + log, bind (&FFmpegDecoder::image_subtitles_during, this, _1, _2), bind (&FFmpegDecoder::text_subtitles_during, this, _1, _2) ) @@ -137,7 +138,7 @@ FFmpegDecoder::pass (PassReason reason, bool accurate) /* 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); + LOG_ERROR (N_("error on av_read_frame (%1) (%2)"), &buf[0], r); } flush (); @@ -348,12 +349,14 @@ FFmpegDecoder::seek (ContentTime time, bool accurate) } av_seek_frame ( _format_context, - _video_stream.get(), - u.seconds() / av_q2d (_format_context->streams[_video_stream.get()]->time_base), + stream.get(), + u.seconds() / av_q2d (_format_context->streams[stream.get()]->time_base), AVSEEK_FLAG_BACKWARD ); - avcodec_flush_buffers (video_codec_context()); + if (video_codec_context ()) { + avcodec_flush_buffers (video_codec_context()); + } /* XXX: should be flushing audio buffers? */ @@ -419,7 +422,12 @@ FFmpegDecoder::decode_audio_packet () ct += ContentTime::from_frames (remove, (*stream)->frame_rate ()); } - if (data->frames() > 0) { + if (ct < ContentTime()) { + LOG_WARNING ("Crazy timestamp %1", to_string (ct)); + } + + /* Give this data provided there is some, and its time is sane */ + if (ct >= ContentTime() && data->frames() > 0) { audio->give (*stream, data, ct); } } @@ -499,13 +507,11 @@ FFmpegDecoder::decode_subtitle_packet () FFmpegSubtitlePeriod sub_period = subtitle_period (sub); ContentTimePeriod period; period.from = sub_period.from + _pts_offset; - if (sub_period.to) { - /* We already know the subtitle period `to' time */ - period.to = sub_period.to.get() + _pts_offset; - } else { - /* We have to look up the `to' time in the stream's records */ - period.to = ffmpeg_content()->subtitle_stream()->find_subtitle_to (subtitle_id (sub)); - } + /* We can't trust the `to' time from sub_period as there are some decoders which + give a sub_period time for `to' which is subsequently overridden by a `stop' subtitle; + see also FFmpegExaminer. + */ + period.to = ffmpeg_content()->subtitle_stream()->find_subtitle_to (subtitle_id (sub)); for (unsigned int i = 0; i < sub.num_rects; ++i) { AVSubtitleRect const * rect = sub.rects[i]; @@ -601,12 +607,13 @@ FFmpegDecoder::decode_bitmap_subtitle (AVSubtitleRect const * rect, ContentTimeP out_p += image->stride()[0] / sizeof (uint32_t); } - dcp::Size const vs = _ffmpeg_content->video->size (); + int const target_width = subtitle_codec_context()->width; + int const target_height = subtitle_codec_context()->height; dcpomatic::Rect const scaled_rect ( - static_cast (rect->x) / vs.width, - static_cast (rect->y) / vs.height, - static_cast (rect->w) / vs.width, - static_cast (rect->h) / vs.height + static_cast (rect->x) / target_width, + static_cast (rect->y) / target_height, + static_cast (rect->w) / target_width, + static_cast (rect->h) / target_height ); subtitle->give_image (period, image, scaled_rect);