1. 程式人生 > 其它 >利用 ffmpeg swr_convert重取樣

利用 ffmpeg swr_convert重取樣

技術標籤:音訊視訊編解碼ffmpeg音訊編碼解碼

利用 ffmpeg swr_convert重取樣

CResample::CResample(int input_channels, int input_rate, int output_channels, int output_rate, enum AVSampleFormat  infmt, enum AVSampleFormat  outfmt)
{
	m_resample_ctx = NULL;
	m_input_channels = input_channels;
	m_input_rate = input_rate;
	m_output_channels = output_channels;
	m_output_rate = output_rate;
	m_infmt = infmt;
	m_outfmt = outfmt;

	int64_t input_layout = convert_speaker_layout(input_channels);
	int64_t output_layout = convert_speaker_layout(output_channels);


	if (input_channels != 0 && input_rate != 0 && output_channels != 0 && output_rate != 0)
	{
		m_resample_ctx = swr_alloc();
		m_resample_ctx = swr_alloc_set_opts(m_resample_ctx, output_layout, m_outfmt, output_rate,
			input_layout, m_infmt, input_rate, 0, NULL);

		if (input_layout == AV_CH_LAYOUT_MONO && output_channels > 1)
		{
			const double matrix[MAX_AUDIO_CHANNELS][MAX_AUDIO_CHANNELS] = {
				{1},
				{1, 1},
				{1, 1, 0},
				{1, 1, 1, 1},
				{1, 1, 1, 0, 1},
				{1, 1, 1, 1, 1, 1},
				{1, 1, 1, 0, 1, 1, 1},
				{1, 1, 1, 0, 1, 1, 1, 1},
			};
			if (swr_set_matrix(m_resample_ctx, matrix[output_channels - 1], 1) <
				0)
			{
				//
			}
		}

		if (0 != swr_init(m_resample_ctx))
		{
			if (m_resample_ctx != NULL)
			{
				swr_free(&m_resample_ctx);
			}
			m_resample_ctx = NULL;
		}
		
	}

}
CResample::~CResample()
{
	if (m_resample_ctx != NULL)
	{
		swr_free(&m_resample_ctx);
	}
	
}
int CResample::Convert(const UINT8 * input, const int input_len, UINT8 *out_buffer, int output_len)
{
	if (m_resample_ctx == NULL)
	{
		return -1;
	}
	int  in_samples = input_len / av_get_bytes_per_sample(m_infmt) / m_input_channels;
	int  out_samples1 = output_len / av_get_bytes_per_sample(m_outfmt) / m_output_channels;
	int out_samples = swr_convert(m_resample_ctx, &out_buffer, out_samples1,
		&input, in_samples);
	if (out_samples < 0)
	{
		
		return -1;
	}
	return av_samples_get_buffer_size(NULL, m_output_channels, out_samples, m_outfmt, 1);
}
int CResample::GetOutBufferLen(int input_len)
{
	if (m_resample_ctx == NULL)
	{
		return 0;
	}
	int in_samples = input_len / av_get_bytes_per_sample(m_infmt) / m_input_channels;
	int out_samples = swr_get_out_samples(m_resample_ctx, in_samples);
	return av_samples_get_buffer_size(NULL, m_output_channels, out_samples, m_outfmt, 1);
}