(cherry picked from commit a3c3a5eac20a51d402c332cdf5220fff40a7943f)
Mark Thompson authored on 2016/12/13 06:25:28... | ... |
@@ -590,6 +590,10 @@ static int vaapi_encode_step(AVCodecContext *avctx, |
590 | 590 |
} else if (ctx->issue_mode == ISSUE_MODE_MAXIMISE_THROUGHPUT) { |
591 | 591 |
int activity; |
592 | 592 |
|
593 |
+ // Run through the list of all available pictures repeatedly |
|
594 |
+ // and issue the first one found which has all dependencies |
|
595 |
+ // available (including previously-issued but not necessarily |
|
596 |
+ // completed pictures). |
|
593 | 597 |
do { |
594 | 598 |
activity = 0; |
595 | 599 |
for (pic = ctx->pic_start; pic; pic = pic->next) { |
... | ... |
@@ -605,9 +609,15 @@ static int vaapi_encode_step(AVCodecContext *avctx, |
605 | 605 |
if (err < 0) |
606 | 606 |
return err; |
607 | 607 |
activity = 1; |
608 |
+ // Start again from the beginning of the list, |
|
609 |
+ // because issuing this picture may have satisfied |
|
610 |
+ // forward dependencies of earlier ones. |
|
611 |
+ break; |
|
608 | 612 |
} |
609 | 613 |
} while(activity); |
610 | 614 |
|
615 |
+ // If we had a defined target for this step then it will |
|
616 |
+ // always have been issued by now. |
|
611 | 617 |
if (target) { |
612 | 618 |
av_assert0(target->encode_issued && "broken dependencies?"); |
613 | 619 |
} |
... | ... |
@@ -639,8 +649,10 @@ static int vaapi_encode_get_next(AVCodecContext *avctx, |
639 | 639 |
if (!pic) |
640 | 640 |
return AVERROR(ENOMEM); |
641 | 641 |
|
642 |
- if (ctx->input_order == 0 || ctx->gop_counter >= avctx->gop_size) { |
|
642 |
+ if (ctx->input_order == 0 || ctx->force_idr || |
|
643 |
+ ctx->gop_counter >= avctx->gop_size) { |
|
643 | 644 |
pic->type = PICTURE_TYPE_IDR; |
645 |
+ ctx->force_idr = 0; |
|
644 | 646 |
ctx->gop_counter = 1; |
645 | 647 |
ctx->p_counter = 0; |
646 | 648 |
} else if (ctx->p_counter >= ctx->p_per_i) { |
... | ... |
@@ -722,7 +734,7 @@ fail: |
722 | 722 |
return AVERROR(ENOMEM); |
723 | 723 |
} |
724 | 724 |
|
725 |
-static int vaapi_encode_mangle_end(AVCodecContext *avctx) |
|
725 |
+static int vaapi_encode_truncate_gop(AVCodecContext *avctx) |
|
726 | 726 |
{ |
727 | 727 |
VAAPIEncodeContext *ctx = avctx->priv_data; |
728 | 728 |
VAAPIEncodePicture *pic, *last_pic, *next; |
... | ... |
@@ -772,7 +784,7 @@ static int vaapi_encode_mangle_end(AVCodecContext *avctx) |
772 | 772 |
// mangle anything. |
773 | 773 |
} |
774 | 774 |
|
775 |
- av_log(avctx, AV_LOG_DEBUG, "Pictures at end of stream:"); |
|
775 |
+ av_log(avctx, AV_LOG_DEBUG, "Pictures ending truncated GOP:"); |
|
776 | 776 |
for (pic = ctx->pic_start; pic; pic = pic->next) { |
777 | 777 |
av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")", |
778 | 778 |
picture_type_name[pic->type], |
... | ... |
@@ -826,6 +838,13 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, |
826 | 826 |
av_log(avctx, AV_LOG_DEBUG, "Encode frame: %ux%u (%"PRId64").\n", |
827 | 827 |
input_image->width, input_image->height, input_image->pts); |
828 | 828 |
|
829 |
+ if (input_image->pict_type == AV_PICTURE_TYPE_I) { |
|
830 |
+ err = vaapi_encode_truncate_gop(avctx); |
|
831 |
+ if (err < 0) |
|
832 |
+ goto fail; |
|
833 |
+ ctx->force_idr = 1; |
|
834 |
+ } |
|
835 |
+ |
|
829 | 836 |
err = vaapi_encode_get_next(avctx, &pic); |
830 | 837 |
if (err) { |
831 | 838 |
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 | 854 |
|
855 | 855 |
} else { |
856 | 856 |
if (!ctx->end_of_stream) { |
857 |
- err = vaapi_encode_mangle_end(avctx); |
|
857 |
+ err = vaapi_encode_truncate_gop(avctx); |
|
858 | 858 |
if (err < 0) |
859 | 859 |
goto fail; |
860 | 860 |
ctx->end_of_stream = 1; |