Browse code

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>

Serhii Marchuk authored on 2014/01/25 00:34:58
Showing 1 changed files
... ...
@@ -374,20 +374,55 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
374 374
         case AVMEDIA_TYPE_SUBTITLE:
375 375
             {
376 376
                 const char default_language[] = "und";
377
-                const char *language = lang && strlen(lang->value)==3 ? lang->value : default_language;
378
-                *q++ = 0x59;
379
-                *q++ = 8;
380
-                *q++ = language[0];
381
-                *q++ = language[1];
382
-                *q++ = language[2];
383
-                *q++ = 0x10; /* normal subtitles (0x20 = if hearing pb) */
384
-                if(st->codec->extradata_size == 4) {
385
-                    memcpy(q, st->codec->extradata, 4);
386
-                    q += 4;
387
-                } else {
388
-                    put16(&q, 1); /* page id */
389
-                    put16(&q, 1); /* ancillary page id */
390
-                }
377
+                const char *language = lang && strlen(lang->value) >= 3 ? lang->value : default_language;
378
+
379
+                if (st->codec->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
380
+                    /* The descriptor tag. subtitling_descriptor */
381
+                    *q++ = 0x59;
382
+                    *q++ = 8;
383
+                    *q++ = language[0];
384
+                    *q++ = language[1];
385
+                    *q++ = language[2];
386
+                    *q++ = 0x10; /* normal subtitles (0x20 = if hearing pb) */
387
+                    if(st->codec->extradata_size == 4) {
388
+                        memcpy(q, st->codec->extradata, 4);
389
+                        q += 4;
390
+                    } else {
391
+                        put16(&q, 1); /* page id */
392
+                        put16(&q, 1); /* ancillary page id */
393
+                    }
394
+                } else if (st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) {
395
+                    uint8_t *len_ptr = NULL;
396
+                    int extradata_copied = 0;
397
+
398
+                    /* The descriptor tag. teletext_descriptor */
399
+                    *q++ = 0x56;
400
+                    len_ptr = q++;
401
+
402
+                    while (strlen(language) >= 3) {
403
+                        *q++ = *language++;
404
+                        *q++ = *language++;
405
+                        *q++ = *language++;
406
+                        /* Skip comma */
407
+                        if (*language != '\0')
408
+                            language++;
409
+
410
+                        if (st->codec->extradata_size - 1 > extradata_copied) {
411
+                            memcpy(q, st->codec->extradata + extradata_copied, 2);
412
+                            extradata_copied += 2;
413
+                            q += 2;
414
+                        } else {
415
+                            /* The Teletext descriptor:
416
+                             * teletext_type: This 5-bit field indicates the type of Teletext page indicated. (0x01 Initial Teletext page)
417
+                             * teletext_magazine_number: This is a 3-bit field which identifies the magazine number.
418
+                             * teletext_page_number: This is an 8-bit field giving two 4-bit hex digits identifying the page number. */
419
+                            *q++ = 0x08;
420
+                            *q++ = 0x00;
421
+                        }
422
+                    }
423
+
424
+                    *len_ptr = q - len_ptr - 1;
425
+                 }
391 426
             }
392 427
             break;
393 428
         case AVMEDIA_TYPE_VIDEO:
... ...
@@ -859,7 +894,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
859 859
     MpegTSWrite *ts = s->priv_data;
860 860
     uint8_t buf[TS_PACKET_SIZE];
861 861
     uint8_t *q;
862
-    int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, flags;
862
+    int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, is_dvb_teletext, flags;
863 863
     int afc_len, stuffing_len;
864 864
     int64_t pcr = -1; /* avoid warning */
865 865
     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,
923 923
         }
924 924
         if (is_start) {
925 925
             int pes_extension = 0;
926
+            int pes_header_stuffing_bytes = 0;
926 927
             /* write PES header */
927 928
             *q++ = 0x00;
928 929
             *q++ = 0x00;
929 930
             *q++ = 0x01;
930 931
             is_dvb_subtitle = 0;
932
+            is_dvb_teletext = 0;
931 933
             if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
932 934
                 if (st->codec->codec_id == AV_CODEC_ID_DIRAC) {
933 935
                     *q++ = 0xfd;
... ...
@@ -944,9 +981,12 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
944 944
                 *q++ = 0xfd;
945 945
             } else {
946 946
                 *q++ = 0xbd;
947
-                if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE &&
948
-                    st->codec->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
949
-                    is_dvb_subtitle = 1;
947
+                if(st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
948
+                    if (st->codec->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
949
+                        is_dvb_subtitle = 1;
950
+                    } else if (st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) {
951
+                        is_dvb_teletext = 1;
952
+                    }
950 953
                 }
951 954
             }
952 955
             header_len = 0;
... ...
@@ -983,6 +1023,10 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
983 983
                         flags |= 0x01;
984 984
                         header_len += 3;
985 985
             }
986
+            if (is_dvb_teletext) {
987
+                pes_header_stuffing_bytes = 0x24 - header_len;
988
+                header_len = 0x24;
989
+            }
986 990
             len = payload_size + header_len + 3;
987 991
             /* 3 extra bytes should be added to DVB subtitle payload: 0x20 0x00 at the beginning and trailing 0xff */
988 992
             if (is_dvb_subtitle) {
... ...
@@ -1036,6 +1080,10 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
1036 1036
                 *q++ = 0x20;
1037 1037
                 *q++ = 0x00;
1038 1038
             }
1039
+            if (is_dvb_teletext) {
1040
+                memset(q, 0xff, pes_header_stuffing_bytes);
1041
+                q += pes_header_stuffing_bytes;
1042
+            }
1039 1043
             is_start = 0;
1040 1044
         }
1041 1045
         /* header size */