diff options
author | Måns Rullgård <mans@mansr.com> | 2007-03-02 21:47:24 +0000 |
---|---|---|
committer | Måns Rullgård <mans@mansr.com> | 2007-03-02 21:47:24 +0000 |
commit | 700b971156f17b4eb03fc7da89d3d94a46b03169 (patch) | |
tree | 173ed51467eb0d7f4cba2dea848cf0afcb342d8e /libavformat/mpegtsenc.c | |
parent | dd9bdeb9f38f0047013cc49bd2a34baa73fe38f3 (diff) | |
download | ffmpeg-700b971156f17b4eb03fc7da89d3d94a46b03169.tar.gz |
write DTS, based on patch by Luca Abeni, lucabe72 email it
Originally committed as revision 8196 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/mpegtsenc.c')
-rw-r--r-- | libavformat/mpegtsenc.c | 69 |
1 files changed, 44 insertions, 25 deletions
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 39868bea48..c521b68b87 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -143,6 +143,7 @@ typedef struct MpegTSWriteStream { int cc; int payload_index; int64_t payload_pts; + int64_t payload_dts; uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE]; } MpegTSWriteStream; @@ -396,6 +397,7 @@ static int mpegts_write_header(AVFormatContext *s) ts_st->service = service; ts_st->pid = DEFAULT_START_PID + i; ts_st->payload_pts = AV_NOPTS_VALUE; + ts_st->payload_dts = AV_NOPTS_VALUE; /* update PCR pid by using the first video stream */ if (st->codec->codec_type == CODEC_TYPE_VIDEO && service->pcr_pid == 0x1fff) @@ -460,15 +462,29 @@ static void retransmit_si_info(AVFormatContext *s) } } +static void write_pts(uint8_t *q, int fourbits, int64_t pts) +{ + int val; + + val = fourbits << 4 | (((pts >> 30) & 0x07) << 1) | 1; + *q++ = val; + val = (((pts >> 15) & 0x7fff) << 1) | 1; + *q++ = val >> 8; + *q++ = val; + val = (((pts) & 0x7fff) << 1) | 1; + *q++ = val >> 8; + *q++ = val; +} + /* NOTE: pes_data contains all the PES packet */ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, const uint8_t *payload, int payload_size, - int64_t pts) + int64_t pts, int64_t dts) { MpegTSWriteStream *ts_st = st->priv_data; uint8_t buf[TS_PACKET_SIZE]; uint8_t *q; - int val, is_start, len, header_len, write_pcr, private_code; + int val, is_start, len, header_len, write_pcr, private_code, flags; int afc_len, stuffing_len; int64_t pcr = -1; /* avoid warning */ @@ -527,13 +543,19 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, private_code = 0x20; } } - if (pts != AV_NOPTS_VALUE) - header_len = 8; - else - header_len = 3; + header_len = 0; + flags = 0; + if (pts != AV_NOPTS_VALUE) { + header_len += 5; + flags |= 0x80; + } + if (dts != AV_NOPTS_VALUE) { + header_len += 5; + flags |= 0x40; + } + len = payload_size + header_len + 3; if (private_code != 0) - header_len++; - len = payload_size + header_len; + len++; *q++ = len >> 8; *q++ = len; val = 0x80; @@ -541,21 +563,15 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) val |= 0x04; *q++ = val; + *q++ = flags; + *q++ = header_len; if (pts != AV_NOPTS_VALUE) { - *q++ = 0x80; /* PTS only */ - *q++ = 0x05; /* header len */ - val = (0x02 << 4) | - (((pts >> 30) & 0x07) << 1) | 1; - *q++ = val; - val = (((pts >> 15) & 0x7fff) << 1) | 1; - *q++ = val >> 8; - *q++ = val; - val = (((pts) & 0x7fff) << 1) | 1; - *q++ = val >> 8; - *q++ = val; - } else { - *q++ = 0x00; - *q++ = 0x00; + write_pts(q, flags >> 6, pts); + q += 5; + } + if (dts != AV_NOPTS_VALUE) { + write_pts(q, 1, dts); + q += 5; } if (private_code != 0) *q++ = private_code; @@ -607,7 +623,7 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) { /* for subtitle, a single PES packet must be generated */ - mpegts_write_pes(s, st, buf, size, pkt->pts); + mpegts_write_pes(s, st, buf, size, pkt->pts, AV_NOPTS_VALUE); return 0; } @@ -622,10 +638,13 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) 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) + 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_pts, ts_st->payload_dts); ts_st->payload_pts = AV_NOPTS_VALUE; + ts_st->payload_dts = AV_NOPTS_VALUE; ts_st->payload_index = 0; } } @@ -646,7 +665,7 @@ static int mpegts_write_end(AVFormatContext *s) ts_st = st->priv_data; if (ts_st->payload_index > 0) { mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index, - ts_st->payload_pts); + ts_st->payload_pts, ts_st->payload_dts); } } put_flush_packet(&s->pb); |