5#include <boost/circular_buffer.hpp>
8#include <libavutil/channel_layout.h>
9#include <libavutil/opt.h>
10#include <libavutil/samplefmt.h>
11#include <libswresample/swresample.h>
16 std::vector<uint8_t> data;
17 struct SwrContextDeleter {
18 void operator()(SwrContext *s) { swr_free(&s); }
20 std::unique_ptr<SwrContext, SwrContextDeleter> swr;
22 AVChannelLayout outChannelLayout = AV_CHANNEL_LAYOUT_MONO;
23 AVSampleFormat outputSampleFormat = AV_SAMPLE_FMT_FLT;
24 int outSampleRate = 48000;
26 bool loopRecording =
false;
27 boost::circular_buffer<uint8_t> circularData;
29 void virtualInit(AVCodecContext *decoderContext)
override {
31 spdlog::info(
"intitializing AudioFrameSink");
33 av_channel_layout_default(&decoderContext->ch_layout,
34 decoderContext->ch_layout.nb_channels);
35 struct SwrContext *temp{
nullptr};
36 swr_alloc_set_opts2(&temp,
40 &decoderContext->ch_layout,
41 decoderContext->sample_fmt,
42 decoderContext->sample_rate,
45 swr = {temp, SwrContextDeleter()};
46 int res = swr_init(swr.get());
48 char error[AV_ERROR_MAX_STRING_SIZE];
49 av_make_error_string(error, AV_ERROR_MAX_STRING_SIZE, res);
50 throw std::runtime_error(
"Error Initializing AudioFrameSink " +
53 spdlog::info(
"intitialized AudioFrameSink");
56 void virtualOutputFrame(AVFrame *frame)
override {
57 int64_t out_samples = av_rescale_rnd(
58 swr_get_delay(swr.get(), frame->sample_rate) + frame->nb_samples,
59 48000, frame->sample_rate, AV_ROUND_UP);
64 data.resize(
static_cast<std::size_t
>(
65 out_samples * av_get_bytes_per_sample(outputSampleFormat)));
70 static_cast<std::size_t
>(
71 out_samples * av_get_bytes_per_sample(outputSampleFormat)));
72 output = data.data() + data.size() -
73 out_samples * av_get_bytes_per_sample(outputSampleFormat);
76 res = swr_convert(swr.get(), &output,
static_cast<int>(out_samples),
77 const_cast<const uint8_t **
>(frame->extended_data),
80 char error[AV_ERROR_MAX_STRING_SIZE];
81 av_make_error_string(error, AV_ERROR_MAX_STRING_SIZE, res);
82 throw std::runtime_error(
83 "Error converting audio in AudioFrameSink: " +
88 circularData.insert(circularData.end(), data.begin(), data.end());
92 void getDataWithoutLock(std::vector<uint8_t> &dataCopy)
override {
94 dataCopy.resize(this->circularData.size());
95 std::copy(this->circularData.begin(), this->circularData.end(),
98 dataCopy.resize(this->data.size());
99 std::copy(this->data.begin(), this->data.end(), dataCopy.begin());
107 AVSampleFormat outputSampleFormat,
int outSampleRate,
108 bool loopRecording =
false, int64_t loopBufferSize = 0)
109 : outChannelLayout(outChannelLayout),
110 outputSampleFormat(outputSampleFormat), outSampleRate(outSampleRate),
111 loopRecording(loopRecording) {
113 circularData.resize(
static_cast<std::size_t
>(
114 loopBufferSize * av_get_bytes_per_sample(outputSampleFormat)));
118 AVMediaType
getType()
const override {
return AVMEDIA_TYPE_AUDIO; }
Definition: AudioFrameSink.h:14
AudioFrameSink(AVChannelLayout outChannelLayout, AVSampleFormat outputSampleFormat, int outSampleRate, bool loopRecording=false, int64_t loopBufferSize=0)
Definition: AudioFrameSink.h:106
AudioFrameSink()
Definition: AudioFrameSink.h:104
AVMediaType getType() const override
Definition: AudioFrameSink.h:118
Definition: FFmpegFrameSink.h:23