[FFmpeg-devel] Patch: add AVOption for extra video descriptors in MPEGTS PMT

Jason Livingston jettoblack at gmail.com
Fri May 25 02:02:06 CEST 2012


On Wed, May 23, 2012 at 03:19:13PM +0200, Michael Niedermayer wrote:
> this looks like a buffer overflow to me
> theres nothing checking that q is large enough for the user specified
> data that is put into it

Good point, thanks Michael.  Fixed in the attached revision.

> also do you have a testcase for this feature ?

I can probably put together some sample ATSC streams that contain the
extra descriptors that I'd like to insert.

I'm trying to implement some of the required descriptors for ATSC or
SCTE spec transport streams.
E.g.: http://www.etherguidesystems.com/Help/SDOs/atsc/semantics/descriptors/Default.aspx

This won't make the MPEGTS muxer fully ATSC/SCTE spec compliant yet
but maybe a small step in the right direction.  If it's a problem, I
can wrap the changes in ifdef, but if the option is not used it will
have zero effect on the output.

Perhaps a more robust solution would be to implement each
ATSC/SCTE/DVB optional/required descriptor as a separate option in the
MPEGTS muxer, but there are quite a few of them and this will add a
lot of options. :)

Thanks.
-------------- next part --------------
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index 36e958f..b5e760d 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -25,6 +25,7 @@
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 #include "libavutil/avassert.h"
+#include "libavutil/base64.h"
 #include "libavcodec/mpegvideo.h"
 #include "avformat.h"
 #include "internal.h"
@@ -80,6 +81,8 @@ typedef struct MpegTSWrite {
     int m2ts_mode;
 
     int reemit_pat_pmt;
+    
+    char *extra_video_descriptors;
 } MpegTSWrite;
 
 /* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
@@ -105,6 +108,8 @@ static const AVOption options[] = {
       offsetof(MpegTSWrite, pes_payload_size), AV_OPT_TYPE_INT, {DEFAULT_PES_PAYLOAD_SIZE}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
     { "resend_headers", "Reemit PAT/PMT before writing the next packet",
       offsetof(MpegTSWrite, reemit_pat_pmt), AV_OPT_TYPE_INT, {0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
+    { "extra_video_descriptors", "BASE64 encoded string of extra video descriptor bytes",
+      offsetof(MpegTSWrite, extra_video_descriptors), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM},
     { NULL },
 };
 
@@ -242,7 +247,7 @@ static void mpegts_write_pat(AVFormatContext *s)
 
 static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
 {
-    //    MpegTSWrite *ts = s->priv_data;
+    MpegTSWrite *ts = s->priv_data;
     uint8_t data[1012], *q, *desc_length_ptr, *program_info_length_ptr;
     int val, stream_type, i;
 
@@ -377,6 +382,23 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
                 *q++ = 'a';
                 *q++ = 'c';
             }
+            if (ts->extra_video_descriptors) {
+                int evd_data_len = strlen(ts->extra_video_descriptors) * 3 / 4;
+                if (evd_data_len > 0) {
+                    uint8_t *evd_data = av_malloc(evd_data_len);
+                    val = av_base64_decode(evd_data, ts->extra_video_descriptors, evd_data_len);
+                    if (val > 0  && (q + val - data < 1012)) {    // data[1012]
+                        memcpy(q, evd_data, val);
+                        q += val;
+                    }
+                    else if (val > 0)
+                        av_log(s, AV_LOG_WARNING, "extra_video_descriptors skipped to prevent buffer overflow\n");
+                    else
+                        av_log(s, AV_LOG_WARNING, "extra_video_descriptors contains invalid BASE64 data\n");
+                    
+                    av_free(evd_data);
+                }               
+            }
             break;
         }
 


More information about the ffmpeg-devel mailing list