changeset 6200:ac9ea0fde990 libavformat

Allow setting streamid when muxing mpegts. Patch by Mike Scheutzow, scheutzow alcatel-lucent com
author cehoyos
date Wed, 30 Jun 2010 22:39:13 +0000
parents fa244b4fe683
children f5cb0b79f58c
files mpegtsenc.c
diffstat 1 files changed, 29 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/mpegtsenc.c	Wed Jun 30 15:38:06 2010 +0000
+++ b/mpegtsenc.c	Wed Jun 30 22:39:13 2010 +0000
@@ -387,8 +387,9 @@
     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 @@
     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 @@
             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 @@
         }
     }
 
+    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 @@
     return 0;
 
  fail:
+    av_free(pids);
     for(i = 0;i < s->nb_streams; i++) {
         st = s->streams[i];
         av_free(st->priv_data);