Switch Controller
Loading...
Searching...
No Matches
AudioFrameSink.h
Go to the documentation of this file.
1#pragma once
2
3#include "FFmpegFrameSink.h"
4
5#include <boost/circular_buffer.hpp>
6
7extern "C" {
8#include <libavutil/channel_layout.h>
9#include <libavutil/opt.h>
10#include <libavutil/samplefmt.h>
11#include <libswresample/swresample.h>
12}
13
15private:
16 std::vector<uint8_t> data;
17 struct SwrContextDeleter {
18 void operator()(SwrContext *s) { swr_free(&s); }
19 };
20 std::unique_ptr<SwrContext, SwrContextDeleter> swr;
21
22 AVChannelLayout outChannelLayout = AV_CHANNEL_LAYOUT_MONO;
23 AVSampleFormat outputSampleFormat = AV_SAMPLE_FMT_FLT;
24 int outSampleRate = 48000;
25
26 bool loopRecording = false;
27 boost::circular_buffer<uint8_t> circularData;
28
29 void virtualInit(AVCodecContext *decoderContext) override {
30
31 spdlog::info("intitializing AudioFrameSink");
32
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, // we're allocating a new context
37 &outChannelLayout, // out_ch_layout
38 outputSampleFormat, // out_sample_fmt
39 outSampleRate, // out_sample_rate
40 &decoderContext->ch_layout, // in_ch_layout
41 decoderContext->sample_fmt, // in_sample_fmt
42 decoderContext->sample_rate, // in_sample_rate
43 0, // log_offset
44 nullptr); // log_ctx
45 swr = {temp, SwrContextDeleter()};
46 int res = swr_init(swr.get());
47 if (res < 0) {
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 " +
51 std::string(error));
52 }
53 spdlog::info("intitialized AudioFrameSink");
54 }
55
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);
60 uint8_t *output;
61 int res;
62
63 if (loopRecording) {
64 data.resize(static_cast<std::size_t>(
65 out_samples * av_get_bytes_per_sample(outputSampleFormat)));
66 output = data.data();
67 } else {
68 data.resize(
69 data.size() +
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);
74 }
75
76 res = swr_convert(swr.get(), &output, static_cast<int>(out_samples),
77 const_cast<const uint8_t **>(frame->extended_data),
78 frame->nb_samples);
79 if (res < 0) {
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: " +
84 std::string(error));
85 }
86
87 if (loopRecording) {
88 circularData.insert(circularData.end(), data.begin(), data.end());
89 }
90 }
91
92 void getDataWithoutLock(std::vector<uint8_t> &dataCopy) override {
93 if (loopRecording) {
94 dataCopy.resize(this->circularData.size());
95 std::copy(this->circularData.begin(), this->circularData.end(),
96 dataCopy.begin());
97 } else {
98 dataCopy.resize(this->data.size());
99 std::copy(this->data.begin(), this->data.end(), dataCopy.begin());
100 }
101 }
102
103public:
105
106 AudioFrameSink(AVChannelLayout outChannelLayout,
107 AVSampleFormat outputSampleFormat, int outSampleRate,
108 bool loopRecording = false, int64_t loopBufferSize = 0)
109 : outChannelLayout(outChannelLayout),
110 outputSampleFormat(outputSampleFormat), outSampleRate(outSampleRate),
111 loopRecording(loopRecording) {
112 if (loopRecording) {
113 circularData.resize(static_cast<std::size_t>(
114 loopBufferSize * av_get_bytes_per_sample(outputSampleFormat)));
115 }
116 }
117
118 AVMediaType getType() const override { return AVMEDIA_TYPE_AUDIO; }
119};
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