2013년 8월 30일 금요일

convert AV_SAMPLE_FMT_FLTP to AV_SAMPLE_FMT_S16 with ffmpeg software resampler

extern "C" {
#include "libavcodec\avcodec.h"
#include "libswresample\swresample.h"
#include "libavutil\opt.h"
};

struct SwrContext *m_pSwrCtx;
AVCodec *m_pCodec;
AVCodecContext *m_pCodecCtx;
AVPacket m_avPacket;
AVFrame *m_pFrame;
uint8_t m_pOutBuf = new uint8_t[AVCODEC_MAX_AUDIO_FRAME_SIZE*5];
...

< open resampler >

m_pSwrCtx = swr_alloc();

uint64_t channel_layout = m_pCodecCtx->channel_layout;
if (channel_layout == 0)
channel_layout = av_get_default_channel_layout(m_pCodecCtx->channels);

av_opt_set_int(m_pSwrCtx, "in_channel_layout", channel_layout, 0);
av_opt_set_int(m_pSwrCtx, "in_sample_rate", m_pCodecCtx->sample_rate, 0);
av_opt_set_sample_fmt(m_pSwrCtx, "in_sample_fmt", m_pCodecCtx->sample_fmt, 0);

av_opt_set_int(m_pSwrCtx, "out_channel_layout", channel_layout, 0);
av_opt_set_int(m_pSwrCtx, "out_sample_rate", m_pCodecCtx->sample_rate, 0);
av_opt_set_sample_fmt(m_pSwrCtx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);


err = swr_init(m_pSwrCtx);

< do resampling >
...
int got_frame;
int retLen = avcodec_decode_audio4(m_pCodecCtx, m_pFrame, &got_frame, &m_avPacket);

if (retLen <= 0) {
DPRINTF("audio decode error : %d\n", retLen);
return retLen;
}

// audio resampling
int out_size = av_samples_get_buffer_size(NULL, m_pCodecCtx->channels, m_pFrame->nb_samples, m_pCodecCtx->sample_fmt, 1);

if (out_size > m_nOutBufSize) {
delete[] m_pOutBuf;
m_pOutBuf = new unsigned char[out_size];
m_nOutBufSize = out_size;
}

retLen = swr_convert(m_pSwrCtx, &m_pOutBuf, out_size,
(const uint8_t **)m_pFrame->extended_data, m_pFrame->nb_samples);

out_size = retLen*m_pCodecCtx->channels*av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
m_nOutBufSize = out_size;

return retLen;

< close resampler >

swr_free(&m_pSwrContext);