Commit a3c3a5ea authored by Mark Thompson's avatar Mark Thompson

vaapi_encode: Support forcing IDR frames via AVFrame.pict_type

parent 37fab066
...@@ -590,6 +590,10 @@ static int vaapi_encode_step(AVCodecContext *avctx, ...@@ -590,6 +590,10 @@ static int vaapi_encode_step(AVCodecContext *avctx,
} else if (ctx->issue_mode == ISSUE_MODE_MAXIMISE_THROUGHPUT) { } else if (ctx->issue_mode == ISSUE_MODE_MAXIMISE_THROUGHPUT) {
int activity; 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 { do {
activity = 0; activity = 0;
for (pic = ctx->pic_start; pic; pic = pic->next) { for (pic = ctx->pic_start; pic; pic = pic->next) {
...@@ -605,9 +609,15 @@ static int vaapi_encode_step(AVCodecContext *avctx, ...@@ -605,9 +609,15 @@ static int vaapi_encode_step(AVCodecContext *avctx,
if (err < 0) if (err < 0)
return err; return err;
activity = 1; 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); } while(activity);
// If we had a defined target for this step then it will
// always have been issued by now.
if (target) { if (target) {
av_assert0(target->encode_issued && "broken dependencies?"); av_assert0(target->encode_issued && "broken dependencies?");
} }
...@@ -639,8 +649,10 @@ static int vaapi_encode_get_next(AVCodecContext *avctx, ...@@ -639,8 +649,10 @@ static int vaapi_encode_get_next(AVCodecContext *avctx,
if (!pic) if (!pic)
return AVERROR(ENOMEM); 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; pic->type = PICTURE_TYPE_IDR;
ctx->force_idr = 0;
ctx->gop_counter = 1; ctx->gop_counter = 1;
ctx->p_counter = 0; ctx->p_counter = 0;
} else if (ctx->p_counter >= ctx->p_per_i) { } else if (ctx->p_counter >= ctx->p_per_i) {
...@@ -722,7 +734,7 @@ fail: ...@@ -722,7 +734,7 @@ fail:
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
static int vaapi_encode_mangle_end(AVCodecContext *avctx) static int vaapi_encode_truncate_gop(AVCodecContext *avctx)
{ {
VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodeContext *ctx = avctx->priv_data;
VAAPIEncodePicture *pic, *last_pic, *next; VAAPIEncodePicture *pic, *last_pic, *next;
...@@ -772,7 +784,7 @@ static int vaapi_encode_mangle_end(AVCodecContext *avctx) ...@@ -772,7 +784,7 @@ static int vaapi_encode_mangle_end(AVCodecContext *avctx)
// mangle anything. // 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) { for (pic = ctx->pic_start; pic; pic = pic->next) {
av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")", av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")",
picture_type_name[pic->type], picture_type_name[pic->type],
...@@ -826,6 +838,13 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, ...@@ -826,6 +838,13 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt,
av_log(avctx, AV_LOG_DEBUG, "Encode frame: %ux%u (%"PRId64").\n", av_log(avctx, AV_LOG_DEBUG, "Encode frame: %ux%u (%"PRId64").\n",
input_image->width, input_image->height, input_image->pts); 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); err = vaapi_encode_get_next(avctx, &pic);
if (err) { if (err) {
av_log(avctx, AV_LOG_ERROR, "Input setup failed: %d.\n", 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, ...@@ -854,7 +873,7 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt,
} else { } else {
if (!ctx->end_of_stream) { if (!ctx->end_of_stream) {
err = vaapi_encode_mangle_end(avctx); err = vaapi_encode_truncate_gop(avctx);
if (err < 0) if (err < 0)
goto fail; goto fail;
ctx->end_of_stream = 1; ctx->end_of_stream = 1;
......
...@@ -192,6 +192,7 @@ typedef struct VAAPIEncodeContext { ...@@ -192,6 +192,7 @@ typedef struct VAAPIEncodeContext {
// Frame type decision. // Frame type decision.
int p_per_i; int p_per_i;
int b_per_p; int b_per_p;
int force_idr;
int gop_counter; int gop_counter;
int p_counter; int p_counter;
int end_of_stream; int end_of_stream;
......
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