Loading...
Searching...
No Matches
AudioFrameEncoder.hpp
1#pragma once
2
3#include <Media/Libav.hpp>
4#if SCORE_HAS_LIBAV
5extern "C" {
6#include <libavutil/frame.h>
7}
8
9#include <ossia/dataflow/float_to_sample.hpp>
10
11namespace Gfx
12{
13
15{
16 explicit AudioFrameEncoder(int target_buffer_size)
17 : target_buffer_size{target_buffer_size}
18 {
19 }
20
21 // We assume that vec has correct channel count here
22 // Also that vec.size() > 0
23 virtual void add_frame(AVFrame& frame, const tcb::span<ossia::float_vector> vec) = 0;
24 virtual ~AudioFrameEncoder() = default;
25 int target_buffer_size{};
26};
27
29{
30 using AudioFrameEncoder::AudioFrameEncoder;
31
32 boost::container::vector<int16_t> data;
33
34 void add_frame(AVFrame& frame, const tcb::span<ossia::float_vector> vec) override
35 {
36 const int channels = vec.size();
37 const int frames = vec[0].size();
38 data.clear();
39 data.resize(frames * channels, boost::container::default_init);
40 auto ptr = data.data();
41 for(int i = 0; i < frames; i++)
42 for(int c = 0; c < channels; c++)
43 *ptr++ = ossia::float_to_sample<int16_t, 16>(vec[c][i]);
44
45 frame.data[0] = (uint8_t*)data.data();
46 frame.data[1] = nullptr;
47 }
48};
49
51{
52 using AudioFrameEncoder::AudioFrameEncoder;
53
54 boost::container::vector<int32_t> data;
55 void add_frame(AVFrame& frame, const tcb::span<ossia::float_vector> vec) override
56 {
57 const int channels = vec.size();
58 const int frames = vec[0].size();
59 data.clear();
60 data.resize(frames * channels, boost::container::default_init);
61 auto ptr = data.data();
62 for(int i = 0; i < frames; i++)
63 for(int c = 0; c < channels; c++)
64 *ptr++ = ossia::float_to_sample<int32_t, 24>(vec[c][i]);
65
66 frame.data[0] = (uint8_t*)data.data();
67 frame.data[1] = nullptr;
68 }
69};
70
72{
73 using AudioFrameEncoder::AudioFrameEncoder;
74
75 boost::container::vector<int32_t> data;
76 void add_frame(AVFrame& frame, const tcb::span<ossia::float_vector> vec) override
77 {
78 const int channels = vec.size();
79 const int frames = vec[0].size();
80 data.clear();
81 data.resize(frames * channels, boost::container::default_init);
82 auto ptr = data.data();
83 for(int i = 0; i < frames; i++)
84 for(int c = 0; c < channels; c++)
85 *ptr++ = ossia::float_to_sample<int32_t, 32>(vec[c][i]);
86
87 frame.data[0] = (uint8_t*)data.data();
88 frame.data[1] = nullptr;
89 }
90};
91
93{
94 using AudioFrameEncoder::AudioFrameEncoder;
95
96 boost::container::vector<float> data;
97
98 void add_frame(AVFrame& frame, const tcb::span<ossia::float_vector> vec) override
99 {
100 const int channels = vec.size();
101 const int frames = vec[0].size();
102 data.clear();
103 data.resize(frames * channels, boost::container::default_init);
104 auto ptr = data.data();
105 for(int i = 0; i < frames; i++)
106 for(int c = 0; c < channels; c++)
107 *ptr++ = vec[c][i];
108
109 frame.data[0] = (uint8_t*)data.data();
110 frame.data[1] = nullptr;
111 }
112};
113
115{
116 using AudioFrameEncoder::AudioFrameEncoder;
117
118 boost::container::vector<double> data;
119
120 void add_frame(AVFrame& frame, const tcb::span<ossia::float_vector> vec) override
121 {
122 const int channels = vec.size();
123 const int frames = vec[0].size();
124 data.clear();
125 data.resize(frames * channels, boost::container::default_init);
126 auto ptr = data.data();
127 for(int i = 0; i < frames; i++)
128 for(int c = 0; c < channels; c++)
129 *ptr++ = vec[c][i];
130
131 frame.data[0] = (uint8_t*)data.data();
132 frame.data[1] = nullptr;
133 }
134};
135
137{
138 using AudioFrameEncoder::AudioFrameEncoder;
139
140 void add_frame(AVFrame& frame, const tcb::span<ossia::float_vector> vec) override
141 {
142 const int channels = vec.size();
143 if(channels <= AV_NUM_DATA_POINTERS)
144 {
145 for(int i = 0; i < channels; ++i)
146 {
147 frame.data[i] = reinterpret_cast<uint8_t*>(vec[i].data());
148 }
149 }
150 else
151 {
152 // FIXME where does this get freed???
153 frame.extended_data
154 = static_cast<uint8_t**>(av_malloc(channels * sizeof(*frame.extended_data)));
155 int i = 0;
156 for(; i < AV_NUM_DATA_POINTERS; ++i)
157 {
158 frame.data[i] = reinterpret_cast<uint8_t*>(vec[i].data());
159 frame.extended_data[i] = reinterpret_cast<uint8_t*>(vec[i].data());
160 }
161 for(; i < channels; ++i)
162 frame.extended_data[i] = reinterpret_cast<uint8_t*>(vec[i].data());
163 }
164 }
165};
166}
167#endif
Binds the rendering pipeline to ossia processes.
Definition CameraDevice.cpp:28
Definition AudioFrameEncoder.hpp:15
Definition AudioFrameEncoder.hpp:115
Definition AudioFrameEncoder.hpp:93
Definition AudioFrameEncoder.hpp:137
Definition AudioFrameEncoder.hpp:29
Definition AudioFrameEncoder.hpp:51
Definition AudioFrameEncoder.hpp:72