#include "Resampler.h" #include "ffcpp.h" #include #include #include extern "C" { #include } namespace ffcpp { Resampler::Resampler(int inChannelLayout, int inSampleRate, AVSampleFormat inSampleFormat, int outChannelLayout, int outSampleRate, AVSampleFormat outSampleFormat) { _dstChannelLayout = outChannelLayout; _dstSampleFormat = outSampleFormat; _dstSampleRate = outSampleRate; _swrContext = swr_alloc(); if(!_swrContext) { throw new std::runtime_error("cannot create resampler"); } av_opt_set_int(_swrContext, "in_channel_layout", inChannelLayout, 0); av_opt_set_int(_swrContext, "in_sample_rate", inSampleRate, 0); av_opt_set_sample_fmt(_swrContext, "in_sample_fmt", inSampleFormat, 0); av_opt_set_int(_swrContext, "out_channel_layout", outChannelLayout, 0); av_opt_set_int(_swrContext, "out_sample_rate", outSampleRate, 0); av_opt_set_sample_fmt(_swrContext, "out_sample_fmt", outSampleFormat, 0); int res = swr_init(_swrContext); throwIfError(res, "cannot init resampler"); } Resampler::Resampler(AVCodecContext *decoderCtx, AVCodecContext *encoderCtx) : Resampler((int)decoderCtx->channel_layout, decoderCtx->sample_rate, decoderCtx->sample_fmt, (int)encoderCtx->channel_layout, encoderCtx->sample_rate, encoderCtx->sample_fmt) { } Resampler::~Resampler() { if(_swrContext) { swr_free(&_swrContext); } } Frame Resampler::resample(Frame& inFrame) { int channelsCount = av_get_channel_layout_nb_channels(_dstChannelLayout); AVFrame* fin = inFrame; int outSamples = swr_get_out_samples(_swrContext, fin->nb_samples); Frame outFrame(outSamples, channelsCount, _dstSampleFormat, _dstSampleRate); int res = swr_convert_frame(_swrContext, outFrame, inFrame); throwIfError(res, "cannot convert audio frame"); return outFrame; } bool Resampler::needResampling(AVCodecContext *decoderCtx, AVCodecContext *encoderCtx) { return (decoderCtx->channels != encoderCtx->channels || decoderCtx->channel_layout != encoderCtx->channel_layout || decoderCtx->sample_fmt != encoderCtx->sample_fmt || decoderCtx->sample_rate != encoderCtx->sample_rate); } }