利用 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);
}