(cherry picked from commit a3c3a5eac20a51d402c332cdf5220fff40a7943f)
Unified · Split
| @@ -590,6 +590,10 @@ static int vaapi_encode_step(AVCodecContext *avctx, · 589 unmodified lines | ||
| 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, · 9 unmodified lines | ||
| 605 | 609 | if (err < 0) |
| 606 | 610 | return err; |
| 607 | 611 | activity = 1; |
| 612 | + // Start again from the beginning of the list, | |
| 613 | + // because issuing this picture may have satisfied | |
| 614 | + // forward dependencies of earlier ones. | |
| 615 | + break; | |
| 608 | 616 | } |
| 609 | 617 | } while(activity); |
| 610 | 618 | |
| 619 | + // If we had a defined target for this step then it will | |
| 620 | + // always have been issued by now. | |
| 611 | 621 | if (target) { |
| 612 | 622 | av_assert0(target->encode_issued && "broken dependencies?"); |
| 613 | 623 | } |
| @@ -639,8 +649,10 @@ static int vaapi_encode_get_next(AVCodecContext *avctx, · 25 unmodified lines | ||
| 639 | 649 | if (!pic) |
| 640 | 650 | return AVERROR(ENOMEM); |
| 641 | 651 | |
| 642 | − if (ctx->input_order == 0 || ctx->gop_counter >= avctx->gop_size) { | |
| 652 | + if (ctx->input_order == 0 || ctx->force_idr || | |
| 653 | + ctx->gop_counter >= avctx->gop_size) { | |
| 643 | 654 | pic->type = PICTURE_TYPE_IDR; |
| 655 | + ctx->force_idr = 0; | |
| 644 | 656 | ctx->gop_counter = 1; |
| 645 | 657 | ctx->p_counter = 0; |
| 646 | 658 | } else if (ctx->p_counter >= ctx->p_per_i) { |
| @@ -722,7 +734,7 @@ fail: · 75 unmodified lines | ||
| 722 | 734 | return AVERROR(ENOMEM); |
| 723 | 735 | } |
| 724 | 736 | |
| 725 | −static int vaapi_encode_mangle_end(AVCodecContext *avctx) | |
| 737 | +static int vaapi_encode_truncate_gop(AVCodecContext *avctx) | |
| 726 | 738 | { |
| 727 | 739 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 728 | 740 | VAAPIEncodePicture *pic, *last_pic, *next; |
| @@ -772,7 +784,7 @@ static int vaapi_encode_mangle_end(AVCodecContext *avctx) · 43 unmodified lines | ||
| 772 | 784 | // mangle anything. |
| 773 | 785 | } |
| 774 | 786 | |
| 775 | − av_log(avctx, AV_LOG_DEBUG, "Pictures at end of stream:"); | |
| 787 | + av_log(avctx, AV_LOG_DEBUG, "Pictures ending truncated GOP:"); | |
| 776 | 788 | for (pic = ctx->pic_start; pic; pic = pic->next) { |
| 777 | 789 | av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")", |
| 778 | 790 | picture_type_name[pic->type], |
| @@ -826,6 +838,13 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, · 47 unmodified lines | ||
| 826 | 838 | av_log(avctx, AV_LOG_DEBUG, "Encode frame: %ux%u (%"PRId64").\n", |
| 827 | 839 | input_image->width, input_image->height, input_image->pts); |
| 828 | 840 | |
| 841 | + if (input_image->pict_type == AV_PICTURE_TYPE_I) { | |
| 842 | + err = vaapi_encode_truncate_gop(avctx); | |
| 843 | + if (err < 0) | |
| 844 | + goto fail; | |
| 845 | + ctx->force_idr = 1; | |
| 846 | + } | |
| 847 | + | |
| 829 | 848 | err = vaapi_encode_get_next(avctx, &pic); |
| 830 | 849 | if (err) { |
| 831 | 850 | av_log(avctx, AV_LOG_ERROR, "Input setup failed: %d.\n", err); |
| @@ -854,7 +873,7 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, · 22 unmodified lines | ||
| 854 | 873 | |
| 855 | 874 | } else { |
| 856 | 875 | if (!ctx->end_of_stream) { |
| 857 | − err = vaapi_encode_mangle_end(avctx); | |
| 876 | + err = vaapi_encode_truncate_gop(avctx); | |
| 858 | 877 | if (err < 0) |
| 859 | 878 | goto fail; |
| 860 | 879 | ctx->end_of_stream = 1; |
| @@ -192,6 +192,7 @@ typedef struct VAAPIEncodeContext { · 191 unmodified lines | ||
| 192 | 192 | // Frame type decision. |
| 193 | 193 | int p_per_i; |
| 194 | 194 | int b_per_p; |
| 195 | + int force_idr; | |
| 195 | 196 | int gop_counter; |
| 196 | 197 | int p_counter; |
| 197 | 198 | int end_of_stream; |