Browse code

lavc: external hardware frame pool initialization

This adds a new API, which allows the API user to query the required
AVHWFramesContext parameters. This also reduces code duplication across
the hwaccels by introducing ff_decode_get_hw_frames_ctx(), which uses
the new API function. It takes care of initializing the hw_frames_ctx
if needed, and does additional error handling and API usage checking.

Support for VDA and Cuvid missing.

Signed-off-by: Anton Khirnov <anton@khirnov.net>

wm4 authored on 2017/10/19 23:38:20
Showing 26 changed files
... ...
@@ -13,6 +13,9 @@ libavutil:     2017-03-23
13 13
 
14 14
 API changes, most recent first:
15 15
 
16
+2017-xx-xx - xxxxxxx - lavc 58.5.0 - avcodec.h
17
+  Add avcodec_get_hw_frames_parameters().
18
+
16 19
 2017-xx-xx - xxxxxxx - lavu 56.6.0 - pixdesc.h
17 20
   Add av_color_range_from_name(), av_color_primaries_from_name(),
18 21
   av_color_transfer_from_name(), av_color_space_from_name(), and
... ...
@@ -2990,6 +2990,16 @@ typedef struct AVHWAccel {
2990 2990
      * Internal hwaccel capabilities.
2991 2991
      */
2992 2992
     int caps_internal;
2993
+
2994
+    /**
2995
+     * Fill the given hw_frames context with current codec parameters. Called
2996
+     * from get_format. Refer to avcodec_get_hw_frames_parameters() for
2997
+     * details.
2998
+     *
2999
+     * This CAN be called before AVHWAccel.init is called, and you must assume
3000
+     * that avctx->hwaccel_priv_data is invalid.
3001
+     */
3002
+    int (*frame_params)(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx);
2993 3003
 } AVHWAccel;
2994 3004
 
2995 3005
 /**
... ...
@@ -3984,6 +3994,109 @@ int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame);
3984 3984
  */
3985 3985
 int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);
3986 3986
 
3987
+/**
3988
+ * Create and return a AVHWFramesContext with values adequate for hardware
3989
+ * decoding. This is meant to get called from the get_format callback, and is
3990
+ * a helper for preparing a AVHWFramesContext for AVCodecContext.hw_frames_ctx.
3991
+ * This API is for decoding with certain hardware acceleration modes/APIs only.
3992
+ *
3993
+ * The returned AVHWFramesContext is not initialized. The caller must do this
3994
+ * with av_hwframe_ctx_init().
3995
+ *
3996
+ * Calling this function is not a requirement, but makes it simpler to avoid
3997
+ * codec or hardware API specific details when manually allocating frames.
3998
+ *
3999
+ * Alternatively to this, an API user can set AVCodecContext.hw_device_ctx,
4000
+ * which sets up AVCodecContext.hw_frames_ctx fully automatically, and makes
4001
+ * it unnecessary to call this function or having to care about
4002
+ * AVHWFramesContext initialization at all.
4003
+ *
4004
+ * There are a number of requirements for calling this function:
4005
+ *
4006
+ * - It must be called from get_format with the same avctx parameter that was
4007
+ *   passed to get_format. Calling it outside of get_format is not allowed, and
4008
+ *   can trigger undefined behavior.
4009
+ * - The function is not always supported (see description of return values).
4010
+ *   Even if this function returns successfully, hwaccel initialization could
4011
+ *   fail later. (The degree to which implementations check whether the stream
4012
+ *   is actually supported varies. Some do this check only after the user's
4013
+ *   get_format callback returns.)
4014
+ * - The hw_pix_fmt must be one of the choices suggested by get_format. If the
4015
+ *   user decides to use a AVHWFramesContext prepared with this API function,
4016
+ *   the user must return the same hw_pix_fmt from get_format.
4017
+ * - The device_ref passed to this function must support the given hw_pix_fmt.
4018
+ * - After calling this API function, it is the user's responsibility to
4019
+ *   initialize the AVHWFramesContext (returned by the out_frames_ref parameter),
4020
+ *   and to set AVCodecContext.hw_frames_ctx to it. If done, this must be done
4021
+ *   before returning from get_format (this is implied by the normal
4022
+ *   AVCodecContext.hw_frames_ctx API rules).
4023
+ * - The AVHWFramesContext parameters may change every time time get_format is
4024
+ *   called. Also, AVCodecContext.hw_frames_ctx is reset before get_format. So
4025
+ *   you are inherently required to go through this process again on every
4026
+ *   get_format call.
4027
+ * - It is perfectly possible to call this function without actually using
4028
+ *   the resulting AVHWFramesContext. One use-case might be trying to reuse a
4029
+ *   previously initialized AVHWFramesContext, and calling this API function
4030
+ *   only to test whether the required frame parameters have changed.
4031
+ * - Fields that use dynamically allocated values of any kind must not be set
4032
+ *   by the user unless setting them is explicitly allowed by the documentation.
4033
+ *   If the user sets AVHWFramesContext.free and AVHWFramesContext.user_opaque,
4034
+ *   the new free callback must call the potentially set previous free callback.
4035
+ *   This API call may set any dynamically allocated fields, including the free
4036
+ *   callback.
4037
+ *
4038
+ * The function will set at least the following fields on AVHWFramesContext
4039
+ * (potentially more, depending on hwaccel API):
4040
+ *
4041
+ * - All fields set by av_hwframe_ctx_alloc().
4042
+ * - Set the format field to hw_pix_fmt.
4043
+ * - Set the sw_format field to the most suited and most versatile format. (An
4044
+ *   implication is that this will prefer generic formats over opaque formats
4045
+ *   with arbitrary restrictions, if possible.)
4046
+ * - Set the width/height fields to the coded frame size, rounded up to the
4047
+ *   API-specific minimum alignment.
4048
+ * - Only _if_ the hwaccel requires a pre-allocated pool: set the initial_pool_size
4049
+ *   field to the number of maximum reference surfaces possible with the codec,
4050
+ *   plus 1 surface for the user to work (meaning the user can safely reference
4051
+ *   at most 1 decoded surface at a time), plus additional buffering introduced
4052
+ *   by frame threading. If the hwaccel does not require pre-allocation, the
4053
+ *   field is left to 0, and the decoder will allocate new surfaces on demand
4054
+ *   during decoding.
4055
+ * - Possibly AVHWFramesContext.hwctx fields, depending on the underlying
4056
+ *   hardware API.
4057
+ *
4058
+ * Essentially, out_frames_ref returns the same as av_hwframe_ctx_alloc(), but
4059
+ * with basic frame parameters set.
4060
+ *
4061
+ * The function is stateless, and does not change the AVCodecContext or the
4062
+ * device_ref AVHWDeviceContext.
4063
+ *
4064
+ * @param avctx The context which is currently calling get_format, and which
4065
+ *              implicitly contains all state needed for filling the returned
4066
+ *              AVHWFramesContext properly.
4067
+ * @param device_ref A reference to the AVHWDeviceContext describing the device
4068
+ *                   which will be used by the hardware decoder.
4069
+ * @param hw_pix_fmt The hwaccel format you are going to return from get_format.
4070
+ * @param out_frames_ref On success, set to a reference to an _uninitialized_
4071
+ *                       AVHWFramesContext, created from the given device_ref.
4072
+ *                       Fields will be set to values required for decoding.
4073
+ *                       Not changed if an error is returned.
4074
+ * @return zero on success, a negative value on error. The following error codes
4075
+ *         have special semantics:
4076
+ *      AVERROR(ENOENT): the decoder does not support this functionality. Setup
4077
+ *                       is always manual, or it is a decoder which does not
4078
+ *                       support setting AVCodecContext.hw_frames_ctx at all,
4079
+ *                       or it is a software format.
4080
+ *      AVERROR(EINVAL): it is known that hardware decoding is not supported for
4081
+ *                       this configuration, or the device_ref is not supported
4082
+ *                       for the hwaccel referenced by hw_pix_fmt.
4083
+ */
4084
+int avcodec_get_hw_frames_parameters(AVCodecContext *avctx,
4085
+                                     AVBufferRef *device_ref,
4086
+                                     enum AVPixelFormat hw_pix_fmt,
4087
+                                     AVBufferRef **out_frames_ref);
4088
+
4089
+
3987 4090
 
3988 4091
 /**
3989 4092
  * @defgroup lavc_parsing Frame parsing
... ...
@@ -669,6 +669,88 @@ static AVHWAccel *find_hwaccel(enum AVCodecID codec_id,
669 669
     return NULL;
670 670
 }
671 671
 
672
+int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx,
673
+                                enum AVHWDeviceType dev_type)
674
+{
675
+    AVHWDeviceContext *device_ctx;
676
+    AVHWFramesContext *frames_ctx;
677
+    int ret;
678
+
679
+    if (!avctx->hwaccel)
680
+        return AVERROR(ENOSYS);
681
+
682
+    if (avctx->hw_frames_ctx)
683
+        return 0;
684
+    if (!avctx->hw_device_ctx) {
685
+        av_log(avctx, AV_LOG_ERROR, "A hardware frames or device context is "
686
+                "required for hardware accelerated decoding.\n");
687
+        return AVERROR(EINVAL);
688
+    }
689
+
690
+    device_ctx = (AVHWDeviceContext *)avctx->hw_device_ctx->data;
691
+    if (device_ctx->type != dev_type) {
692
+        av_log(avctx, AV_LOG_ERROR, "Device type %s expected for hardware "
693
+               "decoding, but got %s.\n", av_hwdevice_get_type_name(dev_type),
694
+               av_hwdevice_get_type_name(device_ctx->type));
695
+        return AVERROR(EINVAL);
696
+    }
697
+
698
+    ret = avcodec_get_hw_frames_parameters(avctx,
699
+                                           avctx->hw_device_ctx,
700
+                                           avctx->hwaccel->pix_fmt,
701
+                                           avctx->hw_frames_ctx);
702
+    if (ret < 0) {
703
+        av_buffer_unref(&avctx->hw_frames_ctx);
704
+        return ret;
705
+    }
706
+
707
+    frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
708
+
709
+
710
+    if (frames_ctx->initial_pool_size) {
711
+        // We guarantee 4 base work surfaces. The function above guarantees 1
712
+        // (the absolute minimum), so add the missing count.
713
+        frames_ctx->initial_pool_size += 3;
714
+
715
+        // Add an additional surface per thread is frame threading is enabled.
716
+        if (avctx->active_thread_type & FF_THREAD_FRAME)
717
+            frames_ctx->initial_pool_size += avctx->thread_count;
718
+    }
719
+
720
+    ret = av_hwframe_ctx_init(avctx->hw_frames_ctx);
721
+    if (ret < 0) {
722
+        av_buffer_unref(&avctx->hw_frames_ctx);
723
+        return ret;
724
+    }
725
+
726
+    return 0;
727
+}
728
+
729
+int avcodec_get_hw_frames_parameters(AVCodecContext *avctx,
730
+                                     AVBufferRef *device_ref,
731
+                                     enum AVPixelFormat hw_pix_fmt,
732
+                                     AVBufferRef **out_frames_ref)
733
+{
734
+    AVBufferRef *frames_ref = NULL;
735
+    AVHWAccel *hwa = find_hwaccel(avctx->codec_id, hw_pix_fmt);
736
+    int ret;
737
+
738
+    if (!hwa || !hwa->frame_params)
739
+        return AVERROR(ENOENT);
740
+
741
+    frames_ref = av_hwframe_ctx_alloc(device_ref);
742
+    if (!frames_ref)
743
+        return AVERROR(ENOMEM);
744
+
745
+    ret = hwa->frame_params(avctx, frames_ref);
746
+    if (ret >= 0) {
747
+        *out_frames_ref = frames_ref;
748
+    } else {
749
+        av_buffer_unref(&frames_ref);
750
+    }
751
+    return ret;
752
+}
753
+
672 754
 static int setup_hwaccel(AVCodecContext *avctx,
673 755
                          const enum AVPixelFormat fmt,
674 756
                          const char *name)
... ...
@@ -23,6 +23,7 @@
23 23
 
24 24
 #include "libavutil/buffer.h"
25 25
 #include "libavutil/frame.h"
26
+#include "libavutil/hwcontext.h"
26 27
 
27 28
 #include "avcodec.h"
28 29
 
... ...
@@ -70,4 +71,12 @@ int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt);
70 70
 
71 71
 void ff_decode_bsfs_uninit(AVCodecContext *avctx);
72 72
 
73
+/**
74
+ * Make sure avctx.hw_frames_ctx is set. If it's not set, the function will
75
+ * try to allocate it from hw_device_ctx. If that is not possible, an error
76
+ * message is printed, and an error code is returned.
77
+ */
78
+int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx,
79
+                                enum AVHWDeviceType dev_type);
80
+
73 81
 #endif /* AVCODEC_DECODE_H */
... ...
@@ -29,6 +29,7 @@
29 29
 #include "libavutil/time.h"
30 30
 
31 31
 #include "avcodec.h"
32
+#include "decode.h"
32 33
 #include "dxva2_internal.h"
33 34
 
34 35
 /* define all the GUIDs used directly here,
... ...
@@ -572,14 +573,20 @@ static void ff_dxva2_unlock(AVCodecContext *avctx)
572 572
 #endif
573 573
 }
574 574
 
575
-// This must work before the decoder is created.
576
-// This somehow needs to be exported to the user.
577
-static void dxva_adjust_hwframes(AVCodecContext *avctx, AVHWFramesContext *frames_ctx)
575
+int ff_dxva2_common_frame_params(AVCodecContext *avctx,
576
+                                 AVBufferRef *hw_frames_ctx)
578 577
 {
579
-    FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
578
+    AVHWFramesContext *frames_ctx = (AVHWFramesContext *)hw_frames_ctx->data;
579
+    AVHWDeviceContext *device_ctx = frames_ctx->device_ctx;
580 580
     int surface_alignment, num_surfaces;
581 581
 
582
-    frames_ctx->format = sctx->pix_fmt;
582
+    if (device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
583
+        frames_ctx->format = AV_PIX_FMT_DXVA2_VLD;
584
+    } else if (device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
585
+        frames_ctx->format = AV_PIX_FMT_D3D11;
586
+    } else {
587
+        return AVERROR(EINVAL);
588
+    }
583 589
 
584 590
     /* decoding MPEG-2 requires additional alignment on some Intel GPUs,
585 591
     but it causes issues for H.264 on certain AMD GPUs..... */
... ...
@@ -592,8 +599,8 @@ static void dxva_adjust_hwframes(AVCodecContext *avctx, AVHWFramesContext *frame
592 592
     else
593 593
         surface_alignment = 16;
594 594
 
595
-    /* 4 base work surfaces */
596
-    num_surfaces = 4;
595
+    /* 1 base work surface */
596
+    num_surfaces = 1;
597 597
 
598 598
     /* add surfaces based on number of possible refs */
599 599
     if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC)
... ...
@@ -627,12 +634,16 @@ static void dxva_adjust_hwframes(AVCodecContext *avctx, AVHWFramesContext *frame
627 627
         frames_hwctx->BindFlags |= D3D11_BIND_DECODER;
628 628
     }
629 629
 #endif
630
+
631
+    return 0;
630 632
 }
631 633
 
632 634
 int ff_dxva2_decode_init(AVCodecContext *avctx)
633 635
 {
634 636
     FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
635
-    AVHWFramesContext *frames_ctx = NULL;
637
+    AVHWFramesContext *frames_ctx;
638
+    enum AVHWDeviceType dev_type = avctx->hwaccel->pix_fmt == AV_PIX_FMT_DXVA2_VLD
639
+                            ? AV_HWDEVICE_TYPE_DXVA2 : AV_HWDEVICE_TYPE_D3D11VA;
636 640
     int ret = 0;
637 641
 
638 642
     // Old API.
... ...
@@ -642,32 +653,14 @@ int ff_dxva2_decode_init(AVCodecContext *avctx)
642 642
     // (avctx->pix_fmt is not updated yet at this point)
643 643
     sctx->pix_fmt = avctx->hwaccel->pix_fmt;
644 644
 
645
-    if (!avctx->hw_frames_ctx && !avctx->hw_device_ctx) {
646
-        av_log(avctx, AV_LOG_ERROR, "Either a hw_frames_ctx or a hw_device_ctx needs to be set for hardware decoding.\n");
647
-        return AVERROR(EINVAL);
648
-    }
649
-
650
-    if (avctx->hw_frames_ctx) {
651
-        frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
652
-    } else {
653
-        avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx);
654
-        if (!avctx->hw_frames_ctx)
655
-            return AVERROR(ENOMEM);
656
-
657
-        frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
658
-
659
-        dxva_adjust_hwframes(avctx, frames_ctx);
660
-
661
-        ret = av_hwframe_ctx_init(avctx->hw_frames_ctx);
662
-        if (ret < 0)
663
-            goto fail;
664
-    }
645
+    ret = ff_decode_get_hw_frames_ctx(avctx, dev_type);
646
+    if (ret < 0)
647
+        return ret;
665 648
 
649
+    frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
666 650
     sctx->device_ctx = frames_ctx->device_ctx;
667 651
 
668
-    if (frames_ctx->format != sctx->pix_fmt ||
669
-        !((sctx->pix_fmt == AV_PIX_FMT_D3D11 && CONFIG_D3D11VA) ||
670
-          (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && CONFIG_DXVA2))) {
652
+    if (frames_ctx->format != sctx->pix_fmt) {
671 653
         av_log(avctx, AV_LOG_ERROR, "Invalid pixfmt for hwaccel!\n");
672 654
         ret = AVERROR(EINVAL);
673 655
         goto fail;
... ...
@@ -523,6 +523,7 @@ AVHWAccel ff_h264_dxva2_hwaccel = {
523 523
     .start_frame    = dxva2_h264_start_frame,
524 524
     .decode_slice   = dxva2_h264_decode_slice,
525 525
     .end_frame      = dxva2_h264_end_frame,
526
+    .frame_params   = ff_dxva2_common_frame_params,
526 527
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
527 528
     .priv_data_size = sizeof(FFDXVASharedContext),
528 529
 };
... ...
@@ -539,6 +540,7 @@ AVHWAccel ff_h264_d3d11va_hwaccel = {
539 539
     .start_frame    = dxva2_h264_start_frame,
540 540
     .decode_slice   = dxva2_h264_decode_slice,
541 541
     .end_frame      = dxva2_h264_end_frame,
542
+    .frame_params   = ff_dxva2_common_frame_params,
542 543
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
543 544
     .priv_data_size = sizeof(FFDXVASharedContext),
544 545
 };
... ...
@@ -555,6 +557,7 @@ AVHWAccel ff_h264_d3d11va2_hwaccel = {
555 555
     .start_frame    = dxva2_h264_start_frame,
556 556
     .decode_slice   = dxva2_h264_decode_slice,
557 557
     .end_frame      = dxva2_h264_end_frame,
558
+    .frame_params   = ff_dxva2_common_frame_params,
558 559
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
559 560
     .priv_data_size = sizeof(FFDXVASharedContext),
560 561
 };
... ...
@@ -432,6 +432,7 @@ AVHWAccel ff_hevc_dxva2_hwaccel = {
432 432
     .start_frame    = dxva2_hevc_start_frame,
433 433
     .decode_slice   = dxva2_hevc_decode_slice,
434 434
     .end_frame      = dxva2_hevc_end_frame,
435
+    .frame_params   = ff_dxva2_common_frame_params,
435 436
     .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
436 437
     .priv_data_size = sizeof(FFDXVASharedContext),
437 438
 };
... ...
@@ -448,6 +449,7 @@ AVHWAccel ff_hevc_d3d11va_hwaccel = {
448 448
     .start_frame    = dxva2_hevc_start_frame,
449 449
     .decode_slice   = dxva2_hevc_decode_slice,
450 450
     .end_frame      = dxva2_hevc_end_frame,
451
+    .frame_params   = ff_dxva2_common_frame_params,
451 452
     .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
452 453
     .priv_data_size = sizeof(FFDXVASharedContext),
453 454
 };
... ...
@@ -464,6 +466,7 @@ AVHWAccel ff_hevc_d3d11va2_hwaccel = {
464 464
     .start_frame    = dxva2_hevc_start_frame,
465 465
     .decode_slice   = dxva2_hevc_decode_slice,
466 466
     .end_frame      = dxva2_hevc_end_frame,
467
+    .frame_params   = ff_dxva2_common_frame_params,
467 468
     .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
468 469
     .priv_data_size = sizeof(FFDXVASharedContext),
469 470
 };
... ...
@@ -156,6 +156,9 @@ int ff_dxva2_decode_init(AVCodecContext *avctx);
156 156
 
157 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 162
 int ff_dxva2_is_d3d11(const AVCodecContext *avctx);
160 163
 
161 164
 #endif /* AVCODEC_DXVA2_INTERNAL_H */
... ...
@@ -328,6 +328,7 @@ AVHWAccel ff_mpeg2_dxva2_hwaccel = {
328 328
     .start_frame    = dxva2_mpeg2_start_frame,
329 329
     .decode_slice   = dxva2_mpeg2_decode_slice,
330 330
     .end_frame      = dxva2_mpeg2_end_frame,
331
+    .frame_params   = ff_dxva2_common_frame_params,
331 332
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
332 333
     .priv_data_size = sizeof(FFDXVASharedContext),
333 334
 };
... ...
@@ -344,6 +345,7 @@ AVHWAccel ff_mpeg2_d3d11va_hwaccel = {
344 344
     .start_frame    = dxva2_mpeg2_start_frame,
345 345
     .decode_slice   = dxva2_mpeg2_decode_slice,
346 346
     .end_frame      = dxva2_mpeg2_end_frame,
347
+    .frame_params   = ff_dxva2_common_frame_params,
347 348
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
348 349
     .priv_data_size = sizeof(FFDXVASharedContext),
349 350
 };
... ...
@@ -360,6 +362,7 @@ AVHWAccel ff_mpeg2_d3d11va2_hwaccel = {
360 360
     .start_frame    = dxva2_mpeg2_start_frame,
361 361
     .decode_slice   = dxva2_mpeg2_decode_slice,
362 362
     .end_frame      = dxva2_mpeg2_end_frame,
363
+    .frame_params   = ff_dxva2_common_frame_params,
363 364
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
364 365
     .priv_data_size = sizeof(FFDXVASharedContext),
365 366
 };
... ...
@@ -328,6 +328,7 @@ AVHWAccel ff_wmv3_dxva2_hwaccel = {
328 328
     .start_frame    = dxva2_vc1_start_frame,
329 329
     .decode_slice   = dxva2_vc1_decode_slice,
330 330
     .end_frame      = dxva2_vc1_end_frame,
331
+    .frame_params   = ff_dxva2_common_frame_params,
331 332
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
332 333
     .priv_data_size = sizeof(FFDXVASharedContext),
333 334
 };
... ...
@@ -344,6 +345,7 @@ AVHWAccel ff_vc1_dxva2_hwaccel = {
344 344
     .start_frame    = dxva2_vc1_start_frame,
345 345
     .decode_slice   = dxva2_vc1_decode_slice,
346 346
     .end_frame      = dxva2_vc1_end_frame,
347
+    .frame_params   = ff_dxva2_common_frame_params,
347 348
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
348 349
     .priv_data_size = sizeof(FFDXVASharedContext),
349 350
 };
... ...
@@ -360,6 +362,7 @@ AVHWAccel ff_wmv3_d3d11va_hwaccel = {
360 360
     .start_frame    = dxva2_vc1_start_frame,
361 361
     .decode_slice   = dxva2_vc1_decode_slice,
362 362
     .end_frame      = dxva2_vc1_end_frame,
363
+    .frame_params   = ff_dxva2_common_frame_params,
363 364
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
364 365
     .priv_data_size = sizeof(FFDXVASharedContext),
365 366
 };
... ...
@@ -376,6 +379,7 @@ AVHWAccel ff_wmv3_d3d11va2_hwaccel = {
376 376
     .start_frame    = dxva2_vc1_start_frame,
377 377
     .decode_slice   = dxva2_vc1_decode_slice,
378 378
     .end_frame      = dxva2_vc1_end_frame,
379
+    .frame_params   = ff_dxva2_common_frame_params,
379 380
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
380 381
     .priv_data_size = sizeof(FFDXVASharedContext),
381 382
 };
... ...
@@ -392,6 +396,7 @@ AVHWAccel ff_vc1_d3d11va_hwaccel = {
392 392
     .start_frame    = dxva2_vc1_start_frame,
393 393
     .decode_slice   = dxva2_vc1_decode_slice,
394 394
     .end_frame      = dxva2_vc1_end_frame,
395
+    .frame_params   = ff_dxva2_common_frame_params,
395 396
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
396 397
     .priv_data_size = sizeof(FFDXVASharedContext),
397 398
 };
... ...
@@ -21,6 +21,7 @@
21 21
 #include "libavutil/pixdesc.h"
22 22
 
23 23
 #include "avcodec.h"
24
+#include "decode.h"
24 25
 #include "internal.h"
25 26
 #include "vaapi_decode.h"
26 27
 
... ...
@@ -270,10 +271,15 @@ static const struct {
270 270
 #undef MAP
271 271
 };
272 272
 
273
-static int vaapi_decode_make_config(AVCodecContext *avctx)
273
+/*
274
+ * Set *va_config and the frames_ref fields from the current codec parameters
275
+ * in avctx.
276
+ */
277
+static int vaapi_decode_make_config(AVCodecContext *avctx,
278
+                                    AVBufferRef *device_ref,
279
+                                    VAConfigID *va_config,
280
+                                    AVBufferRef *frames_ref)
274 281
 {
275
-    VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
276
-
277 282
     AVVAAPIHWConfig       *hwconfig    = NULL;
278 283
     AVHWFramesConstraints *constraints = NULL;
279 284
     VAStatus vas;
... ...
@@ -283,13 +289,16 @@ static int vaapi_decode_make_config(AVCodecContext *avctx)
283 283
     int profile_count, exact_match, alt_profile;
284 284
     const AVPixFmtDescriptor *sw_desc, *desc;
285 285
 
286
+    AVHWDeviceContext    *device = (AVHWDeviceContext*)device_ref->data;
287
+    AVVAAPIDeviceContext *hwctx = device->hwctx;
288
+
286 289
     codec_desc = avcodec_descriptor_get(avctx->codec_id);
287 290
     if (!codec_desc) {
288 291
         err = AVERROR(EINVAL);
289 292
         goto fail;
290 293
     }
291 294
 
292
-    profile_count = vaMaxNumProfiles(ctx->hwctx->display);
295
+    profile_count = vaMaxNumProfiles(hwctx->display);
293 296
     profile_list  = av_malloc_array(profile_count,
294 297
                                     sizeof(VAProfile));
295 298
     if (!profile_list) {
... ...
@@ -297,7 +306,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx)
297 297
         goto fail;
298 298
     }
299 299
 
300
-    vas = vaQueryConfigProfiles(ctx->hwctx->display,
300
+    vas = vaQueryConfigProfiles(hwctx->display,
301 301
                                 profile_list, &profile_count);
302 302
     if (vas != VA_STATUS_SUCCESS) {
303 303
         av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: "
... ...
@@ -355,12 +364,9 @@ static int vaapi_decode_make_config(AVCodecContext *avctx)
355 355
         }
356 356
     }
357 357
 
358
-    ctx->va_profile    = profile;
359
-    ctx->va_entrypoint = VAEntrypointVLD;
360
-
361
-    vas = vaCreateConfig(ctx->hwctx->display, ctx->va_profile,
362
-                         ctx->va_entrypoint, NULL, 0,
363
-                         &ctx->va_config);
358
+    vas = vaCreateConfig(hwctx->display, profile,
359
+                         VAEntrypointVLD, NULL, 0,
360
+                         va_config);
364 361
     if (vas != VA_STATUS_SUCCESS) {
365 362
         av_log(avctx, AV_LOG_ERROR, "Failed to create decode "
366 363
                "configuration: %d (%s).\n", vas, vaErrorStr(vas));
... ...
@@ -368,20 +374,15 @@ static int vaapi_decode_make_config(AVCodecContext *avctx)
368 368
         goto fail;
369 369
     }
370 370
 
371
-    hwconfig = av_hwdevice_hwconfig_alloc(avctx->hw_device_ctx ?
372
-                                          avctx->hw_device_ctx :
373
-                                          ctx->frames->device_ref);
371
+    hwconfig = av_hwdevice_hwconfig_alloc(device_ref);
374 372
     if (!hwconfig) {
375 373
         err = AVERROR(ENOMEM);
376 374
         goto fail;
377 375
     }
378
-    hwconfig->config_id = ctx->va_config;
376
+    hwconfig->config_id = *va_config;
379 377
 
380 378
     constraints =
381
-        av_hwdevice_get_hwframe_constraints(avctx->hw_device_ctx ?
382
-                                            avctx->hw_device_ctx :
383
-                                            ctx->frames->device_ref,
384
-                                            hwconfig);
379
+        av_hwdevice_get_hwframe_constraints(device_ref, hwconfig);
385 380
     if (!constraints) {
386 381
         err = AVERROR(ENOMEM);
387 382
         goto fail;
... ...
@@ -407,48 +408,52 @@ static int vaapi_decode_make_config(AVCodecContext *avctx)
407 407
         goto fail;
408 408
     }
409 409
 
410
-    // Find the first format in the list which matches the expected
411
-    // bit depth and subsampling.  If none are found (this can happen
412
-    // when 10-bit streams are decoded to 8-bit surfaces, for example)
413
-    // then just take the first format on the list.
414
-    ctx->surface_format = constraints->valid_sw_formats[0];
415
-    sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
416
-    for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
417
-        desc = av_pix_fmt_desc_get(constraints->valid_sw_formats[i]);
418
-        if (desc->nb_components != sw_desc->nb_components ||
419
-            desc->log2_chroma_w != sw_desc->log2_chroma_w ||
420
-            desc->log2_chroma_h != sw_desc->log2_chroma_h)
421
-            continue;
422
-        for (j = 0; j < desc->nb_components; j++) {
423
-            if (desc->comp[j].depth != sw_desc->comp[j].depth)
424
-                break;
410
+    if (frames_ref) {
411
+        AVHWFramesContext *frames = (AVHWFramesContext *)frames_ref->data;
412
+
413
+        frames->format = AV_PIX_FMT_VAAPI;
414
+        frames->width = avctx->coded_width;
415
+        frames->height = avctx->coded_height;
416
+
417
+        // Find the first format in the list which matches the expected
418
+        // bit depth and subsampling.  If none are found (this can happen
419
+        // when 10-bit streams are decoded to 8-bit surfaces, for example)
420
+        // then just take the first format on the list.
421
+        frames->sw_format = constraints->valid_sw_formats[0];
422
+        sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
423
+        for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
424
+            desc = av_pix_fmt_desc_get(constraints->valid_sw_formats[i]);
425
+            if (desc->nb_components != sw_desc->nb_components ||
426
+                desc->log2_chroma_w != sw_desc->log2_chroma_w ||
427
+                desc->log2_chroma_h != sw_desc->log2_chroma_h)
428
+                continue;
429
+            for (j = 0; j < desc->nb_components; j++) {
430
+                if (desc->comp[j].depth != sw_desc->comp[j].depth)
431
+                    break;
432
+            }
433
+            if (j < desc->nb_components)
434
+                continue;
435
+            frames->sw_format = constraints->valid_sw_formats[i];
436
+            break;
425 437
         }
426
-        if (j < desc->nb_components)
427
-            continue;
428
-        ctx->surface_format = constraints->valid_sw_formats[i];
429
-        break;
430
-    }
431 438
 
432
-    // Start with at least four surfaces.
433
-    ctx->surface_count = 4;
434
-    // Add per-codec number of surfaces used for storing reference frames.
435
-    switch (avctx->codec_id) {
436
-    case AV_CODEC_ID_H264:
437
-    case AV_CODEC_ID_HEVC:
438
-        ctx->surface_count += 16;
439
-        break;
440
-    case AV_CODEC_ID_VP9:
441
-        ctx->surface_count += 8;
442
-        break;
443
-    case AV_CODEC_ID_VP8:
444
-        ctx->surface_count += 3;
445
-        break;
446
-    default:
447
-        ctx->surface_count += 2;
439
+        frames->initial_pool_size = 1;
440
+        // Add per-codec number of surfaces used for storing reference frames.
441
+        switch (avctx->codec_id) {
442
+        case AV_CODEC_ID_H264:
443
+        case AV_CODEC_ID_HEVC:
444
+            frames->initial_pool_size += 16;
445
+            break;
446
+        case AV_CODEC_ID_VP9:
447
+            frames->initial_pool_size += 8;
448
+            break;
449
+        case AV_CODEC_ID_VP8:
450
+            frames->initial_pool_size += 3;
451
+            break;
452
+        default:
453
+            frames->initial_pool_size += 2;
454
+        }
448 455
     }
449
-    // Add an additional surface per thread is frame threading is enabled.
450
-    if (avctx->active_thread_type & FF_THREAD_FRAME)
451
-        ctx->surface_count += avctx->thread_count;
452 456
 
453 457
     av_hwframe_constraints_free(&constraints);
454 458
     av_freep(&hwconfig);
... ...
@@ -458,14 +463,38 @@ static int vaapi_decode_make_config(AVCodecContext *avctx)
458 458
 fail:
459 459
     av_hwframe_constraints_free(&constraints);
460 460
     av_freep(&hwconfig);
461
-    if (ctx->va_config != VA_INVALID_ID) {
462
-        vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
463
-        ctx->va_config = VA_INVALID_ID;
461
+    if (*va_config != VA_INVALID_ID) {
462
+        vaDestroyConfig(hwctx->display, *va_config);
463
+        *va_config = VA_INVALID_ID;
464 464
     }
465 465
     av_freep(&profile_list);
466 466
     return err;
467 467
 }
468 468
 
469
+int ff_vaapi_common_frame_params(AVCodecContext *avctx,
470
+                                 AVBufferRef *hw_frames_ctx)
471
+{
472
+    AVHWFramesContext *hw_frames = (AVHWFramesContext *)hw_frames_ctx->data;
473
+    AVHWDeviceContext *device_ctx = hw_frames->device_ctx;
474
+    AVVAAPIDeviceContext *hwctx;
475
+    VAConfigID va_config = VA_INVALID_ID;
476
+    int err;
477
+
478
+    if (device_ctx->type != AV_HWDEVICE_TYPE_VAAPI)
479
+        return AVERROR(EINVAL);
480
+    hwctx = device_ctx->hwctx;
481
+
482
+    err = vaapi_decode_make_config(avctx, hw_frames->device_ref, &va_config,
483
+                                   hw_frames_ctx);
484
+    if (err)
485
+        return err;
486
+
487
+    if (va_config != VA_INVALID_ID)
488
+        vaDestroyConfig(hwctx->display, va_config);
489
+
490
+    return 0;
491
+}
492
+
469 493
 int ff_vaapi_decode_init(AVCodecContext *avctx)
470 494
 {
471 495
     VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
... ...
@@ -502,36 +531,8 @@ int ff_vaapi_decode_init(AVCodecContext *avctx)
502 502
         ctx->hwctx->driver_quirks =
503 503
             AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS;
504 504
 
505
-    } else
506
-#endif
507
-    if (avctx->hw_frames_ctx) {
508
-        // This structure has a shorter lifetime than the enclosing
509
-        // AVCodecContext, so we inherit the references from there
510
-        // and do not need to make separate ones.
511
-
512
-        ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
513
-        ctx->hwfc   = ctx->frames->hwctx;
514
-        ctx->device = ctx->frames->device_ctx;
515
-        ctx->hwctx  = ctx->device->hwctx;
516
-
517
-    } else if (avctx->hw_device_ctx) {
518
-        ctx->device = (AVHWDeviceContext*)avctx->hw_device_ctx->data;
519
-        ctx->hwctx  = ctx->device->hwctx;
520
-
521
-        if (ctx->device->type != AV_HWDEVICE_TYPE_VAAPI) {
522
-            av_log(avctx, AV_LOG_ERROR, "Device supplied for VAAPI "
523
-                   "decoding must be a VAAPI device (not %d).\n",
524
-                   ctx->device->type);
525
-            err = AVERROR(EINVAL);
526
-            goto fail;
527
-        }
528
-
529
-    } else {
530
-        av_log(avctx, AV_LOG_ERROR, "A hardware device or frames context "
531
-               "is required for VAAPI decoding.\n");
532
-        err = AVERROR(EINVAL);
533
-        goto fail;
534 505
     }
506
+#endif
535 507
 
536 508
 #if FF_API_VAAPI_CONTEXT
537 509
     if (ctx->have_old_context) {
... ...
@@ -543,34 +544,19 @@ int ff_vaapi_decode_init(AVCodecContext *avctx)
543 543
     } else {
544 544
 #endif
545 545
 
546
-    err = vaapi_decode_make_config(avctx);
547
-    if (err)
546
+    err = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_VAAPI);
547
+    if (err < 0)
548 548
         goto fail;
549 549
 
550
-    if (!avctx->hw_frames_ctx) {
551
-        avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx);
552
-        if (!avctx->hw_frames_ctx) {
553
-            err = AVERROR(ENOMEM);
554
-            goto fail;
555
-        }
556
-        ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
557
-
558
-        ctx->frames->format = AV_PIX_FMT_VAAPI;
559
-        ctx->frames->width  = avctx->coded_width;
560
-        ctx->frames->height = avctx->coded_height;
561
-
562
-        ctx->frames->sw_format         = ctx->surface_format;
563
-        ctx->frames->initial_pool_size = ctx->surface_count;
550
+    ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
551
+    ctx->hwfc   = ctx->frames->hwctx;
552
+    ctx->device = ctx->frames->device_ctx;
553
+    ctx->hwctx  = ctx->device->hwctx;
564 554
 
565
-        err = av_hwframe_ctx_init(avctx->hw_frames_ctx);
566
-        if (err < 0) {
567
-            av_log(avctx, AV_LOG_ERROR, "Failed to initialise internal "
568
-                   "frames context: %d.\n", err);
569
-            goto fail;
570
-        }
571
-
572
-        ctx->hwfc = ctx->frames->hwctx;
573
-    }
555
+    err = vaapi_decode_make_config(avctx, ctx->frames->device_ref,
556
+                                   &ctx->va_config, avctx->hw_frames_ctx);
557
+    if (err)
558
+        goto fail;
574 559
 
575 560
     vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
576 561
                           avctx->coded_width, avctx->coded_height,
... ...
@@ -53,8 +53,6 @@ typedef struct VAAPIDecodePicture {
53 53
 } VAAPIDecodePicture;
54 54
 
55 55
 typedef struct VAAPIDecodeContext {
56
-    VAProfile             va_profile;
57
-    VAEntrypoint          va_entrypoint;
58 56
     VAConfigID            va_config;
59 57
     VAContextID           va_context;
60 58
 
... ...
@@ -96,4 +94,7 @@ int ff_vaapi_decode_cancel(AVCodecContext *avctx,
96 96
 int ff_vaapi_decode_init(AVCodecContext *avctx);
97 97
 int ff_vaapi_decode_uninit(AVCodecContext *avctx);
98 98
 
99
+int ff_vaapi_common_frame_params(AVCodecContext *avctx,
100
+                                 AVBufferRef *hw_frames_ctx);
101
+
99 102
 #endif /* AVCODEC_VAAPI_DECODE_H */
... ...
@@ -399,6 +399,7 @@ AVHWAccel ff_h264_vaapi_hwaccel = {
399 399
     .frame_priv_data_size = sizeof(VAAPIDecodePicture),
400 400
     .init                 = &ff_vaapi_decode_init,
401 401
     .uninit               = &ff_vaapi_decode_uninit,
402
+    .frame_params         = &ff_vaapi_common_frame_params,
402 403
     .priv_data_size       = sizeof(VAAPIDecodeContext),
403 404
     .caps_internal        = HWACCEL_CAP_ASYNC_SAFE,
404 405
 };
... ...
@@ -434,6 +434,7 @@ AVHWAccel ff_hevc_vaapi_hwaccel = {
434 434
     .frame_priv_data_size = sizeof(VAAPIDecodePictureHEVC),
435 435
     .init                 = ff_vaapi_decode_init,
436 436
     .uninit               = ff_vaapi_decode_uninit,
437
+    .frame_params         = ff_vaapi_common_frame_params,
437 438
     .priv_data_size       = sizeof(VAAPIDecodeContext),
438 439
     .caps_internal        = HWACCEL_CAP_ASYNC_SAFE,
439 440
 };
... ...
@@ -184,6 +184,7 @@ AVHWAccel ff_mpeg2_vaapi_hwaccel = {
184 184
     .frame_priv_data_size = sizeof(VAAPIDecodePicture),
185 185
     .init                 = &ff_vaapi_decode_init,
186 186
     .uninit               = &ff_vaapi_decode_uninit,
187
+    .frame_params         = &ff_vaapi_common_frame_params,
187 188
     .priv_data_size       = sizeof(VAAPIDecodeContext),
188 189
     .caps_internal        = HWACCEL_CAP_ASYNC_SAFE,
189 190
 };
... ...
@@ -200,6 +200,7 @@ AVHWAccel ff_mpeg4_vaapi_hwaccel = {
200 200
     .frame_priv_data_size = sizeof(VAAPIDecodePicture),
201 201
     .init                 = &ff_vaapi_decode_init,
202 202
     .uninit               = &ff_vaapi_decode_uninit,
203
+    .frame_params         = &ff_vaapi_common_frame_params,
203 204
     .priv_data_size       = sizeof(VAAPIDecodeContext),
204 205
     .caps_internal        = HWACCEL_CAP_ASYNC_SAFE,
205 206
 };
... ...
@@ -217,6 +218,7 @@ AVHWAccel ff_h263_vaapi_hwaccel = {
217 217
     .frame_priv_data_size = sizeof(VAAPIDecodePicture),
218 218
     .init                 = &ff_vaapi_decode_init,
219 219
     .uninit               = &ff_vaapi_decode_uninit,
220
+    .frame_params         = &ff_vaapi_common_frame_params,
220 221
     .priv_data_size       = sizeof(VAAPIDecodeContext),
221 222
     .caps_internal        = HWACCEL_CAP_ASYNC_SAFE,
222 223
 };
... ...
@@ -399,6 +399,7 @@ AVHWAccel ff_wmv3_vaapi_hwaccel = {
399 399
     .frame_priv_data_size = sizeof(VAAPIDecodePicture),
400 400
     .init                 = &ff_vaapi_decode_init,
401 401
     .uninit               = &ff_vaapi_decode_uninit,
402
+    .frame_params         = &ff_vaapi_common_frame_params,
402 403
     .priv_data_size       = sizeof(VAAPIDecodeContext),
403 404
     .caps_internal        = HWACCEL_CAP_ASYNC_SAFE,
404 405
 };
... ...
@@ -415,6 +416,7 @@ AVHWAccel ff_vc1_vaapi_hwaccel = {
415 415
     .frame_priv_data_size = sizeof(VAAPIDecodePicture),
416 416
     .init                 = &ff_vaapi_decode_init,
417 417
     .uninit               = &ff_vaapi_decode_uninit,
418
+    .frame_params         = &ff_vaapi_common_frame_params,
418 419
     .priv_data_size       = sizeof(VAAPIDecodeContext),
419 420
     .caps_internal        = HWACCEL_CAP_ASYNC_SAFE,
420 421
 };
... ...
@@ -232,5 +232,6 @@ AVHWAccel ff_vp8_vaapi_hwaccel = {
232 232
     .init                 = &ff_vaapi_decode_init,
233 233
     .uninit               = &ff_vaapi_decode_uninit,
234 234
     .priv_data_size       = sizeof(VAAPIDecodeContext),
235
+    .frame_params         = &ff_vaapi_common_frame_params,
235 236
     .caps_internal        = HWACCEL_CAP_ASYNC_SAFE,
236 237
 };
... ...
@@ -24,6 +24,7 @@
24 24
 #include <limits.h>
25 25
 
26 26
 #include "avcodec.h"
27
+#include "decode.h"
27 28
 #include "internal.h"
28 29
 #include "h264dec.h"
29 30
 #include "vc1.h"
... ...
@@ -100,6 +101,25 @@ int av_vdpau_get_surface_parameters(AVCodecContext *avctx,
100 100
     return 0;
101 101
 }
102 102
 
103
+int ff_vdpau_common_frame_params(AVCodecContext *avctx,
104
+                                 AVBufferRef *hw_frames_ctx)
105
+{
106
+    AVHWFramesContext *hw_frames = (AVHWFramesContext*)hw_frames_ctx->data;
107
+    VdpChromaType type;
108
+    uint32_t width;
109
+    uint32_t height;
110
+
111
+    if (av_vdpau_get_surface_parameters(avctx, &type, &width, &height))
112
+        return AVERROR(EINVAL);
113
+
114
+    hw_frames->format    = AV_PIX_FMT_VDPAU;
115
+    hw_frames->sw_format = avctx->sw_pix_fmt;
116
+    hw_frames->width     = width;
117
+    hw_frames->height    = height;
118
+
119
+    return 0;
120
+}
121
+
103 122
 int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile,
104 123
                          int level)
105 124
 {
... ...
@@ -115,6 +135,7 @@ int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile,
115 115
     VdpChromaType type;
116 116
     uint32_t width;
117 117
     uint32_t height;
118
+    int ret;
118 119
 
119 120
     vdctx->width            = UINT32_MAX;
120 121
     vdctx->height           = UINT32_MAX;
... ...
@@ -142,41 +163,14 @@ int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile,
142 142
             type != VDP_CHROMA_TYPE_420)
143 143
             return AVERROR(ENOSYS);
144 144
     } else {
145
-        AVHWFramesContext *frames_ctx = NULL;
145
+        AVHWFramesContext *frames_ctx;
146 146
         AVVDPAUDeviceContext *dev_ctx;
147 147
 
148
-        // We assume the hw_frames_ctx always survives until ff_vdpau_common_uninit
149
-        // is called. This holds true as the user is not allowed to touch
150
-        // hw_device_ctx, or hw_frames_ctx after get_format (and ff_get_format
151
-        // itself also uninits before unreffing hw_frames_ctx).
152
-        if (avctx->hw_frames_ctx) {
153
-            frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
154
-        } else if (avctx->hw_device_ctx) {
155
-            int ret;
156
-
157
-            avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx);
158
-            if (!avctx->hw_frames_ctx)
159
-                return AVERROR(ENOMEM);
160
-
161
-            frames_ctx            = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
162
-            frames_ctx->format    = AV_PIX_FMT_VDPAU;
163
-            frames_ctx->sw_format = avctx->sw_pix_fmt;
164
-            frames_ctx->width     = avctx->coded_width;
165
-            frames_ctx->height    = avctx->coded_height;
166
-
167
-            ret = av_hwframe_ctx_init(avctx->hw_frames_ctx);
168
-            if (ret < 0) {
169
-                av_buffer_unref(&avctx->hw_frames_ctx);
170
-                return ret;
171
-            }
172
-        }
173
-
174
-        if (!frames_ctx) {
175
-            av_log(avctx, AV_LOG_ERROR, "A hardware frames context is "
176
-                   "required for VDPAU decoding.\n");
177
-            return AVERROR(EINVAL);
178
-        }
148
+        ret = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_VDPAU);
149
+        if (ret < 0)
150
+            return ret;
179 151
 
152
+        frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
180 153
         dev_ctx = frames_ctx->device_ctx->hwctx;
181 154
 
182 155
         vdctx->device           = dev_ctx->device;
... ...
@@ -273,6 +273,7 @@ AVHWAccel ff_h264_vdpau_hwaccel = {
273 273
     .frame_priv_data_size = sizeof(struct vdpau_picture_context),
274 274
     .init           = vdpau_h264_init,
275 275
     .uninit         = ff_vdpau_common_uninit,
276
+    .frame_params   = ff_vdpau_common_frame_params,
276 277
     .priv_data_size = sizeof(VDPAUContext),
277 278
     .caps_internal  = HWACCEL_CAP_ASYNC_SAFE,
278 279
 };
... ...
@@ -424,6 +424,7 @@ AVHWAccel ff_hevc_vdpau_hwaccel = {
424 424
     .frame_priv_data_size = sizeof(struct vdpau_picture_context),
425 425
     .init           = vdpau_hevc_init,
426 426
     .uninit         = ff_vdpau_common_uninit,
427
+    .frame_params   = ff_vdpau_common_frame_params,
427 428
     .priv_data_size = sizeof(VDPAUContext),
428 429
     .caps_internal  = HWACCEL_CAP_ASYNC_SAFE,
429 430
 };
... ...
@@ -119,5 +119,7 @@ int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
119 119
 int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx);
120 120
 int ff_vdpau_add_buffer(struct vdpau_picture_context *pic, const uint8_t *buf,
121 121
                         uint32_t buf_size);
122
+int ff_vdpau_common_frame_params(AVCodecContext *avctx,
123
+                                 AVBufferRef *hw_frames_ctx);
122 124
 
123 125
 #endif /* AVCODEC_VDPAU_INTERNAL_H */
... ...
@@ -149,6 +149,7 @@ AVHWAccel ff_mpeg2_vdpau_hwaccel = {
149 149
     .frame_priv_data_size = sizeof(struct vdpau_picture_context),
150 150
     .init           = vdpau_mpeg2_init,
151 151
     .uninit         = ff_vdpau_common_uninit,
152
+    .frame_params   = ff_vdpau_common_frame_params,
152 153
     .priv_data_size = sizeof(VDPAUContext),
153 154
     .caps_internal  = HWACCEL_CAP_ASYNC_SAFE,
154 155
 };
... ...
@@ -118,6 +118,7 @@ AVHWAccel ff_mpeg4_vdpau_hwaccel = {
118 118
     .frame_priv_data_size = sizeof(struct vdpau_picture_context),
119 119
     .init           = vdpau_mpeg4_init,
120 120
     .uninit         = ff_vdpau_common_uninit,
121
+    .frame_params   = ff_vdpau_common_frame_params,
121 122
     .priv_data_size = sizeof(VDPAUContext),
122 123
     .caps_internal  = HWACCEL_CAP_ASYNC_SAFE,
123 124
 };
... ...
@@ -143,6 +143,7 @@ AVHWAccel ff_wmv3_vdpau_hwaccel = {
143 143
     .frame_priv_data_size = sizeof(struct vdpau_picture_context),
144 144
     .init           = vdpau_vc1_init,
145 145
     .uninit         = ff_vdpau_common_uninit,
146
+    .frame_params   = ff_vdpau_common_frame_params,
146 147
     .priv_data_size = sizeof(VDPAUContext),
147 148
     .caps_internal  = HWACCEL_CAP_ASYNC_SAFE,
148 149
 };
... ...
@@ -159,6 +160,7 @@ AVHWAccel ff_vc1_vdpau_hwaccel = {
159 159
     .frame_priv_data_size = sizeof(struct vdpau_picture_context),
160 160
     .init           = vdpau_vc1_init,
161 161
     .uninit         = ff_vdpau_common_uninit,
162
+    .frame_params   = ff_vdpau_common_frame_params,
162 163
     .priv_data_size = sizeof(VDPAUContext),
163 164
     .caps_internal  = HWACCEL_CAP_ASYNC_SAFE,
164 165
 };
... ...
@@ -28,7 +28,7 @@
28 28
 #include "libavutil/version.h"
29 29
 
30 30
 #define LIBAVCODEC_VERSION_MAJOR 58
31
-#define LIBAVCODEC_VERSION_MINOR  4
31
+#define LIBAVCODEC_VERSION_MINOR  5
32 32
 #define LIBAVCODEC_VERSION_MICRO  0
33 33
 
34 34
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \