mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-03-03 14:32:16 +02:00
vaapi_encode: Support forcing IDR frames via AVFrame.pict_type
(cherry picked from commit a3c3a5eac20a51d402c332cdf5220fff40a7943f)
This commit is contained in:
parent
760f1a7727
commit
c667c0979c
@ -590,6 +590,10 @@ static int vaapi_encode_step(AVCodecContext *avctx,
|
||||
} else if (ctx->issue_mode == ISSUE_MODE_MAXIMISE_THROUGHPUT) {
|
||||
int activity;
|
||||
|
||||
// Run through the list of all available pictures repeatedly
|
||||
// and issue the first one found which has all dependencies
|
||||
// available (including previously-issued but not necessarily
|
||||
// completed pictures).
|
||||
do {
|
||||
activity = 0;
|
||||
for (pic = ctx->pic_start; pic; pic = pic->next) {
|
||||
@ -605,9 +609,15 @@ static int vaapi_encode_step(AVCodecContext *avctx,
|
||||
if (err < 0)
|
||||
return err;
|
||||
activity = 1;
|
||||
// Start again from the beginning of the list,
|
||||
// because issuing this picture may have satisfied
|
||||
// forward dependencies of earlier ones.
|
||||
break;
|
||||
}
|
||||
} while(activity);
|
||||
|
||||
// If we had a defined target for this step then it will
|
||||
// always have been issued by now.
|
||||
if (target) {
|
||||
av_assert0(target->encode_issued && "broken dependencies?");
|
||||
}
|
||||
@ -639,8 +649,10 @@ static int vaapi_encode_get_next(AVCodecContext *avctx,
|
||||
if (!pic)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if (ctx->input_order == 0 || ctx->gop_counter >= avctx->gop_size) {
|
||||
if (ctx->input_order == 0 || ctx->force_idr ||
|
||||
ctx->gop_counter >= avctx->gop_size) {
|
||||
pic->type = PICTURE_TYPE_IDR;
|
||||
ctx->force_idr = 0;
|
||||
ctx->gop_counter = 1;
|
||||
ctx->p_counter = 0;
|
||||
} else if (ctx->p_counter >= ctx->p_per_i) {
|
||||
@ -722,7 +734,7 @@ fail:
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
static int vaapi_encode_mangle_end(AVCodecContext *avctx)
|
||||
static int vaapi_encode_truncate_gop(AVCodecContext *avctx)
|
||||
{
|
||||
VAAPIEncodeContext *ctx = avctx->priv_data;
|
||||
VAAPIEncodePicture *pic, *last_pic, *next;
|
||||
@ -772,7 +784,7 @@ static int vaapi_encode_mangle_end(AVCodecContext *avctx)
|
||||
// mangle anything.
|
||||
}
|
||||
|
||||
av_log(avctx, AV_LOG_DEBUG, "Pictures at end of stream:");
|
||||
av_log(avctx, AV_LOG_DEBUG, "Pictures ending truncated GOP:");
|
||||
for (pic = ctx->pic_start; pic; pic = pic->next) {
|
||||
av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")",
|
||||
picture_type_name[pic->type],
|
||||
@ -826,6 +838,13 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt,
|
||||
av_log(avctx, AV_LOG_DEBUG, "Encode frame: %ux%u (%"PRId64").\n",
|
||||
input_image->width, input_image->height, input_image->pts);
|
||||
|
||||
if (input_image->pict_type == AV_PICTURE_TYPE_I) {
|
||||
err = vaapi_encode_truncate_gop(avctx);
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
ctx->force_idr = 1;
|
||||
}
|
||||
|
||||
err = vaapi_encode_get_next(avctx, &pic);
|
||||
if (err) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Input setup failed: %d.\n", err);
|
||||
@ -854,7 +873,7 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt,
|
||||
|
||||
} else {
|
||||
if (!ctx->end_of_stream) {
|
||||
err = vaapi_encode_mangle_end(avctx);
|
||||
err = vaapi_encode_truncate_gop(avctx);
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
ctx->end_of_stream = 1;
|
||||
|
@ -192,6 +192,7 @@ typedef struct VAAPIEncodeContext {
|
||||
// Frame type decision.
|
||||
int p_per_i;
|
||||
int b_per_p;
|
||||
int force_idr;
|
||||
int gop_counter;
|
||||
int p_counter;
|
||||
int end_of_stream;
|
||||
|
Loading…
x
Reference in New Issue
Block a user