History

Merge commit 'b46a77f19ddc4b2b5fa3187835ceb602a5244e24'

* commit 'b46a77f19ddc4b2b5fa3187835ceb602a5244e24': lavc: external hardware frame pool initialization Includes the fix from e724bdfffbd3c27aac53d1f32f20f105f37caef0

James Almer committed 9 years ago

Commit 48e4eda2 parents b125822 b46a77f27 files · +399 −181Browse files

Unified · Split

27 files
  1. doc/APIchanges +3 −0
  2. libavcodec/avcodec.h +113 −0
  3. libavcodec/decode.c +80 −0
  4. libavcodec/decode.h +12 −0
  5. libavcodec/dxva2.c +24 −31
  6. libavcodec/dxva2_h264.c +3 −0
  7. libavcodec/dxva2_hevc.c +3 −0
  8. libavcodec/dxva2_internal.h +3 −0
  9. libavcodec/dxva2_mpeg2.c +3 −0
  10. libavcodec/dxva2_vc1.c +5 −0
  11. libavcodec/dxva2_vp9.c +3 −0
  12. libavcodec/vaapi_decode.c +101 −115
  13. libavcodec/vaapi_decode.h +3 −2
  14. libavcodec/vaapi_h264.c +1 −0
  15. libavcodec/vaapi_hevc.c +1 −0
  16. libavcodec/vaapi_mpeg2.c +1 −0
  17. libavcodec/vaapi_mpeg4.c +2 −0
  18. libavcodec/vaapi_vc1.c +2 −0
  19. libavcodec/vaapi_vp9.c +1 −0
  20. libavcodec/vdpau.c +26 −32
  21. libavcodec/vdpau_h264.c +1 −0
  22. libavcodec/vdpau_hevc.c +1 −0
  23. libavcodec/vdpau_internal.h +2 −0
  24. libavcodec/vdpau_mpeg12.c +1 −0
  25. libavcodec/vdpau_mpeg4.c +1 −0
  26. libavcodec/vdpau_vc1.c +2 −0
  27. libavcodec/version.h +1 −1
doc/APIchanges+3−0
@@ -15,6 +15,9 @@ libavutil: 2017-10-21 · 14 unmodified lines
15 15
16API changes, most recent first:16API changes, most recent first:
17 17
182017-xx-xx - xxxxxxx - lavc 58.3.100 - avcodec.h
19 Add avcodec_get_hw_frames_parameters().
20
18-------- 8< --------- FFmpeg 3.4 was cut here -------- 8< ---------21-------- 8< --------- FFmpeg 3.4 was cut here -------- 8< ---------
19 22
202017-09-28 - b6cf66ae1c - lavc 57.106.104 - avcodec.h232017-09-28 - b6cf66ae1c - lavc 57.106.104 - avcodec.h
libavcodec/avcodec.h+113−0
@@ -3533,6 +3533,16 @@ typedef struct AVHWAccel { · 3532 unmodified lines
3533 */3533 */
3534 int caps_internal;3534 int caps_internal;
3535 3535
3536 /**
3537 * Fill the given hw_frames context with current codec parameters. Called
3538 * from get_format. Refer to avcodec_get_hw_frames_parameters() for
3539 * details.
3540 *
3541 * This CAN be called before AVHWAccel.init is called, and you must assume
3542 * that avctx->hwaccel_priv_data is invalid.
3543 */
3544 int (*frame_params)(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx);
3545
3536 /**3546 /**
3537 * Some hwaccels are ambiguous if only the id and pix_fmt fields are used.3547 * Some hwaccels are ambiguous if only the id and pix_fmt fields are used.
3538 * If non-NULL, the associated AVCodec must have3548 * If non-NULL, the associated AVCodec must have
@@ -4674,6 +4684,109 @@ int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame); · 1135 unmodified lines
4674 */4684 */
4675int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);4685int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);
4676 4686
4687/**
4688 * Create and return a AVHWFramesContext with values adequate for hardware
4689 * decoding. This is meant to get called from the get_format callback, and is
4690 * a helper for preparing a AVHWFramesContext for AVCodecContext.hw_frames_ctx.
4691 * This API is for decoding with certain hardware acceleration modes/APIs only.
4692 *
4693 * The returned AVHWFramesContext is not initialized. The caller must do this
4694 * with av_hwframe_ctx_init().
4695 *
4696 * Calling this function is not a requirement, but makes it simpler to avoid
4697 * codec or hardware API specific details when manually allocating frames.
4698 *
4699 * Alternatively to this, an API user can set AVCodecContext.hw_device_ctx,
4700 * which sets up AVCodecContext.hw_frames_ctx fully automatically, and makes
4701 * it unnecessary to call this function or having to care about
4702 * AVHWFramesContext initialization at all.
4703 *
4704 * There are a number of requirements for calling this function:
4705 *
4706 * - It must be called from get_format with the same avctx parameter that was
4707 * passed to get_format. Calling it outside of get_format is not allowed, and
4708 * can trigger undefined behavior.
4709 * - The function is not always supported (see description of return values).
4710 * Even if this function returns successfully, hwaccel initialization could
4711 * fail later. (The degree to which implementations check whether the stream
4712 * is actually supported varies. Some do this check only after the user's
4713 * get_format callback returns.)
4714 * - The hw_pix_fmt must be one of the choices suggested by get_format. If the
4715 * user decides to use a AVHWFramesContext prepared with this API function,
4716 * the user must return the same hw_pix_fmt from get_format.
4717 * - The device_ref passed to this function must support the given hw_pix_fmt.
4718 * - After calling this API function, it is the user's responsibility to
4719 * initialize the AVHWFramesContext (returned by the out_frames_ref parameter),
4720 * and to set AVCodecContext.hw_frames_ctx to it. If done, this must be done
4721 * before returning from get_format (this is implied by the normal
4722 * AVCodecContext.hw_frames_ctx API rules).
4723 * - The AVHWFramesContext parameters may change every time time get_format is
4724 * called. Also, AVCodecContext.hw_frames_ctx is reset before get_format. So
4725 * you are inherently required to go through this process again on every
4726 * get_format call.
4727 * - It is perfectly possible to call this function without actually using
4728 * the resulting AVHWFramesContext. One use-case might be trying to reuse a
4729 * previously initialized AVHWFramesContext, and calling this API function
4730 * only to test whether the required frame parameters have changed.
4731 * - Fields that use dynamically allocated values of any kind must not be set
4732 * by the user unless setting them is explicitly allowed by the documentation.
4733 * If the user sets AVHWFramesContext.free and AVHWFramesContext.user_opaque,
4734 * the new free callback must call the potentially set previous free callback.
4735 * This API call may set any dynamically allocated fields, including the free
4736 * callback.
4737 *
4738 * The function will set at least the following fields on AVHWFramesContext
4739 * (potentially more, depending on hwaccel API):
4740 *
4741 * - All fields set by av_hwframe_ctx_alloc().
4742 * - Set the format field to hw_pix_fmt.
4743 * - Set the sw_format field to the most suited and most versatile format. (An
4744 * implication is that this will prefer generic formats over opaque formats
4745 * with arbitrary restrictions, if possible.)
4746 * - Set the width/height fields to the coded frame size, rounded up to the
4747 * API-specific minimum alignment.
4748 * - Only _if_ the hwaccel requires a pre-allocated pool: set the initial_pool_size
4749 * field to the number of maximum reference surfaces possible with the codec,
4750 * plus 1 surface for the user to work (meaning the user can safely reference
4751 * at most 1 decoded surface at a time), plus additional buffering introduced
4752 * by frame threading. If the hwaccel does not require pre-allocation, the
4753 * field is left to 0, and the decoder will allocate new surfaces on demand
4754 * during decoding.
4755 * - Possibly AVHWFramesContext.hwctx fields, depending on the underlying
4756 * hardware API.
4757 *
4758 * Essentially, out_frames_ref returns the same as av_hwframe_ctx_alloc(), but
4759 * with basic frame parameters set.
4760 *
4761 * The function is stateless, and does not change the AVCodecContext or the
4762 * device_ref AVHWDeviceContext.
4763 *
4764 * @param avctx The context which is currently calling get_format, and which
4765 * implicitly contains all state needed for filling the returned
4766 * AVHWFramesContext properly.
4767 * @param device_ref A reference to the AVHWDeviceContext describing the device
4768 * which will be used by the hardware decoder.
4769 * @param hw_pix_fmt The hwaccel format you are going to return from get_format.
4770 * @param out_frames_ref On success, set to a reference to an _uninitialized_
4771 * AVHWFramesContext, created from the given device_ref.
4772 * Fields will be set to values required for decoding.
4773 * Not changed if an error is returned.
4774 * @return zero on success, a negative value on error. The following error codes
4775 * have special semantics:
4776 * AVERROR(ENOENT): the decoder does not support this functionality. Setup
4777 * is always manual, or it is a decoder which does not
4778 * support setting AVCodecContext.hw_frames_ctx at all,
4779 * or it is a software format.
4780 * AVERROR(EINVAL): it is known that hardware decoding is not supported for
4781 * this configuration, or the device_ref is not supported
4782 * for the hwaccel referenced by hw_pix_fmt.
4783 */
4784int avcodec_get_hw_frames_parameters(AVCodecContext *avctx,
4785 AVBufferRef *device_ref,
4786 enum AVPixelFormat hw_pix_fmt,
4787 AVBufferRef **out_frames_ref);
4788
4789
4677 4790
4678/**4791/**
4679 * @defgroup lavc_parsing Frame parsing4792 * @defgroup lavc_parsing Frame parsing
libavcodec/decode.c+80−0
@@ -1106,6 +1106,86 @@ static AVHWAccel *find_hwaccel(AVCodecContext *avctx, · 1105 unmodified lines
1106 return NULL;1106 return NULL;
1107}1107}
1108 1108
1109int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx,
1110 enum AVHWDeviceType dev_type)
1111{
1112 AVHWDeviceContext *device_ctx;
1113 AVHWFramesContext *frames_ctx;
1114 int ret;
1115
1116 if (!avctx->hwaccel)
1117 return AVERROR(ENOSYS);
1118
1119 if (avctx->hw_frames_ctx)
1120 return 0;
1121 if (!avctx->hw_device_ctx) {
1122 av_log(avctx, AV_LOG_ERROR, "A hardware frames or device context is "
1123 "required for hardware accelerated decoding.\n");
1124 return AVERROR(EINVAL);
1125 }
1126
1127 device_ctx = (AVHWDeviceContext *)avctx->hw_device_ctx->data;
1128 if (device_ctx->type != dev_type) {
1129 av_log(avctx, AV_LOG_ERROR, "Device type %s expected for hardware "
1130 "decoding, but got %s.\n", av_hwdevice_get_type_name(dev_type),
1131 av_hwdevice_get_type_name(device_ctx->type));
1132 return AVERROR(EINVAL);
1133 }
1134
1135 ret = avcodec_get_hw_frames_parameters(avctx,
1136 avctx->hw_device_ctx,
1137 avctx->hwaccel->pix_fmt,
1138 &avctx->hw_frames_ctx);
1139 if (ret < 0)
1140 return ret;
1141
1142 frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
1143
1144
1145 if (frames_ctx->initial_pool_size) {
1146 // We guarantee 4 base work surfaces. The function above guarantees 1
1147 // (the absolute minimum), so add the missing count.
1148 frames_ctx->initial_pool_size += 3;
1149
1150 // Add an additional surface per thread is frame threading is enabled.
1151 if (avctx->active_thread_type & FF_THREAD_FRAME)
1152 frames_ctx->initial_pool_size += avctx->thread_count;
1153 }
1154
1155 ret = av_hwframe_ctx_init(avctx->hw_frames_ctx);
1156 if (ret < 0) {
1157 av_buffer_unref(&avctx->hw_frames_ctx);
1158 return ret;
1159 }
1160
1161 return 0;
1162}
1163
1164int avcodec_get_hw_frames_parameters(AVCodecContext *avctx,
1165 AVBufferRef *device_ref,
1166 enum AVPixelFormat hw_pix_fmt,
1167 AVBufferRef **out_frames_ref)
1168{
1169 AVBufferRef *frames_ref = NULL;
1170 AVHWAccel *hwa = find_hwaccel(avctx, hw_pix_fmt);
1171 int ret;
1172
1173 if (!hwa || !hwa->frame_params)
1174 return AVERROR(ENOENT);
1175
1176 frames_ref = av_hwframe_ctx_alloc(device_ref);
1177 if (!frames_ref)
1178 return AVERROR(ENOMEM);
1179
1180 ret = hwa->frame_params(avctx, frames_ref);
1181 if (ret >= 0) {
1182 *out_frames_ref = frames_ref;
1183 } else {
1184 av_buffer_unref(&frames_ref);
1185 }
1186 return ret;
1187}
1188
1109static int setup_hwaccel(AVCodecContext *avctx,1189static int setup_hwaccel(AVCodecContext *avctx,
1110 const enum AVPixelFormat fmt,1190 const enum AVPixelFormat fmt,
1111 const char *name)1191 const char *name)
libavcodec/decode.h+12−0
@@ -24,6 +24,10 @@ · 23 unmodified lines
24#include "libavutil/buffer.h"24#include "libavutil/buffer.h"
25#include "libavutil/frame.h"25#include "libavutil/frame.h"
26 26
27#include "libavutil/buffer.h"
28#include "libavutil/frame.h"
29#include "libavutil/hwcontext.h"
30
27#include "avcodec.h"31#include "avcodec.h"
28 32
29/**33/**
@@ -65,6 +69,14 @@ int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt); · 35 unmodified lines
65 69
66void ff_decode_bsfs_uninit(AVCodecContext *avctx);70void ff_decode_bsfs_uninit(AVCodecContext *avctx);
67 71
72/**
73 * Make sure avctx.hw_frames_ctx is set. If it's not set, the function will
74 * try to allocate it from hw_device_ctx. If that is not possible, an error
75 * message is printed, and an error code is returned.
76 */
77int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx,
78 enum AVHWDeviceType dev_type);
79
68int ff_attach_decode_data(AVFrame *frame);80int ff_attach_decode_data(AVFrame *frame);
69 81
70#endif /* AVCODEC_DECODE_H */82#endif /* AVCODEC_DECODE_H */
libavcodec/dxva2.c+24−31
@@ -29,6 +29,7 @@ · 28 unmodified lines
29#include "libavutil/time.h"29#include "libavutil/time.h"
30 30
31#include "avcodec.h"31#include "avcodec.h"
32#include "decode.h"
32#include "dxva2_internal.h"33#include "dxva2_internal.h"
33 34
34/* define all the GUIDs used directly here,35/* define all the GUIDs used directly here,
@@ -576,14 +577,20 @@ static void ff_dxva2_unlock(AVCodecContext *avctx) · 541 unmodified lines
576#endif577#endif
577}578}
578 579
579// This must work before the decoder is created.580int ff_dxva2_common_frame_params(AVCodecContext *avctx,
580// This somehow needs to be exported to the user.581 AVBufferRef *hw_frames_ctx)
581static void dxva_adjust_hwframes(AVCodecContext *avctx, AVHWFramesContext *frames_ctx)
582{582{
583 FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);583 AVHWFramesContext *frames_ctx = (AVHWFramesContext *)hw_frames_ctx->data;
584 AVHWDeviceContext *device_ctx = frames_ctx->device_ctx;
584 int surface_alignment, num_surfaces;585 int surface_alignment, num_surfaces;
585 586
586 frames_ctx->format = sctx->pix_fmt;587 if (device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
588 frames_ctx->format = AV_PIX_FMT_DXVA2_VLD;
589 } else if (device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
590 frames_ctx->format = AV_PIX_FMT_D3D11;
591 } else {
592 return AVERROR(EINVAL);
593 }
587 594
588 /* decoding MPEG-2 requires additional alignment on some Intel GPUs,595 /* decoding MPEG-2 requires additional alignment on some Intel GPUs,
589 but it causes issues for H.264 on certain AMD GPUs..... */596 but it causes issues for H.264 on certain AMD GPUs..... */
@@ -596,8 +603,8 @@ static void dxva_adjust_hwframes(AVCodecContext *avctx, AVHWFramesContext *frame · 6 unmodified lines
596 else603 else
597 surface_alignment = 16;604 surface_alignment = 16;
598 605
599 /* 4 base work surfaces */606 /* 1 base work surface */
600 num_surfaces = 4;607 num_surfaces = 1;
601 608
602 /* add surfaces based on number of possible refs */609 /* add surfaces based on number of possible refs */
603 if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC)610 if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC)
@@ -633,12 +640,16 @@ static void dxva_adjust_hwframes(AVCodecContext *avctx, AVHWFramesContext *frame · 29 unmodified lines
633 frames_hwctx->BindFlags |= D3D11_BIND_DECODER;640 frames_hwctx->BindFlags |= D3D11_BIND_DECODER;
634 }641 }
635#endif642#endif
643
644 return 0;
636}645}
637 646
638int ff_dxva2_decode_init(AVCodecContext *avctx)647int ff_dxva2_decode_init(AVCodecContext *avctx)
639{648{
640 FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);649 FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
641 AVHWFramesContext *frames_ctx = NULL;650 AVHWFramesContext *frames_ctx;
651 enum AVHWDeviceType dev_type = avctx->hwaccel->pix_fmt == AV_PIX_FMT_DXVA2_VLD
652 ? AV_HWDEVICE_TYPE_DXVA2 : AV_HWDEVICE_TYPE_D3D11VA;
642 int ret = 0;653 int ret = 0;
643 654
644 // Old API.655 // Old API.
@@ -648,32 +659,14 @@ int ff_dxva2_decode_init(AVCodecContext *avctx) · 3 unmodified lines
648 // (avctx->pix_fmt is not updated yet at this point)659 // (avctx->pix_fmt is not updated yet at this point)
649 sctx->pix_fmt = avctx->hwaccel->pix_fmt;660 sctx->pix_fmt = avctx->hwaccel->pix_fmt;
650 661
651 if (!avctx->hw_frames_ctx && !avctx->hw_device_ctx) {662 ret = ff_decode_get_hw_frames_ctx(avctx, dev_type);
652 av_log(avctx, AV_LOG_ERROR, "Either a hw_frames_ctx or a hw_device_ctx needs to be set for hardware decoding.\n");663 if (ret < 0)
653 return AVERROR(EINVAL);664 return ret;
654 }
655
656 if (avctx->hw_frames_ctx) {
657 frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
658 } else {
659 avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx);
660 if (!avctx->hw_frames_ctx)
661 return AVERROR(ENOMEM);
662
663 frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
664
665 dxva_adjust_hwframes(avctx, frames_ctx);
666
667 ret = av_hwframe_ctx_init(avctx->hw_frames_ctx);
668 if (ret < 0)
669 goto fail;
670 }
671 665
666 frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
672 sctx->device_ctx = frames_ctx->device_ctx;667 sctx->device_ctx = frames_ctx->device_ctx;
673 668
674 if (frames_ctx->format != sctx->pix_fmt ||669 if (frames_ctx->format != sctx->pix_fmt) {
675 !((sctx->pix_fmt == AV_PIX_FMT_D3D11 && CONFIG_D3D11VA) ||
676 (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && CONFIG_DXVA2))) {
677 av_log(avctx, AV_LOG_ERROR, "Invalid pixfmt for hwaccel!\n");670 av_log(avctx, AV_LOG_ERROR, "Invalid pixfmt for hwaccel!\n");
678 ret = AVERROR(EINVAL);671 ret = AVERROR(EINVAL);
679 goto fail;672 goto fail;
libavcodec/dxva2_h264.c+3−0
@@ -528,6 +528,7 @@ AVHWAccel ff_h264_dxva2_hwaccel = { · 527 unmodified lines
528 .start_frame = dxva2_h264_start_frame,528 .start_frame = dxva2_h264_start_frame,
529 .decode_slice = dxva2_h264_decode_slice,529 .decode_slice = dxva2_h264_decode_slice,
530 .end_frame = dxva2_h264_end_frame,530 .end_frame = dxva2_h264_end_frame,
531 .frame_params = ff_dxva2_common_frame_params,
531 .frame_priv_data_size = sizeof(struct dxva2_picture_context),532 .frame_priv_data_size = sizeof(struct dxva2_picture_context),
532 .priv_data_size = sizeof(FFDXVASharedContext),533 .priv_data_size = sizeof(FFDXVASharedContext),
533};534};
@@ -544,6 +545,7 @@ AVHWAccel ff_h264_d3d11va_hwaccel = { · 10 unmodified lines
544 .start_frame = dxva2_h264_start_frame,545 .start_frame = dxva2_h264_start_frame,
545 .decode_slice = dxva2_h264_decode_slice,546 .decode_slice = dxva2_h264_decode_slice,
546 .end_frame = dxva2_h264_end_frame,547 .end_frame = dxva2_h264_end_frame,
548 .frame_params = ff_dxva2_common_frame_params,
547 .frame_priv_data_size = sizeof(struct dxva2_picture_context),549 .frame_priv_data_size = sizeof(struct dxva2_picture_context),
548 .priv_data_size = sizeof(FFDXVASharedContext),550 .priv_data_size = sizeof(FFDXVASharedContext),
549};551};
@@ -560,6 +562,7 @@ AVHWAccel ff_h264_d3d11va2_hwaccel = { · 10 unmodified lines
560 .start_frame = dxva2_h264_start_frame,562 .start_frame = dxva2_h264_start_frame,
561 .decode_slice = dxva2_h264_decode_slice,563 .decode_slice = dxva2_h264_decode_slice,
562 .end_frame = dxva2_h264_end_frame,564 .end_frame = dxva2_h264_end_frame,
565 .frame_params = ff_dxva2_common_frame_params,
563 .frame_priv_data_size = sizeof(struct dxva2_picture_context),566 .frame_priv_data_size = sizeof(struct dxva2_picture_context),
564 .priv_data_size = sizeof(FFDXVASharedContext),567 .priv_data_size = sizeof(FFDXVASharedContext),
565};568};
libavcodec/dxva2_hevc.c+3−0
@@ -432,6 +432,7 @@ AVHWAccel ff_hevc_dxva2_hwaccel = { · 431 unmodified lines
432 .start_frame = dxva2_hevc_start_frame,432 .start_frame = dxva2_hevc_start_frame,
433 .decode_slice = dxva2_hevc_decode_slice,433 .decode_slice = dxva2_hevc_decode_slice,
434 .end_frame = dxva2_hevc_end_frame,434 .end_frame = dxva2_hevc_end_frame,
435 .frame_params = ff_dxva2_common_frame_params,
435 .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),436 .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
436 .priv_data_size = sizeof(FFDXVASharedContext),437 .priv_data_size = sizeof(FFDXVASharedContext),
437};438};
@@ -448,6 +449,7 @@ AVHWAccel ff_hevc_d3d11va_hwaccel = { · 10 unmodified lines
448 .start_frame = dxva2_hevc_start_frame,449 .start_frame = dxva2_hevc_start_frame,
449 .decode_slice = dxva2_hevc_decode_slice,450 .decode_slice = dxva2_hevc_decode_slice,
450 .end_frame = dxva2_hevc_end_frame,451 .end_frame = dxva2_hevc_end_frame,
452 .frame_params = ff_dxva2_common_frame_params,
451 .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),453 .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
452 .priv_data_size = sizeof(FFDXVASharedContext),454 .priv_data_size = sizeof(FFDXVASharedContext),
453};455};
@@ -464,6 +466,7 @@ AVHWAccel ff_hevc_d3d11va2_hwaccel = { · 10 unmodified lines
464 .start_frame = dxva2_hevc_start_frame,466 .start_frame = dxva2_hevc_start_frame,
465 .decode_slice = dxva2_hevc_decode_slice,467 .decode_slice = dxva2_hevc_decode_slice,
466 .end_frame = dxva2_hevc_end_frame,468 .end_frame = dxva2_hevc_end_frame,
469 .frame_params = ff_dxva2_common_frame_params,
467 .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),470 .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
468 .priv_data_size = sizeof(FFDXVASharedContext),471 .priv_data_size = sizeof(FFDXVASharedContext),
469};472};
libavcodec/dxva2_internal.h+3−0
@@ -156,6 +156,9 @@ int ff_dxva2_decode_init(AVCodecContext *avctx); · 155 unmodified lines
156 156
157int ff_dxva2_decode_uninit(AVCodecContext *avctx);157int ff_dxva2_decode_uninit(AVCodecContext *avctx);
158 158
159int ff_dxva2_common_frame_params(AVCodecContext *avctx,
160 AVBufferRef *hw_frames_ctx);
161
159int ff_dxva2_is_d3d11(const AVCodecContext *avctx);162int ff_dxva2_is_d3d11(const AVCodecContext *avctx);
160 163
161#endif /* AVCODEC_DXVA2_INTERNAL_H */164#endif /* AVCODEC_DXVA2_INTERNAL_H */
libavcodec/dxva2_mpeg2.c+3−0
@@ -327,6 +327,7 @@ AVHWAccel ff_mpeg2_dxva2_hwaccel = { · 326 unmodified lines
327 .start_frame = dxva2_mpeg2_start_frame,327 .start_frame = dxva2_mpeg2_start_frame,
328 .decode_slice = dxva2_mpeg2_decode_slice,328 .decode_slice = dxva2_mpeg2_decode_slice,
329 .end_frame = dxva2_mpeg2_end_frame,329 .end_frame = dxva2_mpeg2_end_frame,
330 .frame_params = ff_dxva2_common_frame_params,
330 .frame_priv_data_size = sizeof(struct dxva2_picture_context),331 .frame_priv_data_size = sizeof(struct dxva2_picture_context),
331 .priv_data_size = sizeof(FFDXVASharedContext),332 .priv_data_size = sizeof(FFDXVASharedContext),
332};333};
@@ -343,6 +344,7 @@ AVHWAccel ff_mpeg2_d3d11va_hwaccel = { · 10 unmodified lines
343 .start_frame = dxva2_mpeg2_start_frame,344 .start_frame = dxva2_mpeg2_start_frame,
344 .decode_slice = dxva2_mpeg2_decode_slice,345 .decode_slice = dxva2_mpeg2_decode_slice,
345 .end_frame = dxva2_mpeg2_end_frame,346 .end_frame = dxva2_mpeg2_end_frame,
347 .frame_params = ff_dxva2_common_frame_params,
346 .frame_priv_data_size = sizeof(struct dxva2_picture_context),348 .frame_priv_data_size = sizeof(struct dxva2_picture_context),
347 .priv_data_size = sizeof(FFDXVASharedContext),349 .priv_data_size = sizeof(FFDXVASharedContext),
348};350};
@@ -359,6 +361,7 @@ AVHWAccel ff_mpeg2_d3d11va2_hwaccel = { · 10 unmodified lines
359 .start_frame = dxva2_mpeg2_start_frame,361 .start_frame = dxva2_mpeg2_start_frame,
360 .decode_slice = dxva2_mpeg2_decode_slice,362 .decode_slice = dxva2_mpeg2_decode_slice,
361 .end_frame = dxva2_mpeg2_end_frame,363 .end_frame = dxva2_mpeg2_end_frame,
364 .frame_params = ff_dxva2_common_frame_params,
362 .frame_priv_data_size = sizeof(struct dxva2_picture_context),365 .frame_priv_data_size = sizeof(struct dxva2_picture_context),
363 .priv_data_size = sizeof(FFDXVASharedContext),366 .priv_data_size = sizeof(FFDXVASharedContext),
364};367};
libavcodec/dxva2_vc1.c+5−0
@@ -388,6 +388,7 @@ AVHWAccel ff_wmv3_dxva2_hwaccel = { · 387 unmodified lines
388 .start_frame = dxva2_vc1_start_frame,388 .start_frame = dxva2_vc1_start_frame,
389 .decode_slice = dxva2_vc1_decode_slice,389 .decode_slice = dxva2_vc1_decode_slice,
390 .end_frame = dxva2_vc1_end_frame,390 .end_frame = dxva2_vc1_end_frame,
391 .frame_params = ff_dxva2_common_frame_params,
391 .frame_priv_data_size = sizeof(struct dxva2_picture_context),392 .frame_priv_data_size = sizeof(struct dxva2_picture_context),
392 .priv_data_size = sizeof(FFDXVASharedContext),393 .priv_data_size = sizeof(FFDXVASharedContext),
393};394};
@@ -404,6 +405,7 @@ AVHWAccel ff_vc1_dxva2_hwaccel = { · 10 unmodified lines
404 .start_frame = dxva2_vc1_start_frame,405 .start_frame = dxva2_vc1_start_frame,
405 .decode_slice = dxva2_vc1_decode_slice,406 .decode_slice = dxva2_vc1_decode_slice,
406 .end_frame = dxva2_vc1_end_frame,407 .end_frame = dxva2_vc1_end_frame,
408 .frame_params = ff_dxva2_common_frame_params,
407 .frame_priv_data_size = sizeof(struct dxva2_picture_context),409 .frame_priv_data_size = sizeof(struct dxva2_picture_context),
408 .priv_data_size = sizeof(FFDXVASharedContext),410 .priv_data_size = sizeof(FFDXVASharedContext),
409};411};
@@ -420,6 +422,7 @@ AVHWAccel ff_wmv3_d3d11va_hwaccel = { · 10 unmodified lines
420 .start_frame = dxva2_vc1_start_frame,422 .start_frame = dxva2_vc1_start_frame,
421 .decode_slice = dxva2_vc1_decode_slice,423 .decode_slice = dxva2_vc1_decode_slice,
422 .end_frame = dxva2_vc1_end_frame,424 .end_frame = dxva2_vc1_end_frame,
425 .frame_params = ff_dxva2_common_frame_params,
423 .frame_priv_data_size = sizeof(struct dxva2_picture_context),426 .frame_priv_data_size = sizeof(struct dxva2_picture_context),
424 .priv_data_size = sizeof(FFDXVASharedContext),427 .priv_data_size = sizeof(FFDXVASharedContext),
425};428};
@@ -436,6 +439,7 @@ AVHWAccel ff_wmv3_d3d11va2_hwaccel = { · 10 unmodified lines
436 .start_frame = dxva2_vc1_start_frame,439 .start_frame = dxva2_vc1_start_frame,
437 .decode_slice = dxva2_vc1_decode_slice,440 .decode_slice = dxva2_vc1_decode_slice,
438 .end_frame = dxva2_vc1_end_frame,441 .end_frame = dxva2_vc1_end_frame,
442 .frame_params = ff_dxva2_common_frame_params,
439 .frame_priv_data_size = sizeof(struct dxva2_picture_context),443 .frame_priv_data_size = sizeof(struct dxva2_picture_context),
440 .priv_data_size = sizeof(FFDXVASharedContext),444 .priv_data_size = sizeof(FFDXVASharedContext),
441};445};
@@ -452,6 +456,7 @@ AVHWAccel ff_vc1_d3d11va_hwaccel = { · 10 unmodified lines
452 .start_frame = dxva2_vc1_start_frame,456 .start_frame = dxva2_vc1_start_frame,
453 .decode_slice = dxva2_vc1_decode_slice,457 .decode_slice = dxva2_vc1_decode_slice,
454 .end_frame = dxva2_vc1_end_frame,458 .end_frame = dxva2_vc1_end_frame,
459 .frame_params = ff_dxva2_common_frame_params,
455 .frame_priv_data_size = sizeof(struct dxva2_picture_context),460 .frame_priv_data_size = sizeof(struct dxva2_picture_context),
456 .priv_data_size = sizeof(FFDXVASharedContext),461 .priv_data_size = sizeof(FFDXVASharedContext),
457};462};
libavcodec/dxva2_vp9.c+3−0
@@ -319,6 +319,7 @@ AVHWAccel ff_vp9_dxva2_hwaccel = { · 318 unmodified lines
319 .start_frame = dxva2_vp9_start_frame,319 .start_frame = dxva2_vp9_start_frame,
320 .decode_slice = dxva2_vp9_decode_slice,320 .decode_slice = dxva2_vp9_decode_slice,
321 .end_frame = dxva2_vp9_end_frame,321 .end_frame = dxva2_vp9_end_frame,
322 .frame_params = ff_dxva2_common_frame_params,
322 .frame_priv_data_size = sizeof(struct vp9_dxva2_picture_context),323 .frame_priv_data_size = sizeof(struct vp9_dxva2_picture_context),
323 .priv_data_size = sizeof(FFDXVASharedContext),324 .priv_data_size = sizeof(FFDXVASharedContext),
324};325};
@@ -335,6 +336,7 @@ AVHWAccel ff_vp9_d3d11va_hwaccel = { · 10 unmodified lines
335 .start_frame = dxva2_vp9_start_frame,336 .start_frame = dxva2_vp9_start_frame,
336 .decode_slice = dxva2_vp9_decode_slice,337 .decode_slice = dxva2_vp9_decode_slice,
337 .end_frame = dxva2_vp9_end_frame,338 .end_frame = dxva2_vp9_end_frame,
339 .frame_params = ff_dxva2_common_frame_params,
338 .frame_priv_data_size = sizeof(struct vp9_dxva2_picture_context),340 .frame_priv_data_size = sizeof(struct vp9_dxva2_picture_context),
339 .priv_data_size = sizeof(FFDXVASharedContext),341 .priv_data_size = sizeof(FFDXVASharedContext),
340};342};
@@ -351,6 +353,7 @@ AVHWAccel ff_vp9_d3d11va2_hwaccel = { · 10 unmodified lines
351 .start_frame = dxva2_vp9_start_frame,353 .start_frame = dxva2_vp9_start_frame,
352 .decode_slice = dxva2_vp9_decode_slice,354 .decode_slice = dxva2_vp9_decode_slice,
353 .end_frame = dxva2_vp9_end_frame,355 .end_frame = dxva2_vp9_end_frame,
356 .frame_params = ff_dxva2_common_frame_params,
354 .frame_priv_data_size = sizeof(struct vp9_dxva2_picture_context),357 .frame_priv_data_size = sizeof(struct vp9_dxva2_picture_context),
355 .priv_data_size = sizeof(FFDXVASharedContext),358 .priv_data_size = sizeof(FFDXVASharedContext),
356};359};
libavcodec/vaapi_decode.c+101−115
@@ -21,6 +21,7 @@ · 20 unmodified lines
21#include "libavutil/pixdesc.h"21#include "libavutil/pixdesc.h"
22 22
23#include "avcodec.h"23#include "avcodec.h"
24#include "decode.h"
24#include "internal.h"25#include "internal.h"
25#include "vaapi_decode.h"26#include "vaapi_decode.h"
26 27
@@ -272,10 +273,15 @@ static const struct { · 245 unmodified lines
272#undef MAP273#undef MAP
273};274};
274 275
275static int vaapi_decode_make_config(AVCodecContext *avctx)276/*
277 * Set *va_config and the frames_ref fields from the current codec parameters
278 * in avctx.
279 */
280static int vaapi_decode_make_config(AVCodecContext *avctx,
281 AVBufferRef *device_ref,
282 VAConfigID *va_config,
283 AVBufferRef *frames_ref)
276{284{
277 VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
278
279 AVVAAPIHWConfig *hwconfig = NULL;285 AVVAAPIHWConfig *hwconfig = NULL;
280 AVHWFramesConstraints *constraints = NULL;286 AVHWFramesConstraints *constraints = NULL;
281 VAStatus vas;287 VAStatus vas;
@@ -285,13 +291,16 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) · 3 unmodified lines
285 int profile_count, exact_match, alt_profile;291 int profile_count, exact_match, alt_profile;
286 const AVPixFmtDescriptor *sw_desc, *desc;292 const AVPixFmtDescriptor *sw_desc, *desc;
287 293
294 AVHWDeviceContext *device = (AVHWDeviceContext*)device_ref->data;
295 AVVAAPIDeviceContext *hwctx = device->hwctx;
296
288 codec_desc = avcodec_descriptor_get(avctx->codec_id);297 codec_desc = avcodec_descriptor_get(avctx->codec_id);
289 if (!codec_desc) {298 if (!codec_desc) {
290 err = AVERROR(EINVAL);299 err = AVERROR(EINVAL);
291 goto fail;300 goto fail;
292 }301 }
293 302
294 profile_count = vaMaxNumProfiles(ctx->hwctx->display);303 profile_count = vaMaxNumProfiles(hwctx->display);
295 profile_list = av_malloc_array(profile_count,304 profile_list = av_malloc_array(profile_count,
296 sizeof(VAProfile));305 sizeof(VAProfile));
297 if (!profile_list) {306 if (!profile_list) {
@@ -299,7 +308,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) · 1 unmodified line
299 goto fail;308 goto fail;
300 }309 }
301 310
302 vas = vaQueryConfigProfiles(ctx->hwctx->display,311 vas = vaQueryConfigProfiles(hwctx->display,
303 profile_list, &profile_count);312 profile_list, &profile_count);
304 if (vas != VA_STATUS_SUCCESS) {313 if (vas != VA_STATUS_SUCCESS) {
305 av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: "314 av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: "
@@ -358,12 +367,9 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) · 52 unmodified lines
358 }367 }
359 }368 }
360 369
361 ctx->va_profile = profile;370 vas = vaCreateConfig(hwctx->display, profile,
362 ctx->va_entrypoint = VAEntrypointVLD;371 VAEntrypointVLD, NULL, 0,
363 372 va_config);
364 vas = vaCreateConfig(ctx->hwctx->display, ctx->va_profile,
365 ctx->va_entrypoint, NULL, 0,
366 &ctx->va_config);
367 if (vas != VA_STATUS_SUCCESS) {373 if (vas != VA_STATUS_SUCCESS) {
368 av_log(avctx, AV_LOG_ERROR, "Failed to create decode "374 av_log(avctx, AV_LOG_ERROR, "Failed to create decode "
369 "configuration: %d (%s).\n", vas, vaErrorStr(vas));375 "configuration: %d (%s).\n", vas, vaErrorStr(vas));
@@ -371,20 +377,15 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) · 1 unmodified line
371 goto fail;377 goto fail;
372 }378 }
373 379
374 hwconfig = av_hwdevice_hwconfig_alloc(avctx->hw_device_ctx ?380 hwconfig = av_hwdevice_hwconfig_alloc(device_ref);
375 avctx->hw_device_ctx :
376 ctx->frames->device_ref);
377 if (!hwconfig) {381 if (!hwconfig) {
378 err = AVERROR(ENOMEM);382 err = AVERROR(ENOMEM);
379 goto fail;383 goto fail;
380 }384 }
381 hwconfig->config_id = ctx->va_config;385 hwconfig->config_id = *va_config;
382 386
383 constraints =387 constraints =
384 av_hwdevice_get_hwframe_constraints(avctx->hw_device_ctx ?388 av_hwdevice_get_hwframe_constraints(device_ref, hwconfig);
385 avctx->hw_device_ctx :
386 ctx->frames->device_ref,
387 hwconfig);
388 if (!constraints) {389 if (!constraints) {
389 err = AVERROR(ENOMEM);390 err = AVERROR(ENOMEM);
390 goto fail;391 goto fail;
@@ -410,48 +411,52 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) · 19 unmodified lines
410 goto fail;411 goto fail;
411 }412 }
412 413
413 // Find the first format in the list which matches the expected414 if (frames_ref) {
414 // bit depth and subsampling. If none are found (this can happen415 AVHWFramesContext *frames = (AVHWFramesContext *)frames_ref->data;
415 // when 10-bit streams are decoded to 8-bit surfaces, for example)416
416 // then just take the first format on the list.417 frames->format = AV_PIX_FMT_VAAPI;
417 ctx->surface_format = constraints->valid_sw_formats[0];418 frames->width = avctx->coded_width;
418 sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);419 frames->height = avctx->coded_height;
419 for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {420
420 desc = av_pix_fmt_desc_get(constraints->valid_sw_formats[i]);421 // Find the first format in the list which matches the expected
421 if (desc->nb_components != sw_desc->nb_components ||422 // bit depth and subsampling. If none are found (this can happen
422 desc->log2_chroma_w != sw_desc->log2_chroma_w ||423 // when 10-bit streams are decoded to 8-bit surfaces, for example)
423 desc->log2_chroma_h != sw_desc->log2_chroma_h)424 // then just take the first format on the list.
424 continue;425 frames->sw_format = constraints->valid_sw_formats[0];
425 for (j = 0; j < desc->nb_components; j++) {426 sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
426 if (desc->comp[j].depth != sw_desc->comp[j].depth)427 for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
427 break;428 desc = av_pix_fmt_desc_get(constraints->valid_sw_formats[i]);
429 if (desc->nb_components != sw_desc->nb_components ||
430 desc->log2_chroma_w != sw_desc->log2_chroma_w ||
431 desc->log2_chroma_h != sw_desc->log2_chroma_h)
432 continue;
433 for (j = 0; j < desc->nb_components; j++) {
434 if (desc->comp[j].depth != sw_desc->comp[j].depth)
435 break;
436 }
437 if (j < desc->nb_components)
438 continue;
439 frames->sw_format = constraints->valid_sw_formats[i];
440 break;
428 }441 }
429 if (j < desc->nb_components)
430 continue;
431 ctx->surface_format = constraints->valid_sw_formats[i];
432 break;
433 }
434 442
435 // Start with at least four surfaces.443 frames->initial_pool_size = 1;
436 ctx->surface_count = 4;444 // Add per-codec number of surfaces used for storing reference frames.
437 // Add per-codec number of surfaces used for storing reference frames.445 switch (avctx->codec_id) {
438 switch (avctx->codec_id) {446 case AV_CODEC_ID_H264:
439 case AV_CODEC_ID_H264:447 case AV_CODEC_ID_HEVC:
440 case AV_CODEC_ID_HEVC:448 frames->initial_pool_size += 16;
441 ctx->surface_count += 16;449 break;
442 break;450 case AV_CODEC_ID_VP9:
443 case AV_CODEC_ID_VP9:451 frames->initial_pool_size += 8;
444 ctx->surface_count += 8;452 break;
445 break;453 case AV_CODEC_ID_VP8:
446 case AV_CODEC_ID_VP8:454 frames->initial_pool_size += 3;
447 ctx->surface_count += 3;455 break;
448 break;456 default:
449 default:457 frames->initial_pool_size += 2;
450 ctx->surface_count += 2;458 }
451 }459 }
452 // Add an additional surface per thread is frame threading is enabled.
453 if (avctx->active_thread_type & FF_THREAD_FRAME)
454 ctx->surface_count += avctx->thread_count;
455 460
456 av_hwframe_constraints_free(&constraints);461 av_hwframe_constraints_free(&constraints);
457 av_freep(&hwconfig);462 av_freep(&hwconfig);
@@ -461,14 +466,38 @@ static int vaapi_decode_make_config(AVCodecContext *avctx) · 3 unmodified lines
461fail:466fail:
462 av_hwframe_constraints_free(&constraints);467 av_hwframe_constraints_free(&constraints);
463 av_freep(&hwconfig);468 av_freep(&hwconfig);
464 if (ctx->va_config != VA_INVALID_ID) {469 if (*va_config != VA_INVALID_ID) {
465 vaDestroyConfig(ctx->hwctx->display, ctx->va_config);470 vaDestroyConfig(hwctx->display, *va_config);
466 ctx->va_config = VA_INVALID_ID;471 *va_config = VA_INVALID_ID;
467 }472 }
468 av_freep(&profile_list);473 av_freep(&profile_list);
469 return err;474 return err;
470}475}
471 476
477int ff_vaapi_common_frame_params(AVCodecContext *avctx,
478 AVBufferRef *hw_frames_ctx)
479{
480 AVHWFramesContext *hw_frames = (AVHWFramesContext *)hw_frames_ctx->data;
481 AVHWDeviceContext *device_ctx = hw_frames->device_ctx;
482 AVVAAPIDeviceContext *hwctx;
483 VAConfigID va_config = VA_INVALID_ID;
484 int err;
485
486 if (device_ctx->type != AV_HWDEVICE_TYPE_VAAPI)
487 return AVERROR(EINVAL);
488 hwctx = device_ctx->hwctx;
489
490 err = vaapi_decode_make_config(avctx, hw_frames->device_ref, &va_config,
491 hw_frames_ctx);
492 if (err)
493 return err;
494
495 if (va_config != VA_INVALID_ID)
496 vaDestroyConfig(hwctx->display, va_config);
497
498 return 0;
499}
500
472int ff_vaapi_decode_init(AVCodecContext *avctx)501int ff_vaapi_decode_init(AVCodecContext *avctx)
473{502{
474 VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;503 VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
@@ -505,36 +534,8 @@ int ff_vaapi_decode_init(AVCodecContext *avctx) · 30 unmodified lines
505 ctx->hwctx->driver_quirks =534 ctx->hwctx->driver_quirks =
506 AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS;535 AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS;
507 536
508 } else
509#endif
510 if (avctx->hw_frames_ctx) {
511 // This structure has a shorter lifetime than the enclosing
512 // AVCodecContext, so we inherit the references from there
513 // and do not need to make separate ones.
514
515 ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
516 ctx->hwfc = ctx->frames->hwctx;
517 ctx->device = ctx->frames->device_ctx;
518 ctx->hwctx = ctx->device->hwctx;
519
520 } else if (avctx->hw_device_ctx) {
521 ctx->device = (AVHWDeviceContext*)avctx->hw_device_ctx->data;
522 ctx->hwctx = ctx->device->hwctx;
523
524 if (ctx->device->type != AV_HWDEVICE_TYPE_VAAPI) {
525 av_log(avctx, AV_LOG_ERROR, "Device supplied for VAAPI "
526 "decoding must be a VAAPI device (not %d).\n",
527 ctx->device->type);
528 err = AVERROR(EINVAL);
529 goto fail;
530 }
531
532 } else {
533 av_log(avctx, AV_LOG_ERROR, "A hardware device or frames context "
534 "is required for VAAPI decoding.\n");
535 err = AVERROR(EINVAL);
536 goto fail;
537 }537 }
538#endif
538 539
539#if FF_API_STRUCT_VAAPI_CONTEXT540#if FF_API_STRUCT_VAAPI_CONTEXT
540 if (ctx->have_old_context) {541 if (ctx->have_old_context) {
@@ -546,34 +547,19 @@ int ff_vaapi_decode_init(AVCodecContext *avctx) · 5 unmodified lines
546 } else {547 } else {
547#endif548#endif
548 549
549 err = vaapi_decode_make_config(avctx);550 err = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_VAAPI);
550 if (err)551 if (err < 0)
551 goto fail;552 goto fail;
552 553
553 if (!avctx->hw_frames_ctx) {554 ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
554 avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx);555 ctx->hwfc = ctx->frames->hwctx;
555 if (!avctx->hw_frames_ctx) {556 ctx->device = ctx->frames->device_ctx;
556 err = AVERROR(ENOMEM);557 ctx->hwctx = ctx->device->hwctx;
557 goto fail;
558 }
559 ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
560
561 ctx->frames->format = AV_PIX_FMT_VAAPI;
562 ctx->frames->width = avctx->coded_width;
563 ctx->frames->height = avctx->coded_height;
564
565 ctx->frames->sw_format = ctx->surface_format;
566 ctx->frames->initial_pool_size = ctx->surface_count;
567 558
568 err = av_hwframe_ctx_init(avctx->hw_frames_ctx);559 err = vaapi_decode_make_config(avctx, ctx->frames->device_ref,
569 if (err < 0) {560 &ctx->va_config, avctx->hw_frames_ctx);
570 av_log(avctx, AV_LOG_ERROR, "Failed to initialise internal "561 if (err)
571 "frames context: %d.\n", err);562 goto fail;
572 goto fail;
573 }
574
575 ctx->hwfc = ctx->frames->hwctx;
576 }
577 563
578 vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,564 vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
579 avctx->coded_width, avctx->coded_height,565 avctx->coded_width, avctx->coded_height,
libavcodec/vaapi_decode.h+3−2
@@ -53,8 +53,6 @@ typedef struct VAAPIDecodePicture { · 52 unmodified lines
53} VAAPIDecodePicture;53} VAAPIDecodePicture;
54 54
55typedef struct VAAPIDecodeContext {55typedef struct VAAPIDecodeContext {
56 VAProfile va_profile;
57 VAEntrypoint va_entrypoint;
58 VAConfigID va_config;56 VAConfigID va_config;
59 VAContextID va_context;57 VAContextID va_context;
60 58
@@ -98,4 +96,7 @@ int ff_vaapi_decode_cancel(AVCodecContext *avctx, · 37 unmodified lines
98int ff_vaapi_decode_init(AVCodecContext *avctx);96int ff_vaapi_decode_init(AVCodecContext *avctx);
99int ff_vaapi_decode_uninit(AVCodecContext *avctx);97int ff_vaapi_decode_uninit(AVCodecContext *avctx);
100 98
99int ff_vaapi_common_frame_params(AVCodecContext *avctx,
100 AVBufferRef *hw_frames_ctx);
101
101#endif /* AVCODEC_VAAPI_DECODE_H */102#endif /* AVCODEC_VAAPI_DECODE_H */
libavcodec/vaapi_h264.c+1−0
@@ -399,6 +399,7 @@ AVHWAccel ff_h264_vaapi_hwaccel = { · 398 unmodified lines
399 .frame_priv_data_size = sizeof(VAAPIDecodePicture),399 .frame_priv_data_size = sizeof(VAAPIDecodePicture),
400 .init = &ff_vaapi_decode_init,400 .init = &ff_vaapi_decode_init,
401 .uninit = &ff_vaapi_decode_uninit,401 .uninit = &ff_vaapi_decode_uninit,
402 .frame_params = &ff_vaapi_common_frame_params,
402 .priv_data_size = sizeof(VAAPIDecodeContext),403 .priv_data_size = sizeof(VAAPIDecodeContext),
403 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,404 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
404};405};
libavcodec/vaapi_hevc.c+1−0
@@ -434,6 +434,7 @@ AVHWAccel ff_hevc_vaapi_hwaccel = { · 433 unmodified lines
434 .frame_priv_data_size = sizeof(VAAPIDecodePictureHEVC),434 .frame_priv_data_size = sizeof(VAAPIDecodePictureHEVC),
435 .init = ff_vaapi_decode_init,435 .init = ff_vaapi_decode_init,
436 .uninit = ff_vaapi_decode_uninit,436 .uninit = ff_vaapi_decode_uninit,
437 .frame_params = ff_vaapi_common_frame_params,
437 .priv_data_size = sizeof(VAAPIDecodeContext),438 .priv_data_size = sizeof(VAAPIDecodeContext),
438 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,439 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
439};440};
libavcodec/vaapi_mpeg2.c+1−0
@@ -183,6 +183,7 @@ AVHWAccel ff_mpeg2_vaapi_hwaccel = { · 182 unmodified lines
183 .frame_priv_data_size = sizeof(VAAPIDecodePicture),183 .frame_priv_data_size = sizeof(VAAPIDecodePicture),
184 .init = &ff_vaapi_decode_init,184 .init = &ff_vaapi_decode_init,
185 .uninit = &ff_vaapi_decode_uninit,185 .uninit = &ff_vaapi_decode_uninit,
186 .frame_params = &ff_vaapi_common_frame_params,
186 .priv_data_size = sizeof(VAAPIDecodeContext),187 .priv_data_size = sizeof(VAAPIDecodeContext),
187 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,188 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
188};189};
libavcodec/vaapi_mpeg4.c+2−0
@@ -189,6 +189,7 @@ AVHWAccel ff_mpeg4_vaapi_hwaccel = { · 188 unmodified lines
189 .frame_priv_data_size = sizeof(VAAPIDecodePicture),189 .frame_priv_data_size = sizeof(VAAPIDecodePicture),
190 .init = &ff_vaapi_decode_init,190 .init = &ff_vaapi_decode_init,
191 .uninit = &ff_vaapi_decode_uninit,191 .uninit = &ff_vaapi_decode_uninit,
192 .frame_params = &ff_vaapi_common_frame_params,
192 .priv_data_size = sizeof(VAAPIDecodeContext),193 .priv_data_size = sizeof(VAAPIDecodeContext),
193 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,194 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
194};195};
@@ -206,6 +207,7 @@ AVHWAccel ff_h263_vaapi_hwaccel = { · 11 unmodified lines
206 .frame_priv_data_size = sizeof(VAAPIDecodePicture),207 .frame_priv_data_size = sizeof(VAAPIDecodePicture),
207 .init = &ff_vaapi_decode_init,208 .init = &ff_vaapi_decode_init,
208 .uninit = &ff_vaapi_decode_uninit,209 .uninit = &ff_vaapi_decode_uninit,
210 .frame_params = &ff_vaapi_common_frame_params,
209 .priv_data_size = sizeof(VAAPIDecodeContext),211 .priv_data_size = sizeof(VAAPIDecodeContext),
210 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,212 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
211};213};
libavcodec/vaapi_vc1.c+2−0
@@ -399,6 +399,7 @@ AVHWAccel ff_wmv3_vaapi_hwaccel = { · 398 unmodified lines
399 .frame_priv_data_size = sizeof(VAAPIDecodePicture),399 .frame_priv_data_size = sizeof(VAAPIDecodePicture),
400 .init = &ff_vaapi_decode_init,400 .init = &ff_vaapi_decode_init,
401 .uninit = &ff_vaapi_decode_uninit,401 .uninit = &ff_vaapi_decode_uninit,
402 .frame_params = &ff_vaapi_common_frame_params,
402 .priv_data_size = sizeof(VAAPIDecodeContext),403 .priv_data_size = sizeof(VAAPIDecodeContext),
403 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,404 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
404};405};
@@ -415,6 +416,7 @@ AVHWAccel ff_vc1_vaapi_hwaccel = { · 10 unmodified lines
415 .frame_priv_data_size = sizeof(VAAPIDecodePicture),416 .frame_priv_data_size = sizeof(VAAPIDecodePicture),
416 .init = &ff_vaapi_decode_init,417 .init = &ff_vaapi_decode_init,
417 .uninit = &ff_vaapi_decode_uninit,418 .uninit = &ff_vaapi_decode_uninit,
419 .frame_params = &ff_vaapi_common_frame_params,
418 .priv_data_size = sizeof(VAAPIDecodeContext),420 .priv_data_size = sizeof(VAAPIDecodeContext),
419 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,421 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
420};422};
libavcodec/vaapi_vp9.c+1−0
@@ -179,6 +179,7 @@ AVHWAccel ff_vp9_vaapi_hwaccel = { · 178 unmodified lines
179 .frame_priv_data_size = sizeof(VAAPIDecodePicture),179 .frame_priv_data_size = sizeof(VAAPIDecodePicture),
180 .init = ff_vaapi_decode_init,180 .init = ff_vaapi_decode_init,
181 .uninit = ff_vaapi_decode_uninit,181 .uninit = ff_vaapi_decode_uninit,
182 .frame_params = ff_vaapi_common_frame_params,
182 .priv_data_size = sizeof(VAAPIDecodeContext),183 .priv_data_size = sizeof(VAAPIDecodeContext),
183 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,184 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
184};185};
libavcodec/vdpau.c+26−32
@@ -24,6 +24,7 @@ · 23 unmodified lines
24#include <limits.h>24#include <limits.h>
25 25
26#include "avcodec.h"26#include "avcodec.h"
27#include "decode.h"
27#include "internal.h"28#include "internal.h"
28#include "h264dec.h"29#include "h264dec.h"
29#include "vc1.h"30#include "vc1.h"
@@ -110,6 +111,25 @@ int av_vdpau_get_surface_parameters(AVCodecContext *avctx, · 80 unmodified lines
110 return 0;111 return 0;
111}112}
112 113
114int ff_vdpau_common_frame_params(AVCodecContext *avctx,
115 AVBufferRef *hw_frames_ctx)
116{
117 AVHWFramesContext *hw_frames = (AVHWFramesContext*)hw_frames_ctx->data;
118 VdpChromaType type;
119 uint32_t width;
120 uint32_t height;
121
122 if (av_vdpau_get_surface_parameters(avctx, &type, &width, &height))
123 return AVERROR(EINVAL);
124
125 hw_frames->format = AV_PIX_FMT_VDPAU;
126 hw_frames->sw_format = avctx->sw_pix_fmt;
127 hw_frames->width = width;
128 hw_frames->height = height;
129
130 return 0;
131}
132
113int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile,133int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile,
114 int level)134 int level)
115{135{
@@ -127,6 +147,7 @@ int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile, · 11 unmodified lines
127 VdpChromaType type;147 VdpChromaType type;
128 uint32_t width;148 uint32_t width;
129 uint32_t height;149 uint32_t height;
150 int ret;
130 151
131 vdctx->width = UINT32_MAX;152 vdctx->width = UINT32_MAX;
132 vdctx->height = UINT32_MAX;153 vdctx->height = UINT32_MAX;
@@ -154,41 +175,14 @@ int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile, · 21 unmodified lines
154 type != VDP_CHROMA_TYPE_420)175 type != VDP_CHROMA_TYPE_420)
155 return AVERROR(ENOSYS);176 return AVERROR(ENOSYS);
156 } else {177 } else {
157 AVHWFramesContext *frames_ctx = NULL;178 AVHWFramesContext *frames_ctx;
158 AVVDPAUDeviceContext *dev_ctx;179 AVVDPAUDeviceContext *dev_ctx;
159 180
160 // We assume the hw_frames_ctx always survives until ff_vdpau_common_uninit181 ret = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_VDPAU);
161 // is called. This holds true as the user is not allowed to touch182 if (ret < 0)
162 // hw_device_ctx, or hw_frames_ctx after get_format (and ff_get_format183 return ret;
163 // itself also uninits before unreffing hw_frames_ctx).
164 if (avctx->hw_frames_ctx) {
165 frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
166 } else if (avctx->hw_device_ctx) {
167 int ret;
168
169 avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx);
170 if (!avctx->hw_frames_ctx)
171 return AVERROR(ENOMEM);
172
173 frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
174 frames_ctx->format = AV_PIX_FMT_VDPAU;
175 frames_ctx->sw_format = avctx->sw_pix_fmt;
176 frames_ctx->width = avctx->coded_width;
177 frames_ctx->height = avctx->coded_height;
178
179 ret = av_hwframe_ctx_init(avctx->hw_frames_ctx);
180 if (ret < 0) {
181 av_buffer_unref(&avctx->hw_frames_ctx);
182 return ret;
183 }
184 }
185
186 if (!frames_ctx) {
187 av_log(avctx, AV_LOG_ERROR, "A hardware frames context is "
188 "required for VDPAU decoding.\n");
189 return AVERROR(EINVAL);
190 }
191 184
185 frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
192 dev_ctx = frames_ctx->device_ctx->hwctx;186 dev_ctx = frames_ctx->device_ctx->hwctx;
193 187
194 vdctx->device = dev_ctx->device;188 vdctx->device = dev_ctx->device;
libavcodec/vdpau_h264.c+1−0
@@ -273,6 +273,7 @@ AVHWAccel ff_h264_vdpau_hwaccel = { · 272 unmodified lines
273 .frame_priv_data_size = sizeof(struct vdpau_picture_context),273 .frame_priv_data_size = sizeof(struct vdpau_picture_context),
274 .init = vdpau_h264_init,274 .init = vdpau_h264_init,
275 .uninit = ff_vdpau_common_uninit,275 .uninit = ff_vdpau_common_uninit,
276 .frame_params = ff_vdpau_common_frame_params,
276 .priv_data_size = sizeof(VDPAUContext),277 .priv_data_size = sizeof(VDPAUContext),
277 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,278 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
278};279};
libavcodec/vdpau_hevc.c+1−0
@@ -424,6 +424,7 @@ AVHWAccel ff_hevc_vdpau_hwaccel = { · 423 unmodified lines
424 .frame_priv_data_size = sizeof(struct vdpau_picture_context),424 .frame_priv_data_size = sizeof(struct vdpau_picture_context),
425 .init = vdpau_hevc_init,425 .init = vdpau_hevc_init,
426 .uninit = ff_vdpau_common_uninit,426 .uninit = ff_vdpau_common_uninit,
427 .frame_params = ff_vdpau_common_frame_params,
427 .priv_data_size = sizeof(VDPAUContext),428 .priv_data_size = sizeof(VDPAUContext),
428 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,429 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
429};430};
libavcodec/vdpau_internal.h+2−0
@@ -119,5 +119,7 @@ int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame, · 118 unmodified lines
119int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx);119int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx);
120int ff_vdpau_add_buffer(struct vdpau_picture_context *pic, const uint8_t *buf,120int ff_vdpau_add_buffer(struct vdpau_picture_context *pic, const uint8_t *buf,
121 uint32_t buf_size);121 uint32_t buf_size);
122int ff_vdpau_common_frame_params(AVCodecContext *avctx,
123 AVBufferRef *hw_frames_ctx);
122 124
123#endif /* AVCODEC_VDPAU_INTERNAL_H */125#endif /* AVCODEC_VDPAU_INTERNAL_H */
libavcodec/vdpau_mpeg12.c+1−0
@@ -149,6 +149,7 @@ AVHWAccel ff_mpeg2_vdpau_hwaccel = { · 148 unmodified lines
149 .frame_priv_data_size = sizeof(struct vdpau_picture_context),149 .frame_priv_data_size = sizeof(struct vdpau_picture_context),
150 .init = vdpau_mpeg2_init,150 .init = vdpau_mpeg2_init,
151 .uninit = ff_vdpau_common_uninit,151 .uninit = ff_vdpau_common_uninit,
152 .frame_params = ff_vdpau_common_frame_params,
152 .priv_data_size = sizeof(VDPAUContext),153 .priv_data_size = sizeof(VDPAUContext),
153 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,154 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
154};155};
libavcodec/vdpau_mpeg4.c+1−0
@@ -121,6 +121,7 @@ AVHWAccel ff_mpeg4_vdpau_hwaccel = { · 120 unmodified lines
121 .frame_priv_data_size = sizeof(struct vdpau_picture_context),121 .frame_priv_data_size = sizeof(struct vdpau_picture_context),
122 .init = vdpau_mpeg4_init,122 .init = vdpau_mpeg4_init,
123 .uninit = ff_vdpau_common_uninit,123 .uninit = ff_vdpau_common_uninit,
124 .frame_params = ff_vdpau_common_frame_params,
124 .priv_data_size = sizeof(VDPAUContext),125 .priv_data_size = sizeof(VDPAUContext),
125 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,126 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
126};127};
libavcodec/vdpau_vc1.c+2−0
@@ -147,6 +147,7 @@ AVHWAccel ff_wmv3_vdpau_hwaccel = { · 146 unmodified lines
147 .frame_priv_data_size = sizeof(struct vdpau_picture_context),147 .frame_priv_data_size = sizeof(struct vdpau_picture_context),
148 .init = vdpau_vc1_init,148 .init = vdpau_vc1_init,
149 .uninit = ff_vdpau_common_uninit,149 .uninit = ff_vdpau_common_uninit,
150 .frame_params = ff_vdpau_common_frame_params,
150 .priv_data_size = sizeof(VDPAUContext),151 .priv_data_size = sizeof(VDPAUContext),
151 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,152 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
152};153};
@@ -163,6 +164,7 @@ AVHWAccel ff_vc1_vdpau_hwaccel = { · 10 unmodified lines
163 .frame_priv_data_size = sizeof(struct vdpau_picture_context),164 .frame_priv_data_size = sizeof(struct vdpau_picture_context),
164 .init = vdpau_vc1_init,165 .init = vdpau_vc1_init,
165 .uninit = ff_vdpau_common_uninit,166 .uninit = ff_vdpau_common_uninit,
167 .frame_params = ff_vdpau_common_frame_params,
166 .priv_data_size = sizeof(VDPAUContext),168 .priv_data_size = sizeof(VDPAUContext),
167 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,169 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
168};170};
libavcodec/version.h+1−1
@@ -28,7 +28,7 @@ · 27 unmodified lines
28#include "libavutil/version.h"28#include "libavutil/version.h"
29 29
30#define LIBAVCODEC_VERSION_MAJOR 5830#define LIBAVCODEC_VERSION_MAJOR 58
31#define LIBAVCODEC_VERSION_MINOR 231#define LIBAVCODEC_VERSION_MINOR 3
32#define LIBAVCODEC_VERSION_MICRO 10032#define LIBAVCODEC_VERSION_MICRO 100
33 33
34#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \34#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \

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