TSDuck v3.38-3696
MPEG Transport Stream Toolkit
Loading...
Searching...
No Matches
ts::PacketEncapsulation Class Reference

An efficient TSDuck-specific TS packets encapsulation in a PID. More...

#include <tsPacketEncapsulation.h>

Public Types

enum  PESMode {
  DISABLED = 0 ,
  FIXED = 1 ,
  VARIABLE = 2
}
 Type of PES encapsulation mode. More...
 

Public Member Functions

 PacketEncapsulation (PID pidOutput=PID_NULL, const PIDSet &pidInput=NoPID, PID pcrReference=PID_NULL)
 Constructor.
 
void addInputPID (PID pid)
 Add one PID to encapsulate.
 
bool hasError () const
 Check if a previous error is pending.
 
const PIDSetinputPIDs () const
 Get the current set of input PID's.
 
const UStringlastError () const
 Get the last error message.
 
PID outputPID () const
 Get the output PID.
 
size_t pidCount () const
 Get the current number of input PID's being encapsulated.
 
bool processPacket (TSPacket &pkt)
 Process a TS packet from the input stream.
 
PID referencePCR () const
 Get the reference PID for PCR's.
 
void removeInputPID (PID pid)
 Remove one PID to encapsulate.
 
void reset (PID pidOutput=PID_NULL, const PIDSet &pidInput=NoPID, PID pcrReference=PID_NULL)
 Reset the encapsulation.
 
void resetError ()
 Reset the last error.
 
void setInputPIDs (const PIDSet &pidInput)
 Replace the set of input PID's.
 
void setMaxBufferedPackets (size_t count)
 Set the maximum number of buffered packets.
 
void setOutputPID (PID pid)
 Change the output PID.
 
void setPacking (bool on, size_t limit)
 Set packing mode.
 
void setPES (PESMode mode)
 Set PES mode.
 
void setPESOffset (size_t offset)
 Set PES Offset.
 
void setReferencePCR (PID pid)
 Change the reference PID for PCR's.
 

Static Public Attributes

static constexpr size_t DEFAULT_MAX_BUFFERED_PACKETS = 1024
 Default maximum number of buffered packets.
 

Detailed Description

An efficient TSDuck-specific TS packets encapsulation in a PID.

An instance of this class encapsulates several PID's from the input transport stream into one single output PID. Functionally, this is a subset of the features of T2-MI but much more lightweight and significantly faster to process.

Encapsulation format (plain)

In the output elementary stream (ES), all input TS packets are contiguous, without encapsulation. The initial 0x47 synchronization byte is removed. Only the remaining 187 bytes are encapsulated.

In the output PID, the packetization is similar to sections, with 187-bytes packets instead of sections. The Payload Unit Start Indicator (PUSI) bit is set in the header of TS packets containing the start of an encapsulated packet. When the PUSI bit is set, the first byte of the payload is a "pointer field" to the beginning of the first encapsulated packet.

Due to the overhead of the TS header, the number of output packets is slightly larger than the input packets. The input streams must contain a few null packets to absorb the extra output packets. For this reason, null packets (PID 0x1FFF) are never encapsulated.

Encapsulation format (PES)

When selecting the PES encapsulation the same plain elementary stream is used, but with a PES envelope. This reduces the payload size, but makes the outer encapsulation more transparent. The full overhead is around 14-20% of additional data.

The PES envelope uses a KLVA SMPTE-336M encapsulation to insert the inner payload into one private (testing) key. Each TS packet contains only one key, with a size no larger than the payload of one TS packet. So each PES packet fits into a single TS packet.

The SMPTE-336M encapsulation implemented can be either the asynchronous (without timestamps) or the synchronous (with PTS). The latter consumes more space (+10 bytes), and it's only useful when it's needed to remux the encapsulated stream with an external tool that requires to use PTS marks. No other advantages are provided.

Two variant strategies are implemented. The FIXED mode uses the short (7-bit) BER encoding. This limits the PES payload to a maximum of 127 bytes. And the adaptation field of the outer packet is enlarged with some stuff. However, the advantage is that the PES is sufficient small to include more data in the outer TS packet. This reduces the possibility than some external processing will split the outer packet in two to accommodate the entire PES data.

The VARIABLE mode does not impose this restriction and outer packets are filled to the maximum. The drawback is that sometimes the long form of BER encoding is used with two bytes and others the short form with one byte. Furthermore, this increases the chances that some external processing occupies two outer packets for the same inner PES packet. Still, support for those split PES packets is included. The only requirement is that the 26|27 PES+KLVA header is inserted in the first packet (with PUSI on). The remaining payload can be distributed in the following TS packets.

The PES envelope has an overhead of 26|27|36|37 bytes based on:

  • 9 bytes for the PES header.
  • 0|5 bytes for the PTS (only in synchronous mode)
  • 0|5 bytes for the Metadata AU Header (only in synchronous mode)
  • 16 bytes for the UL key
  • 1|2 bytes for the payload size (BER short or long format)

To enable the use of the Synchronous encapsulation is required to use PCRs and provide one offset. This value (positive or negative) will be added to the PCR to compute the PTS. Recommended values are between -90000 and +90000 (-1,+1 second). If you use negative values then you can restore in advance the encapsulated stream after remuxing. However, this will be valid only if you use an external tool to remux. If you're unsure, then don't enable it.

A warning about the Synchronous mode: At start the PTS marks can't be in synch with the target pcr-pid. This is because the PCR value isn't readed at start. But the PTS is required to be in all PES packets of the encapsulation. So, it's recommended to discard the outcoming stream until valid PTS values appear in the encapsulated stream.

In order to correctly identify the encapsulated PES stream, it is recommended to include in the PMT table a format identifier descriptor for "KLVA" (0x4B4C5641); and use the associated metadata for the stream type based on the selected Sync/Async mode:

  • Asynchronous mode: Private Type (0x06)
  • Synchronous mode: Metadata Type (0x15)

Example (Asynchronous):

tsp ...
-P encap -o 7777 --pes-mode ...
-P pmt -s 100 -a 7777/0x06 --add-programinfo-id 0x4B4C5641
...

where the outer PID is 7777 and the attached service is 100.

Example (Synchronous):

tsp ...
-P encap -o 7777 --pes-mode ... --pcr-pid 101 --pes-offset=-50000
-P pmt -s 100 -a 7777/0x15 --add-programinfo-id 0x4B4C5641
...

where the outer PID is 7777, the pid 101 carries the PCR of the service, the attached service is 100 and the PTS is advanced around half second.

See also
https://impleotv.com/2017/02/17/klv-encoded-metadata-in-stanag-4609-streams/

Member Enumeration Documentation

◆ PESMode

Type of PES encapsulation mode.

Enumerator
DISABLED 

PES mode is disabled.

FIXED 

Fixed PES mode.

VARIABLE 

Variable PES mode.

Constructor & Destructor Documentation

◆ PacketEncapsulation()

ts::PacketEncapsulation::PacketEncapsulation ( PID  pidOutput = PID_NULL,
const PIDSet pidInput = NoPID,
PID  pcrReference = PID_NULL 
)

Constructor.

Parameters
[in]pidOutputThe output PID. When PID_NULL, no encapsulation is done.
[in]pidInputThe initial set of PID's to encapsulate.
[in]pcrReferenceThe PID with PCR's to use as reference to add PCR's in the encapsulating PID. When PID_NULL, do not add PCR.

Member Function Documentation

◆ reset()

void ts::PacketEncapsulation::reset ( PID  pidOutput = PID_NULL,
const PIDSet pidInput = NoPID,
PID  pcrReference = PID_NULL 
)

Reset the encapsulation.

Parameters
[in]pidOutputThe new output PID. When PID_NULL, no encapsulation is done.
[in]pidInputThe new set of PID's to encapsulate.
[in]pcrReferenceThe PID with PCR's to use as reference to add PCR's in the encapsulating PID. When PID_NULL, do not add PCR.

◆ processPacket()

bool ts::PacketEncapsulation::processPacket ( TSPacket pkt)

Process a TS packet from the input stream.

Parameters
[in,out]pktA TS packet. If the packet belongs to one of the input PID's, it is replaced by an encapsulating packet in the output PID. Some null packets are also replaced to absorb the encapsulation overhead.
Returns
True on success, false on error (PID conflict, output overflow). In case of error, use lastError().

◆ lastError()

const UString & ts::PacketEncapsulation::lastError ( ) const
inline

Get the last error message.

Returns
The last error message.

◆ hasError()

bool ts::PacketEncapsulation::hasError ( ) const
inline

Check if a previous error is pending.

Returns
True if a previous error is pending.
See also
resetError()

◆ outputPID()

PID ts::PacketEncapsulation::outputPID ( ) const
inline

Get the output PID.

Returns
The output PID.

◆ setOutputPID()

void ts::PacketEncapsulation::setOutputPID ( PID  pid)

Change the output PID.

Parameters
[in]pidThe new output PID.

◆ inputPIDs()

const PIDSet & ts::PacketEncapsulation::inputPIDs ( ) const
inline

Get the current set of input PID's.

Returns
A constant reference to the set of input PID's.

◆ pidCount()

size_t ts::PacketEncapsulation::pidCount ( ) const
inline

Get the current number of input PID's being encapsulated.

Returns
The crrent number of PID's being encapsulated.

◆ setInputPIDs()

void ts::PacketEncapsulation::setInputPIDs ( const PIDSet pidInput)

Replace the set of input PID's.

Parameters
[in]pidInputThe new set of PID's to encapsulate.

◆ addInputPID()

void ts::PacketEncapsulation::addInputPID ( PID  pid)

Add one PID to encapsulate.

Parameters
[in]pidThe new PID to encapsulate.

◆ removeInputPID()

void ts::PacketEncapsulation::removeInputPID ( PID  pid)

Remove one PID to encapsulate.

Parameters
[in]pidThe PID to no longer encapsulate.

◆ referencePCR()

PID ts::PacketEncapsulation::referencePCR ( ) const
inline

Get the reference PID for PCR's.

Returns
The reference PID for PCR's. PID_NULL if there is none.

◆ setReferencePCR()

void ts::PacketEncapsulation::setReferencePCR ( PID  pid)

Change the reference PID for PCR's.

Parameters
[in]pidThe new reference PID for PCR's. PID_NULL if there is none.

◆ setMaxBufferedPackets()

void ts::PacketEncapsulation::setMaxBufferedPackets ( size_t  count)

Set the maximum number of buffered packets.

The buffered packets are produced by the encapsulation overhead. An overflow is usually caused by insufficient null packets in the input stream.

Parameters
[in]countThe maximum number of buffered packets.

◆ setPacking()

void ts::PacketEncapsulation::setPacking ( bool  on,
size_t  limit 
)
inline

Set packing mode.

When packing mode is off (the default), encapsulated packets are issued as soon as null packet are available for replacement, potentially leaving unused part in some outer packet. When packing mode if on, outer packets are emitted only when they are full.

Parameters
[in]onPacking mode.
[in]limitNumber of packets after which encapsulation is forced, even when packing is off.

◆ setPES()

void ts::PacketEncapsulation::setPES ( PESMode  mode)
inline

Set PES mode.

Enables the PES mode encapsulation (disabled by default).

Parameters
[in]modePES mode.

◆ setPESOffset()

void ts::PacketEncapsulation::setPESOffset ( size_t  offset)
inline

Set PES Offset.

When using the PES mode it enables the PES Synchronous encapsulation when != 0. The offset value is used to compute the PTS of the encap stream based on the PCR.

Parameters
[in]offsetvalue. Use 0 for Asynchronous PES mode (default).

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