From 22c5d46c65b2b94bf25f977f1e0319cfe0462ad0 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Sun, 12 May 2019 12:14:03 -0400 Subject: [PATCH] rescale audio packet duration and pts before feeding to codec after resample --- src/zm_videostore.cpp | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/zm_videostore.cpp b/src/zm_videostore.cpp index 978dfd328..2130db03b 100644 --- a/src/zm_videostore.cpp +++ b/src/zm_videostore.cpp @@ -1011,7 +1011,6 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) { } zm_dump_frame(out_frame, "Out frame after resample"); - out_frame->pts = in_frame->pts; // out_frame pts is in the input pkt pts... needs to be adjusted before sending to the encoder if ( out_frame->pts != AV_NOPTS_VALUE ) { if ( !audio_first_pts ) { @@ -1065,6 +1064,8 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) { return 0; } #endif +#if 0 + // These should be set by encoder. They may not directly relate to ipkt due to buffering in codec. opkt.duration = av_rescale_q(opkt.duration, audio_in_stream->time_base, audio_out_stream->time_base); @@ -1074,6 +1075,7 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) { opkt.dts = av_rescale_q(opkt.dts, audio_in_stream->time_base, audio_out_stream->time_base); +#endif dumpPacket(audio_out_stream, &opkt, "raw opkt"); } else { @@ -1179,16 +1181,32 @@ int VideoStore::resample_audio() { Debug(2, "Converting %d to %d samples using swresample", in_frame->nb_samples, out_frame->nb_samples); ret = swr_convert_frame(resample_ctx, out_frame, in_frame); - zm_dump_frame(out_frame, "Out frame after convert"); - - // resampling doesn't change the duration, or set it. - out_frame->pkt_duration = in_frame->pkt_duration; - if ( ret < 0 ) { Error("Could not resample frame (error '%s')", av_make_error_string(ret).c_str()); return 0; } + zm_dump_frame(out_frame, "Out frame after convert"); + + +#if 0 + // out_frame pts is in the input pkt pts... needs to be adjusted before sending to the encoder + if ( out_frame->pts != AV_NOPTS_VALUE ) { + if ( !audio_first_pts ) { + audio_first_pts = out_frame->pts; + Debug(1, "No audio_first_pts setting to %" PRId64, audio_first_pts); + out_frame->pts = 0; + } else { + out_frame->pts = out_frame->pts - audio_first_pts; + } + // + } else { + // sending AV_NOPTS_VALUE doesn't really work but we seem to get it in ffmpeg 2.8 + out_frame->pts = audio_next_pts; + } + audio_next_pts = out_frame->pts + out_frame->nb_samples; +#endif + if ((ret = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + out_frame->nb_samples)) < 0) { Error("Could not reallocate FIFO"); return 0; @@ -1214,6 +1232,17 @@ int VideoStore::resample_audio() { return 0; } out_frame->nb_samples = frame_size; + // resampling changes the duration because the timebase is 1/samples + if ( in_frame->pts != AV_NOPTS_VALUE ) { + out_frame->pkt_duration = av_rescale_q( + in_frame->pkt_duration, + audio_in_stream->time_base, + audio_out_stream->time_base); + out_frame->pts = av_rescale_q( + in_frame->pts, + audio_in_stream->time_base, + audio_out_stream->time_base); + } #else #if defined(HAVE_LIBAVRESAMPLE) ret = avresample_convert(resample_ctx, NULL, 0, 0, in_frame->data,