FFmpeg volume filter处理裸pcm数据 采样个数发生变化的原因

背景:最近使用FFmpeg 中的volume filter进行音频数据增益的时候出现一个很奇怪的现象,送给filter的数据和取出来的数据大小不等。

  • 单声道,16bit的pcm数据1024个采样,大小是 116/21024=2048,送进source再从sink取出时,应该也是2048个大小才对。但实际上我们看AVFrame中的linesize大小是2112,为什么呢?这种情况我们该如何处理呢?
  • 先上测试代码
int VolumeFilter::ProcessData(char* pData, int iDataSize, int& iOutSize)
{
	Poco::Mutex::ScopedLock lk(m_mutexOpr);
	int iRet = -1;
	iOutSize = 0;
	if (m_bInit && pData && iDataSize > 0)
	{
		iRet = avcodec_fill_audio_frame(m_pAVFrame, m_iChannels, m_sampleFmt, (const uint8_t *)pData, iDataSize, 1);
		if (iRet >= 0)
		{
			//如这里m_pAVFrame是1024个采样
			iRet = av_buffersrc_add_frame(m_pABufferSrcCtx, m_pAVFrame);
			while (iRet == 0)
			{
				//这里拿到的是2112个采样
				iRet = av_buffersink_get_frame(m_pABufferSinkCtx, m_pAVFrame);
				if (iRet < 0)
					break;
				iOutSize = m_pAVFrame->nb_samples * av_get_bytes_per_sample(m_sampleFmt);
				memcpy(pData, m_pAVFrame->data[0], iOutSize);
			}
			if (iOutSize > 0)
				iRet = 0;
		}
	}
	return iRet;
}

查看FFmpeg源码,看调用堆栈发现最终是在filter_frame中将采样个数修改了。
FFmpeg volume filter处理裸pcm数据 采样个数发生变化的原因_第1张图片
FFmpeg volume filter处理裸pcm数据 采样个数发生变化的原因_第2张图片

解码出AVFrame -> abuffer-> 其他过滤器(volume)...->aformat->abuffersink->过滤后的AVFrame

这里有三个通用的过滤器,abuffer,aformat,abuffersink。
abuffer用于接收输入frame,形成待处理的数据缓存,abuffersink用于传出输出Frame,aformat过滤器约束最终的输出格式(采样率,声道数,存储位数等),这三个不可缺少。
而中间的其他过滤器可以串联多个filter,如volume,atempo。
所以volume后面添加一个aformat将格式转换为我们期望的输出格式,那么就是这里引入经过了resample filter,将采样个数修改了。

  • 该如何操作呢,只需要按采样个数取出对应数值就可以了,linesize多出来的数据可以认为是resample所需申请的,不用关心。

你可能感兴趣的:(FFMPEG)