mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-08 13:22:53 +02:00
avcodec/vaapi_encode: extract gop configuration and two options to base layer
idr_interval and desired_b_depth are moved to HW_BASE_ENCODE_COMMON_OPTIONS. Signed-off-by: Tong Wu <tong1.wu@intel.com>
This commit is contained in:
parent
1242abdcee
commit
3ca740f19c
@ -593,6 +593,60 @@ end:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ff_hw_base_init_gop_structure(AVCodecContext *avctx, uint32_t ref_l0, uint32_t ref_l1,
|
||||||
|
int flags, int prediction_pre_only)
|
||||||
|
{
|
||||||
|
FFHWBaseEncodeContext *ctx = avctx->priv_data;
|
||||||
|
|
||||||
|
if (flags & FF_HW_FLAG_INTRA_ONLY || avctx->gop_size <= 1) {
|
||||||
|
av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
|
||||||
|
ctx->gop_size = 1;
|
||||||
|
} else if (ref_l0 < 1) {
|
||||||
|
av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
|
||||||
|
"reference frames.\n");
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
} else if (!(flags & FF_HW_FLAG_B_PICTURES) || ref_l1 < 1 ||
|
||||||
|
avctx->max_b_frames < 1 || prediction_pre_only) {
|
||||||
|
if (ctx->p_to_gpb)
|
||||||
|
av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
|
||||||
|
"(supported references: %d / %d).\n",
|
||||||
|
ref_l0, ref_l1);
|
||||||
|
else
|
||||||
|
av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
|
||||||
|
"(supported references: %d / %d).\n", ref_l0, ref_l1);
|
||||||
|
ctx->gop_size = avctx->gop_size;
|
||||||
|
ctx->p_per_i = INT_MAX;
|
||||||
|
ctx->b_per_p = 0;
|
||||||
|
} else {
|
||||||
|
if (ctx->p_to_gpb)
|
||||||
|
av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
|
||||||
|
"(supported references: %d / %d).\n",
|
||||||
|
ref_l0, ref_l1);
|
||||||
|
else
|
||||||
|
av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
|
||||||
|
"(supported references: %d / %d).\n", ref_l0, ref_l1);
|
||||||
|
ctx->gop_size = avctx->gop_size;
|
||||||
|
ctx->p_per_i = INT_MAX;
|
||||||
|
ctx->b_per_p = avctx->max_b_frames;
|
||||||
|
if (flags & FF_HW_FLAG_B_PICTURE_REFERENCES) {
|
||||||
|
ctx->max_b_depth = FFMIN(ctx->desired_b_depth,
|
||||||
|
av_log2(ctx->b_per_p) + 1);
|
||||||
|
} else {
|
||||||
|
ctx->max_b_depth = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & FF_HW_FLAG_NON_IDR_KEY_PICTURES) {
|
||||||
|
ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);
|
||||||
|
ctx->gop_per_idr = ctx->idr_interval + 1;
|
||||||
|
} else {
|
||||||
|
ctx->closed_gop = 1;
|
||||||
|
ctx->gop_per_idr = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int ff_hw_base_encode_init(AVCodecContext *avctx)
|
int ff_hw_base_encode_init(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
FFHWBaseEncodeContext *ctx = avctx->priv_data;
|
FFHWBaseEncodeContext *ctx = avctx->priv_data;
|
||||||
|
@ -120,6 +120,14 @@ typedef struct FFHWBaseEncodeContext {
|
|||||||
// Hardware-specific hooks.
|
// Hardware-specific hooks.
|
||||||
const struct FFHWEncodePictureOperation *op;
|
const struct FFHWEncodePictureOperation *op;
|
||||||
|
|
||||||
|
// Global options.
|
||||||
|
|
||||||
|
// Number of I frames between IDR frames.
|
||||||
|
int idr_interval;
|
||||||
|
|
||||||
|
// Desired B frame reference depth.
|
||||||
|
int desired_b_depth;
|
||||||
|
|
||||||
// The hardware device context.
|
// The hardware device context.
|
||||||
AVBufferRef *device_ref;
|
AVBufferRef *device_ref;
|
||||||
AVHWDeviceContext *device;
|
AVHWDeviceContext *device;
|
||||||
@ -198,11 +206,22 @@ typedef struct FFHWBaseEncodeContext {
|
|||||||
|
|
||||||
int ff_hw_base_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt);
|
int ff_hw_base_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt);
|
||||||
|
|
||||||
|
int ff_hw_base_init_gop_structure(AVCodecContext *avctx, uint32_t ref_l0, uint32_t ref_l1,
|
||||||
|
int flags, int prediction_pre_only);
|
||||||
|
|
||||||
int ff_hw_base_encode_init(AVCodecContext *avctx);
|
int ff_hw_base_encode_init(AVCodecContext *avctx);
|
||||||
|
|
||||||
int ff_hw_base_encode_close(AVCodecContext *avctx);
|
int ff_hw_base_encode_close(AVCodecContext *avctx);
|
||||||
|
|
||||||
#define HW_BASE_ENCODE_COMMON_OPTIONS \
|
#define HW_BASE_ENCODE_COMMON_OPTIONS \
|
||||||
|
{ "idr_interval", \
|
||||||
|
"Distance (in I-frames) between key frames", \
|
||||||
|
OFFSET(common.base.idr_interval), AV_OPT_TYPE_INT, \
|
||||||
|
{ .i64 = 0 }, 0, INT_MAX, FLAGS }, \
|
||||||
|
{ "b_depth", \
|
||||||
|
"Maximum B-frame reference depth", \
|
||||||
|
OFFSET(common.base.desired_b_depth), AV_OPT_TYPE_INT, \
|
||||||
|
{ .i64 = 1 }, 1, INT_MAX, FLAGS }, \
|
||||||
{ "async_depth", "Maximum processing parallelism. " \
|
{ "async_depth", "Maximum processing parallelism. " \
|
||||||
"Increase this to improve single channel performance.", \
|
"Increase this to improve single channel performance.", \
|
||||||
OFFSET(common.base.async_depth), AV_OPT_TYPE_INT, \
|
OFFSET(common.base.async_depth), AV_OPT_TYPE_INT, \
|
||||||
|
@ -1638,7 +1638,7 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
|
|||||||
VAStatus vas;
|
VAStatus vas;
|
||||||
VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
|
VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
|
||||||
uint32_t ref_l0, ref_l1;
|
uint32_t ref_l0, ref_l1;
|
||||||
int prediction_pre_only;
|
int prediction_pre_only, err;
|
||||||
|
|
||||||
vas = vaGetConfigAttributes(ctx->hwctx->display,
|
vas = vaGetConfigAttributes(ctx->hwctx->display,
|
||||||
ctx->va_profile,
|
ctx->va_profile,
|
||||||
@ -1702,53 +1702,9 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ctx->codec->flags & FF_HW_FLAG_INTRA_ONLY ||
|
err = ff_hw_base_init_gop_structure(avctx, ref_l0, ref_l1, ctx->codec->flags, prediction_pre_only);
|
||||||
avctx->gop_size <= 1) {
|
if (err < 0)
|
||||||
av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
|
return err;
|
||||||
base_ctx->gop_size = 1;
|
|
||||||
} else if (ref_l0 < 1) {
|
|
||||||
av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
|
|
||||||
"reference frames.\n");
|
|
||||||
return AVERROR(EINVAL);
|
|
||||||
} else if (!(ctx->codec->flags & FF_HW_FLAG_B_PICTURES) ||
|
|
||||||
ref_l1 < 1 || avctx->max_b_frames < 1 ||
|
|
||||||
prediction_pre_only) {
|
|
||||||
if (base_ctx->p_to_gpb)
|
|
||||||
av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
|
|
||||||
"(supported references: %d / %d).\n",
|
|
||||||
ref_l0, ref_l1);
|
|
||||||
else
|
|
||||||
av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
|
|
||||||
"(supported references: %d / %d).\n", ref_l0, ref_l1);
|
|
||||||
base_ctx->gop_size = avctx->gop_size;
|
|
||||||
base_ctx->p_per_i = INT_MAX;
|
|
||||||
base_ctx->b_per_p = 0;
|
|
||||||
} else {
|
|
||||||
if (base_ctx->p_to_gpb)
|
|
||||||
av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
|
|
||||||
"(supported references: %d / %d).\n",
|
|
||||||
ref_l0, ref_l1);
|
|
||||||
else
|
|
||||||
av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
|
|
||||||
"(supported references: %d / %d).\n", ref_l0, ref_l1);
|
|
||||||
base_ctx->gop_size = avctx->gop_size;
|
|
||||||
base_ctx->p_per_i = INT_MAX;
|
|
||||||
base_ctx->b_per_p = avctx->max_b_frames;
|
|
||||||
if (ctx->codec->flags & FF_HW_FLAG_B_PICTURE_REFERENCES) {
|
|
||||||
base_ctx->max_b_depth = FFMIN(ctx->desired_b_depth,
|
|
||||||
av_log2(base_ctx->b_per_p) + 1);
|
|
||||||
} else {
|
|
||||||
base_ctx->max_b_depth = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx->codec->flags & FF_HW_FLAG_NON_IDR_KEY_PICTURES) {
|
|
||||||
base_ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);
|
|
||||||
base_ctx->gop_per_idr = ctx->idr_interval + 1;
|
|
||||||
} else {
|
|
||||||
base_ctx->closed_gop = 1;
|
|
||||||
base_ctx->gop_per_idr = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -151,17 +151,9 @@ typedef struct VAAPIEncodeContext {
|
|||||||
// Codec-specific hooks.
|
// Codec-specific hooks.
|
||||||
const struct VAAPIEncodeType *codec;
|
const struct VAAPIEncodeType *codec;
|
||||||
|
|
||||||
// Global options.
|
|
||||||
|
|
||||||
// Use low power encoding mode.
|
// Use low power encoding mode.
|
||||||
int low_power;
|
int low_power;
|
||||||
|
|
||||||
// Number of I frames between IDR frames.
|
|
||||||
int idr_interval;
|
|
||||||
|
|
||||||
// Desired B frame reference depth.
|
|
||||||
int desired_b_depth;
|
|
||||||
|
|
||||||
// Max Frame Size
|
// Max Frame Size
|
||||||
int max_frame_size;
|
int max_frame_size;
|
||||||
|
|
||||||
@ -371,14 +363,6 @@ int ff_vaapi_encode_close(AVCodecContext *avctx);
|
|||||||
"may not support all encoding features)", \
|
"may not support all encoding features)", \
|
||||||
OFFSET(common.low_power), AV_OPT_TYPE_BOOL, \
|
OFFSET(common.low_power), AV_OPT_TYPE_BOOL, \
|
||||||
{ .i64 = 0 }, 0, 1, FLAGS }, \
|
{ .i64 = 0 }, 0, 1, FLAGS }, \
|
||||||
{ "idr_interval", \
|
|
||||||
"Distance (in I-frames) between IDR frames", \
|
|
||||||
OFFSET(common.idr_interval), AV_OPT_TYPE_INT, \
|
|
||||||
{ .i64 = 0 }, 0, INT_MAX, FLAGS }, \
|
|
||||||
{ "b_depth", \
|
|
||||||
"Maximum B-frame reference depth", \
|
|
||||||
OFFSET(common.desired_b_depth), AV_OPT_TYPE_INT, \
|
|
||||||
{ .i64 = 1 }, 1, INT_MAX, FLAGS }, \
|
|
||||||
{ "max_frame_size", \
|
{ "max_frame_size", \
|
||||||
"Maximum frame size (in bytes)",\
|
"Maximum frame size (in bytes)",\
|
||||||
OFFSET(common.max_frame_size), AV_OPT_TYPE_INT, \
|
OFFSET(common.max_frame_size), AV_OPT_TYPE_INT, \
|
||||||
|
Loading…
Reference in New Issue
Block a user