How to Set Custom MPEG-TS PIDs in FFmpeg

When multiplexing video and audio streams into an MPEG Transport Stream (MPEG-TS) container, FFmpeg automatically assigns default Packet Identifier (PID) values to the streams and tables. This article provides a clear, step-by-step guide on how to override these defaults and manually set custom PID values for your video, audio, and Program Map Table (PMT) using FFmpeg command-line options.

The FFmpeg Command Structure

To assign custom PIDs, you use a combination of the -mpegts_pmt_start_pid option (for the PMT) and the -streamid option (for the individual video and audio elementary streams).

Here is the template command to achieve this:

ffmpeg -i input.mp4 \
  -map 0:v:0 -map 0:a:0 \
  -c copy \
  -f mpegts \
  -mpegts_pmt_start_pid 4000 \
  -streamid 0:4001 \
  -streamid 1:4002 \
  output.ts

Parameter Breakdown

  • -map 0:v:0 -map 0:a:0: Selects the first video stream and the first audio stream from the input file to ensure they are mapped to specific output indexes.
  • -c copy: Copies the video and audio codecs without re-encoding, which speeds up the process. You can replace this with specific encoders (e.g., -c:v libx264 -c:a aac) if transcoding is required.
  • -f mpegts: Forces the output format to be MPEG Transport Stream.
  • -mpegts_pmt_start_pid 4000: Sets the PID for the Program Map Table (PMT). In this example, it is assigned to decimal value 4000 (hexadecimal 0x0FA0).
  • -streamid 0:4001: Assigns custom PID 4001 to the first output stream (index 0, which is the video stream).
  • -streamid 1:4002: Assigns custom PID 4002 to the second output stream (index 1, which is the audio stream).

Important Considerations

  1. Decimal vs. Hexadecimal: FFmpeg accepts PID values in decimal format. If your hardware or broadcasting specifications require hexadecimal PIDs, you must convert them to decimal before entering them into the command. For example, hex 0x100 converts to decimal 256.
  2. Reserved PIDs: Avoid using reserved PID values. PIDs between 0 and 31 (decimal) are reserved for standard tables like the Program Association Table (PAT, PID 0) and the Conditional Access Table (CAT, PID 1).
  3. Stream Mapping Order: The stream index in -streamid <index>:<PID> corresponds directly to the order in which the streams are mapped to the output. Verify your stream order using ffprobe on the output file to ensure the PIDs were assigned to the correct tracks.