aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/d3d12va_decode.h
blob: b64994760a8d2d490f5eebba71ebc506cb7bd5e2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
 * Direct3D 12 HW acceleration video decoder
 *
 * copyright (c) 2022-2023 Wu Jianhua <toqsxw@outlook.com>
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef AVCODEC_D3D12VA_DECODE_H
#define AVCODEC_D3D12VA_DECODE_H

#include "libavutil/fifo.h"
#include "libavutil/hwcontext.h"
#include "libavutil/hwcontext_d3d12va.h"
#include "avcodec.h"
#include "internal.h"
#include "hwaccel_internal.h"

/**
 * @brief This structure is used to provide the necessary configurations and data
 * to the FFmpeg Direct3D 12 HWAccel implementation for video decoder.
 */
typedef struct D3D12VADecodeContext {
    AVBufferRef *decoder_ref;

    /**
     * D3D12 video decoder
     */
    ID3D12VideoDecoder *decoder;

    /**
     * D3D12 video decoder heap
     */
    ID3D12VideoDecoderHeap *decoder_heap;

    /**
     * D3D12 configuration used to create the decoder
     *
     * Specified by decoders
     */
    D3D12_VIDEO_DECODE_CONFIGURATION cfg;

    /**
     * A cached queue for reusing the D3D12 command allocators and upload buffers
     *
     * @see https://learn.microsoft.com/en-us/windows/win32/direct3d12/recording-command-lists-and-bundles#id3d12commandallocator
     */
    AVFifo *objects_queue;

    /**
     * D3D12 command queue
     */
    ID3D12CommandQueue *command_queue;

    /**
     * D3D12 video decode command list
     */
    ID3D12VideoDecodeCommandList *command_list;

    /**
     * The array of resources used for reference frames
     *
     * The ref_resources.length is the same as D3D12VADecodeContext.max_num_ref
     */
    ID3D12Resource **ref_resources;

    /**
     * The array of subresources used for reference frames
     *
     * The ref_subresources.length is the same as D3D12VADecodeContext.max_num_ref
     */
    UINT *ref_subresources;

    /**
     * Maximum number of reference frames
     */
    UINT max_num_ref;

    /**
     * Used mask used to record reference frames indices
     */
    UINT used_mask;

    /**
     * Bitstream size for each frame
     */
    UINT bitstream_size;

    /**
     * The sync context used to sync command queue
     */
    AVD3D12VASyncContext sync_ctx;

    /**
     * A pointer to AVD3D12VADeviceContext used to create D3D12 objects
     */
    AVD3D12VADeviceContext *device_ctx;

    /**
     * Pixel format
     */
    enum AVPixelFormat pix_fmt;

    /**
     * Private to the FFmpeg AVHWAccel implementation
     */
    unsigned report_id;
} D3D12VADecodeContext;

/**
 * @}
 */
#define D3D12VA_VIDEO_DEC_ASYNC_DEPTH 36
#define D3D12VA_DECODE_CONTEXT(avctx) ((D3D12VADecodeContext *)((avctx)->internal->hwaccel_priv_data))
#define D3D12VA_FRAMES_CONTEXT(avctx) ((AVHWFramesContext *)(avctx)->hw_frames_ctx->data)

/**
 * @brief Get a suitable maximum bitstream size
 *
 * Creating and destroying a resource on d3d12 needs sync and reallocation, so use this function
 * to help allocate a big enough bitstream buffer to avoid recreating resources when decoding.
 *
 * @return the suitable size
 */
int ff_d3d12va_get_suitable_max_bitstream_size(AVCodecContext *avctx);

/**
 * @brief init D3D12VADecodeContext
 *
 * @return Error code (ret < 0 if failed)
 */
int ff_d3d12va_decode_init(AVCodecContext *avctx);

/**
 * @brief uninit D3D12VADecodeContext
 *
 * @return Error code (ret < 0 if failed)
 */
int ff_d3d12va_decode_uninit(AVCodecContext *avctx);

/**
 * @brief d3d12va common frame params
 *
 * @return Error code (ret < 0 if failed)
 */
int ff_d3d12va_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx);

/**
 * @brief d3d12va common end frame
 *
 * @param avctx    codec context
 * @param frame    current output frame
 * @param pp       picture parameters
 * @param pp_size  the size of the picture parameters
 * @param qm       quantization matrix
 * @param qm_size  the size of the quantization matrix
 * @param callback update decoder-specified input stream arguments
 * @return Error code (ret < 0 if failed)
 */
int ff_d3d12va_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
    const void *pp, unsigned pp_size,
    const void *qm, unsigned qm_size,
    int(*)(AVCodecContext *, D3D12_VIDEO_DECODE_INPUT_STREAM_ARGUMENTS *, ID3D12Resource *));

#endif /* AVCODEC_D3D12VA_DEC_H */