[FFmpeg-devel] [PATCH] libavutil: AVEncodeInfo data structures and AV_FRAME_DATA_ENCODE_INFO AVFrameSideDataType
Hendrik Leppkes
h.leppkes at gmail.com
Fri Aug 9 20:58:34 EEST 2019
On Fri, Aug 9, 2019 at 7:52 PM James Almer <jamrial at gmail.com> wrote:
>
> On 8/9/2019 2:38 PM, Juan De León wrote:
> > AVEncodeInfoFrame data structure to store as AVFrameSideData of type AV_FRAME_DATA_ENCODE_INFO.
> > The structure stores quantization index for each plane, DC/AC deltas for luma and chroma planes, and an array of AVEncodeInfoBlock struct denoting position, size, and delta quantizer for each block in the frame.
> > Can be extended to support extraction of other block information.
> >
> > Signed-off-by: Juan De León <juandl at google.com>
> > ---
> > fixed a typo in frame.h comment
> > libavutil/Makefile | 2 +
> > libavutil/encode_info.c | 67 +++++++++++++++++++++++++++++++
> > libavutil/encode_info.h | 87 +++++++++++++++++++++++++++++++++++++++++
> > libavutil/frame.c | 1 +
> > libavutil/frame.h | 7 ++++
> > 5 files changed, 164 insertions(+)
> > create mode 100644 libavutil/encode_info.c
> > create mode 100644 libavutil/encode_info.h
> >
> > diff --git a/libavutil/Makefile b/libavutil/Makefile
> > index 57e6e3d7e8..37cfb099e9 100644
> > --- a/libavutil/Makefile
> > +++ b/libavutil/Makefile
> > @@ -24,6 +24,7 @@ HEADERS = adler32.h \
> > dict.h \
> > display.h \
> > downmix_info.h \
> > + encode_info.h \
> > encryption_info.h \
> > error.h \
> > eval.h \
> > @@ -111,6 +112,7 @@ OBJS = adler32.o \
> > dict.o \
> > display.o \
> > downmix_info.o \
> > + encode_info.o \
> > encryption_info.o \
> > error.o \
> > eval.o \
> > diff --git a/libavutil/encode_info.c b/libavutil/encode_info.c
> > new file mode 100644
> > index 0000000000..68c30af4d7
> > --- /dev/null
> > +++ b/libavutil/encode_info.c
> > @@ -0,0 +1,67 @@
> > +/*
> > + * This file is part of FFmpeg.
> > + *
> > + * FFmpeg is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU Lesser General Public
> > + * License as published by the Free Software Foundation; either
> > + * version 2.1 of the License, or (at your option) any later version.
> > + *
> > + * FFmpeg is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> > + * Lesser General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU Lesser General Public
> > + * License along with FFmpeg; if not, write to the Free Software
> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> > + */
> > +
> > +#include "libavutil/encode_info.h"
> > +#include "libavutil/mem.h"
> > +
> > +static int init_encode_info_data(AVEncodeInfoFrame *ptr, int nb_blocks) {
> > + ptr->nb_blocks = nb_blocks;
> > + ptr->dc_q = ptr->ac_q = -1;
> > + ptr->dc_chroma_q = ptr->ac_chroma_q = -1;
> > +
> > + for(int i=0;i<AV_NUM_DATA_POINTERS;i++)
> > + ptr->plane_q[i] = -1;
> > +
> > + return 0;
> > +}
> > +
> > +AVEncodeInfoFrame *av_encode_info_alloc(int nb_blocks)
> > +{
> > + AVEncodeInfoFrame *ptr;
> > + size_t size = sizeof(AVEncodeInfoFrame) + sizeof(AVEncodeInfoBlock)*nb_blocks;
> > +
> > + if (nb_blocks < 0 || size >= INT_MAX)
> > + return NULL;
> > +
> > + ptr = av_mallocz(size);
> > + if (!ptr)
> > + return NULL;
> > +
> > + init_encode_info_data(ptr, nb_blocks);
> > +
> > + return ptr;
> > +}
> > +
> > +AVEncodeInfoFrame *av_encode_info_create_side_data(AVFrame *frame, int nb_blocks)
> > +{
> > + size_t size = sizeof(AVEncodeInfoFrame) + sizeof(AVEncodeInfoBlock)*nb_blocks;
> > +
> > + if (nb_blocks < 0 || size >= INT_MAX)
> > + return NULL;
> > +
> > + AVFrameSideData *sd = av_frame_new_side_data(frame,
> > + AV_FRAME_DATA_ENCODE_INFO,
> > + size);
> > + if (!sd)
> > + return NULL;
> > +
> > + memset(sd->data, 0, size);
> > + init_encode_info_data((AVEncodeInfoFrame*)sd->data, nb_blocks);
> > +
> > + return (AVEncodeInfoFrame*)sd->data;
> > +}
> > diff --git a/libavutil/encode_info.h b/libavutil/encode_info.h
> > new file mode 100644
> > index 0000000000..cbe8be2891
> > --- /dev/null
> > +++ b/libavutil/encode_info.h
> > @@ -0,0 +1,87 @@
> > +/*
> > + * This file is part of FFmpeg.
> > + *
> > + * FFmpeg is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU Lesser General Public
> > + * License as published by the Free Software Foundation; either
> > + * version 2.1 of the License, or (at your option) any later version.
> > + *
> > + * FFmpeg is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> > + * Lesser General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU Lesser General Public
> > + * License along with FFmpeg; if not, write to the Free Software
> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> > + */
> > +
> > +#ifndef AVUTIL_ENCODE_INFO_H
> > +#define AVUTIL_ENCODE_INFO_H
> > +
> > +#include "libavutil/frame.h"
> > +
> > +/**
> > + * Data structure for extracting block data stored in an array in AVEncodeInfoFrame
> > + */
> > +typedef struct AVEncodeInfoBlock{
> > + /**
> > + * Distance in luma pixels from the top-left corner of the visible frame
> > + * to the top-left corner of the block.
> > + * Can be negative if top/right padding is present on the coded frame.
> > + */
> > + int src_x, src_y;
> > + /**
> > + * Width and height of the block in luma pixels
> > + */
> > + int w, h;
> > + /**
> > + * Delta quantization index for the block
> > + */
> > + int delta_q;
> > +
> > + uint8_t reserved[128];
> > +} AVEncodeInfoBlock;
> > +
> > +/**
> > + * Frame encoding info, used as AVFrameSideData
> > + */
> > +typedef struct AVEncodeInfoFrame {
> > + /**
> > + * Number of blocks in the array
> > + */
> > + int nb_blocks;
> > + /**
> > + * Base plane quantizer for the frame, set to -1 when value is unsupported
> > + */
> > + int plane_q[AV_NUM_DATA_POINTERS];
> > + /**
> > + * DC/AC quantizer index delta, set to -1 when value is value unsupported.
> > + */
> > + int ac_q, dc_q;
> > + /**
> > + * DC/AC chroma quantizer index delta, set to -1 when value is value unsupported.
> > + */
> > + int ac_chroma_q, dc_chroma_q;
> > +
> > + uint8_t reserved[256];
> > +
> > + AVEncodeInfoBlock blocks[];
>
> Flexible array members will break compatibility with C++ projects.
>
If its the last element in the struct, just make it blocks[1] or
something and document that dynamically allocated data follows in its
place. This is common-place even in C++ compatible structs.
I believe we even use it in some structs ourself.
- Hendrik
More information about the ffmpeg-devel
mailing list