[FFmpeg-devel] [PATCH] exporting mpeg user_data

Måns Rullgård mans
Tue Mar 18 00:38:18 CET 2008


Eric Hennigan <the.theorist at gmail.com> writes:

> Last month, I posted a simple request
> http://lists.mplayerhq.hu/pipermail/libav-user/2008-February/000045.html
> on libav-user asking if there was a way in which to extract klv/mxf
> data from the user_data section of an mpeg. Since I was answered in
> the negative, I'm providing the solution that I came up
> with. Hopefully you guys can find a use for it.
>
>
> 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;
> +    int userdata_size;

Sizes are better represented as unsigned numbers.

> +
>  } AVCodecContext;
>  
>  /**
> 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;
>  }

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.

>  static void mpeg_decode_gop(AVCodecContext *avctx,
> 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},

This makes no sense at all.

>  {NULL},
>  };
>  
> @@ -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;

-- 
M?ns Rullg?rd
mans at mansr.com




More information about the ffmpeg-devel mailing list