ffconv/ffcpp/Resampler.cpp

67 lines
2.2 KiB
C++

#include "Resampler.h"
#include "ffcpp.h"
#include <stdexcept>
#include <memory>
#include <iostream>
extern "C" {
#include <libavutil/opt.h>
}
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);
}
}