[FFmpeg-devel] [PATCH] libavutil: AVEncodeInfo data structures and AV_FRAME_DATA_ENCODE_INFO AVFrameSideDataType

James Almer jamrial at gmail.com
Fri Aug 9 21:02:04 EEST 2019


On 8/9/2019 2:58 PM, Hendrik Leppkes wrote:
> 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.

Or just a pointer that points to the first byte after itself.


More information about the ffmpeg-devel mailing list