summaryrefslogtreecommitdiff
path: root/libavformat/mpegtsenc.c
diff options
context:
space:
mode:
authorBaptiste Coudurier <baptiste.coudurier@gmail.com>2009-01-14 21:57:10 +0000
committerBaptiste Coudurier <baptiste.coudurier@gmail.com>2009-01-14 21:57:10 +0000
commitde34dc39c048a5e641f9d739d82a5281d00d7699 (patch)
treeb4c5e44949d8cba99ac3e0ad374e398470dd2357 /libavformat/mpegtsenc.c
parent49cdad8d78b0abdfba6dbaeb79a9c8f91dcf3ba4 (diff)
set pts and dts of pes packets exactly according to specs
Originally committed as revision 16603 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/mpegtsenc.c')
-rw-r--r--libavformat/mpegtsenc.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index dc8916baa6..0170a5acb8 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -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 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
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 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
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 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
buf += len;
size -= len;
ts_st->payload_index += len;
- if (ts_st->payload_pts == AV_NOPTS_VALUE)
- ts_st->payload_pts = pkt->pts;
- if (ts_st->payload_dts == 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_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;