Commit 4d47cc1d authored by mru's avatar mru

write DTS, based on patch by Luca Abeni, lucabe72 email it

git-svn-id: file:///var/local/repositories/ffmpeg/trunk@8196 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent 2991da28
...@@ -143,6 +143,7 @@ typedef struct MpegTSWriteStream { ...@@ -143,6 +143,7 @@ typedef struct MpegTSWriteStream {
int cc; int cc;
int payload_index; int payload_index;
int64_t payload_pts; int64_t payload_pts;
int64_t payload_dts;
uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE]; uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE];
} MpegTSWriteStream; } MpegTSWriteStream;
...@@ -396,6 +397,7 @@ static int mpegts_write_header(AVFormatContext *s) ...@@ -396,6 +397,7 @@ static int mpegts_write_header(AVFormatContext *s)
ts_st->service = service; ts_st->service = service;
ts_st->pid = DEFAULT_START_PID + i; ts_st->pid = DEFAULT_START_PID + i;
ts_st->payload_pts = AV_NOPTS_VALUE; ts_st->payload_pts = AV_NOPTS_VALUE;
ts_st->payload_dts = AV_NOPTS_VALUE;
/* update PCR pid by using the first video stream */ /* update PCR pid by using the first video stream */
if (st->codec->codec_type == CODEC_TYPE_VIDEO && if (st->codec->codec_type == CODEC_TYPE_VIDEO &&
service->pcr_pid == 0x1fff) service->pcr_pid == 0x1fff)
...@@ -460,15 +462,29 @@ static void retransmit_si_info(AVFormatContext *s) ...@@ -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 */ /* NOTE: pes_data contains all the PES packet */
static void mpegts_write_pes(AVFormatContext *s, AVStream *st, static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
const uint8_t *payload, int payload_size, const uint8_t *payload, int payload_size,
int64_t pts) int64_t pts, int64_t dts)
{ {
MpegTSWriteStream *ts_st = st->priv_data; MpegTSWriteStream *ts_st = st->priv_data;
uint8_t buf[TS_PACKET_SIZE]; uint8_t buf[TS_PACKET_SIZE];
uint8_t *q; 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; int afc_len, stuffing_len;
int64_t pcr = -1; /* avoid warning */ int64_t pcr = -1; /* avoid warning */
...@@ -527,13 +543,19 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, ...@@ -527,13 +543,19 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
private_code = 0x20; private_code = 0x20;
} }
} }
if (pts != AV_NOPTS_VALUE) header_len = 0;
header_len = 8; flags = 0;
else if (pts != AV_NOPTS_VALUE) {
header_len = 3; 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) if (private_code != 0)
header_len++; len++;
len = payload_size + header_len;
*q++ = len >> 8; *q++ = len >> 8;
*q++ = len; *q++ = len;
val = 0x80; val = 0x80;
...@@ -541,21 +563,15 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, ...@@ -541,21 +563,15 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) if (st->codec->codec_type == CODEC_TYPE_SUBTITLE)
val |= 0x04; val |= 0x04;
*q++ = val; *q++ = val;
*q++ = flags;
*q++ = header_len;
if (pts != AV_NOPTS_VALUE) { if (pts != AV_NOPTS_VALUE) {
*q++ = 0x80; /* PTS only */ write_pts(q, flags >> 6, pts);
*q++ = 0x05; /* header len */ q += 5;
val = (0x02 << 4) | }
(((pts >> 30) & 0x07) << 1) | 1; if (dts != AV_NOPTS_VALUE) {
*q++ = val; write_pts(q, 1, dts);
val = (((pts >> 15) & 0x7fff) << 1) | 1; q += 5;
*q++ = val >> 8;
*q++ = val;
val = (((pts) & 0x7fff) << 1) | 1;
*q++ = val >> 8;
*q++ = val;
} else {
*q++ = 0x00;
*q++ = 0x00;
} }
if (private_code != 0) if (private_code != 0)
*q++ = private_code; *q++ = private_code;
...@@ -607,7 +623,7 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -607,7 +623,7 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) { if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) {
/* for subtitle, a single PES packet must be generated */ /* 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; return 0;
} }
...@@ -622,10 +638,13 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -622,10 +638,13 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
ts_st->payload_index += len; ts_st->payload_index += len;
if (ts_st->payload_pts == AV_NOPTS_VALUE) if (ts_st->payload_pts == AV_NOPTS_VALUE)
ts_st->payload_pts = pkt->pts; 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) { if (ts_st->payload_index >= max_payload_size) {
mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index, 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_pts = AV_NOPTS_VALUE;
ts_st->payload_dts = AV_NOPTS_VALUE;
ts_st->payload_index = 0; ts_st->payload_index = 0;
} }
} }
...@@ -646,7 +665,7 @@ static int mpegts_write_end(AVFormatContext *s) ...@@ -646,7 +665,7 @@ static int mpegts_write_end(AVFormatContext *s)
ts_st = st->priv_data; ts_st = st->priv_data;
if (ts_st->payload_index > 0) { if (ts_st->payload_index > 0) {
mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index, 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); put_flush_packet(&s->pb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment