[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