Commit 064b875e authored by Anton Khirnov's avatar Anton Khirnov

h264dec: support exporting QP tables through the AVVideoEncParams API

parent 37140ebd
...@@ -15,6 +15,9 @@ libavutil: 2017-10-21 ...@@ -15,6 +15,9 @@ libavutil: 2017-10-21
API changes, most recent first: API changes, most recent first:
2020-05-23 - xxxxxxxxxx - lavu 56.49.100 - video_enc_params.h
Add AV_VIDEO_ENC_PARAMS_H264.
2020-05-23 - xxxxxxxxxx - lavu 56.48.100 - hwcontext.h 2020-05-23 - xxxxxxxxxx - lavu 56.48.100 - hwcontext.h
Add av_hwdevice_ctx_create_derived_opts. Add av_hwdevice_ctx_create_derived_opts.
......
...@@ -54,6 +54,7 @@ void ff_h264_unref_picture(H264Context *h, H264Picture *pic) ...@@ -54,6 +54,7 @@ void ff_h264_unref_picture(H264Context *h, H264Picture *pic)
av_buffer_unref(&pic->qscale_table_buf); av_buffer_unref(&pic->qscale_table_buf);
av_buffer_unref(&pic->mb_type_buf); av_buffer_unref(&pic->mb_type_buf);
av_buffer_unref(&pic->pps_buf);
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
av_buffer_unref(&pic->motion_val_buf[i]); av_buffer_unref(&pic->motion_val_buf[i]);
av_buffer_unref(&pic->ref_index_buf[i]); av_buffer_unref(&pic->ref_index_buf[i]);
...@@ -77,12 +78,14 @@ int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src) ...@@ -77,12 +78,14 @@ int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src)
dst->qscale_table_buf = av_buffer_ref(src->qscale_table_buf); dst->qscale_table_buf = av_buffer_ref(src->qscale_table_buf);
dst->mb_type_buf = av_buffer_ref(src->mb_type_buf); dst->mb_type_buf = av_buffer_ref(src->mb_type_buf);
if (!dst->qscale_table_buf || !dst->mb_type_buf) { dst->pps_buf = av_buffer_ref(src->pps_buf);
if (!dst->qscale_table_buf || !dst->mb_type_buf || !dst->pps_buf) {
ret = AVERROR(ENOMEM); ret = AVERROR(ENOMEM);
goto fail; goto fail;
} }
dst->qscale_table = src->qscale_table; dst->qscale_table = src->qscale_table;
dst->mb_type = src->mb_type; dst->mb_type = src->mb_type;
dst->pps = src->pps;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
dst->motion_val_buf[i] = av_buffer_ref(src->motion_val_buf[i]); dst->motion_val_buf[i] = av_buffer_ref(src->motion_val_buf[i]);
...@@ -120,6 +123,9 @@ int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src) ...@@ -120,6 +123,9 @@ int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src)
dst->recovered = src->recovered; dst->recovered = src->recovered;
dst->invalid_gap = src->invalid_gap; dst->invalid_gap = src->invalid_gap;
dst->sei_recovery_frame_cnt = src->sei_recovery_frame_cnt; dst->sei_recovery_frame_cnt = src->sei_recovery_frame_cnt;
dst->mb_width = src->mb_width;
dst->mb_height = src->mb_height;
dst->mb_stride = src->mb_stride;
return 0; return 0;
fail: fail:
......
...@@ -243,6 +243,15 @@ static int alloc_picture(H264Context *h, H264Picture *pic) ...@@ -243,6 +243,15 @@ static int alloc_picture(H264Context *h, H264Picture *pic)
pic->ref_index[i] = pic->ref_index_buf[i]->data; pic->ref_index[i] = pic->ref_index_buf[i]->data;
} }
pic->pps_buf = av_buffer_ref(h->ps.pps_ref);
if (!pic->pps_buf)
goto fail;
pic->pps = (const PPS*)pic->pps_buf->data;
pic->mb_width = h->mb_width;
pic->mb_height = h->mb_height;
pic->mb_stride = h->mb_stride;
return 0; return 0;
fail: fail:
ff_h264_unref_picture(h, pic); ff_h264_unref_picture(h, pic);
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include "libavutil/imgutils.h" #include "libavutil/imgutils.h"
#include "libavutil/opt.h" #include "libavutil/opt.h"
#include "libavutil/stereo3d.h" #include "libavutil/stereo3d.h"
#include "libavutil/video_enc_params.h"
#include "internal.h" #include "internal.h"
#include "bytestream.h" #include "bytestream.h"
#include "cabac.h" #include "cabac.h"
...@@ -812,6 +814,40 @@ static int get_consumed_bytes(int pos, int buf_size) ...@@ -812,6 +814,40 @@ static int get_consumed_bytes(int pos, int buf_size)
return pos; return pos;
} }
static int h264_export_enc_params(AVFrame *f, H264Picture *p)
{
AVVideoEncParams *par;
unsigned int nb_mb = p->mb_height * p->mb_width;
unsigned int x, y;
par = av_video_enc_params_create_side_data(f, AV_VIDEO_ENC_PARAMS_H264, nb_mb);
if (!par)
return AVERROR(ENOMEM);
par->qp = p->pps->init_qp;
par->delta_qp[1][0] = p->pps->chroma_qp_index_offset[0];
par->delta_qp[1][1] = p->pps->chroma_qp_index_offset[0];
par->delta_qp[2][0] = p->pps->chroma_qp_index_offset[1];
par->delta_qp[2][1] = p->pps->chroma_qp_index_offset[1];
for (y = 0; y < p->mb_height; y++)
for (x = 0; x < p->mb_width; x++) {
const unsigned int block_idx = y * p->mb_width + x;
const unsigned int mb_xy = y * p->mb_stride + x;
AVVideoBlockParams *b = av_video_enc_params_block(par, block_idx);
b->src_x = x * 16;
b->src_y = y * 16;
b->w = 16;
b->h = 16;
b->delta_qp = p->qscale_table[mb_xy] - par->qp;
}
return 0;
}
static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp) static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
{ {
AVFrame *src = srcp->f; AVFrame *src = srcp->f;
...@@ -826,7 +862,16 @@ static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp) ...@@ -826,7 +862,16 @@ static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
if (srcp->sei_recovery_frame_cnt == 0) if (srcp->sei_recovery_frame_cnt == 0)
dst->key_frame = 1; dst->key_frame = 1;
if (h->avctx->export_side_data & AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS) {
ret = h264_export_enc_params(dst, srcp);
if (ret < 0)
goto fail;
}
return 0; return 0;
fail:
av_frame_unref(dst);
return ret;
} }
static int is_extra(const uint8_t *buf, int buf_size) static int is_extra(const uint8_t *buf, int buf_size)
......
...@@ -161,6 +161,12 @@ typedef struct H264Picture { ...@@ -161,6 +161,12 @@ typedef struct H264Picture {
int recovered; ///< picture at IDR or recovery point + recovery count int recovered; ///< picture at IDR or recovery point + recovery count
int invalid_gap; int invalid_gap;
int sei_recovery_frame_cnt; int sei_recovery_frame_cnt;
AVBufferRef *pps_buf;
const PPS *pps;
int mb_width, mb_height;
int mb_stride;
} H264Picture; } H264Picture;
typedef struct H264Ref { typedef struct H264Ref {
......
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
*/ */
#define LIBAVUTIL_VERSION_MAJOR 56 #define LIBAVUTIL_VERSION_MAJOR 56
#define LIBAVUTIL_VERSION_MINOR 48 #define LIBAVUTIL_VERSION_MINOR 49
#define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
......
...@@ -42,6 +42,19 @@ enum AVVideoEncParamsType { ...@@ -42,6 +42,19 @@ enum AVVideoEncParamsType {
* unsigned 8-bit. * unsigned 8-bit.
*/ */
AV_VIDEO_ENC_PARAMS_VP9, AV_VIDEO_ENC_PARAMS_VP9,
/**
* H.264 stores:
* - in PPS (per-picture):
* * initial QP_Y (luma) value, exported as AVVideoEncParams.qp
* * delta(s) for chroma QP values (same for both, or each separately),
* exported as in the corresponding entries in AVVideoEncParams.delta_qp
* - per-slice QP delta, not exported directly, added to the per-MB value
* - per-MB delta; not exported directly; the final per-MB quantizer
* parameter - QP_Y - minus the value in AVVideoEncParams.qp is exported
* as AVVideoBlockParams.qp_delta.
*/
AV_VIDEO_ENC_PARAMS_H264,
}; };
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment