* commit 'b46a77f19ddc4b2b5fa3187835ceb602a5244e24': lavc: external hardware frame pool initialization Includes the fix from e724bdfffbd3c27aac53d1f32f20f105f37caef0
Unified · Split
| @@ -15,6 +15,9 @@ libavutil: 2017-10-21 · 14 unmodified lines | |||
| 15 | 15 | ||
| 16 | API changes, most recent first: | 16 | API changes, most recent first: |
| 17 | 17 | ||
| 18 | 2017-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 | ||
| 20 | 2017-09-28 - b6cf66ae1c - lavc 57.106.104 - avcodec.h | 23 | 2017-09-28 - b6cf66ae1c - lavc 57.106.104 - avcodec.h |
| @@ -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 have | 3548 | * 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 | */ |
| 4675 | int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt); | 4685 | int 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 | */ | ||
| 4784 | int 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 parsing | 4792 | * @defgroup lavc_parsing Frame parsing |
| @@ -1106,6 +1106,86 @@ static AVHWAccel *find_hwaccel(AVCodecContext *avctx, · 1105 unmodified lines | |||
| 1106 | return NULL; | 1106 | return NULL; |
| 1107 | } | 1107 | } |
| 1108 | 1108 | ||
| 1109 | int 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 | |||
| 1164 | int 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 | |||
| 1109 | static int setup_hwaccel(AVCodecContext *avctx, | 1189 | static int setup_hwaccel(AVCodecContext *avctx, |
| 1110 | const enum AVPixelFormat fmt, | 1190 | const enum AVPixelFormat fmt, |
| 1111 | const char *name) | 1191 | const char *name) |
| @@ -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 | ||
| 66 | void ff_decode_bsfs_uninit(AVCodecContext *avctx); | 70 | void 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 | */ | ||
| 77 | int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx, | ||
| 78 | enum AVHWDeviceType dev_type); | ||
| 79 | |||
| 68 | int ff_attach_decode_data(AVFrame *frame); | 80 | int ff_attach_decode_data(AVFrame *frame); |
| 69 | 81 | ||
| 70 | #endif /* AVCODEC_DECODE_H */ | 82 | #endif /* AVCODEC_DECODE_H */ |
| @@ -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 | #endif | 577 | #endif |
| 577 | } | 578 | } |
| 578 | 579 | ||
| 579 | // This must work before the decoder is created. | 580 | int ff_dxva2_common_frame_params(AVCodecContext *avctx, |
| 580 | // This somehow needs to be exported to the user. | 581 | AVBufferRef *hw_frames_ctx) |
| 581 | static 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 | else | 603 | 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 | #endif | 642 | #endif |
| 643 | |||
| 644 | return 0; | ||
| 636 | } | 645 | } |
| 637 | 646 | ||
| 638 | int ff_dxva2_decode_init(AVCodecContext *avctx) | 647 | int 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; |
| @@ -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 | }; |
| @@ -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 | }; |
| @@ -156,6 +156,9 @@ int ff_dxva2_decode_init(AVCodecContext *avctx); · 155 unmodified lines | |||
| 156 | 156 | ||
| 157 | int ff_dxva2_decode_uninit(AVCodecContext *avctx); | 157 | int ff_dxva2_decode_uninit(AVCodecContext *avctx); |
| 158 | 158 | ||
| 159 | int ff_dxva2_common_frame_params(AVCodecContext *avctx, | ||
| 160 | AVBufferRef *hw_frames_ctx); | ||
| 161 | |||
| 159 | int ff_dxva2_is_d3d11(const AVCodecContext *avctx); | 162 | int ff_dxva2_is_d3d11(const AVCodecContext *avctx); |
| 160 | 163 | ||
| 161 | #endif /* AVCODEC_DXVA2_INTERNAL_H */ | 164 | #endif /* AVCODEC_DXVA2_INTERNAL_H */ |
| @@ -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 | }; |
| @@ -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 | }; |
| @@ -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 | }; |
| @@ -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 MAP | 273 | #undef MAP |
| 273 | }; | 274 | }; |
| 274 | 275 | ||
| 275 | static 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 | */ | ||
| 280 | static 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 expected | 414 | if (frames_ref) { |
| 414 | // bit depth and subsampling. If none are found (this can happen | 415 | 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 | |||
| 461 | fail: | 466 | fail: |
| 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 | ||
| 477 | int 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 | |||
| 472 | int ff_vaapi_decode_init(AVCodecContext *avctx) | 501 | int 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_CONTEXT | 540 | #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 | #endif | 548 | #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, |
| @@ -53,8 +53,6 @@ typedef struct VAAPIDecodePicture { · 52 unmodified lines | |||
| 53 | } VAAPIDecodePicture; | 53 | } VAAPIDecodePicture; |
| 54 | 54 | ||
| 55 | typedef struct VAAPIDecodeContext { | 55 | typedef 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 | |||
| 98 | int ff_vaapi_decode_init(AVCodecContext *avctx); | 96 | int ff_vaapi_decode_init(AVCodecContext *avctx); |
| 99 | int ff_vaapi_decode_uninit(AVCodecContext *avctx); | 97 | int ff_vaapi_decode_uninit(AVCodecContext *avctx); |
| 100 | 98 | ||
| 99 | int 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 */ |
| @@ -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 | }; |
| @@ -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 | }; |
| @@ -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 | }; |
| @@ -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 | }; |
| @@ -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 | }; |
| @@ -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 | }; |
| @@ -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 | ||
| 114 | int 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 | |||
| 113 | int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile, | 133 | int 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_uninit | 181 | 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 touch | 182 | if (ret < 0) |
| 162 | // hw_device_ctx, or hw_frames_ctx after get_format (and ff_get_format | 183 | 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; |
| @@ -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 | }; |
| @@ -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 | }; |
| @@ -119,5 +119,7 @@ int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame, · 118 unmodified lines | |||
| 119 | int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx); | 119 | int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx); |
| 120 | int ff_vdpau_add_buffer(struct vdpau_picture_context *pic, const uint8_t *buf, | 120 | int ff_vdpau_add_buffer(struct vdpau_picture_context *pic, const uint8_t *buf, |
| 121 | uint32_t buf_size); | 121 | uint32_t buf_size); |
| 122 | int 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 */ |
| @@ -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 | }; |
| @@ -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 | }; |
| @@ -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 | }; |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | |||
| 28 | #include "libavutil/version.h" | 28 | #include "libavutil/version.h" |
| 29 | 29 | ||
| 30 | #define LIBAVCODEC_VERSION_MAJOR 58 | 30 | #define LIBAVCODEC_VERSION_MAJOR 58 |
| 31 | #define LIBAVCODEC_VERSION_MINOR 2 | 31 | #define LIBAVCODEC_VERSION_MINOR 3 |
| 32 | #define LIBAVCODEC_VERSION_MICRO 100 | 32 | #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, \ |