From 2985562b346fa0ed0b4c74e1d20061c9d02b9fae Mon Sep 17 00:00:00 2001 From: SuRuoyan Date: Wed, 5 Feb 2025 12:45:23 +0800 Subject: [PATCH] fix audio format change in resample case Signed-off-by: SuRuoyan --- .../audio_decoder/ffmpeg_base_decoder.cpp | 11 ++++++++--- .../audio_decoder/ffmpeg_base_decoder.h | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/services/media_engine/plugins/ffmpeg_adapter/audio_decoder/ffmpeg_base_decoder.cpp b/services/media_engine/plugins/ffmpeg_adapter/audio_decoder/ffmpeg_base_decoder.cpp index af9194bb7..48d1b8e1c 100644 --- a/services/media_engine/plugins/ffmpeg_adapter/audio_decoder/ffmpeg_base_decoder.cpp +++ b/services/media_engine/plugins/ffmpeg_adapter/audio_decoder/ffmpeg_base_decoder.cpp @@ -38,6 +38,7 @@ namespace Ffmpeg { FfmpegBaseDecoder::FfmpegBaseDecoder() : isFirst(true), hasExtra_(false), + currentFrameFormatChanged_(false), maxInputSize_(-1), nextPts_(0), durationTime_(0.f), @@ -157,8 +158,8 @@ Status FfmpegBaseDecoder::ReceiveBuffer(std::shared_ptr &outBuffer) if (cachedFrame_->pts == AV_NOPTS_VALUE) { cachedFrame_->pts = nextPts_; } - status = ReceiveFrameSucc(outBuffer); CheckFormatChange(); + status = ReceiveFrameSucc(outBuffer); dataCallback_->OnOutputBufferDone(outBuffer); } else if (ret == AVERROR_EOF) { AVCODEC_LOGI("eos received"); @@ -201,6 +202,7 @@ void FfmpegBaseDecoder::CheckFormatChange() AVCODEC_LOGI("decode format changed, sample rate:%{public}d->%{public}d, channel:%{public}d->%{public}d, " "sample format:%{public}d->%{public}d", preSampleRate, avCodecContext_->sample_rate, preChannels, avCodecContext_->channels, preFormat, currentFormat); + currentFrameFormatChanged_ = true; format_->SetData(Tag::AUDIO_SAMPLE_RATE, avCodecContext_->sample_rate); format_->SetData(Tag::AUDIO_CHANNEL_COUNT, avCodecContext_->channels); format_->SetData(Tag::AUDIO_SAMPLE_FORMAT, currentFormat); @@ -214,7 +216,7 @@ void FfmpegBaseDecoder::CheckFormatChange() Status FfmpegBaseDecoder::ReceiveFrameSucc(std::shared_ptr &outBuffer) { - if (isFirst) { + if (isFirst || currentFrameFormatChanged_) { isFirst = false; auto layout = FFMpegConverter::ConvertFFToOHAudioChannelLayoutV2(avCodecContext_->channel_layout, avCodecContext_->channels); @@ -227,10 +229,12 @@ Status FfmpegBaseDecoder::ReceiveFrameSucc(std::shared_ptr &outBuffer) avCodecContext_->channels, avCodecContext_->ch_layout.nb_channels); format_->SetData(Tag::AUDIO_CHANNEL_LAYOUT, layout); if (InitResample() != Status::OK) { + currentFrameFormatChanged_ = false; return Status::ERROR_UNKNOWN; } int32_t sampleRate = avCodecContext_->sample_rate; durationTime_ = TIME_BASE_FFMPEG / sampleRate; + currentFrameFormatChanged_ = false; } nextPts_ = cachedFrame_->pts + static_cast(cachedFrame_->nb_samples * durationTime_); auto outFrame = cachedFrame_; @@ -381,7 +385,8 @@ Status FfmpegBaseDecoder::InitResample() AVCODEC_LOGI("ffmpeg default sample_fmt :%{public}" PRId32, avCodecContext_->sample_fmt); AVCODEC_LOGI("need sample_fmt :%{public}" PRId32, destFmt_); AVCODEC_LOGI("frameSize :%{public}" PRId32, avCodecContext_->frame_size); - if (avCodecContext_->sample_fmt != destFmt_) { + if ((!needResample_ && avCodecContext_->sample_fmt != destFmt_) + || (needResample_ && currentFrameFormatChanged_)) { ResamplePara resamplePara; resamplePara.channels = static_cast(avCodecContext_->channels); resamplePara.sampleRate = static_cast(avCodecContext_->sample_rate); diff --git a/services/media_engine/plugins/ffmpeg_adapter/audio_decoder/ffmpeg_base_decoder.h b/services/media_engine/plugins/ffmpeg_adapter/audio_decoder/ffmpeg_base_decoder.h index ae3a6470c..1856e48f5 100644 --- a/services/media_engine/plugins/ffmpeg_adapter/audio_decoder/ffmpeg_base_decoder.h +++ b/services/media_engine/plugins/ffmpeg_adapter/audio_decoder/ffmpeg_base_decoder.h @@ -83,6 +83,7 @@ public: private: bool isFirst; bool hasExtra_; + bool currentFrameFormatChanged_; int32_t maxInputSize_; int64_t nextPts_; float durationTime_; -- Gitee