diff mbox

[FFmpeg-devel] Extract QP from h264 encoded videos

Message ID 20190730023902.156266-1-juandl@google.com
State Superseded
Headers show

Commit Message

=?UTF-8?q?Juan=20De=20Le=C3=B3n?= July 30, 2019, 2:39 a.m. UTC
I tried to fix all you suggested, please have a look and let me know what you think.

design doc: https://docs.google.com/document/d/1WClt3EqhjwdGXhEw386O0wfn3IBQ1Ib-_5emVM1gbnA/edit?usp=sharing

Signed-off-by: Juan De León <juandl@google.com>
---
 libavutil/Makefile              |   2 +
 libavutil/frame.h               |   6 ++
 libavutil/quantization_params.c |  42 ++++++++++++
 libavutil/quantization_params.h | 114 ++++++++++++++++++++++++++++++++
 4 files changed, 164 insertions(+)
 create mode 100644 libavutil/quantization_params.c
 create mode 100644 libavutil/quantization_params.h

Comments

Andrey Semashev July 30, 2019, 9:11 a.m. UTC | #1
On 7/30/19 5:39 AM, Juan De León wrote:
> I tried to fix all you suggested, please have a look and let me know what you think.
> 
> design doc: https://docs.google.com/document/d/1WClt3EqhjwdGXhEw386O0wfn3IBQ1Ib-_5emVM1gbnA/edit?usp=sharing
> 
> Signed-off-by: Juan De León <juandl@google.com>
> ---
>   libavutil/Makefile              |   2 +
>   libavutil/frame.h               |   6 ++
>   libavutil/quantization_params.c |  42 ++++++++++++
>   libavutil/quantization_params.h | 114 ++++++++++++++++++++++++++++++++
>   4 files changed, 164 insertions(+)
>   create mode 100644 libavutil/quantization_params.c
>   create mode 100644 libavutil/quantization_params.h
> 
> diff --git a/libavutil/Makefile b/libavutil/Makefile
> index 8a7a44e4b5..be1a9c3a9c 100644
> --- a/libavutil/Makefile
> +++ b/libavutil/Makefile
> @@ -60,6 +60,7 @@ HEADERS = adler32.h                                                     \
>             pixdesc.h                                                     \
>             pixelutils.h                                                  \
>             pixfmt.h                                                      \
> +          quantization_params.h                                         \
>             random_seed.h                                                 \
>             rc4.h                                                         \
>             rational.h                                                    \
> @@ -140,6 +141,7 @@ OBJS = adler32.o                                                        \
>          parseutils.o                                                     \
>          pixdesc.o                                                        \
>          pixelutils.o                                                     \
> +       quantization_params.o                                            \
>          random_seed.o                                                    \
>          rational.o                                                       \
>          reverse.o                                                        \
> diff --git a/libavutil/frame.h b/libavutil/frame.h
> index 5d3231e7bb..b64fd9c02c 100644
> --- a/libavutil/frame.h
> +++ b/libavutil/frame.h
> @@ -179,6 +179,12 @@ enum AVFrameSideDataType {
>        * array element is implied by AVFrameSideData.size / AVRegionOfInterest.self_size.
>        */
>       AV_FRAME_DATA_REGIONS_OF_INTEREST,
> +    /**
> +     * To extract quantization parameters from supported decoders.
> +     * The data is stored as AVQuantizationParamsArray type, described in
> +     * libavuitl/quantization_params.h
> +     */
> +    AV_FRAME_DATA_QUANTIZATION_PARAMS,
>   };
>   
>   enum AVActiveFormatDescription {
> diff --git a/libavutil/quantization_params.c b/libavutil/quantization_params.c
> new file mode 100644
> index 0000000000..fc51b55eee
> --- /dev/null
> +++ b/libavutil/quantization_params.c
> @@ -0,0 +1,42 @@
> +/*
> + * 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/quantization_params.h"
> +#include "libavutil/mem.h"
> +
> +static const char* const QP_NAMES_H264[] = {"qpy", "qpuv"};
> +
> +static const char* const QP_NAMES_VP9[] = {"qyac", "qydc", "quvdc", "quvac",
> +                                           "qiyac", "qiydc", "qiuvdc", "qiuvac"};
> +
> +static const char* const QP_NAMES_AV1[] = {"qydc", "qyac", "qudc", "quac", "qvdc", "qvac",
> +                                      "qiydc", "qiyac", "qiudc", "qiuac", "qivdc", "qivac"};
> +
> +char* av_get_qp_type_string(enum AVExtractQPSupportedCodecs codec_id, int index)
> +{
> +    switch (codec_id) {
> +        case AV_EXTRACT_QP_CODEC_ID_H264:
> +            return index < AV_QP_ARR_SIZE_H264 ? av_strdup(QP_NAMES_H264[index]) :NULL;
> +        case AV_EXTRACT_QP_CODEC_ID_VP9:
> +            return index < AV_QP_ARR_SIZE_VP9  ? av_strdup(QP_NAMES_VP9[index])  :NULL;
> +        case AV_EXTRACT_QP_CODEC_ID_AV1:
> +            return index < AV_QP_ARR_SIZE_AV1  ? av_strdup(QP_NAMES_AV1[index])  :NULL;
> +        default:
> +            return NULL;
> +    }
> +}
> diff --git a/libavutil/quantization_params.h b/libavutil/quantization_params.h
> new file mode 100644
> index 0000000000..d123aade3b
> --- /dev/null
> +++ b/libavutil/quantization_params.h
> @@ -0,0 +1,114 @@
> +/*
> + * 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_QUANTIZATION_PARAMS_H
> +#define AVUTIL_QUANTIZATION_PARAMS_H
> +
> +/*
> + * Supported decoders
> + */
> +enum AVExtractQPSupportedCodecs {
> +    AV_EXTRACT_QP_CODEC_ID_H264 = 0,
> +    AV_EXTRACT_QP_CODEC_ID_VP9,
> +    AV_EXTRACT_QP_CODEC_ID_AV1,
> +};

Just a thought. If you need codec ids and implement codec-specific 
functionality, then this whole thing probably belongs to libavcodec, not 
libavutil.

> +
> +/**
> + * Enums for different codecs to store qp in the type array
> + * Each enum must have an array of strings describing each field
> + * declared in quantization_params.c
> + */
> +
> +enum AVQPArrIndexesH264 {
> +    AV_QP_Y_H264 = 0,       // qp value index in qp_type array
> +    AV_QP_UV_H264,
> +    AV_QP_ARR_SIZE_H264     // number of QP stored for this codec
> +};
> +
> +enum AVQPArrIndexesVP9 {
> +    AV_QP_YAC_VP9 = 0,    // get_dc_quant[][AV_QP_INDEX_YAC_VP9]
> +    AV_QP_YDC_VP9,        // get_dc_quant[][AV_QP_INDEX_YDC_VP9]
> +    AV_QP_UVDC_VP9,       // get_dc_quant[][AV_QP_INDEX_UVDC_VP9]
> +    AV_QP_UVAC_VP9,       // get_ac_quant[][AV_QP_INDEX_UVAC_VP9]
> +    AV_QP_INDEX_YAC_VP9,  // base_q_idx
> +    AV_QP_INDEX_YDC_VP9,  // base_q_idx+delta_q_y_dc
> +    AV_QP_INDEX_UVDC_VP9, // base_q_idx+delta_q_uv_dc
> +    AV_QP_INDEX_UVAC_VP9, // base_q_idx+delta_q_uv_ac
> +    AV_QP_ARR_SIZE_VP9
> +};
> +
> +enum AVQPArrIndexesAV1 {
> +    AV_QP_YDC_AV1 = 0,
> +    AV_QP_YAC_AV1,
> +    AV_QP_UDC_AV1,
> +    AV_QP_UAC_AV1,
> +    AV_QP_VDC_AV1,
> +    AV_QP_VAC_AV1,
> +    AV_QP_INDEX_YDC_AV1,
> +    AV_QP_INDEX_YAC_AV1,
> +    AV_QP_INDEX_UDC_AV1,
> +    AV_QP_INDEX_UAC_AV1,
> +    AV_QP_INDEX_VDC_AV1,
> +    AV_QP_INDEX_VAC_AV1,
> +    AV_QP_ARR_SIZE_AV1
> +};
> +
> +/**
> + * Data structure for extracting Quantization Parameters, codec independent
> + */
> +typedef struct AVQuantizationParams {
> +    /**
> +     * x and y coordinates of the block in pixels
> +     */
> +    int x, y;
> +    /**
> +     * width and height of the block in pixels
> +     */
> +    int w, h;
> +    /**
> +     * qp array, indexed by type according to
> +     * the enum corresponding to the codec
> +     */
> +    int qp_type[AV_QP_ARR_SIZE_AV1];
> +} AVQuantizationParams;
> +
> +/**
> + * For storing an array of AVQuantization parameters and its size
> + * Used as AVFrameSideData
> + */
> +typedef struct AVQuantizationParamsArray {
> +    /**
> +     * Array of AVQuantizationParams type blocks
> +     */
> +    AVQuantizationParams *qp_block_array;
> +    /**
> +     * size of the array
> +     */
> +    int nb_blocks;
> +    /**
> +     * Stores an id corresponding to one of the suppported codecs
> +     */
> +    enum AVExtractQPSupportedCodecs codec_id;
> +} AVQuantizationParamsArray;
> +
> +/**
> + * Get the string describing the qp type for the given codec
> + */
> +char* av_get_qp_type_string(enum AVExtractQPSupportedCodecs codec_id, int index);
> +
> +#endif /* AVUTIL_QUANTIZATION_PARAMS_H */
>
Andrey Semashev July 30, 2019, 9:19 a.m. UTC | #2
On 7/30/19 12:11 PM, Andrey Semashev wrote:
> On 7/30/19 5:39 AM, Juan De León wrote:
>> I tried to fix all you suggested, please have a look and let me know 
>> what you think.
>>
>> design doc: 
>> https://docs.google.com/document/d/1WClt3EqhjwdGXhEw386O0wfn3IBQ1Ib-_5emVM1gbnA/edit?usp=sharing 
>>
>>
>> Signed-off-by: Juan De León <juandl@google.com>
>> ---
>>   libavutil/Makefile              |   2 +
>>   libavutil/frame.h               |   6 ++
>>   libavutil/quantization_params.c |  42 ++++++++++++
>>   libavutil/quantization_params.h | 114 ++++++++++++++++++++++++++++++++
>>   4 files changed, 164 insertions(+)
>>   create mode 100644 libavutil/quantization_params.c
>>   create mode 100644 libavutil/quantization_params.h
>>
>> diff --git a/libavutil/Makefile b/libavutil/Makefile
>> index 8a7a44e4b5..be1a9c3a9c 100644
>> --- a/libavutil/Makefile
>> +++ b/libavutil/Makefile
>> @@ -60,6 +60,7 @@ HEADERS = 
>> adler32.h                                                     \
>>             
>> pixdesc.h                                                     \
>>             
>> pixelutils.h                                                  \
>>             
>> pixfmt.h                                                      \
>> +          
>> quantization_params.h                                         \
>>             
>> random_seed.h                                                 \
>>             
>> rc4.h                                                         \
>>             
>> rational.h                                                    \
>> @@ -140,6 +141,7 @@ OBJS = 
>> adler32.o                                                        \
>>          
>> parseutils.o                                                     \
>>          
>> pixdesc.o                                                        \
>>          
>> pixelutils.o                                                     \
>> +       
>> quantization_params.o                                            \
>>          
>> random_seed.o                                                    \
>>          
>> rational.o                                                       \
>>          
>> reverse.o                                                        \
>> diff --git a/libavutil/frame.h b/libavutil/frame.h
>> index 5d3231e7bb..b64fd9c02c 100644
>> --- a/libavutil/frame.h
>> +++ b/libavutil/frame.h
>> @@ -179,6 +179,12 @@ enum AVFrameSideDataType {
>>        * array element is implied by AVFrameSideData.size / 
>> AVRegionOfInterest.self_size.
>>        */
>>       AV_FRAME_DATA_REGIONS_OF_INTEREST,
>> +    /**
>> +     * To extract quantization parameters from supported decoders.
>> +     * The data is stored as AVQuantizationParamsArray type, 
>> described in
>> +     * libavuitl/quantization_params.h
>> +     */
>> +    AV_FRAME_DATA_QUANTIZATION_PARAMS,
>>   };
>>   enum AVActiveFormatDescription {
>> diff --git a/libavutil/quantization_params.c 
>> b/libavutil/quantization_params.c
>> new file mode 100644
>> index 0000000000..fc51b55eee
>> --- /dev/null
>> +++ b/libavutil/quantization_params.c
>> @@ -0,0 +1,42 @@
>> +/*
>> + * 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/quantization_params.h"
>> +#include "libavutil/mem.h"
>> +
>> +static const char* const QP_NAMES_H264[] = {"qpy", "qpuv"};
>> +
>> +static const char* const QP_NAMES_VP9[] = {"qyac", "qydc", "quvdc", 
>> "quvac",
>> +                                           "qiyac", "qiydc", 
>> "qiuvdc", "qiuvac"};
>> +
>> +static const char* const QP_NAMES_AV1[] = {"qydc", "qyac", "qudc", 
>> "quac", "qvdc", "qvac",
>> +                                      "qiydc", "qiyac", "qiudc", 
>> "qiuac", "qivdc", "qivac"};
>> +
>> +char* av_get_qp_type_string(enum AVExtractQPSupportedCodecs codec_id, 
>> int index)
>> +{
>> +    switch (codec_id) {
>> +        case AV_EXTRACT_QP_CODEC_ID_H264:
>> +            return index < AV_QP_ARR_SIZE_H264 ? 
>> av_strdup(QP_NAMES_H264[index]) :NULL;
>> +        case AV_EXTRACT_QP_CODEC_ID_VP9:
>> +            return index < AV_QP_ARR_SIZE_VP9  ? 
>> av_strdup(QP_NAMES_VP9[index])  :NULL;
>> +        case AV_EXTRACT_QP_CODEC_ID_AV1:
>> +            return index < AV_QP_ARR_SIZE_AV1  ? 
>> av_strdup(QP_NAMES_AV1[index])  :NULL;
>> +        default:
>> +            return NULL;
>> +    }
>> +}

Why strdup here? Why not return the pointer from the static array?

If you really do intend to strdup, the function documentation should 
state clearly that the caller is supposed to av_free the returned pointer.

>> diff --git a/libavutil/quantization_params.h 
>> b/libavutil/quantization_params.h
>> new file mode 100644
>> index 0000000000..d123aade3b
>> --- /dev/null
>> +++ b/libavutil/quantization_params.h
>> @@ -0,0 +1,114 @@
>> +/*
>> + * 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_QUANTIZATION_PARAMS_H
>> +#define AVUTIL_QUANTIZATION_PARAMS_H
>> +
>> +/*
>> + * Supported decoders
>> + */
>> +enum AVExtractQPSupportedCodecs {
>> +    AV_EXTRACT_QP_CODEC_ID_H264 = 0,
>> +    AV_EXTRACT_QP_CODEC_ID_VP9,
>> +    AV_EXTRACT_QP_CODEC_ID_AV1,
>> +};
> 
> Just a thought. If you need codec ids and implement codec-specific 
> functionality, then this whole thing probably belongs to libavcodec, not 
> libavutil.
> 
>> +
>> +/**
>> + * Enums for different codecs to store qp in the type array
>> + * Each enum must have an array of strings describing each field
>> + * declared in quantization_params.c
>> + */
>> +
>> +enum AVQPArrIndexesH264 {
>> +    AV_QP_Y_H264 = 0,       // qp value index in qp_type array
>> +    AV_QP_UV_H264,
>> +    AV_QP_ARR_SIZE_H264     // number of QP stored for this codec
>> +};
>> +
>> +enum AVQPArrIndexesVP9 {
>> +    AV_QP_YAC_VP9 = 0,    // get_dc_quant[][AV_QP_INDEX_YAC_VP9]
>> +    AV_QP_YDC_VP9,        // get_dc_quant[][AV_QP_INDEX_YDC_VP9]
>> +    AV_QP_UVDC_VP9,       // get_dc_quant[][AV_QP_INDEX_UVDC_VP9]
>> +    AV_QP_UVAC_VP9,       // get_ac_quant[][AV_QP_INDEX_UVAC_VP9]
>> +    AV_QP_INDEX_YAC_VP9,  // base_q_idx
>> +    AV_QP_INDEX_YDC_VP9,  // base_q_idx+delta_q_y_dc
>> +    AV_QP_INDEX_UVDC_VP9, // base_q_idx+delta_q_uv_dc
>> +    AV_QP_INDEX_UVAC_VP9, // base_q_idx+delta_q_uv_ac
>> +    AV_QP_ARR_SIZE_VP9
>> +};
>> +
>> +enum AVQPArrIndexesAV1 {
>> +    AV_QP_YDC_AV1 = 0,
>> +    AV_QP_YAC_AV1,
>> +    AV_QP_UDC_AV1,
>> +    AV_QP_UAC_AV1,
>> +    AV_QP_VDC_AV1,
>> +    AV_QP_VAC_AV1,
>> +    AV_QP_INDEX_YDC_AV1,
>> +    AV_QP_INDEX_YAC_AV1,
>> +    AV_QP_INDEX_UDC_AV1,
>> +    AV_QP_INDEX_UAC_AV1,
>> +    AV_QP_INDEX_VDC_AV1,
>> +    AV_QP_INDEX_VAC_AV1,
>> +    AV_QP_ARR_SIZE_AV1
>> +};
>> +
>> +/**
>> + * Data structure for extracting Quantization Parameters, codec 
>> independent
>> + */
>> +typedef struct AVQuantizationParams {
>> +    /**
>> +     * x and y coordinates of the block in pixels
>> +     */
>> +    int x, y;
>> +    /**
>> +     * width and height of the block in pixels
>> +     */
>> +    int w, h;
>> +    /**
>> +     * qp array, indexed by type according to
>> +     * the enum corresponding to the codec
>> +     */
>> +    int qp_type[AV_QP_ARR_SIZE_AV1];
>> +} AVQuantizationParams;
>> +
>> +/**
>> + * For storing an array of AVQuantization parameters and its size
>> + * Used as AVFrameSideData
>> + */
>> +typedef struct AVQuantizationParamsArray {
>> +    /**
>> +     * Array of AVQuantizationParams type blocks
>> +     */
>> +    AVQuantizationParams *qp_block_array;
>> +    /**
>> +     * size of the array
>> +     */
>> +    int nb_blocks;
>> +    /**
>> +     * Stores an id corresponding to one of the suppported codecs
>> +     */
>> +    enum AVExtractQPSupportedCodecs codec_id;
>> +} AVQuantizationParamsArray;
>> +
>> +/**
>> + * Get the string describing the qp type for the given codec
>> + */
>> +char* av_get_qp_type_string(enum AVExtractQPSupportedCodecs codec_id, 
>> int index);

Also, as it was mentioned, this function should return a const pointer.

>> +
>> +#endif /* AVUTIL_QUANTIZATION_PARAMS_H */
>>
>
=?UTF-8?q?Juan=20De=20Le=C3=B3n?= July 30, 2019, 6:40 p.m. UTC | #3
On Tue, Jul 30, 2019 at 2:20 AM Andrey Semashev <andrey.semashev@gmail.com>
wrote:

> Just a thought. If you need codec ids and implement codec-specific
> functionality, then this whole thing probably belongs to libavcodec, not
> libavutil.
>

My understanding is that only encoders and decoders are supposed to be in
libavcodec.
I believe this fits better in libavutil for consistency.
diff mbox

Patch

diff --git a/libavutil/Makefile b/libavutil/Makefile
index 8a7a44e4b5..be1a9c3a9c 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -60,6 +60,7 @@  HEADERS = adler32.h                                                     \
           pixdesc.h                                                     \
           pixelutils.h                                                  \
           pixfmt.h                                                      \
+          quantization_params.h                                         \
           random_seed.h                                                 \
           rc4.h                                                         \
           rational.h                                                    \
@@ -140,6 +141,7 @@  OBJS = adler32.o                                                        \
        parseutils.o                                                     \
        pixdesc.o                                                        \
        pixelutils.o                                                     \
+       quantization_params.o                                            \
        random_seed.o                                                    \
        rational.o                                                       \
        reverse.o                                                        \
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 5d3231e7bb..b64fd9c02c 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -179,6 +179,12 @@  enum AVFrameSideDataType {
      * array element is implied by AVFrameSideData.size / AVRegionOfInterest.self_size.
      */
     AV_FRAME_DATA_REGIONS_OF_INTEREST,
+    /**
+     * To extract quantization parameters from supported decoders.
+     * The data is stored as AVQuantizationParamsArray type, described in
+     * libavuitl/quantization_params.h
+     */
+    AV_FRAME_DATA_QUANTIZATION_PARAMS,
 };
 
 enum AVActiveFormatDescription {
diff --git a/libavutil/quantization_params.c b/libavutil/quantization_params.c
new file mode 100644
index 0000000000..fc51b55eee
--- /dev/null
+++ b/libavutil/quantization_params.c
@@ -0,0 +1,42 @@ 
+/*
+ * 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/quantization_params.h"
+#include "libavutil/mem.h"
+
+static const char* const QP_NAMES_H264[] = {"qpy", "qpuv"};
+
+static const char* const QP_NAMES_VP9[] = {"qyac", "qydc", "quvdc", "quvac",
+                                           "qiyac", "qiydc", "qiuvdc", "qiuvac"};
+
+static const char* const QP_NAMES_AV1[] = {"qydc", "qyac", "qudc", "quac", "qvdc", "qvac",
+                                      "qiydc", "qiyac", "qiudc", "qiuac", "qivdc", "qivac"};
+
+char* av_get_qp_type_string(enum AVExtractQPSupportedCodecs codec_id, int index)
+{
+    switch (codec_id) {
+        case AV_EXTRACT_QP_CODEC_ID_H264:
+            return index < AV_QP_ARR_SIZE_H264 ? av_strdup(QP_NAMES_H264[index]) :NULL;
+        case AV_EXTRACT_QP_CODEC_ID_VP9:
+            return index < AV_QP_ARR_SIZE_VP9  ? av_strdup(QP_NAMES_VP9[index])  :NULL;
+        case AV_EXTRACT_QP_CODEC_ID_AV1:
+            return index < AV_QP_ARR_SIZE_AV1  ? av_strdup(QP_NAMES_AV1[index])  :NULL;
+        default:
+            return NULL;
+    }
+}
diff --git a/libavutil/quantization_params.h b/libavutil/quantization_params.h
new file mode 100644
index 0000000000..d123aade3b
--- /dev/null
+++ b/libavutil/quantization_params.h
@@ -0,0 +1,114 @@ 
+/*
+ * 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_QUANTIZATION_PARAMS_H
+#define AVUTIL_QUANTIZATION_PARAMS_H
+
+/*
+ * Supported decoders
+ */
+enum AVExtractQPSupportedCodecs {
+    AV_EXTRACT_QP_CODEC_ID_H264 = 0,
+    AV_EXTRACT_QP_CODEC_ID_VP9,
+    AV_EXTRACT_QP_CODEC_ID_AV1,
+};
+
+/**
+ * Enums for different codecs to store qp in the type array
+ * Each enum must have an array of strings describing each field
+ * declared in quantization_params.c
+ */
+
+enum AVQPArrIndexesH264 {
+    AV_QP_Y_H264 = 0,       // qp value index in qp_type array
+    AV_QP_UV_H264,
+    AV_QP_ARR_SIZE_H264     // number of QP stored for this codec
+};
+
+enum AVQPArrIndexesVP9 {
+    AV_QP_YAC_VP9 = 0,    // get_dc_quant[][AV_QP_INDEX_YAC_VP9]
+    AV_QP_YDC_VP9,        // get_dc_quant[][AV_QP_INDEX_YDC_VP9]
+    AV_QP_UVDC_VP9,       // get_dc_quant[][AV_QP_INDEX_UVDC_VP9]
+    AV_QP_UVAC_VP9,       // get_ac_quant[][AV_QP_INDEX_UVAC_VP9]
+    AV_QP_INDEX_YAC_VP9,  // base_q_idx
+    AV_QP_INDEX_YDC_VP9,  // base_q_idx+delta_q_y_dc
+    AV_QP_INDEX_UVDC_VP9, // base_q_idx+delta_q_uv_dc
+    AV_QP_INDEX_UVAC_VP9, // base_q_idx+delta_q_uv_ac
+    AV_QP_ARR_SIZE_VP9
+};
+
+enum AVQPArrIndexesAV1 {
+    AV_QP_YDC_AV1 = 0,
+    AV_QP_YAC_AV1,
+    AV_QP_UDC_AV1,
+    AV_QP_UAC_AV1,
+    AV_QP_VDC_AV1,
+    AV_QP_VAC_AV1,
+    AV_QP_INDEX_YDC_AV1,
+    AV_QP_INDEX_YAC_AV1,
+    AV_QP_INDEX_UDC_AV1,
+    AV_QP_INDEX_UAC_AV1,
+    AV_QP_INDEX_VDC_AV1,
+    AV_QP_INDEX_VAC_AV1,
+    AV_QP_ARR_SIZE_AV1
+};
+
+/**
+ * Data structure for extracting Quantization Parameters, codec independent
+ */
+typedef struct AVQuantizationParams {
+    /**
+     * x and y coordinates of the block in pixels
+     */
+    int x, y;
+    /**
+     * width and height of the block in pixels
+     */
+    int w, h;
+    /**
+     * qp array, indexed by type according to
+     * the enum corresponding to the codec
+     */
+    int qp_type[AV_QP_ARR_SIZE_AV1];
+} AVQuantizationParams;
+
+/**
+ * For storing an array of AVQuantization parameters and its size
+ * Used as AVFrameSideData
+ */
+typedef struct AVQuantizationParamsArray {
+    /**
+     * Array of AVQuantizationParams type blocks
+     */
+    AVQuantizationParams *qp_block_array;
+    /**
+     * size of the array
+     */
+    int nb_blocks;
+    /**
+     * Stores an id corresponding to one of the suppported codecs
+     */
+    enum AVExtractQPSupportedCodecs codec_id;
+} AVQuantizationParamsArray;
+
+/**
+ * Get the string describing the qp type for the given codec
+ */
+char* av_get_qp_type_string(enum AVExtractQPSupportedCodecs codec_id, int index);
+
+#endif /* AVUTIL_QUANTIZATION_PARAMS_H */