[FFmpeg-devel] [PATCH] exporting mpeg user_data

Eric Hennigan the.theorist
Tue Mar 18 22:25:40 CET 2008


diff -ur ffmpeg/libavcodec/avcodec.h 
ffmpeg-userdata-modified/libavcodec/avcodec.h
--- ffmpeg/libavcodec/avcodec.h       2007-06-16 02:01:28.000000000 -0700
+++ ffmpeg-userdata-modified/libavcodec/avcodec.h     2008-03-17 
14:37:05.000000000 -0700
@@ -2119,6 +2119,13 @@
      * - decoding: unused
      */
     int64_t timecode_frame_start;
+
+    /** User Data section
+     * - decoding: Set/allocated/freed by libavcodec.
+     */
+    uint8_t *userdata;
+    size_t userdata_size;
+
 } AVCodecContext;

Sorry, about the signed-ness earlier, I was simply following the types used 
for extradata.


diff -ur ffmpeg/libavcodec/utils.c ffmpeg-userdata-modified/libavcodec/utils.c
--- ffmpeg/libavcodec/utils.c   2007-06-16 02:01:28.000000000 -0700
+++ ffmpeg-userdata-modified/libavcodec/utils.c 2008-03-17 
14:42:38.000000000 -0700
@@ -729,6 +729,7 @@
 {"timecode_frame_start", "GOP timecode frame start number, in non drop frame 
format", OFFSET(timecode_frame_start), FF_OPT_TYPE_INT, 0, 0, INT_MAX, V|E},
 {"drop_frame_timecode", NULL, 0, FF_OPT_TYPE_CONST, 
CODEC_FLAG2_DROP_FRAME_TIMECODE, INT_MIN, INT_MAX, V|E, "flags2"},
 {"non_linear_q", "use non linear quantizer", 0, FF_OPT_TYPE_CONST, 
CODEC_FLAG2_NON_LINEAR_QUANT, INT_MIN, INT_MAX, V|E, "flags2"},
+{"userdata_size", NULL, OFFSET(userdata_size), FF_OPT_TYPE_INT, DEFAULT, 
INT_MIN, INT_MAX},
 {NULL},
 };

> Michael says: see FF_OPT_TYPE_BINARY
> M?ns Rullg?rd says: This makes no sense at all.

Honestly, I have to plead ignorance on this one. I don't fully know what the 
hell I'm doing, I'm not intimately familiar with the design of ffmpeg. So, 
being a complete noob, I simply copied what was done for the extradata field. 
The intent was to get the avcodec initialization routines to provide default 
values of avctx->userdata = NULL, and avctx->userdata_size = 0. Putting this 
line in the AVOption options[] was probably completely misguided, and doesn't 
accomplish my intent, but I didn't really have any better ideas.

diff -ur ffmpeg/libavcodec/mpeg12.c 
ffmpeg-userdata-modified/libavcodec/mpeg12.c
--- ffmpeg/libavcodec/mpeg12.c  2007-06-16 02:01:28.000000000 -0700
+++ ffmpeg-userdata-modified/libavcodec/mpeg12.c        2008-03-14 
15:46:16.000000000 -0700
@@ -2996,6 +2996,28 @@
             avctx->dtg_active_format = p[0] & 0x0f;
         }
     }
+    else if (len > 16 &&  /* klv detection, assumes that klv is wrapped 
inside of klv */
+        buf[0] == 0x06 && buf[1] == 0x0e && buf[2] == 0x2b && buf[3] == 0x34) 
{
+        int size = buf[16];
+        if ( size < 128 ) {
+            len = 17 + size;
+            goto end;
+        } else
+            size -= 128;
+
+        int i;
+        uint64_t real_size =0;
+        for ( i=0; i<size; ++i) {
+            real_size *= 256;
+            real_size += buf[i+17];
+        }
+        len = 17 + i + real_size;
+    }
+
+end:
+    avctx->userdata = av_realloc( avctx->userdata, len );
+    memcpy( avctx->userdata, buf, len );
+    avctx->userdata_size = len;
 }

> M?ns Rullg?rd says:
> Would it not be better to simply export any user_data that might be
> present in the stream, and let the app deal with interpreting it?
> Also, you seem not to handle cleanly all the places user_data may
> occur, i.e. following sequence_header, group_of_pictures_header, or
> picture_header.  Assuming you're talking about ISO 13818-2 user_data,
> not some other bastardised format.

Yes, actually I agree. The issue here was that the klv that was embedded in 
the user_data field of the mpeg files that I'm working with unfortunately 
contains 0x000001, which is supposed to indicate a next_start_code in the 
mpeg; so reading up to that point, and exporting all the bytes in between 
would pick up too few bytes. So, considering that 
mpeg12.c:mpeg_decode_user_data already had a piece that parsed the DTG active 
format info, I thought that adding code for klv detection would be 
appropriate. Also, I'm not certain about when mpeg_decode_user_data gets 
called, I'd just assumed that it was whenever user_data_start_code was 
encountered in the mpeg file. But you do bring up a good point: that is if a 
user of ffmpeg is checking the contents of user_data every time 
av_decode_video returns a frame_finished, then they stand a good chance of 
missing some of the user_data sections. For the videos I had, this turned out 
not to be a problem, since user_data fields tended to be present only for 
I-frames.

@@ -983,6 +984,7 @@
         avctx->codec->close(avctx);
     avcodec_default_free_buffers(avctx);
     av_freep(&avctx->priv_data);
+    av_free(avctx->userdata);
     avctx->codec = NULL;
     entangled_thread_counter--;
     return 0;

Also, I did want to ask, which one the two is more appropriate:
av_free( avctx->userdata );
av_freep( &avctx->userdata );





More information about the ffmpeg-devel mailing list