arduino-audio-tools
Loading...
Searching...
No Matches
Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | List of all members

ISO/IEC 13818-1 MPEG Transport Stream Demuxer: parses the fixed 188-byte TS packet framing, follows PAT -> PMT to discover the video and (optional) audio elementary stream PIDs and their codec (stream_type), reassembles each PES packet's payload from the TS packets between one payload_unit_start_indicator and the next, and forwards the raw elementary-stream bytes to setOutputVideo()/setOutputAudio() - same scope and design as DemuxerMPG (ContainerMPG.h): no decoding happens here, point the outputs at whatever decoder understands the codec. More...

#include <ContainerMTS.h>

Inheritance diagram for DemuxerMTS:
Demuxer ContainerDecoder MimeSource VideoInfoSource AudioDecoder AudioWriter AudioInfoSource AudioInfoSupport

Public Member Functions

 DemuxerMTS (int bufferSize=8 *MTS_PACKET_SIZE)
 
virtual void addNotifyAudioChange (AudioInfoSupport &bi)
 Adds target to be notified about audio changes.
 
AudioInfo audioInfo () override
 provides the actual input AudioInfo
 
virtual AudioInfo audioInfoOut ()
 
bool begin () override
 
virtual bool begin (AudioInfo info) override
 
virtual void clearNotifyAudioChange ()
 Deletes all change notify subscriptions.
 
void end () override
 
AudioInfoFormat getAudioInfo () override
 
PrintgetOutput ()
 
VideoInfo getVideoInfo () override
 
bool isNotifyActive ()
 Checks if the automatic AudioInfo update is active.
 
bool isValid (const uint8_t *data, size_t len) override
 
const char * mime () override
 
const char * mimeVideo () override
 The container's MIME type (e.g. "video/avi", "video/mp4").
 
 operator bool () override
 
virtual bool removeNotifyAudioChange (AudioInfoSupport &bi)
 Removes a target in order not to be notified about audio changes.
 
void setAudioInfo (AudioInfo from) override
 for most decoders this is not needed
 
virtual bool setCodecConfig (const uint8_t *data, size_t len)
 Some decoders need e.g. a magic cookie to provide the relevant info for decoding.
 
void setNotifyActive (bool flag)
 Deactivate/Reactivate automatic AudioInfo updates: (default is active)
 
virtual void setOutput (AudioOutput &out_stream)
 Defines where the decoded result is written to.
 
virtual void setOutput (AudioStream &out_stream)
 Defines where the decoded result is written to.
 
void setOutput (Print &out) override
 Defines where the decoded result is written to.
 
void setOutputAudio (Print &out) override
 
void setOutputVideo (Print &out) override
 
void setOutputVideo (VideoOutput &out) override
 
void setSendWavHeader (bool flag) override
 
VideoInfo videoInfo () override
 
size_t write (const uint8_t *data, size_t len) override
 

Public Attributes

int id
 custom id to be used by application
 

Protected Member Functions

void appendToAudio (const uint8_t *data, size_t len)
 
void appendToUnit (bool isVideo, const uint8_t *data, size_t len)
 
void appendToVideo (const uint8_t *data, size_t len)
 
void flushAudioUnit ()
 
void flushUnit (bool isVideo)
 
void flushVideoUnit ()
 
void handlePesPayload (bool isVideo, const uint8_t *payload, size_t len, bool pusi)
 
void notifyAudioChange (AudioInfo info)
 
bool parse ()
 
void parsePacket (const uint8_t *pkt)
 
void parsePat (const uint8_t *data, size_t len, bool pusi)
 
void parsePmt (const uint8_t *data, size_t len, bool pusi)
 
void probeAudioHeader (const uint8_t *data, size_t len)
 
void writeBlocking (Print *out, uint8_t *data, size_t len)
 

Protected Attributes

uint8_t audio_channels = 0
 
bool audio_frame_open = false
 
bool audio_header_parsed = false
 
uint16_t audio_pid = 0xFFFF
 
Vector< uint8_t > audio_probe
 
uint32_t audio_sample_rate = 0
 
uint8_t audio_stream_type = 0
 
Vector< uint8_t > audio_unit_buffer
 
size_t audio_unit_len = 0
 
AudioInfo info
 
bool is_notify_active = true
 
bool is_parsing_active = false
 
Vector< AudioInfoSupport * > notify_vector
 
Printp_output_audio = nullptr
 
Printp_output_video = nullptr
 
VideoOutputp_output_video_video = nullptr
 
Printp_print = nullptr
 
MTSParseBuffer parse_buffer
 
uint16_t pmt_pid = 0xFFFF
 
uint32_t total_bytes = 0
 
bool video_frame_open = false
 
uint16_t video_pid = 0xFFFF
 
uint8_t video_stream_type = 0
 
Vector< uint8_t > video_unit_buffer
 
size_t video_unit_len = 0
 

Detailed Description

ISO/IEC 13818-1 MPEG Transport Stream Demuxer: parses the fixed 188-byte TS packet framing, follows PAT -> PMT to discover the video and (optional) audio elementary stream PIDs and their codec (stream_type), reassembles each PES packet's payload from the TS packets between one payload_unit_start_indicator and the next, and forwards the raw elementary-stream bytes to setOutputVideo()/setOutputAudio() - same scope and design as DemuxerMPG (ContainerMPG.h): no decoding happens here, point the outputs at whatever decoder understands the codec.

PES packet boundaries (marked by payload_unit_start_indicator) are used directly as access-unit boundaries - i.e. every new PES packet on the video/audio PID flushes the previous one as one complete write() call to the corresponding output, mirroring how a real TS muxer (including MuxerMTS itself) packetizes one access unit per PES packet. This is simpler than DemuxerMPG's own PES-length/start-code-driven framing, because TS's own PID demultiplexing already separates the elementary streams apart - no need to hunt for start codes in a mixed byte stream.

Note
v1 scope: a single video track and a single audio track (the first of each found in the PMT) - multi-program and multi-track transport streams are not supported. Recognized video stream_types are H.264 (0x1B), MPEG-1/2 (0x01/0x02), MPEG-4 (0x10) and MJPEG (0x06 - see MTS_STREAM_TYPE_MJPEG's own comment on why that mapping is a convention, not an ISO standard one); recognized audio stream_types are AAC/ADTS (0x0F) and MPEG-1/2 audio (0x03/0x04). The PES header is assumed to fit within the first TS packet of its PES packet (always true in practice - the PES optional header used here is at most 14 bytes, far under a TS packet's 184-byte payload capacity even with heavy adaptation-field stuffing); a PES header split across a TS packet boundary is logged and that access unit is dropped. Video width/height are not parsed (unlike DemuxerMPG, which can read them from MPEG-1's own sequence_header) - H.264 SPS parsing is out of scope for this library; getVideoInfo() reports only the codec (VideoFormat) and total bytes seen.
DemuxerMTS demuxer;
H264Decoder h264; // or any AudioTools H264 decoder
demuxer.setOutputVideo(videoOutput);
EncodedAudioStream audioOut(&i2s, &aac);
demuxer.setOutputAudio(audioOut);
demuxer.begin();
// feed raw .ts bytes:
demuxer.write(tsData, len);
AAC Decoder using libhelix: https://github.com/pschatzmann/codec-helix This is basically just a simpl...
Definition CodecAACHelix.h:20
ISO/IEC 13818-1 MPEG Transport Stream Demuxer: parses the fixed 188-byte TS packet framing,...
Definition ContainerMTS.h:234
void setOutputAudio(Print &out) override
Definition ContainerMTS.h:289
size_t write(const uint8_t *data, size_t len) override
Definition ContainerMTS.h:323
bool begin() override
Definition ContainerMTS.h:259
void setOutputVideo(Print &out) override
Definition ContainerMTS.h:291
A more natural Stream class to process encoded data (aac, wav, mp3...) which also supports the decodi...
Definition AudioEncoded.h:282
H.264 video decoder: wraps TinyH264Decoder (https://github.com/pschatzmann/TinyH264) as a VideoOutput...
Definition CodecH264.h:58
Author
Phil Schatzmann

Constructor & Destructor Documentation

◆ DemuxerMTS()

DemuxerMTS ( int  bufferSize = 8 * MTS_PACKET_SIZE)
inline
Parameters
bufferSizeinternal parse buffer size - must be able to hold at least one full 188-byte TS packet; a few packets' worth (the default) keeps write() from truncating a typical caller-sized chunk.

Member Function Documentation

◆ addNotifyAudioChange()

virtual void addNotifyAudioChange ( AudioInfoSupport bi)
inlinevirtualinherited

◆ appendToAudio()

void appendToAudio ( const uint8_t *  data,
size_t  len 
)
inlineprotected

◆ appendToUnit()

void appendToUnit ( bool  isVideo,
const uint8_t *  data,
size_t  len 
)
inlineprotected

◆ appendToVideo()

void appendToVideo ( const uint8_t *  data,
size_t  len 
)
inlineprotected

Appends to video_unit_buffer with amortized (doubling) growth, same rationale as ContainerMPG.h's own appendToVideo/appendToAudio.

◆ audioInfo()

AudioInfo audioInfo ( )
inlineoverridevirtualinherited

◆ audioInfoOut()

virtual AudioInfo audioInfoOut ( )
inlinevirtualinherited

◆ begin() [1/2]

bool begin ( )
inlineoverridevirtual

Reimplemented from AudioDecoder.

◆ begin() [2/2]

virtual bool begin ( AudioInfo  info)
inlineoverridevirtualinherited

Reimplemented from AudioWriter.

Reimplemented in DecoderBasic, and OggContainerDecoder.

◆ clearNotifyAudioChange()

virtual void clearNotifyAudioChange ( )
inlinevirtualinherited

Deletes all change notify subscriptions.

Reimplemented in RTSPClient< TcpClient, UdpSocket >.

◆ end()

void end ( )
inlineoverridevirtual

Reimplemented from AudioDecoder.

◆ flushAudioUnit()

void flushAudioUnit ( )
inlineprotected

◆ flushUnit()

void flushUnit ( bool  isVideo)
inlineprotected

◆ flushVideoUnit()

void flushVideoUnit ( )
inlineprotected

◆ getAudioInfo()

AudioInfoFormat getAudioInfo ( )
inlineoverridevirtual

Common audio info, parsed from the audio ES's own ADTS/MPEG-audio frame header once seen - falls back to 44100/stereo if not yet available.

Implements Demuxer.

◆ getOutput()

Print * getOutput ( )
inlineinherited

◆ getVideoInfo()

VideoInfo getVideoInfo ( )
inlineoverridevirtual

Common video info - format is the PMT-reported codec once the PMT has been parsed (VideoFormat::UNKNOWN before then, or if the stream_type isn't one this container recognizes); width/height/fps are not parsed (see class comment) and stay 0.

Implements Demuxer.

◆ handlePesPayload()

void handlePesPayload ( bool  isVideo,
const uint8_t *  payload,
size_t  len,
bool  pusi 
)
inlineprotected

Reassembles one PES packet's payload per PID from the TS packets between one payload_unit_start_indicator and the next - see class comment for why a PUSI boundary is used directly as the access-unit boundary instead of tracking PES_packet_length.

◆ isNotifyActive()

bool isNotifyActive ( )
inlineinherited

Checks if the automatic AudioInfo update is active.

◆ isValid()

bool isValid ( const uint8_t *  data,
size_t  len 
)
inlineoverridevirtual

True if data starts with the TS sync byte (0x47), confirmed by a second sync byte 188 bytes later when enough data is available - see Demuxer::isValid().

Reimplemented from Demuxer.

◆ mime()

const char * mime ( )
inlineoverridevirtual

Provides the audio mime, derived from the PMT's audio stream_type once parsed - "audio/aac" (the common case for .ts/HLS content) before that.

Implements Demuxer.

◆ mimeVideo()

const char * mimeVideo ( )
inlineoverridevirtual

The container's MIME type (e.g. "video/avi", "video/mp4").

Implements Demuxer.

◆ notifyAudioChange()

void notifyAudioChange ( AudioInfo  info)
inlineprotectedinherited

◆ operator bool()

operator bool ( )
inlineoverridevirtual

Implements AudioWriter.

◆ parse()

bool parse ( )
inlineprotected

Consumes one 188-byte packet (resyncing on the sync byte first, if needed) and parses it. Returns true if progress was made (call again

  • more packets may already be buffered), false if it needs more data.

◆ parsePacket()

void parsePacket ( const uint8_t *  pkt)
inlineprotected

◆ parsePat()

void parsePat ( const uint8_t *  data,
size_t  len,
bool  pusi 
)
inlineprotected

Parses the Program Association Section, picking the PID of the PMT for the first program listed (program_number != 0).

◆ parsePmt()

void parsePmt ( const uint8_t *  data,
size_t  len,
bool  pusi 
)
inlineprotected

Parses the (single-section) Program Map, picking out the PID/ stream_type of the first video and first audio elementary stream.

◆ probeAudioHeader()

void probeAudioHeader ( const uint8_t *  data,
size_t  len 
)
inlineprotected

Inspects the first bytes of the audio ES for an ADTS (AAC) or MPEG audio frame header - whichever matches audio_stream_type - to determine sample_rate/channels. Same approach as ContainerMPG.h's probeAudioHeader(), adapted for ADTS's layout.

◆ removeNotifyAudioChange()

virtual bool removeNotifyAudioChange ( AudioInfoSupport bi)
inlinevirtualinherited

Removes a target in order not to be notified about audio changes.

Reimplemented in RTSPClient< TcpClient, UdpSocket >.

◆ setAudioInfo()

void setAudioInfo ( AudioInfo  from)
inlineoverridevirtualinherited

for most decoders this is not needed

Implements AudioWriter.

Reimplemented in DecoderALAC, CodecChain, DSFDecoder, DecoderL8, OpusAudioDecoder, OpusMultiStreamAudioDecoder, CodecNOP, G729Decoder, and G7xxDecoder.

◆ setCodecConfig()

virtual bool setCodecConfig ( const uint8_t *  data,
size_t  len 
)
inlinevirtualinherited

Some decoders need e.g. a magic cookie to provide the relevant info for decoding.

Reimplemented in DecoderALAC, and MultiDecoder.

◆ setNotifyActive()

void setNotifyActive ( bool  flag)
inlineinherited

Deactivate/Reactivate automatic AudioInfo updates: (default is active)

◆ setOutput() [1/3]

virtual void setOutput ( AudioOutput out_stream)
inlinevirtualinherited

Defines where the decoded result is written to.

Reimplemented in ADTSDecoder, CodecChain, MTSDecoder, MTSDecoderTSDemux, and MetaDataFilterDecoder.

◆ setOutput() [2/3]

virtual void setOutput ( AudioStream out_stream)
inlinevirtualinherited

Defines where the decoded result is written to.

Reimplemented in ADTSDecoder, CodecChain, MTSDecoder, MTSDecoderTSDemux, and MetaDataFilterDecoder.

◆ setOutput() [3/3]

void setOutput ( Print out_stream)
inlineoverridevirtual

Defines where the decoded result is written to.

Reimplemented from AudioDecoder.

◆ setOutputAudio()

void setOutputAudio ( Print out)
inlineoverridevirtual

Defines the audio output stream - e.g. an EncodedAudioStream wrapping an AudioDecoder that matches the track's codec, or any other Print if you want the raw payload as-is.

Implements Demuxer.

◆ setOutputVideo() [1/2]

void setOutputVideo ( Print out)
inlineoverridevirtual

Defines the video output - e.g. a VideoOutput implementation, or any other Print if you want the raw payload as-is.

Implements Demuxer.

◆ setOutputVideo() [2/2]

void setOutputVideo ( VideoOutput out)
inlineoverridevirtual

Defines the video output - the VideoOutput-specific counterpart of setOutputVideo(Print&), for a target like PacedVideoOutput/ OutputTinyGPU/OutputOpenCV that implements VideoOutput but not Print (the two are unrelated types - see VideoFrameMeter's own comment). Part of the base interface (unlike other concrete-class-specific extras) so code holding only a Demuxer& (e.g. VideoPlayer) can wire it to an arbitrary VideoOutput& without knowing the concrete container format - every current demuxer already implemented this identically before it was pulled up into the interface.

Implements Demuxer.

◆ setSendWavHeader()

void setSendWavHeader ( bool  flag)
inlineoverridevirtual

Not applicable: both AAC (ADTS) and MPEG audio are compressed and self-framed, never PCM - provided only to satisfy the Demuxer interface.

Implements Demuxer.

◆ videoInfo()

VideoInfo videoInfo ( )
inlineoverridevirtualinherited

Fulfills VideoInfoSource::videoInfo(), so any Demuxer can be passed directly to e.g. OutputOpenCV::setVideoInfoSource() - note the reported 'format' is the container's codec (e.g. H264), not necessarily what ends up written to a raw-picture VideoOutput/Print (that depends on whatever decoder sits between the demuxer and the output); consumers that care about the decoded format should still set it explicitly and rely on this only for width/height.

Implements VideoInfoSource.

◆ write()

size_t write ( const uint8_t *  data,
size_t  len 
)
inlineoverridevirtual

Implements AudioWriter.

◆ writeBlocking()

void writeBlocking ( Print out,
uint8_t *  data,
size_t  len 
)
inlineprotectedinherited

Member Data Documentation

◆ audio_channels

uint8_t audio_channels = 0
protected

◆ audio_frame_open

bool audio_frame_open = false
protected

◆ audio_header_parsed

bool audio_header_parsed = false
protected

◆ audio_pid

uint16_t audio_pid = 0xFFFF
protected

◆ audio_probe

Vector<uint8_t> audio_probe
protected

◆ audio_sample_rate

uint32_t audio_sample_rate = 0
protected

◆ audio_stream_type

uint8_t audio_stream_type = 0
protected

◆ audio_unit_buffer

Vector<uint8_t> audio_unit_buffer
protected

◆ audio_unit_len

size_t audio_unit_len = 0
protected

◆ id

int id
inherited

custom id to be used by application

◆ info

AudioInfo info
protectedinherited

◆ is_notify_active

bool is_notify_active = true
protectedinherited

◆ is_parsing_active

bool is_parsing_active = false
protected

◆ notify_vector

Vector<AudioInfoSupport*> notify_vector
protectedinherited

◆ p_output_audio

Print* p_output_audio = nullptr
protected

◆ p_output_video

Print* p_output_video = nullptr
protected

◆ p_output_video_video

VideoOutput* p_output_video_video = nullptr
protected

◆ p_print

Print* p_print = nullptr
protectedinherited

◆ parse_buffer

MTSParseBuffer parse_buffer
protected

◆ pmt_pid

uint16_t pmt_pid = 0xFFFF
protected

◆ total_bytes

uint32_t total_bytes = 0
protected

◆ video_frame_open

bool video_frame_open = false
protected

◆ video_pid

uint16_t video_pid = 0xFFFF
protected

◆ video_stream_type

uint8_t video_stream_type = 0
protected

◆ video_unit_buffer

Vector<uint8_t> video_unit_buffer
protected

◆ video_unit_len

size_t video_unit_len = 0
protected

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