From: Carl Hetherington Date: Mon, 1 Mar 2021 19:35:12 +0000 (+0100) Subject: Extract process_audio_frame. X-Git-Tag: v2.15.133~4 X-Git-Url: https://git.carlh.net/gitweb/?a=commitdiff_plain;h=6c092a6abef4bf38fe62112544f7b6247cdb07d0;hp=fd542231f5f8a4933fb1d3fa9285c1a92d9833c0;p=dcpomatic.git Extract process_audio_frame. --- diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 54d7981a0..b2bb1a466 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -442,6 +442,57 @@ FFmpegDecoder::audio_stream_from_index (int index) const } +void +FFmpegDecoder::process_audio_frame (shared_ptr stream, int stream_index, int64_t packet_pts) +{ + auto data = deinterleave_audio (stream); + + ContentTime ct; + 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). + */ + if (_next_time[stream_index]) { + ct = *_next_time[stream_index]; + } + } else { + ct = ContentTime::from_seconds ( + _frame->best_effort_timestamp * + av_q2d (stream->stream(_format_context)->time_base)) + + _pts_offset; + } + + _next_time[stream_index] = ct + ContentTime::from_frames(data->frames(), stream->frame_rate()); + + if (ct < ContentTime()) { + /* Discard audio data that comes before time 0 */ + auto const remove = min (int64_t(data->frames()), (-ct).frames_ceil(double(stream->frame_rate()))); + data->move (data->frames() - remove, remove, 0); + data->set_frames (data->frames() - remove); + ct += ContentTime::from_frames (remove, stream->frame_rate()); + } + + if (ct < ContentTime()) { + LOG_WARNING ( + "Crazy timestamp %1 for %2 samples in stream %3 packet pts %4 (ts=%5 tb=%6, off=%7)", + to_string(ct), + data->frames(), + stream_index, + packet_pts, + _frame->best_effort_timestamp, + av_q2d(stream->stream(_format_context)->time_base), + to_string(_pts_offset) + ); + } + + /* Give this data provided there is some, and its time is sane */ + if (ct >= ContentTime() && data->frames() > 0) { + audio->emit (film(), stream, data, ct); + } +} + + void FFmpegDecoder::decode_audio_packet () { @@ -454,15 +505,14 @@ FFmpegDecoder::decode_audio_packet () auto stream = audio_stream_from_index (stream_index); if (!stream) { - /* The packet's stream may not be an audio one; just ignore it in this method if so */ return; } -DCPOMATIC_DISABLE_WARNINGS while (copy_packet.size > 0) { - int frame_finished; + DCPOMATIC_DISABLE_WARNINGS int decode_result = avcodec_decode_audio4 (stream->stream(_format_context)->codec, _frame, &frame_finished, ©_packet); + DCPOMATIC_ENABLE_WARNINGS if (decode_result < 0) { /* avcodec_decode_audio4 can sometimes return an error even though it has decoded some valid data; for example dca_subframe_footer can return AVERROR_INVALIDDATA @@ -480,52 +530,7 @@ DCPOMATIC_DISABLE_WARNINGS } if (frame_finished) { - auto data = deinterleave_audio (stream); - - ContentTime ct; - 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). - */ - if (_next_time[stream_index]) { - ct = *_next_time[stream_index]; - } - } else { - ct = ContentTime::from_seconds ( - av_frame_get_best_effort_timestamp (_frame) * - av_q2d (stream->stream(_format_context)->time_base)) - + _pts_offset; - } - - _next_time[stream_index] = ct + ContentTime::from_frames(data->frames(), stream->frame_rate()); - - if (ct < ContentTime()) { - /* Discard audio data that comes before time 0 */ - auto const remove = min (int64_t(data->frames()), (-ct).frames_ceil(double(stream->frame_rate()))); - data->move (data->frames() - remove, remove, 0); - data->set_frames (data->frames() - remove); - ct += ContentTime::from_frames (remove, stream->frame_rate()); - } - - if (ct < ContentTime()) { - LOG_WARNING ( - "Crazy timestamp %1 for %2 samples in stream %3 packet pts %4 (ts=%5 tb=%6, off=%7)", - to_string(ct), - data->frames(), - copy_packet.stream_index, - copy_packet.pts, - av_frame_get_best_effort_timestamp(_frame), - av_q2d(stream->stream(_format_context)->time_base), - to_string(_pts_offset) - ); - } -DCPOMATIC_ENABLE_WARNINGS - - /* Give this data provided there is some, and its time is sane */ - if (ct >= ContentTime() && data->frames() > 0) { - audio->emit (film(), stream, data, ct); - } + process_audio_frame (stream, stream_index, copy_packet.pts); } copy_packet.data += decode_result; diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 009d61b48..7a1fa40d2 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -58,6 +58,7 @@ private: int bytes_per_audio_sample (std::shared_ptr stream) const; std::shared_ptr audio_stream_from_index (int index) const; + void process_audio_frame (std::shared_ptr stream, int stream_index, int64_t packet_pts); bool decode_video_packet (); void decode_audio_packet ();