avformat/mpegtsenc: use standard pids for m2ts
authorMarton Balint <cus@passwd.hu>
Sun, 10 Nov 2019 23:06:01 +0000 (00:06 +0100)
committerMarton Balint <cus@passwd.hu>
Tue, 21 Apr 2020 19:28:29 +0000 (21:28 +0200)
Signed-off-by: Marton Balint <cus@passwd.hu>
doc/muxers.texi
libavformat/mpegts.h
libavformat/mpegtsenc.c

index 1a1cdb9..cb2bb42 100644 (file)
@@ -1660,11 +1660,13 @@ Advanced Codec Digital HDTV service.
 
 @item mpegts_pmt_start_pid @var{integer}
 Set the first PID for PMTs. Default is @code{0x1000}, minimum is @code{0x0020},
-maximum is @code{0x1ffa}.
+maximum is @code{0x1ffa}. This option has no effect in m2ts mode where the PMT
+PID is fixed @code{0x0100}.
 
 @item mpegts_start_pid @var{integer}
 Set the first PID for elementary streams. Default is @code{0x0100}, minimum is
-@code{0x0020}, maximum is @code{0x1ffa}.
+@code{0x0020}, maximum is @code{0x1ffa}. This option has no effect in m2ts mode
+where the elementary stream PIDs are fixed.
 
 @item mpegts_m2ts_mode @var{boolean}
 Enable m2ts mode if set to @code{1}. Default value is @code{-1} which
index 86a3eba..059b693 100644 (file)
  * streams and other data tables */
 #define NULL_PID        0x1FFF /* Null packet (used for fixed bandwidth padding) */
 
+/* m2ts pids */
+#define M2TS_PMT_PID                      0x0100
+#define M2TS_PCR_PID                      0x1001
+#define M2TS_VIDEO_PID                    0x1011
+#define M2TS_AUDIO_START_PID              0x1100
+#define M2TS_PGSSUB_START_PID             0x1200
+#define M2TS_TEXTSUB_PID                  0x1800
+#define M2TS_SECONDARY_AUDIO_START_PID    0x1A00
+#define M2TS_SECONDARY_VIDEO_START_PID    0x1B00
+
 /* table ids */
 #define PAT_TID         0x00 /* Program Association section */
 #define CAT_TID         0x01 /* Conditional Access section */
index ccb631d..bee996a 100644 (file)
@@ -94,6 +94,10 @@ typedef struct MpegTSWrite {
     int pmt_start_pid;
     int start_pid;
     int m2ts_mode;
+    int m2ts_video_pid;
+    int m2ts_audio_pid;
+    int m2ts_pgssub_pid;
+    int m2ts_textsub_pid;
 
     int pcr_period_ms;
 #define MPEGTS_FLAG_REEMIT_PAT_PMT  0x01
@@ -860,6 +864,14 @@ static int mpegts_init(AVFormatContext *s)
         }
     }
 
+    ts->m2ts_video_pid   = M2TS_VIDEO_PID;
+    ts->m2ts_audio_pid   = M2TS_AUDIO_START_PID;
+    ts->m2ts_pgssub_pid  = M2TS_PGSSUB_START_PID;
+    ts->m2ts_textsub_pid = M2TS_TEXTSUB_PID;
+
+    if (ts->m2ts_mode)
+        ts->pmt_start_pid = M2TS_PMT_PID;
+
     if (s->max_delay < 0) /* Not set by the caller */
         s->max_delay = 0;
 
@@ -923,7 +935,37 @@ static int mpegts_init(AVFormatContext *s)
         /* MPEG pid values < 16 are reserved. Applications which set st->id in
          * this range are assigned a calculated pid. */
         if (st->id < 16) {
-            ts_st->pid = ts->start_pid + i;
+            if (ts->m2ts_mode) {
+                switch (st->codecpar->codec_type) {
+                case AVMEDIA_TYPE_VIDEO:
+                    ts_st->pid = ts->m2ts_video_pid++;
+                    break;
+                case AVMEDIA_TYPE_AUDIO:
+                    ts_st->pid = ts->m2ts_audio_pid++;
+                    break;
+                case AVMEDIA_TYPE_SUBTITLE:
+                    switch (st->codecpar->codec_id) {
+                    case AV_CODEC_ID_HDMV_PGS_SUBTITLE:
+                        ts_st->pid = ts->m2ts_pgssub_pid++;
+                        break;
+                    case AV_CODEC_ID_HDMV_TEXT_SUBTITLE:
+                        ts_st->pid = ts->m2ts_textsub_pid++;
+                        break;
+                    }
+                    break;
+                }
+                if (ts->m2ts_video_pid   > M2TS_VIDEO_PID + 1          ||
+                    ts->m2ts_audio_pid   > M2TS_AUDIO_START_PID + 32   ||
+                    ts->m2ts_pgssub_pid  > M2TS_PGSSUB_START_PID + 32  ||
+                    ts->m2ts_textsub_pid > M2TS_TEXTSUB_PID + 1        ||
+                    ts_st->pid < 16) {
+                    av_log(s, AV_LOG_ERROR, "Cannot automatically assign PID for stream %d\n", st->index);
+                    ret = AVERROR(EINVAL);
+                    goto fail;
+                }
+            } else {
+                ts_st->pid = ts->start_pid + i;
+            }
         } else {
             ts_st->pid = st->id;
         }