|
arduino-audio-tools
|
MPEG-1 System (Program) Stream Encoder, as defined by ISO/IEC 11172-1: muxes an already-encoded MPEG-1 video elementary stream (ISO/IEC 11172-2) and an optional MPEG-1 audio elementary stream (ISO/IEC 11172-3, Layer I/II/III) into pack_header/system_header/PES_packet framing written to a Print (a local File to record, or e.g. a network Client to publish a live stream). More...
#include <ContainerMPG.h>
Public Member Functions | |
| MuxerMPG () | |
| MuxerMPG (Print &out) | |
| size_t | addAudioFrame (const uint8_t *data, size_t len) override |
| size_t | addI420Frame (const uint8_t *data, size_t len) override |
| size_t | addJpegFrame (const uint8_t *data, size_t len) override |
| size_t | addRGB565Frame (const uint8_t *data, size_t len) override |
| size_t | addVideoFrame (const uint8_t *data, size_t len, bool isKeyFrame=true) override |
| size_t | addYUV422Frame (const uint8_t *data, size_t len) override |
| uint32_t | audioFrameCount () |
| AudioInfoFormat & | audioInfo () override |
| Provides read/write access to the audio track's AudioInfoFormat. | |
| bool | begin () override |
| void | end () override |
| Writes the MPEG_program_end_code trailer and closes the muxer. | |
| virtual void | flush () |
| float | getAudioSamplesPerVideoFrame () |
| MuxerVideoConfig | getVideoInfo () override |
| Provides the video track configuration. | |
| const char * | mime () override |
| operator bool () override | |
| void | setAudioInfo (AudioInfoFormat info) override |
| void | setOutput (Print &out) override |
| Defines the output: e.g. a local File or a network Client. | |
| void | setStreamType (StreamContentType type) override |
| Selects whether write() feeds the video or the audio track. | |
| void | setVideoInfo (MuxerVideoConfig config) override |
| StreamContentType | streamType () override |
| The track write() currently targets (see setStreamType()) | |
| uint32_t | videoFrameCount () |
| size_t | write (const uint8_t *data, size_t len) override |
Protected Member Functions | |
| uint64_t | audioPts () |
| uint64_t | clampScr (uint64_t scr) |
| uint64_t | videoPts () |
| size_t | writeAccessUnit (uint8_t stream_id, const uint8_t *data, size_t len, uint64_t pts) |
| size_t | writeElementaryChunk (uint8_t stream_id, const uint8_t *data, size_t len, bool withPts, uint64_t pts) |
| Writes one pack_header + PES header + payload chunk (<= a few KB). | |
| void | writePackHeader (uint64_t scr_in) |
| void | writeStreamEntry (uint8_t id, bool isVideo) |
| void | writeSystemHeader () |
| void | writeTimestampField (uint8_t id4, uint64_t ts) |
Protected Attributes | |
| uint32_t | audio_frame_count = 0 |
| AudioInfoFormat | audio_info |
| bool | has_audio = false |
| bool | is_open = false |
| uint64_t | last_scr = 0 |
| Print * | p_out = nullptr |
| Print * | p_print = nullptr |
| MuxerVideoConfig | video_cfg |
| uint32_t | video_frame_count = 0 |
| StreamContentType | write_stream_type = StreamContentType::Video |
Static Protected Attributes | |
| static const uint32_t | AUDIO_SAMPLES_PER_FRAME = 1152 |
| MPEG-1 Layer II/III audio frames are always 1152 samples. | |
| static const size_t | MAX_PES_PAYLOAD = 4096 |
| static const uint32_t | MUX_RATE = 0x3FFFFF |
MPEG-1 System (Program) Stream Encoder, as defined by ISO/IEC 11172-1: muxes an already-encoded MPEG-1 video elementary stream (ISO/IEC 11172-2) and an optional MPEG-1 audio elementary stream (ISO/IEC 11172-3, Layer I/II/III) into pack_header/system_header/PES_packet framing written to a Print (a local File to record, or e.g. a network Client to publish a live stream).
This is a streaming writer, like MuxerAVI: mux_rate is written as an unspecified placeholder (all bits set) and there is no index/seek table - sufficient for sequential playback but not for random access. Each addVideoFrame()/addAudioFrame() call is one complete access unit; large video frames are automatically split across multiple pack/PES units (PES payload is limited to 16 bits) - only the first fragment of an access unit carries a PTS, exactly what DemuxerMPG uses to find frame boundaries again. SCR/PTS are derived from the frame/sample counters and the configured fps/sample_rate (MPEG-1 audio access units are assumed to be 1152 samples, true for Layer II and Layer III), not a wall clock.
Usage:
An MPEG audio track can be fed directly from an AudioEncoder (e.g. MP3EncoderLAME) - Muxer is itself a Print, so pointing the encoder's output at the muxer and toggling setStreamType() around the PCM write() is all that is needed:
(VideoMuxer/VideoMuxerWithTasks do this setStreamType() toggling, and the video-side driving, automatically - MuxerMPG implements the same Muxer interface as MuxerAVI/MuxerMP4, so it plugs into them unmodified.) Note that the SCR/PTS this muxer writes assume each addAudioFrame()/write() call is exactly one 1152-sample MPEG audio frame; an encoder whose write() calls don't align to real frame boundaries (LAME's often don't) will still produce a byte-correct, fully decodable elementary stream - only the fine-grained timestamp hinting in the file becomes approximate.
|
inline |
|
inlineoverridevirtual |
Writes one complete MPEG-1 audio frame (e.g. one Layer II/III frame, starting at its sync word) as a single pack/PES unit. Ignored (returns 0) if no audio track was configured via setAudioInfo().
Implements Muxer.
|
inlineoverridevirtual |
Writes one planar 4:2:0 YUV (I420/IYUV) frame. Expects exactly width*height*3/2 bytes.
Implements Muxer.
|
inlineoverridevirtual |
|
inlineoverridevirtual |
Writes one uncompressed RGB565 (16-bit, 5-6-5) frame. Expects exactly width*height*2 bytes.
Implements Muxer.
|
inlineoverridevirtual |
Writes one complete MPEG-1 picture (a run of video ES bytes, normally starting at its picture_start_code) as one or more pack/PES units.
| isKeyFrame | accepted for interface compatibility with Muxer::addVideoFrame() - the MPEG-1 video ES already encodes I/P/B picture_coding_type itself, so there is no separate container-level flag to write it into (same convention as MuxerAVI). |
Implements Muxer.
|
inlineoverridevirtual |
Writes one packed 4:2:2 YUV frame (YUY2/YUYV byte order). Expects exactly width*height*2 bytes.
Implements Muxer.
|
inline |
|
inlineoverridevirtual |
Provides read/write access to the audio track's AudioInfoFormat.
Implements Muxer.
|
inlineprotected |
|
inlineoverridevirtual |
Writes the initial pack_header + system_header. Call after configuring video (and audio, if any) and before writing any frames.
Implements Muxer.
|
inlineprotected |
|
inlineoverridevirtual |
Writes the MPEG_program_end_code trailer and closes the muxer.
Implements Muxer.
|
inlinevirtualinherited |
Finalizes the frame most recently written via one or more write() calls - see class comment. Default no-op for implementations that display/decode synchronously in write() instead.
Reimplemented from VideoOutput.
|
inlineinherited |
Average number of audio samples per video frame, derived from audioInfo().sample_rate and getVideoInfo().fps - the natural audio chunk size to write once per video frame if you want to keep both tracks advancing at roughly the same pace as you write them (not a hard requirement - see addAudioFrame()/addVideoFrame()). 0 if fps hasn't been set.
|
inlineoverridevirtual |
Provides the video track configuration.
Implements Muxer.
|
inlineoverridevirtual |
The container's MIME type (e.g. "video/avi", "video/mp4") - useful for e.g. an HTTP Content-Type header when streaming the muxed output to a client.
Implements Muxer.
|
inlineoverridevirtual |
Implements Muxer.
|
inlineoverridevirtual |
Adds an (optional) audio track. info.format selects the codec tag (default/only meaningful choice: AudioFormat::MP3, used generically here for any MPEG-1 Layer I/II/III elementary stream). Call before begin().
Implements Muxer.
|
inlineoverridevirtual |
|
inlineoverridevirtual |
|
inlineoverridevirtual |
Defines the video track configuration - call before begin(). Set config.format = VideoFormat::MPEG1 (the only format this container carries as a real video track).
Implements Muxer.
|
inlineoverridevirtual |
The track write() currently targets (see setStreamType())
Implements Muxer.
|
inline |
|
inlineprotected |
|
inlineoverridevirtual |
VideoOutput API / generic sink: writes one complete frame to whichever track streamType() currently selects.
Implements VideoOutput.
|
inlineprotected |
Splits one access unit (a full encoded video picture, or one audio frame) across as many pack/PES units as needed; only the first carries a PTS.
|
inlineprotected |
Writes one pack_header + PES header + payload chunk (<= a few KB).
|
inlineprotected |
|
inlineprotected |
|
inlineprotected |
|
inlineprotected |
|
protected |
|
protected |
|
staticprotected |
MPEG-1 Layer II/III audio frames are always 1152 samples.
|
protected |
|
protected |
|
protected |
|
staticprotected |
Video/audio PES payload is chunked at this size so the 16-bit PES_packet_length field (and the optional-header bytes) always fit, with margin to spare - real encoders commonly interleave in similarly sized packets rather than one huge PES per access unit.
|
staticprotected |
mux_rate: 22-bit field, unit 50 bytes/sec - all-ones is used here as an "unspecified/streaming" placeholder, the same convention MuxerAVI uses for its unknown RIFF/movi sizes.
|
protected |
|
protectedinherited |
|
protected |
|
protected |
|
protected |