[FFmpeg-devel] [PATCH] Extract QP from h264 encoded videos

Juan De León juandl at google.com
Wed Jul 31 04:47:23 EEST 2019


Removed AVQuantizationParamsArray to prevent ambiguous memory allocation.
For simplicity, the side data will be allocated as an array of AVQuantizationParams and the last element of the array will have w and h set to 0.

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

Signed-off-by: Juan De León <juandl at google.com>
---
 libavutil/Makefile              |   2 +
 libavutil/frame.h               |   6 ++
 libavutil/quantization_params.c |  41 +++++++++++++
 libavutil/quantization_params.h | 101 ++++++++++++++++++++++++++++++++
 4 files changed, 150 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..7d8b0a4526
--- /dev/null
+++ b/libavutil/quantization_params.c
@@ -0,0 +1,41 @@
+/*
+ * 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"
+
+static const char* const QP_NAMES_H264[] = {"qp", "qpcb", "qpcr"};
+
+static const char* const QP_NAMES_VP9[] = {"qyac", "qydc", "quvdc", "quvac",
+                                           "qiyac", "qiydc", "qiuvdc", "qiuvac"};
+
+static const char* const QP_NAMES_AV1[] = {"qyac", "qydc", "qudc", "quac", "qvdc", "qvac",
+                                      "qiyac", "qiydc", "qiudc", "qiuac", "qivdc", "qivac"};
+
+const 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 ? QP_NAMES_H264[index] :NULL;
+        case AV_EXTRACT_QP_CODEC_ID_VP9:
+            return index < AV_QP_ARR_SIZE_VP9  ? QP_NAMES_VP9[index]  :NULL;
+        case AV_EXTRACT_QP_CODEC_ID_AV1:
+            return index < AV_QP_ARR_SIZE_AV1  ? 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..23f4311293
--- /dev/null
+++ b/libavutil/quantization_params.h
@@ -0,0 +1,101 @@
+/*
+ * 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 for extraction and filter
+ */
+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,      // QPy
+    AV_QP_U_H264,          // QPcb
+    AV_QP_V_H264,          // QPcr
+    AV_QP_ARR_SIZE_H264
+};
+
+enum AVQPArrIndexesVP9 {
+    AV_QP_YAC_VP9 = 0,     // get_dc_quant[][base_q_idx] - in spec
+    AV_QP_YDC_VP9,         // get_dc_quant[][base_q_idx+delta_q_y_dc]
+    AV_QP_UVDC_VP9,        // get_dc_quant[][base_q_idx+delta_q_uv_dc]
+    AV_QP_UVAC_VP9,        // get_ac_quant[][base_q_idx+delta_q_uv_ac]
+    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_YAC_AV1 = 0,    // dc_q(base_q_idx) - in spec
+    AV_QP_YDC_AV1,        // dc_q(base_q_idx+DeltaQYDc)
+    AV_QP_UDC_AV1,        // dc_q(base_q_idx+DeltaQUDc)
+    AV_QP_UAC_AV1,        // dc_q(base_q_idx+DeltaQUAc)
+    AV_QP_VDC_AV1,        // dc_q(base_q_idx+DeltaQVDc)
+    AV_QP_VAC_AV1,        // dc_q(base_q_idx+DeltaQVAc)
+    AV_QP_INDEX_YAC_AV1,  // base_q_idx
+    AV_QP_INDEX_YDC_AV1,  // base_q_idx+DeltaQYDc
+    AV_QP_INDEX_UDC_AV1,  // base_q_idx+DeltaQUDc
+    AV_QP_INDEX_UAC_AV1,  // base_q_idx+DeltaQUAc
+    AV_QP_INDEX_VDC_AV1,  // base_q_idx+DeltaQVDc
+    AV_QP_INDEX_VAC_AV1,  // base_q_idx+DeltaQVAc
+    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
+     * set to 0 for the last block in the array
+     */
+    int w, h;
+    /**
+     * qp array, indexed by type according to
+     * the enum corresponding to the codec
+     */
+    int qp_type[AV_QP_ARR_SIZE_AV1];
+    /**
+     * Stores an id corresponding to one of the supported codecs
+     */
+    enum AVExtractQPSupportedCodecs codec_id;
+} AVQuantizationParams;
+
+/**
+ * Get the string describing the qp type for the given codec
+ */
+const char* av_get_qp_type_string(enum AVExtractQPSupportedCodecs codec_id, int index);
+
+#endif /* AVUTIL_QUANTIZATION_PARAMS_H */
-- 
2.22.0.709.g102302147b-goog



More information about the ffmpeg-devel mailing list