MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ encode_frames()

bool MayaFlux::IO::AudioEncodeContext::encode_frames ( std::span< const double >  interleaved,
uint32_t  num_frames,
FFmpegMuxContext mux 
)

Encode a block of interleaved double-precision PCM frames.

Converts input via SwrContext, writes converted samples into the FIFO, then drains the FIFO in encoder-frame-sized chunks. For encoders with frame_size == 0 (PCM, some raw formats) the entire FIFO content is submitted as one frame per call.

Non-blocking: returns false only on a hard encode error, not on FIFO underrun. Safe to call with any number of frames per call.

Parameters
interleavedInterleaved samples in double precision.
num_framesNumber of PCM frames (samples / channels).
muxMux context to receive encoded packets.
Returns
True on success.

Definition at line 228 of file AudioEncodeContext.cpp.

231{
232 if (!is_valid())
233 return false;
234
235 uint8_t** conv = nullptr;
236 int linesize = 0;
237 int alloc = av_samples_alloc_array_and_samples(
238 &conv, &linesize,
239 static_cast<int>(m_channels),
240 static_cast<int>(num_frames),
241 codec_context->sample_fmt, 0);
242
243 if (alloc < 0 || !conv) {
244 m_last_error = "av_samples_alloc_array_and_samples failed during encode";
245 return false;
246 }
247
248 const auto* src = reinterpret_cast<const uint8_t*>(interleaved.data());
249 int converted = swr_convert(
251 conv, static_cast<int>(num_frames),
252 &src, static_cast<int>(num_frames));
253
254 if (converted < 0) {
255 av_freep(static_cast<void*>(&conv[0]));
256 av_freep(static_cast<void*>(&conv));
257 m_last_error = "swr_convert failed";
258 return false;
259 }
260
261 int written = av_audio_fifo_write(fifo,
262 reinterpret_cast<void**>(conv), converted);
263
264 av_freep(static_cast<void*>(&conv[0]));
265 av_freep(static_cast<void*>(&conv));
266
267 if (written < converted) {
268 m_last_error = "av_audio_fifo_write wrote fewer samples than expected";
269 return false;
270 }
271
272 int frame_size = codec_context->frame_size > 0
273 ? codec_context->frame_size
274 : av_audio_fifo_size(fifo);
275
276 while (av_audio_fifo_size(fifo) >= frame_size) {
277 if (!send_fifo_frame(mux, false))
278 return false;
279 }
280
281 return true;
282}
bool is_valid() const
True if codec, resampler, and FIFO are all ready.
bool send_fifo_frame(FFmpegMuxContext &mux, bool pad_to_frame_size)
Pull one frame from the FIFO and send it to the encoder.
AVCodecContext * codec_context
Owned; freed in destructor.
SwrContext * swr_context
Owned; freed in destructor.
AVAudioFifo * fifo
Owned; freed in destructor.

References codec_context, fifo, is_valid(), m_channels, m_last_error, send_fifo_frame(), and swr_context.

Referenced by MayaFlux::IO::SoundFileWriter::worker_loop().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: