changeset 4211:5e5654752973 libavformat

set pts and dts of pes packets exactly according to specs
author bcoudurier
date Wed, 14 Jan 2009 21:57:10 +0000
parents ec95366371ba
children 3aaa3da02aea
files mpegtsenc.c
diffstat 1 files changed, 29 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/mpegtsenc.c	Wed Jan 14 17:19:17 2009 +0000
+++ b/mpegtsenc.c	Wed Jan 14 21:57:10 2009 +0000
@@ -21,6 +21,7 @@
 
 #include "libavutil/bswap.h"
 #include "libavutil/crc.h"
+#include "libavcodec/mpegvideo.h"
 #include "avformat.h"
 #include "mpegts.h"
 
@@ -670,6 +671,7 @@
     uint8_t *buf= pkt->data;
     MpegTSWriteStream *ts_st = st->priv_data;
     int len, max_payload_size;
+    const uint8_t *access_unit_index = NULL;
 
     if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) {
         /* for subtitle, a single PES packet must be generated */
@@ -683,6 +685,27 @@
         return 0;
     }
     max_payload_size = DEFAULT_PES_PAYLOAD_SIZE;
+    if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO ||
+        st->codec->codec_id == CODEC_ID_MPEG1VIDEO) {
+        const uint8_t *p = pkt->data;
+        const uint8_t *end = pkt->data+pkt->size;
+        uint32_t state = -1;
+        while (p < end) {
+            p = ff_find_start_code(p, end, &state);
+            if (state == PICTURE_START_CODE) {
+                access_unit_index = p - 4;
+                break;
+            }
+        }
+    } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
+        access_unit_index = pkt->data;
+    }
+
+    if (!access_unit_index) {
+        av_log(s, AV_LOG_ERROR, "error, could not find access unit start\n");
+        return -1;
+    }
+
     while (size > 0) {
         len = max_payload_size - ts_st->payload_index;
         if (len > size)
@@ -691,16 +714,19 @@
         buf += len;
         size -= len;
         ts_st->payload_index += len;
-        if (ts_st->payload_pts == AV_NOPTS_VALUE)
+        if (access_unit_index && access_unit_index < buf &&
+            ts_st->payload_pts == AV_NOPTS_VALUE &&
+            ts_st->payload_dts == AV_NOPTS_VALUE) {
+            ts_st->payload_dts = pkt->dts;
             ts_st->payload_pts = pkt->pts;
-        if (ts_st->payload_dts == AV_NOPTS_VALUE)
-            ts_st->payload_dts = pkt->dts;
+        }
         if (ts_st->payload_index >= max_payload_size) {
             mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index,
                              ts_st->payload_pts, ts_st->payload_dts);
             ts_st->payload_pts = AV_NOPTS_VALUE;
             ts_st->payload_dts = AV_NOPTS_VALUE;
             ts_st->payload_index = 0;
+            access_unit_index = NULL; // unset access unit to avoid setting pts/dts again
         }
     }
     return 0;