arduino-audio-tools
Loading...
Searching...
No Matches
Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Static Protected Attributes | List of all members
VideoMuxerWithTasks Class Reference

Feeds a Muxer (MuxerAVI, MuxerMP4, ...) from two background Tasks instead of a single loop()/copy() call - one per track, each write wrapped in a LockGuard over a shared mutex (real by default; override via setMutex()), since a Muxer is not safe to call from two threads concurrently. More...

#include <VideoMuxerWithTasks.h>

Public Member Functions

 VideoMuxerWithTasks ()=default
 
 VideoMuxerWithTasks (Muxer &muxer)
 
bool begin ()
 
void end ()
 Stops both tasks and closes the Muxer.
 
bool isRunning ()
 
void setAudioEncoder (AudioEncoder &encoder)
 
void setAudioInfo (AudioInfo info)
 
void setAudioSource (AudioStream &out)
 Defines the AudioSource that we can configure with setAudioInfo()
 
void setAudioSource (Stream &pcm)
 
void setMutex (MutexBase &mutex)
 
void setMuxer (Muxer &muxer)
 Defines the Muxer both tasks write to - call before begin().
 
void setTaskParameters (uint32_t stackSizeWords, uint8_t priority, int core=-1)
 
void setVideoEncoder (VideoEncoder &encoder)
 
void setVideoSource (VideoFrameSource &video)
 

Protected Types

using DefaultMutex = Mutex
 

Protected Member Functions

void audioTaskLoop ()
 
void videoTaskLoop ()
 

Protected Attributes

AudioInfo audio_info
 
Task audio_task
 
DefaultMutex default_mutex
 
Streamp_audio = nullptr
 
AudioEncoderp_audio_encoder = nullptr
 
MutexBasep_mutex = &default_mutex
 
Muxerp_muxer = nullptr
 
AudioInfoSupportp_source_audio_info = nullptr
 
VideoFrameSourcep_video = nullptr
 
VideoEncoderp_video_encoder = nullptr
 
int task_core = -1
 
uint8_t task_priority = 2
 
uint32_t task_stack_size = 4096
 
uint32_t video_interval_ms = 33
 
MuxerVideoSink video_sink
 
Task video_task
 

Static Protected Attributes

static constexpr size_t kAudioReadChunkSize = 512
 

Detailed Description

Feeds a Muxer (MuxerAVI, MuxerMP4, ...) from two background Tasks instead of a single loop()/copy() call - one per track, each write wrapped in a LockGuard over a shared mutex (real by default; override via setMutex()), since a Muxer is not safe to call from two threads concurrently.

Audio (setAudioSource() + optional setAudioEncoder()): reads PCM from a Stream expected to deliver data synchronously, at the real capture rate (e.g. a blocking I2S read) - that's this task's only pacing, no timer/delay() of its own. With an encoder, each chunk is handed to it (framed and written to the Muxer by the encoder itself); without one, each chunk is written to the Muxer as raw PCM directly (call setAudioInfo() in that case).

Video (setVideoSource() + optional setVideoEncoder()): pulls one frame per iteration, timed by VideoFrameSource::videoInfo().fps. With an encoder, each raw picture is passed to VideoEncoder::write(); without one, the frame is written to the Muxer as-is (already-encoded).

begin() derives both Muxer tracks from the source/encoder objects above (VideoEncoder::videoInfo().format decides the real container format, not VideoFrameSource's, since that describes the raw picture when an encoder is used) and calls Muxer::begin() itself - the only Muxer setup still needed from the caller is Muxer::setOutput(). end() stops both tasks and closes the Muxer.

Author
Phil Schatzmann

Member Typedef Documentation

◆ DefaultMutex

using DefaultMutex = Mutex
protected

Real mutex type used for the default_mutex member (see setMutex()) - audio_tools::Mutex (MutexRTOS) on RTOS platforms, StdMutex on desktop - both real, so two tasks are protected out of the box without requiring setMutex().

Constructor & Destructor Documentation

◆ VideoMuxerWithTasks() [1/2]

VideoMuxerWithTasks ( )
default

◆ VideoMuxerWithTasks() [2/2]

VideoMuxerWithTasks ( Muxer muxer)
inline

Member Function Documentation

◆ audioTaskLoop()

void audioTaskLoop ( )
inlineprotected

Reads one PCM chunk and either hands it to the audio encoder (which frames and writes it to the Muxer itself) or, without one, writes it to the Muxer directly as one raw PCM frame - no delay() on success: pacing is the PCM Stream's own responsibility (see class comment); a short fallback delay only kicks in if it returned nothing, so a Stream that violates that contract (e.g. non-blocking) can't spin this task at full CPU.

◆ begin()

bool begin ( )
inline

Configures the Muxer's video/audio tracks from the source/encoder objects above, calls Muxer::begin(), then starts the audio and/or video task - see the class comment for exactly what's still the caller's own responsibility beforehand.

◆ end()

void end ( )
inline

Stops both tasks and closes the Muxer.

◆ isRunning()

bool isRunning ( )
inline

◆ setAudioEncoder()

void setAudioEncoder ( AudioEncoder encoder)
inline

Defines the (optional) encoder the audio task hands each PCM chunk to - responsible for framing and writing the encoded result to the Muxer itself; its setOutput() is pointed at the Muxer by begin(), overriding any output previously set on it. Its audioInfo() (set it on the encoder, as usual, before calling this) and mime() (see AudioFormat.h's fromMime() - best-effort; falls back to AudioFormat::PCM if it doesn't map) configure the Muxer's audio track. Leave unset to write setAudioSource()'s PCM straight through instead (see setAudioInfo()).

◆ setAudioInfo()

void setAudioInfo ( AudioInfo  info)
inline

Defines the sample_rate/channels/bits_per_sample of setAudioSource()'s PCM data - only used (instead of AudioEncoder::audioInfo()) when no setAudioEncoder() was called, i.e. the PCM is written to the Muxer as-is. Call before begin().

◆ setAudioSource() [1/2]

void setAudioSource ( AudioStream out)
inline

Defines the AudioSource that we can configure with setAudioInfo()

◆ setAudioSource() [2/2]

void setAudioSource ( Stream pcm)
inline

Defines the raw PCM source the audio task reads from - expected to deliver data synchronously, at the real capture rate (see class comment). On its own (no setAudioEncoder()) each chunk is written to the Muxer as raw PCM - call setAudioInfo() too in that case.

◆ setMutex()

void setMutex ( MutexBase mutex)
inline

Assigns the shared mutex protecting the Muxer from concurrent access by the audio and video tasks - defaults to a real platform mutex (see DefaultMutex below), so this is normally only needed to swap in a different implementation. Call before begin().

◆ setMuxer()

void setMuxer ( Muxer muxer)
inline

Defines the Muxer both tasks write to - call before begin().

◆ setTaskParameters()

void setTaskParameters ( uint32_t  stackSizeWords,
uint8_t  priority,
int  core = -1 
)
inline

Stack size (words, not bytes)/priority/core applied to both tasks - see audio_tools::Task's own constructor comment for what each parameter means and its platform-specific caveats. Call before begin().

◆ setVideoEncoder()

void setVideoEncoder ( VideoEncoder encoder)
inline

Defines the (optional) encoder the video task hands each raw picture from setVideoSource() to - e.g. an H264Encoder (AudioTools/Video/ CodecH264.h), configured as usual (setSize()/setVideoFormat()/...) before passing it here. Leave unset to write setVideoSource()'s bytes straight through as already-encoded frames instead.

◆ setVideoSource()

void setVideoSource ( VideoFrameSource video)
inline

Defines the video frame provider the video task pulls one frame from per iteration - already-encoded unless setVideoEncoder() is also called (see class comment). Leave unset to run the audio task only.

◆ videoTaskLoop()

void videoTaskLoop ( )
inlineprotected

Pulls one frame, encodes/writes it, then sleeps only the remainder of video_interval_ms - compensating for time spent above (a slow encoder otherwise makes the real capture cadence slower than the fps written into the Muxer's video track).

Member Data Documentation

◆ audio_info

AudioInfo audio_info
protected

◆ audio_task

Task audio_task
protected

◆ default_mutex

DefaultMutex default_mutex
protected

◆ kAudioReadChunkSize

constexpr size_t kAudioReadChunkSize = 512
staticconstexprprotected

Size (bytes) of the PCM chunk read from setAudioSource() and handed to setAudioEncoder()'s write() per audio task iteration - purely a throughput/latency knob (the encoder does its own framing on top of however much data it's given), not a correctness-critical value.

◆ p_audio

Stream* p_audio = nullptr
protected

◆ p_audio_encoder

AudioEncoder* p_audio_encoder = nullptr
protected

◆ p_mutex

MutexBase* p_mutex = &default_mutex
protected

◆ p_muxer

Muxer* p_muxer = nullptr
protected

◆ p_source_audio_info

AudioInfoSupport* p_source_audio_info = nullptr
protected

◆ p_video

VideoFrameSource* p_video = nullptr
protected

◆ p_video_encoder

VideoEncoder* p_video_encoder = nullptr
protected

◆ task_core

int task_core = -1
protected

◆ task_priority

uint8_t task_priority = 2
protected

◆ task_stack_size

uint32_t task_stack_size = 4096
protected

◆ video_interval_ms

uint32_t video_interval_ms = 33
protected

◆ video_sink

MuxerVideoSink video_sink
protected

◆ video_task

Task video_task
protected

The documentation for this class was generated from the following file: