@@ -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) | |||||
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) | |||||
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) | |||||
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) | |||||
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 @@ | |||||
#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) | |||||
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) | |||||
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 { | |||||
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 @@ | |||||
*/ | */ | ||||
#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 { | |||||
* 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, | |||||
}; | }; | ||||
/** | /** | ||||