[FFmpeg-devel,2/3] libavcodec: extractqp changes for h264 decoder

Submitted by =?UTF-8?q?Juan=20De=20Le=C3=B3n?= on Aug. 19, 2019, 11:36 p.m.

Details

Message ID 20190819233655.171637-3-juandl@google.com
State New
Headers show

Commit Message

=?UTF-8?q?Juan=20De=20Le=C3=B3n?= Aug. 19, 2019, 11:36 p.m.
Added extractqp flag as an argument to the -debug flag to enable qp extraction
for the h264 decoder using AVEncodeInfo as AVFrameSideData.

Signed-off-by: Juan De León <juandl@google.com>
---
 libavcodec/avcodec.h       |  1 +
 libavcodec/h264dec.c       | 40 ++++++++++++++++++++++++++++++++++++++
 libavcodec/options_table.h |  1 +
 3 files changed, 42 insertions(+)

Patch hide | download patch | download mbox

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index d234271c5b..9e3185720a 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2671,6 +2671,7 @@  typedef struct AVCodecContext {
 #endif
 #define FF_DEBUG_BUFFERS     0x00008000
 #define FF_DEBUG_THREADS     0x00010000
+#define FF_DEBUG_EXTRACTQP   0x00020000
 #define FF_DEBUG_GREEN_MD    0x00800000
 #define FF_DEBUG_NOMC        0x01000000
 
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index 8d1bd16a8e..1edbfde65e 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -28,6 +28,7 @@ 
 #define UNCHECKED_BITSTREAM_READER 1
 
 #include "libavutil/avassert.h"
+#include "libavutil/encode_info.h"
 #include "libavutil/display.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/opt.h"
@@ -906,6 +907,45 @@  static int finalize_frame(H264Context *h, AVFrame *dst, H264Picture *out, int *g
                           f->format, f->width, f->height>>1);
         }
 
+        if (h->avctx->debug & FF_DEBUG_EXTRACTQP) {
+            int mb_height = h->height / 16;
+            int mb_width = h->width / 16;
+            int mb_xy = mb_width * mb_height;
+            const PPS *pps = (const PPS*)h->ps.pps;
+
+            AVEncodeInfoFrame *encode_info = av_encode_info_create_side_data(out->f, mb_xy);
+            if (!encode_info) {
+                av_log(h->avctx, AV_LOG_ERROR, "Failed to allocate encode info in side data\n");
+                return AVERROR(ENOMEM);
+            }
+
+            encode_info->plane_q[0] = pps->init_qp; //base Y qp
+            if (pps->chroma_qp_index_offset[0] != 0) {
+                encode_info->plane_q[1] = pps->init_qp + pps->chroma_qp_index_offset[0];
+            }
+            if (pps->chroma_qp_diff != 0) {
+                encode_info->plane_q[2] = pps->init_qp + pps->chroma_qp_index_offset[1];
+            }
+
+            // loop allocate qp
+            int qs_index, mb_y, mb_x;
+            int idx = 0;
+            AVEncodeInfoBlock *block;
+            for (mb_y = 0; mb_y < mb_height; mb_y++) {
+                for (mb_x = 0; mb_x < mb_width; mb_x++) {
+                    qs_index = mb_x + mb_y * h->mb_stride; //qscale table index
+
+                    block = av_encode_info_get_block(encode_info, idx);
+                    block->src_x = mb_x * 16 - h->crop_left;
+                    block->src_y = mb_y * 16 - h->crop_top;
+                    block->w = block->h = 16;
+
+                    block->delta_q = out->qscale_table[qs_index] - pps->init_qp;
+                    idx++;
+                }
+            }
+        }
+
         ret = output_frame(h, dst, out);
         if (ret < 0)
             return ret;
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index 4a266eca16..e0e78a69c5 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -219,6 +219,7 @@  static const AVOption avcodec_options[] = {
 {"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"},
 {"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|A|D, "debug"},
 {"nomc", "skip motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_NOMC }, INT_MIN, INT_MAX, V|A|D, "debug"},
+{"extractqp", "enable QP extraction per frame", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_EXTRACTQP }, INT_MIN, INT_MAX, V|D, "debug"},
 {"dia_size", "diamond type & size for motion estimation", OFFSET(dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"last_pred", "amount of motion predictors from the previous frame", OFFSET(last_predictor_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 #if FF_API_PRIVATE_OPT