[FFmpeg-devel] [PATCH] avcodec/wrapped_avframe: allocate a buffer with padding

wm4 nfxjfg at googlemail.com
Wed Feb 22 07:31:42 EET 2017


On Wed, 22 Feb 2017 00:14:32 +0100
Marton Balint <cus at passwd.hu> wrote:

> This ensures that the wrapped avframe will not get reallocated later, which
> would invalidate internal references such as extended data.
> 
> Signed-off-by: Marton Balint <cus at passwd.hu>
> ---
>  libavcodec/wrapped_avframe.c | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/libavcodec/wrapped_avframe.c b/libavcodec/wrapped_avframe.c
> index 13c8d8a..1436032 100644
> --- a/libavcodec/wrapped_avframe.c
> +++ b/libavcodec/wrapped_avframe.c
> @@ -43,19 +43,31 @@ static int wrapped_avframe_encode(AVCodecContext *avctx, AVPacket *pkt,
>                       const AVFrame *frame, int *got_packet)
>  {
>      AVFrame *wrapped = av_frame_clone(frame);
> +    uint8_t *data;
> +    int size = sizeof(*wrapped) + AV_INPUT_BUFFER_PADDING_SIZE;
>  
>      if (!wrapped)
>          return AVERROR(ENOMEM);
>  
> -    pkt->buf = av_buffer_create((uint8_t *)wrapped, sizeof(*wrapped),
> +    data = av_mallocz(size);
> +    if (!data) {
> +        av_frame_free(&wrapped);
> +        return AVERROR(ENOMEM);
> +    }
> +
> +    pkt->buf = av_buffer_create(data, size,
>                                  wrapped_avframe_release_buffer, NULL,
>                                  AV_BUFFER_FLAG_READONLY);
>      if (!pkt->buf) {
>          av_frame_free(&wrapped);
> +        av_freep(&data);
>          return AVERROR(ENOMEM);
>      }
>  
> -    pkt->data = (uint8_t *)wrapped;
> +    av_frame_move_ref((AVFrame*)data, wrapped);
> +    av_frame_free(&wrapped);

I think this could be done as just

  av_frame_ref((AVFrame*)data, frame);

without calling av_frame_clone(), but it doesn't hurt either. (Changing
it might be an optional, minor improvement.)

> +
> +    pkt->data = data;
>      pkt->size = sizeof(*wrapped);
>  
>      pkt->flags |= AV_PKT_FLAG_KEY;

Patch looks good, and I like it better than checking the codec ID.

And now something in general:

wrapped_avframe is a special-case, because it stores a pointer in what
is supposed to be just a raw byte array. So it's always possible that
AVPacket use with it breaks in tricky ways that is fine with normal
codecs. To make wrapped_avframe absolutely safe, we could either
introduce a separate AVBuffer field just for wrapped_avframe, or we
could make side-data refcounted (like with AVFrame), and store the
AVFrame in side-data, which would probably be slightly more robust.
Maybe something to consider on the next ABI bump.


More information about the ffmpeg-devel mailing list