(cherry picked from commit a3c3a5eac20a51d402c332cdf5220fff40a7943f)
Unified · Split
| @@ -590,6 +590,10 @@ static int vaapi_encode_step(AVCodecContext *avctx, · 589 unmodified lines | |||
| 590 | } else if (ctx->issue_mode == ISSUE_MODE_MAXIMISE_THROUGHPUT) { | 590 | } else if (ctx->issue_mode == ISSUE_MODE_MAXIMISE_THROUGHPUT) { |
| 591 | int activity; | 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 | do { | 597 | do { |
| 594 | activity = 0; | 598 | activity = 0; |
| 595 | for (pic = ctx->pic_start; pic; pic = pic->next) { | 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 | if (err < 0) | 609 | if (err < 0) |
| 606 | return err; | 610 | return err; |
| 607 | activity = 1; | 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 | } while(activity); | 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 | if (target) { | 621 | if (target) { |
| 612 | av_assert0(target->encode_issued && "broken dependencies?"); | 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 | if (!pic) | 649 | if (!pic) |
| 640 | return AVERROR(ENOMEM); | 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 | pic->type = PICTURE_TYPE_IDR; | 654 | pic->type = PICTURE_TYPE_IDR; |
| 655 | ctx->force_idr = 0; | ||
| 644 | ctx->gop_counter = 1; | 656 | ctx->gop_counter = 1; |
| 645 | ctx->p_counter = 0; | 657 | ctx->p_counter = 0; |
| 646 | } else if (ctx->p_counter >= ctx->p_per_i) { | 658 | } else if (ctx->p_counter >= ctx->p_per_i) { |
| @@ -722,7 +734,7 @@ fail: · 75 unmodified lines | |||
| 722 | return AVERROR(ENOMEM); | 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 | VAAPIEncodeContext *ctx = avctx->priv_data; | 739 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 728 | VAAPIEncodePicture *pic, *last_pic, *next; | 740 | VAAPIEncodePicture *pic, *last_pic, *next; |
| @@ -772,7 +784,7 @@ static int vaapi_encode_mangle_end(AVCodecContext *avctx) · 43 unmodified lines | |||
| 772 | // mangle anything. | 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 | for (pic = ctx->pic_start; pic; pic = pic->next) { | 788 | for (pic = ctx->pic_start; pic; pic = pic->next) { |
| 777 | av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")", | 789 | av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")", |
| 778 | picture_type_name[pic->type], | 790 | picture_type_name[pic->type], |
| @@ -826,6 +838,13 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, · 47 unmodified lines | |||
| 826 | av_log(avctx, AV_LOG_DEBUG, "Encode frame: %ux%u (%"PRId64").\n", | 838 | av_log(avctx, AV_LOG_DEBUG, "Encode frame: %ux%u (%"PRId64").\n", |
| 827 | input_image->width, input_image->height, input_image->pts); | 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 | err = vaapi_encode_get_next(avctx, &pic); | 848 | err = vaapi_encode_get_next(avctx, &pic); |
| 830 | if (err) { | 849 | if (err) { |
| 831 | av_log(avctx, AV_LOG_ERROR, "Input setup failed: %d.\n", err); | 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 | } else { | 874 | } else { |
| 856 | if (!ctx->end_of_stream) { | 875 | if (!ctx->end_of_stream) { |
| 857 | err = vaapi_encode_mangle_end(avctx); | 876 | err = vaapi_encode_truncate_gop(avctx); |
| 858 | if (err < 0) | 877 | if (err < 0) |
| 859 | goto fail; | 878 | goto fail; |
| 860 | ctx->end_of_stream = 1; | 879 | ctx->end_of_stream = 1; |
| @@ -192,6 +192,7 @@ typedef struct VAAPIEncodeContext { · 191 unmodified lines | |||
| 192 | // Frame type decision. | 192 | // Frame type decision. |
| 193 | int p_per_i; | 193 | int p_per_i; |
| 194 | int b_per_p; | 194 | int b_per_p; |
| 195 | int force_idr; | ||
| 195 | int gop_counter; | 196 | int gop_counter; |
| 196 | int p_counter; | 197 | int p_counter; |
| 197 | int end_of_stream; | 198 | int end_of_stream; |