History

vaapi_encode: Convert to send/receive API

This attaches the logic of picking the mode of for the next picture to the output, which simplifies some choices by removing the concept of the picture for which input is not yet available. At the same time, we allow more complex reference structures and track more reference metadata (particularly the contents of the DPB) for use in the codec-specific code. It also adds flags to explicitly track the available features of the different codecs. The new structure also allows open-GOP support, so that is now available for codecs which can do it.

Mark Thompson committed 7 years ago

Commit 5fdcf851 parent 26ce3a49 files · +433 −331Browse files

Unified · Split

9 files
  1. doc/encoders.texi +14 −5
  2. libavcodec/vaapi_encode.c +334 −301
  3. libavcodec/vaapi_encode.h +59 −15
  4. libavcodec/vaapi_encode_h264.c +5 −2
  5. libavcodec/vaapi_encode_h265.c +5 −2
  6. libavcodec/vaapi_encode_mjpeg.c +6 −3
  7. libavcodec/vaapi_encode_mpeg2.c +4 −1
  8. libavcodec/vaapi_encode_vp8.c +2 −1
  9. libavcodec/vaapi_encode_vp9.c +4 −1
doc/encoders.texi+14−5
@@ -2807,15 +2807,24 @@ Size / quality tradeoff: higher values are smaller / worse quality. · 2806 unmodified lines
2807@end itemize2807@end itemize
2808 2808
2809All encoders support the following options:2809All encoders support the following options:
2810@itemize2810@table @option
2811@item2811@item low_power
2812@option{low_power}
2813
2814Some drivers/platforms offer a second encoder for some codecs intended to use2812Some drivers/platforms offer a second encoder for some codecs intended to use
2815less power than the default encoder; setting this option will attempt to use2813less power than the default encoder; setting this option will attempt to use
2816that encoder. Note that it may support a reduced feature set, so some other2814that encoder. Note that it may support a reduced feature set, so some other
2817options may not be available in this mode.2815options may not be available in this mode.
2818@end itemize2816
2817@item idr_interval
2818Set the number of normal intra frames between full-refresh (IDR) frames in
2819open-GOP mode. The intra frames are still IRAPs, but will not include global
2820headers and may have non-decodable leading pictures.
2821
2822@item b_depth
2823Set the B-frame reference depth. When set to one (the default), all B-frames
2824will refer only to P- or I-frames. When set to greater values multiple layers
2825of B-frames will be present, frames in each layer only referring to frames in
2826higher layers.
2827@end table
2819 2828
2820Each encoder also has its own specific options:2829Each encoder also has its own specific options:
2821@table @option2830@table @option
libavcodec/vaapi_encode.c+334−301
@@ -158,16 +158,10 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 157 unmodified lines
158 av_log(avctx, AV_LOG_DEBUG, ".\n");158 av_log(avctx, AV_LOG_DEBUG, ".\n");
159 }159 }
160 160
161 av_assert0(pic->input_available && !pic->encode_issued);161 av_assert0(!pic->encode_issued);
162 for (i = 0; i < pic->nb_refs; i++) {162 for (i = 0; i < pic->nb_refs; i++) {
163 av_assert0(pic->refs[i]);163 av_assert0(pic->refs[i]);
164 // If we are serialised then the references must have already164 av_assert0(pic->refs[i]->encode_issued);
165 // completed. If not, they must have been issued but need not
166 // have completed yet.
167 if (ctx->issue_mode == ISSUE_MODE_SERIALISE_EVERYTHING)
168 av_assert0(pic->refs[i]->encode_complete);
169 else
170 av_assert0(pic->refs[i]->encode_issued);
171 }165 }
172 166
173 av_log(avctx, AV_LOG_DEBUG, "Input surface is %#x.\n", pic->input_surface);167 av_log(avctx, AV_LOG_DEBUG, "Input surface is %#x.\n", pic->input_surface);
@@ -466,10 +460,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 292 unmodified lines
466 460
467 pic->encode_issued = 1;461 pic->encode_issued = 1;
468 462
469 if (ctx->issue_mode == ISSUE_MODE_SERIALISE_EVERYTHING)463 return 0;
470 return vaapi_encode_wait(avctx, pic);
471 else
472 return 0;
473 464
474fail_with_picture:465fail_with_picture:
475 vaEndPicture(ctx->hwctx->display, ctx->va_context);466 vaEndPicture(ctx->hwctx->display, ctx->va_context);
@@ -626,315 +617,330 @@ static int vaapi_encode_free(AVCodecContext *avctx, · 150 unmodified lines
626 return 0;617 return 0;
627}618}
628 619
629static int vaapi_encode_step(AVCodecContext *avctx,620static void vaapi_encode_add_ref(AVCodecContext *avctx,
630 VAAPIEncodePicture *target)621 VAAPIEncodePicture *pic,
622 VAAPIEncodePicture *target,
623 int is_ref, int in_dpb, int prev)
631{624{
632 VAAPIEncodeContext *ctx = avctx->priv_data;625 int refs = 0;
633 VAAPIEncodePicture *pic;
634 int i, err;
635 626
636 if (ctx->issue_mode == ISSUE_MODE_SERIALISE_EVERYTHING ||627 if (is_ref) {
637 ctx->issue_mode == ISSUE_MODE_MINIMISE_LATENCY) {628 av_assert0(pic != target);
638 // These two modes are equivalent, except that we wait for629 av_assert0(pic->nb_refs < MAX_PICTURE_REFERENCES);
639 // immediate completion on each operation if serialised.630 pic->refs[pic->nb_refs++] = target;
640 631 ++refs;
641 if (!target) {632 }
642 // No target, nothing to do yet.
643 return 0;
644 }
645
646 if (target->encode_complete) {
647 // Already done.
648 return 0;
649 }
650
651 pic = target;
652 for (i = 0; i < pic->nb_refs; i++) {
653 if (!pic->refs[i]->encode_complete) {
654 err = vaapi_encode_step(avctx, pic->refs[i]);
655 if (err < 0)
656 return err;
657 }
658 }
659
660 err = vaapi_encode_issue(avctx, pic);
661 if (err < 0)
662 return err;
663
664 } else if (ctx->issue_mode == ISSUE_MODE_MAXIMISE_THROUGHPUT) {
665 int activity;
666
667 // Run through the list of all available pictures repeatedly
668 // and issue the first one found which has all dependencies
669 // available (including previously-issued but not necessarily
670 // completed pictures).
671 do {
672 activity = 0;
673 for (pic = ctx->pic_start; pic; pic = pic->next) {
674 if (!pic->input_available || pic->encode_issued)
675 continue;
676 for (i = 0; i < pic->nb_refs; i++) {
677 if (!pic->refs[i]->encode_issued)
678 break;
679 }
680 if (i < pic->nb_refs)
681 continue;
682 err = vaapi_encode_issue(avctx, pic);
683 if (err < 0)
684 return err;
685 activity = 1;
686 // Start again from the beginning of the list,
687 // because issuing this picture may have satisfied
688 // forward dependencies of earlier ones.
689 break;
690 }
691 } while(activity);
692 633
693 // If we had a defined target for this step then it will634 if (in_dpb) {
694 // always have been issued by now.635 av_assert0(pic->nb_dpb_pics < MAX_DPB_SIZE);
695 if (target) {636 pic->dpb[pic->nb_dpb_pics++] = target;
696 av_assert0(target->encode_issued && "broken dependencies?");637 ++refs;
697 }638 }
698 639
699 } else {640 if (prev) {
700 av_assert0(0);641 av_assert0(!pic->prev);
642 pic->prev = target;
643 ++refs;
701 }644 }
702 645
703 return 0;646 target->ref_count[0] += refs;
647 target->ref_count[1] += refs;
704}648}
705 649
706static int vaapi_encode_get_next(AVCodecContext *avctx,650static void vaapi_encode_remove_refs(AVCodecContext *avctx,
707 VAAPIEncodePicture **pic_out)651 VAAPIEncodePicture *pic,
652 int level)
708{653{
709 VAAPIEncodeContext *ctx = avctx->priv_data;
710 VAAPIEncodePicture *start, *end, *pic;
711 int i;654 int i;
712 655
713 for (pic = ctx->pic_start; pic; pic = pic->next) {656 if (pic->ref_removed[level])
714 if (pic->next)657 return;
715 av_assert0(pic->display_order + 1 == pic->next->display_order);658
716 if (pic->display_order == ctx->input_order) {659 for (i = 0; i < pic->nb_refs; i++) {
717 *pic_out = pic;660 av_assert0(pic->refs[i]);
718 return 0;661 --pic->refs[i]->ref_count[level];
719 }662 av_assert0(pic->refs[i]->ref_count[level] >= 0);
720 }663 }
721 664
722 pic = vaapi_encode_alloc(avctx);665 for (i = 0; i < pic->nb_dpb_pics; i++) {
723 if (!pic)666 av_assert0(pic->dpb[i]);
724 return AVERROR(ENOMEM);667 --pic->dpb[i]->ref_count[level];
668 av_assert0(pic->dpb[i]->ref_count[level] >= 0);
669 }
725 670
726 if (ctx->input_order == 0 || ctx->force_idr ||671 av_assert0(pic->prev || pic->type == PICTURE_TYPE_IDR);
727 ctx->gop_counter >= ctx->gop_size) {672 if (pic->prev) {
728 pic->type = PICTURE_TYPE_IDR;673 --pic->prev->ref_count[level];
729 ctx->force_idr = 0;674 av_assert0(pic->prev->ref_count[level] >= 0);
730 ctx->gop_counter = 1;
731 ctx->p_counter = 0;
732 } else if (ctx->p_counter >= ctx->p_per_i) {
733 pic->type = PICTURE_TYPE_I;
734 ++ctx->gop_counter;
735 ctx->p_counter = 0;
736 } else {
737 pic->type = PICTURE_TYPE_P;
738 pic->refs[0] = ctx->pic_end;
739 pic->nb_refs = 1;
740 ++ctx->gop_counter;
741 ++ctx->p_counter;
742 }675 }
743 start = end = pic;
744 676
745 if (pic->type != PICTURE_TYPE_IDR) {677 pic->ref_removed[level] = 1;
746 // If that was not an IDR frame, add B-frames display-before and678}
747 // encode-after it, but not exceeding the GOP size.
748 679
749 for (i = 0; i < ctx->b_per_p &&680static void vaapi_encode_set_b_pictures(AVCodecContext *avctx,
750 ctx->gop_counter < ctx->gop_size; i++) {681 VAAPIEncodePicture *start,
751 pic = vaapi_encode_alloc(avctx);682 VAAPIEncodePicture *end,
752 if (!pic)683 VAAPIEncodePicture *prev,
753 goto fail;684 int current_depth,
685 VAAPIEncodePicture **last)
686{
687 VAAPIEncodeContext *ctx = avctx->priv_data;
688 VAAPIEncodePicture *pic, *next, *ref;
689 int i, len;
754 690
755 pic->type = PICTURE_TYPE_B;691 av_assert0(start && end && start != end && start->next != end);
756 pic->refs[0] = ctx->pic_end;
757 pic->refs[1] = end;
758 pic->nb_refs = 2;
759 692
760 pic->next = start;693 // If we are at the maximum depth then encode all pictures as
761 pic->display_order = ctx->input_order + ctx->b_per_p - i - 1;694 // non-referenced B-pictures. Also do this if there is exactly one
762 pic->encode_order = pic->display_order + 1;695 // picture left, since there will be nothing to reference it.
763 start = pic;696 if (current_depth == ctx->max_b_depth || start->next->next == end) {
697 for (pic = start->next; pic; pic = pic->next) {
698 if (pic == end)
699 break;
700 pic->type = PICTURE_TYPE_B;
701 pic->b_depth = current_depth;
702
703 vaapi_encode_add_ref(avctx, pic, start, 1, 1, 0);
704 vaapi_encode_add_ref(avctx, pic, end, 1, 1, 0);
705 vaapi_encode_add_ref(avctx, pic, prev, 0, 0, 1);
764 706
765 ++ctx->gop_counter;707 for (ref = end->refs[1]; ref; ref = ref->refs[1])
708 vaapi_encode_add_ref(avctx, pic, ref, 0, 1, 0);
766 }709 }
767 }710 *last = prev;
768 711
769 if (ctx->input_order == 0) {712 } else {
770 pic->display_order = 0;713 // Split the current list at the midpoint with a referenced
771 pic->encode_order = 0;714 // B-picture, then descend into each side separately.
715 len = 0;
716 for (pic = start->next; pic != end; pic = pic->next)
717 ++len;
718 for (pic = start->next, i = 1; 2 * i < len; pic = pic->next, i++);
772 719
773 ctx->pic_start = ctx->pic_end = pic;720 pic->type = PICTURE_TYPE_B;
721 pic->b_depth = current_depth;
774 722
775 } else {723 pic->is_reference = 1;
776 for (i = 0, pic = start; pic; i++, pic = pic->next) {
777 pic->display_order = ctx->input_order + i;
778 if (end->type == PICTURE_TYPE_IDR)
779 pic->encode_order = ctx->input_order + i;
780 else if (pic == end)
781 pic->encode_order = ctx->input_order;
782 else
783 pic->encode_order = ctx->input_order + i + 1;
784 }
785 724
786 av_assert0(ctx->pic_end);725 vaapi_encode_add_ref(avctx, pic, pic, 0, 1, 0);
787 ctx->pic_end->next = start;726 vaapi_encode_add_ref(avctx, pic, start, 1, 1, 0);
788 ctx->pic_end = end;727 vaapi_encode_add_ref(avctx, pic, end, 1, 1, 0);
789 }728 vaapi_encode_add_ref(avctx, pic, prev, 0, 0, 1);
790 *pic_out = start;
791 729
792 av_log(avctx, AV_LOG_DEBUG, "Pictures:");730 for (ref = end->refs[1]; ref; ref = ref->refs[1])
793 for (pic = ctx->pic_start; pic; pic = pic->next) {731 vaapi_encode_add_ref(avctx, pic, ref, 0, 1, 0);
794 av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")",
795 picture_type_name[pic->type],
796 pic->display_order, pic->encode_order);
797 }
798 av_log(avctx, AV_LOG_DEBUG, "\n");
799 732
800 return 0;733 if (i > 1)
734 vaapi_encode_set_b_pictures(avctx, start, pic, pic,
735 current_depth + 1, &next);
736 else
737 next = pic;
801 738
802fail:739 vaapi_encode_set_b_pictures(avctx, pic, end, next,
803 while (start) {740 current_depth + 1, last);
804 pic = start->next;
805 vaapi_encode_free(avctx, start);
806 start = pic;
807 }741 }
808 return AVERROR(ENOMEM);
809}742}
810 743
811static int vaapi_encode_truncate_gop(AVCodecContext *avctx)744static int vaapi_encode_pick_next(AVCodecContext *avctx,
745 VAAPIEncodePicture **pic_out)
812{746{
813 VAAPIEncodeContext *ctx = avctx->priv_data;747 VAAPIEncodeContext *ctx = avctx->priv_data;
814 VAAPIEncodePicture *pic, *last_pic, *next;748 VAAPIEncodePicture *pic = NULL, *next, *start;
749 int i, b_counter, closed_gop_end;
815 750
816 av_assert0(!ctx->pic_start || ctx->pic_start->input_available);751 // If there are any B-frames already queued, the next one to encode
817 752 // is the earliest not-yet-issued frame for which all references are
818 // Find the last picture we actually have input for.753 // available.
819 for (pic = ctx->pic_start; pic; pic = pic->next) {754 for (pic = ctx->pic_start; pic; pic = pic->next) {
820 if (!pic->input_available)755 if (pic->encode_issued)
756 continue;
757 if (pic->type != PICTURE_TYPE_B)
758 continue;
759 for (i = 0; i < pic->nb_refs; i++) {
760 if (!pic->refs[i]->encode_issued)
761 break;
762 }
763 if (i == pic->nb_refs)
821 break;764 break;
822 last_pic = pic;
823 }765 }
824 766
825 if (pic) {767 if (pic) {
826 if (last_pic->type == PICTURE_TYPE_B) {768 av_log(avctx, AV_LOG_DEBUG, "Pick B-picture at depth %d to "
827 // Some fixing up is required. Change the type of this769 "encode next.\n", pic->b_depth);
828 // picture to P, then modify preceding B references which770 *pic_out = pic;
829 // point beyond it to point at it instead.771 return 0;
830 772 }
831 last_pic->type = PICTURE_TYPE_P;
832 last_pic->encode_order = last_pic->refs[1]->encode_order;
833
834 for (pic = ctx->pic_start; pic != last_pic; pic = pic->next) {
835 if (pic->type == PICTURE_TYPE_B &&
836 pic->refs[1] == last_pic->refs[1])
837 pic->refs[1] = last_pic;
838 }
839 773
840 last_pic->nb_refs = 1;774 // Find the B-per-Pth available picture to become the next picture
841 last_pic->refs[1] = NULL;775 // on the top layer.
842 } else {776 start = NULL;
843 // We can use the current structure (no references point777 b_counter = 0;
844 // beyond the end), but there are unused pics to discard.778 closed_gop_end = ctx->closed_gop ||
779 ctx->idr_counter == ctx->gop_per_idr;
780 for (pic = ctx->pic_start; pic; pic = next) {
781 next = pic->next;
782 if (pic->encode_issued) {
783 start = pic;
784 continue;
845 }785 }
786 // If the next available picture is force-IDR, encode it to start
787 // a new GOP immediately.
788 if (pic->force_idr)
789 break;
790 if (b_counter == ctx->b_per_p)
791 break;
792 // If this picture ends a closed GOP or starts a new GOP then it
793 // needs to be in the top layer.
794 if (ctx->gop_counter + b_counter + closed_gop_end >= ctx->gop_size)
795 break;
796 // If the picture after this one is force-IDR, we need to encode
797 // this one in the top layer.
798 if (next && next->force_idr)
799 break;
800 ++b_counter;
801 }
846 802
847 // Discard all following pics, they will never be used.803 // At the end of the stream the last picture must be in the top layer.
848 for (pic = last_pic->next; pic; pic = next) {804 if (!pic && ctx->end_of_stream) {
849 next = pic->next;805 --b_counter;
850 vaapi_encode_free(avctx, pic);806 pic = ctx->pic_end;
851 }807 if (pic->encode_issued)
808 return AVERROR_EOF;
809 }
852 810
853 last_pic->next = NULL;811 if (!pic) {
854 ctx->pic_end = last_pic;812 av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - "
813 "need more input for reference pictures.\n");
814 return AVERROR(EAGAIN);
815 }
816 if (ctx->input_order <= ctx->decode_delay && !ctx->end_of_stream) {
817 av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - "
818 "need more input for timestamps.\n");
819 return AVERROR(EAGAIN);
820 }
821
822 if (pic->force_idr) {
823 av_log(avctx, AV_LOG_DEBUG, "Pick forced IDR-picture to "
824 "encode next.\n");
825 pic->type = PICTURE_TYPE_IDR;
826 ctx->idr_counter = 1;
827 ctx->gop_counter = 1;
828
829 } else if (ctx->gop_counter + b_counter >= ctx->gop_size) {
830 if (ctx->idr_counter == ctx->gop_per_idr) {
831 av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP IDR-picture to "
832 "encode next.\n");
833 pic->type = PICTURE_TYPE_IDR;
834 ctx->idr_counter = 1;
835 } else {
836 av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP I-picture to "
837 "encode next.\n");
838 pic->type = PICTURE_TYPE_I;
839 ++ctx->idr_counter;
840 }
841 ctx->gop_counter = 1;
855 842
856 } else {843 } else {
857 // Input is available for all pictures, so we don't need to844 if (ctx->gop_counter + b_counter + closed_gop_end == ctx->gop_size) {
858 // mangle anything.845 av_log(avctx, AV_LOG_DEBUG, "Pick group-end P-picture to "
846 "encode next.\n");
847 } else {
848 av_log(avctx, AV_LOG_DEBUG, "Pick normal P-picture to "
849 "encode next.\n");
850 }
851 pic->type = PICTURE_TYPE_P;
852 av_assert0(start);
853 ctx->gop_counter += 1 + b_counter;
859 }854 }
855 pic->is_reference = 1;
856 *pic_out = pic;
860 857
861 av_log(avctx, AV_LOG_DEBUG, "Pictures ending truncated GOP:");858 vaapi_encode_add_ref(avctx, pic, pic, 0, 1, 0);
862 for (pic = ctx->pic_start; pic; pic = pic->next) {859 if (pic->type != PICTURE_TYPE_IDR) {
863 av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")",860 vaapi_encode_add_ref(avctx, pic, start,
864 picture_type_name[pic->type],861 pic->type == PICTURE_TYPE_P,
865 pic->display_order, pic->encode_order);862 b_counter > 0, 0);
863 vaapi_encode_add_ref(avctx, pic, ctx->next_prev, 0, 0, 1);
866 }864 }
867 av_log(avctx, AV_LOG_DEBUG, "\n");865 if (ctx->next_prev)
866 --ctx->next_prev->ref_count[0];
868 867
868 if (b_counter > 0) {
869 vaapi_encode_set_b_pictures(avctx, start, pic, pic, 1,
870 &ctx->next_prev);
871 } else {
872 ctx->next_prev = pic;
873 }
874 ++ctx->next_prev->ref_count[0];
869 return 0;875 return 0;
870}876}
871 877
872static int vaapi_encode_clear_old(AVCodecContext *avctx)878static int vaapi_encode_clear_old(AVCodecContext *avctx)
873{879{
874 VAAPIEncodeContext *ctx = avctx->priv_data;880 VAAPIEncodeContext *ctx = avctx->priv_data;
875 VAAPIEncodePicture *pic, *old;881 VAAPIEncodePicture *pic, *prev, *next;
876 int i;
877 882
878 while (ctx->pic_start != ctx->pic_end) {883 av_assert0(ctx->pic_start);
879 old = ctx->pic_start;
880 if (old->encode_order > ctx->output_order)
881 break;
882 884
883 for (pic = old->next; pic; pic = pic->next) {885 // Remove direct references once each picture is complete.
884 if (pic->encode_complete)886 for (pic = ctx->pic_start; pic; pic = pic->next) {
885 continue;887 if (pic->encode_complete && pic->next)
886 for (i = 0; i < pic->nb_refs; i++) {888 vaapi_encode_remove_refs(avctx, pic, 0);
887 if (pic->refs[i] == old) {889 }
888 // We still need this picture because it's referred to
889 // directly by a later one, so it and all following
890 // pictures have to stay.
891 return 0;
892 }
893 }
894 }
895 890
896 pic = ctx->pic_start;891 // Remove indirect references once a picture has no direct references.
897 ctx->pic_start = pic->next;892 for (pic = ctx->pic_start; pic; pic = pic->next) {
898 vaapi_encode_free(avctx, pic);893 if (pic->encode_complete && pic->ref_count[0] == 0)
894 vaapi_encode_remove_refs(avctx, pic, 1);
895 }
896
897 // Clear out all complete pictures with no remaining references.
898 prev = NULL;
899 for (pic = ctx->pic_start; pic; pic = next) {
900 next = pic->next;
901 if (pic->encode_complete && pic->ref_count[1] == 0) {
902 av_assert0(pic->ref_removed[0] && pic->ref_removed[1]);
903 if (prev)
904 prev->next = next;
905 else
906 ctx->pic_start = next;
907 vaapi_encode_free(avctx, pic);
908 } else {
909 prev = pic;
910 }
899 }911 }
900 912
901 return 0;913 return 0;
902}914}
903 915
904int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt,916int ff_vaapi_encode_send_frame(AVCodecContext *avctx, const AVFrame *frame)
905 const AVFrame *input_image, int *got_packet)
906{917{
907 VAAPIEncodeContext *ctx = avctx->priv_data;918 VAAPIEncodeContext *ctx = avctx->priv_data;
908 VAAPIEncodePicture *pic;919 VAAPIEncodePicture *pic;
909 int err;920 int err;
910 921
911 if (input_image) {922 if (frame) {
912 av_log(avctx, AV_LOG_DEBUG, "Encode frame: %ux%u (%"PRId64").\n",923 av_log(avctx, AV_LOG_DEBUG, "Input frame: %ux%u (%"PRId64").\n",
913 input_image->width, input_image->height, input_image->pts);924 frame->width, frame->height, frame->pts);
914 925
915 if (input_image->pict_type == AV_PICTURE_TYPE_I) {926 pic = vaapi_encode_alloc(avctx);
916 err = vaapi_encode_truncate_gop(avctx);927 if (!pic)
917 if (err < 0)928 return AVERROR(ENOMEM);
918 goto fail;
919 ctx->force_idr = 1;
920 }
921
922 err = vaapi_encode_get_next(avctx, &pic);
923 if (err) {
924 av_log(avctx, AV_LOG_ERROR, "Input setup failed: %d.\n", err);
925 return err;
926 }
927 929
928 pic->input_image = av_frame_alloc();930 pic->input_image = av_frame_alloc();
929 if (!pic->input_image) {931 if (!pic->input_image) {
930 err = AVERROR(ENOMEM);932 err = AVERROR(ENOMEM);
931 goto fail;933 goto fail;
932 }934 }
933 err = av_frame_ref(pic->input_image, input_image);935 err = av_frame_ref(pic->input_image, frame);
934 if (err < 0)936 if (err < 0)
935 goto fail;937 goto fail;
936 pic->input_surface = (VASurfaceID)(uintptr_t)input_image->data[3];938
937 pic->pts = input_image->pts;939 if (ctx->input_order == 0)
940 pic->force_idr = 1;
941
942 pic->input_surface = (VASurfaceID)(uintptr_t)frame->data[3];
943 pic->pts = frame->pts;
938 944
939 if (ctx->input_order == 0)945 if (ctx->input_order == 0)
940 ctx->first_pts = pic->pts;946 ctx->first_pts = pic->pts;
@@ -943,72 +949,89 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, · 2 unmodified lines
943 if (ctx->output_delay > 0)949 if (ctx->output_delay > 0)
944 ctx->ts_ring[ctx->input_order % (3 * ctx->output_delay)] = pic->pts;950 ctx->ts_ring[ctx->input_order % (3 * ctx->output_delay)] = pic->pts;
945 951
946 pic->input_available = 1;952 pic->display_order = ctx->input_order;
953 ++ctx->input_order;
947 954
948 } else {955 if (ctx->pic_start) {
949 if (!ctx->end_of_stream) {956 ctx->pic_end->next = pic;
950 err = vaapi_encode_truncate_gop(avctx);957 ctx->pic_end = pic;
951 if (err < 0)958 } else {
952 goto fail;959 ctx->pic_start = pic;
953 ctx->end_of_stream = 1;960 ctx->pic_end = pic;
954 }961 }
962
963 } else {
964 ctx->end_of_stream = 1;
965
966 // Fix timestamps if we hit end-of-stream before the initial decode
967 // delay has elapsed.
968 if (ctx->input_order < ctx->decode_delay)
969 ctx->dts_pts_diff = ctx->pic_end->pts - ctx->first_pts;
955 }970 }
956 971
957 ++ctx->input_order;972 return 0;
958 ++ctx->output_order;
959 av_assert0(ctx->output_order + ctx->output_delay + 1 == ctx->input_order);
960 973
961 for (pic = ctx->pic_start; pic; pic = pic->next)974fail:
962 if (pic->encode_order == ctx->output_order)975 return err;
963 break;976}
964 977
965 // pic can be null here if we don't have a specific target in this978int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
966 // iteration. We might still issue encodes if things can be overlapped,979{
967 // even though we don't intend to output anything.980 VAAPIEncodeContext *ctx = avctx->priv_data;
981 VAAPIEncodePicture *pic;
982 int err;
968 983
969 err = vaapi_encode_step(avctx, pic);984 if (!ctx->pic_start) {
970 if (err < 0) {985 if (ctx->end_of_stream)
971 av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);986 return AVERROR_EOF;
972 goto fail;987 else
988 return AVERROR(EAGAIN);
973 }989 }
974 990
975 if (!pic) {991 pic = NULL;
976 *got_packet = 0;992 err = vaapi_encode_pick_next(avctx, &pic);
977 } else {993 if (err < 0)
978 err = vaapi_encode_output(avctx, pic, pkt);994 return err;
979 if (err < 0) {995 av_assert0(pic);
980 av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err);
981 goto fail;
982 }
983 996
984 if (ctx->output_delay == 0) {997 pic->encode_order = ctx->encode_order++;
985 pkt->dts = pkt->pts;
986 } else if (ctx->output_order < ctx->decode_delay) {
987 if (ctx->ts_ring[ctx->output_order] < INT64_MIN + ctx->dts_pts_diff)
988 pkt->dts = INT64_MIN;
989 else
990 pkt->dts = ctx->ts_ring[ctx->output_order] - ctx->dts_pts_diff;
991 } else {
992 pkt->dts = ctx->ts_ring[(ctx->output_order - ctx->decode_delay) %
993 (3 * ctx->output_delay)];
994 }
995 998
996 *got_packet = 1;999 err = vaapi_encode_issue(avctx, pic);
1000 if (err < 0) {
1001 av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
1002 return err;
997 }1003 }
998 1004
999 err = vaapi_encode_clear_old(avctx);1005 err = vaapi_encode_output(avctx, pic, pkt);
1000 if (err < 0) {1006 if (err < 0) {
1001 av_log(avctx, AV_LOG_ERROR, "List clearing failed: %d.\n", err);1007 av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err);
1002 goto fail;1008 return err;
1003 }1009 }
1004 1010
1011 if (ctx->output_delay == 0) {
1012 pkt->dts = pkt->pts;
1013 } else if (pic->encode_order < ctx->decode_delay) {
1014 if (ctx->ts_ring[pic->encode_order] < INT64_MIN + ctx->dts_pts_diff)
1015 pkt->dts = INT64_MIN;
1016 else
1017 pkt->dts = ctx->ts_ring[pic->encode_order] - ctx->dts_pts_diff;
1018 } else {
1019 pkt->dts = ctx->ts_ring[(pic->encode_order - ctx->decode_delay) %
1020 (3 * ctx->output_delay)];
1021 }
1022 av_log(avctx, AV_LOG_DEBUG, "Output packet: pts %"PRId64" dts %"PRId64".\n",
1023 pkt->pts, pkt->dts);
1024
1025 ctx->output_order = pic->encode_order;
1026 vaapi_encode_clear_old(avctx);
1027
1005 return 0;1028 return 0;
1029}
1006 1030
1007fail:1031int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt,
1008 // Unclear what to clean up on failure. There are probably some things we1032 const AVFrame *input_image, int *got_packet)
1009 // could do usefully clean up here, but for now just leave them for uninit()1033{
1010 // to do instead.1034 return AVERROR(ENOSYS);
1011 return err;
1012}1035}
1013 1036
1014static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx,1037static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx,
@@ -1475,14 +1498,16 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 460 unmodified lines
1475 ref_l1 = attr.value >> 16 & 0xffff;1498 ref_l1 = attr.value >> 16 & 0xffff;
1476 }1499 }
1477 1500
1478 if (avctx->gop_size <= 1) {1501 if (ctx->codec->flags & FLAG_INTRA_ONLY ||
1502 avctx->gop_size <= 1) {
1479 av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");1503 av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
1480 ctx->gop_size = 1;1504 ctx->gop_size = 1;
1481 } else if (ref_l0 < 1) {1505 } else if (ref_l0 < 1) {
1482 av_log(avctx, AV_LOG_ERROR, "Driver does not support any "1506 av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
1483 "reference frames.\n");1507 "reference frames.\n");
1484 return AVERROR(EINVAL);1508 return AVERROR(EINVAL);
1485 } else if (ref_l1 < 1 || avctx->max_b_frames < 1) {1509 } else if (!(ctx->codec->flags & FLAG_B_PICTURES) ||
1510 ref_l1 < 1 || avctx->max_b_frames < 1) {
1486 av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "1511 av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
1487 "(supported references: %d / %d).\n", ref_l0, ref_l1);1512 "(supported references: %d / %d).\n", ref_l0, ref_l1);
1488 ctx->gop_size = avctx->gop_size;1513 ctx->gop_size = avctx->gop_size;
@@ -1494,6 +1519,20 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 5 unmodified lines
1494 ctx->gop_size = avctx->gop_size;1519 ctx->gop_size = avctx->gop_size;
1495 ctx->p_per_i = INT_MAX;1520 ctx->p_per_i = INT_MAX;
1496 ctx->b_per_p = avctx->max_b_frames;1521 ctx->b_per_p = avctx->max_b_frames;
1522 if (ctx->codec->flags & FLAG_B_PICTURE_REFERENCES) {
1523 ctx->max_b_depth = FFMIN(ctx->desired_b_depth,
1524 av_log2(ctx->b_per_p) + 1);
1525 } else {
1526 ctx->max_b_depth = 1;
1527 }
1528 }
1529
1530 if (ctx->codec->flags & FLAG_NON_IDR_KEY_PICTURES) {
1531 ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);
1532 ctx->gop_per_idr = ctx->idr_interval + 1;
1533 } else {
1534 ctx->closed_gop = 1;
1535 ctx->gop_per_idr = 1;
1497 }1536 }
1498 1537
1499 return 0;1538 return 0;
@@ -1946,10 +1985,8 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 446 unmodified lines
1946 goto fail;1985 goto fail;
1947 }1986 }
1948 1987
1949 ctx->input_order = 0;
1950 ctx->output_delay = ctx->b_per_p;1988 ctx->output_delay = ctx->b_per_p;
1951 ctx->decode_delay = 1;1989 ctx->decode_delay = ctx->max_b_depth;
1952 ctx->output_order = - ctx->output_delay - 1;
1953 1990
1954 if (ctx->codec->sequence_params_size > 0) {1991 if (ctx->codec->sequence_params_size > 0) {
1955 ctx->codec_sequence_params =1992 ctx->codec_sequence_params =
@@ -1977,10 +2014,6 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 21 unmodified lines
1977 }2014 }
1978 }2015 }
1979 2016
1980 // This should be configurable somehow. (Needs testing on a machine
1981 // where it actually overlaps properly, though.)
1982 ctx->issue_mode = ISSUE_MODE_MAXIMISE_THROUGHPUT;
1983
1984 if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&2017 if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
1985 ctx->codec->write_sequence_header &&2018 ctx->codec->write_sequence_header &&
1986 avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {2019 avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
libavcodec/vaapi_encode.h+59−15
@@ -38,6 +38,7 @@ struct VAAPIEncodePicture; · 37 unmodified lines
38enum {38enum {
39 MAX_CONFIG_ATTRIBUTES = 4,39 MAX_CONFIG_ATTRIBUTES = 4,
40 MAX_GLOBAL_PARAMS = 4,40 MAX_GLOBAL_PARAMS = 4,
41 MAX_DPB_SIZE = 16,
41 MAX_PICTURE_REFERENCES = 2,42 MAX_PICTURE_REFERENCES = 2,
42 MAX_REORDER_DELAY = 16,43 MAX_REORDER_DELAY = 16,
43 MAX_PARAM_BUFFER_SIZE = 1024,44 MAX_PARAM_BUFFER_SIZE = 1024,
@@ -66,9 +67,10 @@ typedef struct VAAPIEncodePicture { · 22 unmodified lines
66 int64_t display_order;67 int64_t display_order;
67 int64_t encode_order;68 int64_t encode_order;
68 int64_t pts;69 int64_t pts;
70 int force_idr;
69 71
70 int type;72 int type;
71 int input_available;73 int b_depth;
72 int encode_issued;74 int encode_issued;
73 int encode_complete;75 int encode_complete;
74 76
@@ -87,8 +89,26 @@ typedef struct VAAPIEncodePicture { · 12 unmodified lines
87 void *priv_data;89 void *priv_data;
88 void *codec_picture_params;90 void *codec_picture_params;
89 91
90 int nb_refs;92 // Whether this picture is a reference picture.
93 int is_reference;
94
95 // The contents of the DPB after this picture has been decoded.
96 // This will contain the picture itself if it is a reference picture,
97 // but not if it isn't.
98 int nb_dpb_pics;
99 struct VAAPIEncodePicture *dpb[MAX_DPB_SIZE];
100 // The reference pictures used in decoding this picture. If they are
101 // used by later pictures they will also appear in the DPB.
102 int nb_refs;
91 struct VAAPIEncodePicture *refs[MAX_PICTURE_REFERENCES];103 struct VAAPIEncodePicture *refs[MAX_PICTURE_REFERENCES];
104 // The previous reference picture in encode order. Must be in at least
105 // one of the reference list and DPB list.
106 struct VAAPIEncodePicture *prev;
107 // Reference count for other pictures referring to this one through
108 // the above pointers, directly from incomplete pictures and indirectly
109 // through completed pictures.
110 int ref_count[2];
111 int ref_removed[2];
92 112
93 int nb_slices;113 int nb_slices;
94 VAAPIEncodeSlice *slices;114 VAAPIEncodeSlice *slices;
@@ -120,6 +140,12 @@ typedef struct VAAPIEncodeContext { · 25 unmodified lines
120 // Use low power encoding mode.140 // Use low power encoding mode.
121 int low_power;141 int low_power;
122 142
143 // Number of I frames between IDR frames.
144 int idr_interval;
145
146 // Desired B frame reference depth.
147 int desired_b_depth;
148
123 // Desired packed headers.149 // Desired packed headers.
124 unsigned int desired_packed_headers;150 unsigned int desired_packed_headers;
125 151
@@ -207,26 +233,21 @@ typedef struct VAAPIEncodeContext { · 81 unmodified lines
207 233
208 // Current encoding window, in display (input) order.234 // Current encoding window, in display (input) order.
209 VAAPIEncodePicture *pic_start, *pic_end;235 VAAPIEncodePicture *pic_start, *pic_end;
236 // The next picture to use as the previous reference picture in
237 // encoding order.
238 VAAPIEncodePicture *next_prev;
210 239
211 // Next input order index (display order).240 // Next input order index (display order).
212 int64_t input_order;241 int64_t input_order;
213 // Number of frames that output is behind input.242 // Number of frames that output is behind input.
214 int64_t output_delay;243 int64_t output_delay;
244 // Next encode order index.
245 int64_t encode_order;
215 // Number of frames decode output will need to be delayed.246 // Number of frames decode output will need to be delayed.
216 int64_t decode_delay;247 int64_t decode_delay;
217 // Next output order index (encode order).248 // Next output order index (in encode order).
218 int64_t output_order;249 int64_t output_order;
219 250
220 enum {
221 // All encode operations are done independently (synchronise
222 // immediately after every operation).
223 ISSUE_MODE_SERIALISE_EVERYTHING = 0,
224 // Overlap as many operations as possible.
225 ISSUE_MODE_MAXIMISE_THROUGHPUT,
226 // Overlap operations only when satisfying parallel dependencies.
227 ISSUE_MODE_MINIMISE_LATENCY,
228 } issue_mode;
229
230 // Timestamp handling.251 // Timestamp handling.
231 int64_t first_pts;252 int64_t first_pts;
232 int64_t dts_pts_diff;253 int64_t dts_pts_diff;
@@ -240,11 +261,14 @@ typedef struct VAAPIEncodeContext { · 7 unmodified lines
240 261
241 // Frame type decision.262 // Frame type decision.
242 int gop_size;263 int gop_size;
264 int closed_gop;
265 int gop_per_idr;
243 int p_per_i;266 int p_per_i;
267 int max_b_depth;
244 int b_per_p;268 int b_per_p;
245 int force_idr;269 int force_idr;
270 int idr_counter;
246 int gop_counter;271 int gop_counter;
247 int p_counter;
248 int end_of_stream;272 int end_of_stream;
249} VAAPIEncodeContext;273} VAAPIEncodeContext;
250 274
@@ -253,6 +277,15 @@ enum { · 2 unmodified lines
253 FLAG_SLICE_CONTROL = 1 << 0,277 FLAG_SLICE_CONTROL = 1 << 0,
254 // Codec only supports constant quality (no rate control).278 // Codec only supports constant quality (no rate control).
255 FLAG_CONSTANT_QUALITY_ONLY = 1 << 1,279 FLAG_CONSTANT_QUALITY_ONLY = 1 << 1,
280 // Codec is intra-only.
281 FLAG_INTRA_ONLY = 1 << 2,
282 // Codec supports B-pictures.
283 FLAG_B_PICTURES = 1 << 3,
284 // Codec supports referencing B-pictures.
285 FLAG_B_PICTURE_REFERENCES = 1 << 4,
286 // Codec supports non-IDR key pictures (that is, key pictures do
287 // not necessarily empty the DPB).
288 FLAG_NON_IDR_KEY_PICTURES = 1 << 5,
256};289};
257 290
258typedef struct VAAPIEncodeType {291typedef struct VAAPIEncodeType {
@@ -327,6 +360,9 @@ typedef struct VAAPIEncodeType { · 68 unmodified lines
327int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt,360int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt,
328 const AVFrame *input_image, int *got_packet);361 const AVFrame *input_image, int *got_packet);
329 362
363int ff_vaapi_encode_send_frame(AVCodecContext *avctx, const AVFrame *frame);
364int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt);
365
330int ff_vaapi_encode_init(AVCodecContext *avctx);366int ff_vaapi_encode_init(AVCodecContext *avctx);
331int ff_vaapi_encode_close(AVCodecContext *avctx);367int ff_vaapi_encode_close(AVCodecContext *avctx);
332 368
@@ -336,7 +372,15 @@ int ff_vaapi_encode_close(AVCodecContext *avctx); · 3 unmodified lines
336 "Use low-power encoding mode (only available on some platforms; " \372 "Use low-power encoding mode (only available on some platforms; " \
337 "may not support all encoding features)", \373 "may not support all encoding features)", \
338 OFFSET(common.low_power), AV_OPT_TYPE_BOOL, \374 OFFSET(common.low_power), AV_OPT_TYPE_BOOL, \
339 { .i64 = 0 }, 0, 1, FLAGS }375 { .i64 = 0 }, 0, 1, FLAGS }, \
376 { "idr_interval", \
377 "Distance (in I-frames) between IDR frames", \
378 OFFSET(common.idr_interval), AV_OPT_TYPE_INT, \
379 { .i64 = 0 }, 0, INT_MAX, FLAGS }, \
380 { "b_depth", \
381 "Maximum B-frame reference depth", \
382 OFFSET(common.desired_b_depth), AV_OPT_TYPE_INT, \
383 { .i64 = 1 }, 1, INT_MAX, FLAGS }
340 384
341 385
342#endif /* AVCODEC_VAAPI_ENCODE_H */386#endif /* AVCODEC_VAAPI_ENCODE_H */
libavcodec/vaapi_encode_h264.c+5−2
@@ -902,7 +902,9 @@ static const VAAPIEncodeProfile vaapi_encode_h264_profiles[] = { · 901 unmodified lines
902static const VAAPIEncodeType vaapi_encode_type_h264 = {902static const VAAPIEncodeType vaapi_encode_type_h264 = {
903 .profiles = vaapi_encode_h264_profiles,903 .profiles = vaapi_encode_h264_profiles,
904 904
905 .flags = FLAG_SLICE_CONTROL,905 .flags = FLAG_SLICE_CONTROL |
906 FLAG_B_PICTURES |
907 FLAG_NON_IDR_KEY_PICTURES,
906 908
907 .configure = &vaapi_encode_h264_configure,909 .configure = &vaapi_encode_h264_configure,
908 910
@@ -1095,7 +1097,8 @@ AVCodec ff_h264_vaapi_encoder = { · 186 unmodified lines
1095 .id = AV_CODEC_ID_H264,1097 .id = AV_CODEC_ID_H264,
1096 .priv_data_size = sizeof(VAAPIEncodeH264Context),1098 .priv_data_size = sizeof(VAAPIEncodeH264Context),
1097 .init = &vaapi_encode_h264_init,1099 .init = &vaapi_encode_h264_init,
1098 .encode2 = &ff_vaapi_encode2,1100 .send_frame = &ff_vaapi_encode_send_frame,
1101 .receive_packet = &ff_vaapi_encode_receive_packet,
1099 .close = &vaapi_encode_h264_close,1102 .close = &vaapi_encode_h264_close,
1100 .priv_class = &vaapi_encode_h264_class,1103 .priv_class = &vaapi_encode_h264_class,
1101 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,1104 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
libavcodec/vaapi_encode_h265.c+5−2
@@ -1082,7 +1082,9 @@ static const VAAPIEncodeProfile vaapi_encode_h265_profiles[] = { · 1081 unmodified lines
1082static const VAAPIEncodeType vaapi_encode_type_h265 = {1082static const VAAPIEncodeType vaapi_encode_type_h265 = {
1083 .profiles = vaapi_encode_h265_profiles,1083 .profiles = vaapi_encode_h265_profiles,
1084 1084
1085 .flags = FLAG_SLICE_CONTROL,1085 .flags = FLAG_SLICE_CONTROL |
1086 FLAG_B_PICTURES |
1087 FLAG_NON_IDR_KEY_PICTURES,
1086 1088
1087 .configure = &vaapi_encode_h265_configure,1089 .configure = &vaapi_encode_h265_configure,
1088 1090
@@ -1237,7 +1239,8 @@ AVCodec ff_hevc_vaapi_encoder = { · 148 unmodified lines
1237 .id = AV_CODEC_ID_HEVC,1239 .id = AV_CODEC_ID_HEVC,
1238 .priv_data_size = sizeof(VAAPIEncodeH265Context),1240 .priv_data_size = sizeof(VAAPIEncodeH265Context),
1239 .init = &vaapi_encode_h265_init,1241 .init = &vaapi_encode_h265_init,
1240 .encode2 = &ff_vaapi_encode2,1242 .send_frame = &ff_vaapi_encode_send_frame,
1243 .receive_packet = &ff_vaapi_encode_receive_packet,
1241 .close = &vaapi_encode_h265_close,1244 .close = &vaapi_encode_h265_close,
1242 .priv_class = &vaapi_encode_h265_class,1245 .priv_class = &vaapi_encode_h265_class,
1243 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,1246 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
libavcodec/vaapi_encode_mjpeg.c+6−3
@@ -230,6 +230,8 @@ static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx, · 229 unmodified lines
230 const uint8_t *components;230 const uint8_t *components;
231 int t, i, quant_scale, len;231 int t, i, quant_scale, len;
232 232
233 av_assert0(pic->type == PICTURE_TYPE_IDR);
234
233 desc = av_pix_fmt_desc_get(priv->common.input_frames->sw_format);235 desc = av_pix_fmt_desc_get(priv->common.input_frames->sw_format);
234 av_assert0(desc);236 av_assert0(desc);
235 if (desc->flags & AV_PIX_FMT_FLAG_RGB)237 if (desc->flags & AV_PIX_FMT_FLAG_RGB)
@@ -476,7 +478,8 @@ static const VAAPIEncodeProfile vaapi_encode_mjpeg_profiles[] = { · 240 unmodified lines
476static const VAAPIEncodeType vaapi_encode_type_mjpeg = {478static const VAAPIEncodeType vaapi_encode_type_mjpeg = {
477 .profiles = vaapi_encode_mjpeg_profiles,479 .profiles = vaapi_encode_mjpeg_profiles,
478 480
479 .flags = FLAG_CONSTANT_QUALITY_ONLY,481 .flags = FLAG_CONSTANT_QUALITY_ONLY |
482 FLAG_INTRA_ONLY,
480 483
481 .configure = &vaapi_encode_mjpeg_configure,484 .configure = &vaapi_encode_mjpeg_configure,
482 485
@@ -535,7 +538,6 @@ static const AVOption vaapi_encode_mjpeg_options[] = { · 52 unmodified lines
535static const AVCodecDefault vaapi_encode_mjpeg_defaults[] = {538static const AVCodecDefault vaapi_encode_mjpeg_defaults[] = {
536 { "global_quality", "80" },539 { "global_quality", "80" },
537 { "b", "0" },540 { "b", "0" },
538 { "g", "1" },
539 { NULL },541 { NULL },
540};542};
541 543
@@ -553,7 +555,8 @@ AVCodec ff_mjpeg_vaapi_encoder = { · 11 unmodified lines
553 .id = AV_CODEC_ID_MJPEG,555 .id = AV_CODEC_ID_MJPEG,
554 .priv_data_size = sizeof(VAAPIEncodeMJPEGContext),556 .priv_data_size = sizeof(VAAPIEncodeMJPEGContext),
555 .init = &vaapi_encode_mjpeg_init,557 .init = &vaapi_encode_mjpeg_init,
556 .encode2 = &ff_vaapi_encode2,558 .send_frame = &ff_vaapi_encode_send_frame,
559 .receive_packet = &ff_vaapi_encode_receive_packet,
557 .close = &vaapi_encode_mjpeg_close,560 .close = &vaapi_encode_mjpeg_close,
558 .priv_class = &vaapi_encode_mjpeg_class,561 .priv_class = &vaapi_encode_mjpeg_class,
559 .capabilities = AV_CODEC_CAP_HARDWARE |562 .capabilities = AV_CODEC_CAP_HARDWARE |
libavcodec/vaapi_encode_mpeg2.c+4−1
@@ -563,6 +563,8 @@ static const VAAPIEncodeProfile vaapi_encode_mpeg2_profiles[] = { · 562 unmodified lines
563static const VAAPIEncodeType vaapi_encode_type_mpeg2 = {563static const VAAPIEncodeType vaapi_encode_type_mpeg2 = {
564 .profiles = vaapi_encode_mpeg2_profiles,564 .profiles = vaapi_encode_mpeg2_profiles,
565 565
566 .flags = FLAG_B_PICTURES,
567
566 .configure = &vaapi_encode_mpeg2_configure,568 .configure = &vaapi_encode_mpeg2_configure,
567 569
568 .sequence_params_size = sizeof(VAEncSequenceParameterBufferMPEG2),570 .sequence_params_size = sizeof(VAEncSequenceParameterBufferMPEG2),
@@ -689,7 +691,8 @@ AVCodec ff_mpeg2_vaapi_encoder = { · 120 unmodified lines
689 .id = AV_CODEC_ID_MPEG2VIDEO,691 .id = AV_CODEC_ID_MPEG2VIDEO,
690 .priv_data_size = sizeof(VAAPIEncodeMPEG2Context),692 .priv_data_size = sizeof(VAAPIEncodeMPEG2Context),
691 .init = &vaapi_encode_mpeg2_init,693 .init = &vaapi_encode_mpeg2_init,
692 .encode2 = &ff_vaapi_encode2,694 .send_frame = &ff_vaapi_encode_send_frame,
695 .receive_packet = &ff_vaapi_encode_receive_packet,
693 .close = &vaapi_encode_mpeg2_close,696 .close = &vaapi_encode_mpeg2_close,
694 .priv_class = &vaapi_encode_mpeg2_class,697 .priv_class = &vaapi_encode_mpeg2_class,
695 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,698 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
libavcodec/vaapi_encode_vp8.c+2−1
@@ -246,7 +246,8 @@ AVCodec ff_vp8_vaapi_encoder = { · 245 unmodified lines
246 .id = AV_CODEC_ID_VP8,246 .id = AV_CODEC_ID_VP8,
247 .priv_data_size = sizeof(VAAPIEncodeVP8Context),247 .priv_data_size = sizeof(VAAPIEncodeVP8Context),
248 .init = &vaapi_encode_vp8_init,248 .init = &vaapi_encode_vp8_init,
249 .encode2 = &ff_vaapi_encode2,249 .send_frame = &ff_vaapi_encode_send_frame,
250 .receive_packet = &ff_vaapi_encode_receive_packet,
250 .close = &ff_vaapi_encode_close,251 .close = &ff_vaapi_encode_close,
251 .priv_class = &vaapi_encode_vp8_class,252 .priv_class = &vaapi_encode_vp8_class,
252 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,253 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,
libavcodec/vaapi_encode_vp9.c+4−1
@@ -213,6 +213,8 @@ static const VAAPIEncodeProfile vaapi_encode_vp9_profiles[] = { · 212 unmodified lines
213static const VAAPIEncodeType vaapi_encode_type_vp9 = {213static const VAAPIEncodeType vaapi_encode_type_vp9 = {
214 .profiles = vaapi_encode_vp9_profiles,214 .profiles = vaapi_encode_vp9_profiles,
215 215
216 .flags = FLAG_B_PICTURES,
217
216 .configure = &vaapi_encode_vp9_configure,218 .configure = &vaapi_encode_vp9_configure,
217 219
218 .sequence_params_size = sizeof(VAEncSequenceParameterBufferVP9),220 .sequence_params_size = sizeof(VAEncSequenceParameterBufferVP9),
@@ -275,7 +277,8 @@ AVCodec ff_vp9_vaapi_encoder = { · 56 unmodified lines
275 .id = AV_CODEC_ID_VP9,277 .id = AV_CODEC_ID_VP9,
276 .priv_data_size = sizeof(VAAPIEncodeVP9Context),278 .priv_data_size = sizeof(VAAPIEncodeVP9Context),
277 .init = &vaapi_encode_vp9_init,279 .init = &vaapi_encode_vp9_init,
278 .encode2 = &ff_vaapi_encode2,280 .send_frame = &ff_vaapi_encode_send_frame,
281 .receive_packet = &ff_vaapi_encode_receive_packet,
279 .close = &ff_vaapi_encode_close,282 .close = &ff_vaapi_encode_close,
280 .priv_class = &vaapi_encode_vp9_class,283 .priv_class = &vaapi_encode_vp9_class,
281 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,284 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t