From: Carl Hetherington Date: Sun, 12 Sep 2021 20:43:52 +0000 (+0200) Subject: Fix missing subtitles embedded in files decoded by FFmpeg (#2060). X-Git-Tag: v2.15.161~1 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=60450bd93af0b331d7b98c88aa199366305f0721 Fix missing subtitles embedded in files decoded by FFmpeg (#2060). Since the FFmpeg 4.4 update it seems that AVSubtitle::pts is no longer set (it's AV_NOPTS_VALUE, i think). Instead we apparently need to get the PTS from the packet, which in turn requires the stream's timebase. --- diff --git a/src/lib/ffmpeg.cc b/src/lib/ffmpeg.cc index d476b4c29..31aa18293 100644 --- a/src/lib/ffmpeg.cc +++ b/src/lib/ffmpeg.cc @@ -284,9 +284,9 @@ FFmpeg::avio_seek (int64_t const pos, int whence) FFmpegSubtitlePeriod -FFmpeg::subtitle_period (AVSubtitle const & sub) +FFmpeg::subtitle_period (AVPacket const* packet, AVStream const* stream, AVSubtitle const & sub) { - auto const packet_time = ContentTime::from_seconds (static_cast (sub.pts) / AV_TIME_BASE); + auto const packet_time = ContentTime::from_seconds (packet->pts * av_q2d(stream->time_base)); if (sub.end_display_time == static_cast (-1)) { /* End time is not known */ diff --git a/src/lib/ffmpeg.h b/src/lib/ffmpeg.h index 58223fa97..b0769971e 100644 --- a/src/lib/ffmpeg.h +++ b/src/lib/ffmpeg.h @@ -36,6 +36,7 @@ DCPOMATIC_ENABLE_WARNINGS struct AVFormatContext; struct AVFrame; +struct AVStream; struct AVIOContext; class FFmpegContent; @@ -63,7 +64,7 @@ protected: std::vector> audio_streams, boost::optional first_video, double video_frame_rate ) const; - static FFmpegSubtitlePeriod subtitle_period (AVSubtitle const & sub); + static FFmpegSubtitlePeriod subtitle_period (AVPacket const* packet, AVStream const* stream, AVSubtitle const & sub); std::shared_ptr _ffmpeg_content; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 3202dcd3e..72372fca8 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -622,12 +622,14 @@ FFmpegDecoder::decode_and_process_subtitle_packet (AVPacket* packet) return; } + auto sub_period = subtitle_period (packet, ffmpeg_content()->subtitle_stream()->stream(_format_context), sub); + /* Stop any current subtitle, either at the time it was supposed to stop, or now if now is sooner */ if (_have_current_subtitle) { if (_current_subtitle_to) { - only_text()->emit_stop (min(*_current_subtitle_to, subtitle_period(sub).from + _pts_offset)); + only_text()->emit_stop (min(*_current_subtitle_to, sub_period.from + _pts_offset)); } else { - only_text()->emit_stop (subtitle_period(sub).from + _pts_offset); + only_text()->emit_stop (sub_period.from + _pts_offset); } _have_current_subtitle = false; } @@ -641,7 +643,6 @@ FFmpegDecoder::decode_and_process_subtitle_packet (AVPacket* packet) /* Subtitle PTS (within the source, not taking into account any of the source that we may have chopped off for the DCP). */ - auto sub_period = subtitle_period (sub); ContentTime from; from = sub_period.from + _pts_offset; if (sub_period.to) {