OSDN Git Service

Allow setting streamid when muxing mpegts.
authorMike Scheutzow <scheutzow@alcatel-lucent.com>
Wed, 30 Jun 2010 22:39:13 +0000 (22:39 +0000)
committerCarl Eugen Hoyos <cehoyos@rainbow.studorg.tuwien.ac.at>
Wed, 30 Jun 2010 22:39:13 +0000 (22:39 +0000)
Patch by Mike Scheutzow, scheutzow alcatel-lucent com

Originally committed as revision 23918 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavformat/mpegtsenc.c

index 3fc6dc1..52ecd1d 100644 (file)
@@ -387,8 +387,9 @@ static int mpegts_write_header(AVFormatContext *s)
     MpegTSService *service;
     AVStream *st, *pcr_st = NULL;
     AVMetadataTag *title;
-    int i;
+    int i, j;
     const char *service_name;
+    int *pids;
 
     ts->tsid = DEFAULT_TSID;
     ts->onid = DEFAULT_ONID;
@@ -411,6 +412,10 @@ static int mpegts_write_header(AVFormatContext *s)
     ts->sdt.write_packet = section_write_packet;
     ts->sdt.opaque = s;
 
+    pids = av_malloc(s->nb_streams);
+    if (!pids)
+        return AVERROR(ENOMEM);
+
     /* assign pids to each stream */
     for(i = 0;i < s->nb_streams; i++) {
         st = s->streams[i];
@@ -419,7 +424,26 @@ static int mpegts_write_header(AVFormatContext *s)
             goto fail;
         st->priv_data = ts_st;
         ts_st->service = service;
-        ts_st->pid = DEFAULT_START_PID + i;
+        /* 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 = DEFAULT_START_PID + i;
+        } else if (st->id < 0x1FFF) {
+            ts_st->pid = st->id;
+        } else {
+            av_log(s, AV_LOG_ERROR, "Invalid stream id %d, must be less than 8191\n", st->id);
+            goto fail;
+        }
+        if (ts_st->pid == service->pmt.pid) {
+            av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);
+            goto fail;
+        }
+        for (j = 0; j < i; j++)
+            if (pids[j] == ts_st->pid) {
+                av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);
+                goto fail;
+            }
+        pids[i] = ts_st->pid;
         ts_st->payload_pts = AV_NOPTS_VALUE;
         ts_st->payload_dts = AV_NOPTS_VALUE;
         ts_st->first_pts_check = 1;
@@ -441,6 +465,8 @@ static int mpegts_write_header(AVFormatContext *s)
         }
     }
 
+    av_free(pids);
+
     /* if no video stream, use the first stream as PCR */
     if (service->pcr_pid == 0x1fff && s->nb_streams > 0) {
         pcr_st = s->streams[0];
@@ -496,6 +522,7 @@ static int mpegts_write_header(AVFormatContext *s)
     return 0;
 
  fail:
+    av_free(pids);
     for(i = 0;i < s->nb_streams; i++) {
         st = s->streams[i];
         av_free(st->priv_data);