[FFmpeg-devel] [PATCH] lavformat: Fixed processing teletext descriptor and packets in mpegts

Dzmitry Kamiahin dzmitry.kamiahin at gmail.com
Tue May 21 15:17:54 CEST 2013


Hi!

I attached patch which fixed muxing dvb_teletext problem for mpegts

Thanks.
---
 libavformat/mpegts.c    |    7 +++++++
 libavformat/mpegtsenc.c |   33 ++++++++++++++++++++++++++++++---
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 85b5146..da8bba8 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -1365,6 +1365,13 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc,
AVStream *st, int stream_type
         }
         break;
     case 0x56: /* DVB teletext descriptor */
+        /* copy all descriptor's data (ETSI EN 300 468 - 6.2.43) */
+        if (!st->codec->extradata) {
+            st->codec->extradata = av_malloc(desc_len +
FF_INPUT_BUFFER_PADDING_SIZE);
+            st->codec->extradata_size = desc_len;
+            memcpy(st->codec->extradata, *pp, desc_len);
+        }
+        /* parse language in first descriptor */
         language[0] = get8(pp, desc_end);
         language[1] = get8(pp, desc_end);
         language[2] = get8(pp, desc_end);
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index 0ddae65..c143619 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -372,8 +372,21 @@ static void mpegts_write_pmt(AVFormatContext *s,
MpegTSService *service)
             {
                 const char *language;
                 language = lang && strlen(lang->value)==3 ? lang->value :
"eng";
-                *q++ = 0x59;
-                *q++ = 8;
+
+                /* write teletext descriptors (ETSI EN 300 468 - 6.2.43) */
+                if (st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) {
+                    if (st->codec->extradata_size != 0) {
+                        *q++ = 0x56;
+                        *q++ = st->codec->extradata_size;
+
+                        memcpy(q, st->codec->extradata,
st->codec->extradata_size);
+                        q += st->codec->extradata_size;
+                    }
+                    break;
+                } else {
+                    *q++ = 0x59;
+                    *q++ = 8;
+                }
                 *q++ = language[0];
                 *q++ = language[1];
                 *q++ = language[2];
@@ -910,6 +923,7 @@ 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;
@@ -931,7 +945,8 @@ static void mpegts_write_pes(AVFormatContext *s,
AVStream *st,
                 *q++ = 0xfd;
             } else {
                 *q++ = 0xbd;
-                if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+                if ((st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) &&
+                    (st->codec->codec_id != AV_CODEC_ID_DVB_TELETEXT)) {
                     private_code = 0x20;
                 }
             }
@@ -982,6 +997,12 @@ static void mpegts_write_pes(AVFormatContext *s,
AVStream *st,
                 val |= 0x04;
             *q++ = val;
             *q++ = flags;
+            /* PES header length is always fixed (set to 0x24) for
teletext streams (ETSI EN 300 472 - 4.1) */
+            if ((st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) &&
+                (st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT)) {
+                pes_header_stuffing_bytes = 0x24 - header_len;
+                header_len = 0x24;
+            }
             *q++ = header_len;
             if (pts != AV_NOPTS_VALUE) {
                 write_pts(q, flags >> 6, pts);
@@ -1011,6 +1032,12 @@ static void mpegts_write_pes(AVFormatContext *s,
AVStream *st,
                       *q++ = 0x00 | 0x71; /* for AC3 Audio (specifically
on blue-rays) */
               }

+            if ((st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) &&
+                (st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT)) {
+                int i;
+                for (i = 0; i < pes_header_stuffing_bytes; i++)
+                    *q++ = 0xff;
+            }

             if (private_code != 0)
                 *q++ = private_code;
-- 
1.7.10.4


More information about the ffmpeg-devel mailing list