summaryrefslogtreecommitdiff
path: root/libavformat/mpegtsenc.c
diff options
context:
space:
mode:
authorSerhii Marchuk <serhii.marchuk@gmail.com>2014-01-24 17:34:58 +0200
committerMichael Niedermayer <michaelni@gmx.at>2014-01-24 22:07:40 +0100
commit2ebee19e1ed2a300c542cbaa06b6e27784d0314d (patch)
treead907b6734e5171fbd69e8b70994afcb8ccfe4aa /libavformat/mpegtsenc.c
parentf8051bd31a23fa10faa7c9ae66397963dc4ec285 (diff)
mpegts muxer: restore PMT table of DVB teletext from extradata
* Using extradata by TS muxer to correctly restore PMT table * PES_header_data_length should be always 0x24 for DVB teletext, according to DVB standard Reviewed-by: Marton Balint <cus@passwd.hu> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/mpegtsenc.c')
-rw-r--r--libavformat/mpegtsenc.c84
1 files changed, 66 insertions, 18 deletions
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index 0ade014b01..9b42e48c7c 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -374,20 +374,55 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
case AVMEDIA_TYPE_SUBTITLE:
{
const char default_language[] = "und";
- const char *language = lang && strlen(lang->value)==3 ? lang->value : default_language;
- *q++ = 0x59;
- *q++ = 8;
- *q++ = language[0];
- *q++ = language[1];
- *q++ = language[2];
- *q++ = 0x10; /* normal subtitles (0x20 = if hearing pb) */
- if(st->codec->extradata_size == 4) {
- memcpy(q, st->codec->extradata, 4);
- q += 4;
- } else {
- put16(&q, 1); /* page id */
- put16(&q, 1); /* ancillary page id */
- }
+ const char *language = lang && strlen(lang->value) >= 3 ? lang->value : default_language;
+
+ if (st->codec->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
+ /* The descriptor tag. subtitling_descriptor */
+ *q++ = 0x59;
+ *q++ = 8;
+ *q++ = language[0];
+ *q++ = language[1];
+ *q++ = language[2];
+ *q++ = 0x10; /* normal subtitles (0x20 = if hearing pb) */
+ if(st->codec->extradata_size == 4) {
+ memcpy(q, st->codec->extradata, 4);
+ q += 4;
+ } else {
+ put16(&q, 1); /* page id */
+ put16(&q, 1); /* ancillary page id */
+ }
+ } else if (st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) {
+ uint8_t *len_ptr = NULL;
+ int extradata_copied = 0;
+
+ /* The descriptor tag. teletext_descriptor */
+ *q++ = 0x56;
+ len_ptr = q++;
+
+ while (strlen(language) >= 3) {
+ *q++ = *language++;
+ *q++ = *language++;
+ *q++ = *language++;
+ /* Skip comma */
+ if (*language != '\0')
+ language++;
+
+ if (st->codec->extradata_size - 1 > extradata_copied) {
+ memcpy(q, st->codec->extradata + extradata_copied, 2);
+ extradata_copied += 2;
+ q += 2;
+ } else {
+ /* The Teletext descriptor:
+ * teletext_type: This 5-bit field indicates the type of Teletext page indicated. (0x01 Initial Teletext page)
+ * teletext_magazine_number: This is a 3-bit field which identifies the magazine number.
+ * teletext_page_number: This is an 8-bit field giving two 4-bit hex digits identifying the page number. */
+ *q++ = 0x08;
+ *q++ = 0x00;
+ }
+ }
+
+ *len_ptr = q - len_ptr - 1;
+ }
}
break;
case AVMEDIA_TYPE_VIDEO:
@@ -859,7 +894,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
MpegTSWrite *ts = s->priv_data;
uint8_t buf[TS_PACKET_SIZE];
uint8_t *q;
- int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, flags;
+ int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, is_dvb_teletext, flags;
int afc_len, stuffing_len;
int64_t pcr = -1; /* avoid warning */
int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
@@ -923,11 +958,13 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
}
if (is_start) {
int pes_extension = 0;
+ int pes_header_stuffing_bytes = 0;
/* write PES header */
*q++ = 0x00;
*q++ = 0x00;
*q++ = 0x01;
is_dvb_subtitle = 0;
+ is_dvb_teletext = 0;
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
if (st->codec->codec_id == AV_CODEC_ID_DIRAC) {
*q++ = 0xfd;
@@ -944,9 +981,12 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
*q++ = 0xfd;
} else {
*q++ = 0xbd;
- if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE &&
- st->codec->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
- is_dvb_subtitle = 1;
+ if(st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+ if (st->codec->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
+ is_dvb_subtitle = 1;
+ } else if (st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) {
+ is_dvb_teletext = 1;
+ }
}
}
header_len = 0;
@@ -983,6 +1023,10 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
flags |= 0x01;
header_len += 3;
}
+ if (is_dvb_teletext) {
+ pes_header_stuffing_bytes = 0x24 - header_len;
+ header_len = 0x24;
+ }
len = payload_size + header_len + 3;
/* 3 extra bytes should be added to DVB subtitle payload: 0x20 0x00 at the beginning and trailing 0xff */
if (is_dvb_subtitle) {
@@ -1036,6 +1080,10 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
*q++ = 0x20;
*q++ = 0x00;
}
+ if (is_dvb_teletext) {
+ memset(q, 0xff, pes_header_stuffing_bytes);
+ q += pes_header_stuffing_bytes;
+ }
is_start = 0;
}
/* header size */