1 /*
2 * Copyright © Microsoft Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "d3d12_video_dec.h"
25 #include "d3d12_video_dec_av1.h"
26 #include <cmath>
27
28 void
d3d12_video_decoder_refresh_dpb_active_references_av1(struct d3d12_video_decoder * pD3D12Dec)29 d3d12_video_decoder_refresh_dpb_active_references_av1(struct d3d12_video_decoder *pD3D12Dec)
30 {
31 // Method overview
32 // 1. Codec specific strategy in switch statement regarding reference frames eviction policy. Should only mark active
33 // DPB references, leaving evicted ones as unused
34 // 2. Call release_unused_references_texture_memory(); at the end of this method. Any references (and texture
35 // allocations associated)
36 // that were left not marked as used in m_spDPBManager by step (2) are lost.
37
38 // Assign DXVA original Index indices to current frame and references
39 DXVA_PicParams_AV1 *pCurrPicParams = d3d12_video_decoder_get_current_dxva_picparams<DXVA_PicParams_AV1>(pD3D12Dec);
40
41 for (uint8_t i = 0; i < _countof(pCurrPicParams->RefFrameMapTextureIndex); i++) {
42 if (pD3D12Dec->m_pCurrentReferenceTargets[i]) {
43 pCurrPicParams->RefFrameMapTextureIndex[i] =
44 pD3D12Dec->m_spDPBManager->get_index7bits(pD3D12Dec->m_pCurrentReferenceTargets[i]);
45 }
46 }
47
48 pD3D12Dec->m_spDPBManager->mark_all_references_as_unused();
49 pD3D12Dec->m_spDPBManager->mark_references_in_use_av1(pCurrPicParams->RefFrameMapTextureIndex);
50
51 // Releases the underlying reference picture texture objects of all references that were not marked as used in this
52 // method.
53 pD3D12Dec->m_spDPBManager->release_unused_references_texture_memory();
54
55 pCurrPicParams->CurrPicTextureIndex = pD3D12Dec->m_spDPBManager->get_index7bits(pD3D12Dec->m_pCurrentDecodeTarget);
56 }
57
58 void
d3d12_video_decoder_get_frame_info_av1(struct d3d12_video_decoder * pD3D12Dec,uint32_t * pWidth,uint32_t * pHeight,uint16_t * pMaxDPB)59 d3d12_video_decoder_get_frame_info_av1(
60 struct d3d12_video_decoder *pD3D12Dec, uint32_t *pWidth, uint32_t *pHeight, uint16_t *pMaxDPB)
61 {
62 auto pPicParams = d3d12_video_decoder_get_current_dxva_picparams<DXVA_PicParams_AV1>(pD3D12Dec);
63 /* width, height
64 Specify the coded width and height of the current frame.
65 These correspond to the syntax elements of: frame_width_minus_1 and frame_height_minus_1.
66 If these values are derived for the frame (for example via the frame_size_override_flag),
67 the host decoder will derive the appropriate values and store the result here.
68 If superres is enabled these values represent the post-scaled frame resolution
69 (referred to in the specification as UpscaledWidth). */
70 *pWidth = pPicParams->width;
71 *pHeight = pPicParams->height;
72
73 /*
74 Note – The AV1 decoder maintains a pool (RefFrameMapTextureIndex[]) of 8 reference pictures at all times.
75 Each frame may pick up to 7 reference frames (frame_refs[]) from the pool to use for inter prediction of the current frame.
76 */
77 *pMaxDPB = 8 + 1 /*current picture*/;
78 }
79
80 void
d3d12_video_decoder_prepare_current_frame_references_av1(struct d3d12_video_decoder * pD3D12Dec,ID3D12Resource * pTexture2D,uint32_t subresourceIndex)81 d3d12_video_decoder_prepare_current_frame_references_av1(struct d3d12_video_decoder *pD3D12Dec,
82 ID3D12Resource *pTexture2D,
83 uint32_t subresourceIndex)
84 {
85 DXVA_PicParams_AV1 *pPicParams = d3d12_video_decoder_get_current_dxva_picparams<DXVA_PicParams_AV1>(pD3D12Dec);
86 pPicParams->CurrPicTextureIndex = pD3D12Dec->m_spDPBManager->store_future_reference(pPicParams->CurrPicTextureIndex,
87 pD3D12Dec->m_spVideoDecoderHeap,
88 pTexture2D,
89 subresourceIndex);
90 pD3D12Dec->m_spDPBManager->update_entries_av1(
91 d3d12_video_decoder_get_current_dxva_picparams<DXVA_PicParams_AV1>(pD3D12Dec)->RefFrameMapTextureIndex,
92 pD3D12Dec->m_transitionsStorage);
93
94 pD3D12Dec->m_spDecodeCommandList->ResourceBarrier(pD3D12Dec->m_transitionsStorage.size(), pD3D12Dec->m_transitionsStorage.data());
95
96 // Schedule reverse (back to common) transitions before command list closes for current frame
97 for (auto BarrierDesc : pD3D12Dec->m_transitionsStorage) {
98 std::swap(BarrierDesc.Transition.StateBefore, BarrierDesc.Transition.StateAfter);
99 pD3D12Dec->m_transitionsBeforeCloseCmdList.push_back(BarrierDesc);
100 }
101
102 debug_printf(
103 "[d3d12_video_decoder_prepare_current_frame_references_av1] DXVA_PicParams_AV1 after index remapping)\n");
104 d3d12_video_decoder_log_pic_params_av1(
105 d3d12_video_decoder_get_current_dxva_picparams<DXVA_PicParams_AV1>(pD3D12Dec));
106 }
107
108 void
d3d12_video_decoder_log_pic_params_av1(DXVA_PicParams_AV1 * pPicParams)109 d3d12_video_decoder_log_pic_params_av1(DXVA_PicParams_AV1 *pPicParams)
110 {
111
112 debug_printf("\n=============================================\n");
113 debug_printf("width = %d\n", pPicParams->width);
114 debug_printf("height = %d\n", pPicParams->height);
115
116 debug_printf("max_width = %d\n", pPicParams->max_width);
117 debug_printf("max_height = %d\n", pPicParams->max_height);
118
119 debug_printf("CurrPicTextureIndex = %d\n", pPicParams->CurrPicTextureIndex);
120 debug_printf("superres_denom = %d\n", pPicParams->superres_denom);
121 debug_printf("bitdepth = %d\n", pPicParams->bitdepth);
122 debug_printf("seq_profile = %d\n", pPicParams->seq_profile);
123
124 debug_printf("cols = %d\n", pPicParams->tiles.cols);
125 debug_printf("rows = %d\n", pPicParams->tiles.rows);
126 debug_printf("context_update_id = %d\n", pPicParams->tiles.context_update_id);
127 for (uint32_t i = 0; i < pPicParams->tiles.cols; i++)
128 debug_printf("widths[%d] = %d\n", i, pPicParams->tiles.widths[i]);
129 for (uint32_t i = 0; i < pPicParams->tiles.rows; i++)
130 debug_printf("heights[%d] = %d\n", i, pPicParams->tiles.heights[i]);
131
132 debug_printf("coding.use_128x128_superblock = %d\n", pPicParams->coding.use_128x128_superblock);
133 debug_printf("coding.intra_edge_filter = %d\n", pPicParams->coding.intra_edge_filter);
134 debug_printf("coding.interintra_compound = %d\n", pPicParams->coding.interintra_compound);
135 debug_printf("coding.masked_compound = %d\n", pPicParams->coding.masked_compound);
136 debug_printf("coding.warped_motion = %d\n", pPicParams->coding.warped_motion);
137 debug_printf("coding.dual_filter = %d\n", pPicParams->coding.dual_filter);
138 debug_printf("coding.jnt_comp = %d\n", pPicParams->coding.jnt_comp);
139 debug_printf("coding.screen_content_tools = %d\n", pPicParams->coding.screen_content_tools);
140 debug_printf("coding.integer_mv = %d\n", pPicParams->coding.integer_mv);
141 debug_printf("coding.cdef = %d\n", pPicParams->coding.cdef);
142 debug_printf("coding.restoration = %d\n", pPicParams->coding.restoration);
143 debug_printf("coding.film_grain = %d\n", pPicParams->coding.film_grain);
144 debug_printf("coding.intrabc = %d\n", pPicParams->coding.intrabc);
145 debug_printf("coding.high_precision_mv = %d\n", pPicParams->coding.high_precision_mv);
146 debug_printf("coding.switchable_motion_mode = %d\n", pPicParams->coding.switchable_motion_mode);
147 debug_printf("coding.filter_intra = %d\n", pPicParams->coding.filter_intra);
148 debug_printf("coding.disable_frame_end_update_cdf = %d\n", pPicParams->coding.disable_frame_end_update_cdf);
149 debug_printf("coding.disable_cdf_update = %d\n", pPicParams->coding.disable_cdf_update);
150 debug_printf("coding.reference_mode = %d\n", pPicParams->coding.reference_mode);
151 debug_printf("coding.skip_mode = %d\n", pPicParams->coding.skip_mode);
152 debug_printf("coding.reduced_tx_set = %d\n", pPicParams->coding.reduced_tx_set);
153 debug_printf("coding.superres = %d\n", pPicParams->coding.superres);
154 debug_printf("coding.tx_mode = %d\n", pPicParams->coding.tx_mode);
155 debug_printf("coding.use_ref_frame_mvs = %d\n", pPicParams->coding.use_ref_frame_mvs);
156 debug_printf("coding.enable_ref_frame_mvs = %d\n", pPicParams->coding.enable_ref_frame_mvs);
157 debug_printf("coding.reference_frame_update = %d\n", pPicParams->coding.reference_frame_update);
158 debug_printf("coding.Reserved = %d\n", pPicParams->coding.Reserved);
159 debug_printf("coding.CodingParamToolFlags = %d\n", pPicParams->coding.CodingParamToolFlags);
160
161 debug_printf("format.frame_type = %d\n", pPicParams->format.frame_type);
162 debug_printf("format.show_frame = %d\n", pPicParams->format.show_frame);
163 debug_printf("format.showable_frame = %d\n", pPicParams->format.showable_frame);
164 debug_printf("format.subsampling_x = %d\n", pPicParams->format.subsampling_x);
165 debug_printf("format.subsampling_y = %d\n", pPicParams->format.subsampling_y);
166 debug_printf("format.mono_chrome = %d\n", pPicParams->format.mono_chrome);
167 debug_printf("format.Reserved = %d\n", pPicParams->format.Reserved);
168
169 debug_printf("primary_ref_frame = %d\n", pPicParams->primary_ref_frame);
170 debug_printf("order_hint = %d\n", pPicParams->order_hint);
171 debug_printf("order_hint_bits = %d\n", pPicParams->order_hint_bits);
172
173 for (uint32_t i = 0; i < _countof(pPicParams->frame_refs); i++) {
174 debug_printf("frame_refs[%d]\n", i);
175 debug_printf("\twidth = %d\n", pPicParams->frame_refs[i].width);
176 debug_printf("\theight = %d\n", pPicParams->frame_refs[i].height);
177
178 // Global motion parameters
179 for (uint32_t j = 0; j < 6; j++)
180 debug_printf("\t\twmmat[%d] = %d\n", j, pPicParams->frame_refs[i].wmmat[j]);
181 debug_printf("\twminvalid = %d\n", pPicParams->frame_refs[i].wminvalid);
182 debug_printf("\twmtype = %d\n", pPicParams->frame_refs[i].wmtype);
183 debug_printf("\tGlobalMotionFlags = %d\n", pPicParams->frame_refs[i].GlobalMotionFlags);
184 debug_printf("\tIndex = %d\n", pPicParams->frame_refs[i].Index);
185 }
186
187 for (uint32_t i = 0; i < _countof(pPicParams->RefFrameMapTextureIndex); i++)
188 debug_printf("RefFrameMapTextureIndex[%d] = %d\n", i, pPicParams->RefFrameMapTextureIndex[i]);
189
190 // Loop filter parameters
191 debug_printf("filter_level[0] = %d\n", pPicParams->loop_filter.filter_level[0]);
192 debug_printf("filter_level[1] = %d\n", pPicParams->loop_filter.filter_level[1]);
193 debug_printf("filter_level_u = %d\n", pPicParams->loop_filter.filter_level_u);
194 debug_printf("filter_level_v = %d\n", pPicParams->loop_filter.filter_level_v);
195 debug_printf("sharpness_level = %d\n", pPicParams->loop_filter.sharpness_level);
196 debug_printf("mode_ref_delta_enabled = %d\n", pPicParams->loop_filter.mode_ref_delta_enabled);
197 debug_printf("mode_ref_delta_update = %d\n", pPicParams->loop_filter.mode_ref_delta_update);
198 debug_printf("delta_lf_multi = %d\n", pPicParams->loop_filter.delta_lf_multi);
199 debug_printf("delta_lf_present = %d\n", pPicParams->loop_filter.delta_lf_present);
200 debug_printf("ControlFlags = %d\n", pPicParams->loop_filter.ControlFlags);
201
202 for (uint32_t i = 0; i < _countof(pPicParams->loop_filter.ref_deltas); i++)
203 debug_printf("loop_filter.ref_deltas[%d] = %d\n", i, pPicParams->loop_filter.ref_deltas[i]);
204 for (uint32_t i = 0; i < _countof(pPicParams->loop_filter.mode_deltas); i++)
205 debug_printf("loop_filter.mode_deltas[%d] = %d\n", i, pPicParams->loop_filter.mode_deltas[i]);
206
207 debug_printf("delta_lf_res = %d\n", pPicParams->loop_filter.delta_lf_res);
208
209 for (uint32_t i = 0; i < _countof(pPicParams->loop_filter.frame_restoration_type); i++)
210 debug_printf("loop_filter.frame_restoration_type[%d] = %d\n", i, pPicParams->loop_filter.frame_restoration_type[i]);
211
212 for (uint32_t i = 0; i < _countof(pPicParams->loop_filter.log2_restoration_unit_size); i++)
213 debug_printf("loop_filter.log2_restoration_unit_size[%d] = %d\n", i, pPicParams->loop_filter.log2_restoration_unit_size[i]);
214
215 // Quantization
216 debug_printf("delta_q_present = %d\n", pPicParams->quantization.delta_q_present);
217 debug_printf("delta_q_res = %d\n", pPicParams->quantization.delta_q_res);
218 debug_printf("ControlFlags = %d\n", pPicParams->quantization.ControlFlags);
219 debug_printf("quantization.base_qindex = %d\n", pPicParams->quantization.base_qindex);
220 debug_printf("quantization.y_dc_delta_q = %d\n", pPicParams->quantization.y_dc_delta_q);
221 debug_printf("quantization.u_dc_delta_q = %d\n", pPicParams->quantization.u_dc_delta_q);
222 debug_printf("quantization.v_dc_delta_q = %d\n", pPicParams->quantization.v_dc_delta_q);
223 debug_printf("quantization.u_ac_delta_q = %d\n", pPicParams->quantization.u_ac_delta_q);
224 debug_printf("quantization.v_ac_delta_q = %d\n", pPicParams->quantization.v_ac_delta_q);
225 // using_qmatrix:
226 debug_printf("quantization.qm_y = %d\n", pPicParams->quantization.qm_y);
227 debug_printf("quantization.qm_u = %d\n", pPicParams->quantization.qm_u);
228 debug_printf("quantization.qm_v = %d\n", pPicParams->quantization.qm_v);
229
230 // Cdef parameters
231 debug_printf("cdef.damping = %d\n", pPicParams->cdef.damping);
232 debug_printf("cdef.bits = %d\n", pPicParams->cdef.bits);
233 debug_printf("cdef.Reserved = %d\n", pPicParams->cdef.Reserved);
234 debug_printf("cdef.ControlFlags = %d\n", pPicParams->cdef.ControlFlags);
235
236 for (uint32_t i = 0; i < _countof(pPicParams->cdef.y_strengths); i++) {
237 debug_printf("cdef.primaryuv_strengthsy%d] = %d\n", i, pPicParams->cdef.y_strengths[i].primary);
238 debug_printf("cdef.y_strengths.secondary[%d] = %d\n", i, pPicParams->cdef.y_strengths[i].secondary);
239 debug_printf("cdef.y_strengths.combined[%d] = %d\n", i, pPicParams->cdef.y_strengths[i].combined);
240 }
241
242 for (uint32_t i = 0; i < _countof(pPicParams->cdef.uv_strengths); i++) {
243 debug_printf("cdef.uv_strengths.primary[%d] = %d\n", i, pPicParams->cdef.uv_strengths[i].primary);
244 debug_printf("cdef.uv_strengths.secondary[%d] = %d\n", i, pPicParams->cdef.uv_strengths[i].secondary);
245 debug_printf("cdef.uv_strengths.combined[%d] = %d\n", i, pPicParams->cdef.uv_strengths[i].combined);
246 }
247
248 debug_printf("interp_filter = %d\n", pPicParams->interp_filter);
249
250 // Segmentation
251 debug_printf("segmentation.enabled = %d\n", pPicParams->segmentation.enabled);
252 debug_printf("segmentation.update_map = %d\n", pPicParams->segmentation.update_map);
253 debug_printf("segmentation.update_data = %d\n", pPicParams->segmentation.update_data);
254 debug_printf("segmentation.temporal_update = %d\n", pPicParams->segmentation.temporal_update);
255 debug_printf("segmentation.Reserved = %d\n", pPicParams->segmentation.Reserved);
256 debug_printf("segmentation.ControlFlags = %d\n", pPicParams->segmentation.ControlFlags);
257
258 for (uint32_t i = 0; i < _countof(pPicParams->segmentation.feature_mask); i++) {
259 debug_printf("segmentation.feature_mask[%d].alt_q = %d\n", i, pPicParams->segmentation.feature_mask[i].alt_q);
260 debug_printf("segmentation.feature_mask[%d].alt_lf_y_v = %d\n", i, pPicParams->segmentation.feature_mask[i].alt_lf_y_v);
261 debug_printf("segmentation.feature_mask[%d].alt_lf_y_h = %d\n", i, pPicParams->segmentation.feature_mask[i].alt_lf_y_h);
262 debug_printf("segmentation.feature_mask[%d].alt_lf_u = %d\n", i, pPicParams->segmentation.feature_mask[i].alt_lf_u);
263 debug_printf("segmentation.feature_mask[%d].alt_lf_v = %d\n", i, pPicParams->segmentation.feature_mask[i].alt_lf_v);
264 debug_printf("segmentation.feature_mask[%d].ref_frame = %d\n", i, pPicParams->segmentation.feature_mask[i].ref_frame);
265 debug_printf("segmentation.feature_mask[%d].skip = %d\n", i, pPicParams->segmentation.feature_mask[i].skip);
266 debug_printf("segmentation.feature_mask[%d].globalmv = %d\n", i, pPicParams->segmentation.feature_mask[i].globalmv);
267 debug_printf("segmentation.feature_mask[%d].mask = %d\n", i, pPicParams->segmentation.feature_mask[i].mask);
268 }
269
270 for (uint32_t i = 0; i < 8; i++)
271 for (uint32_t j = 0; j < 8; j++)
272 debug_printf("segmentation.feature_data[%d][%d] = %d\n", i, j, pPicParams->segmentation.feature_data[i][j]);
273
274 debug_printf("film_grain.apply_grain = %d\n", pPicParams->film_grain.apply_grain);
275 debug_printf("film_grain.scaling_shift_minus8 = %d\n", pPicParams->film_grain.scaling_shift_minus8);
276 debug_printf("film_grain.chroma_scaling_from_luma = %d\n", pPicParams->film_grain.chroma_scaling_from_luma);
277 debug_printf("film_grain.ar_coeff_lag = %d\n", pPicParams->film_grain.ar_coeff_lag);
278 debug_printf("film_grain.ar_coeff_shift_minus6 = %d\n", pPicParams->film_grain.ar_coeff_shift_minus6);
279 debug_printf("film_grain.grain_scale_shift = %d\n", pPicParams->film_grain.grain_scale_shift);
280 debug_printf("film_grain.overlap_flag = %d\n", pPicParams->film_grain.overlap_flag);
281 debug_printf("film_grain.clip_to_restricted_range = %d\n", pPicParams->film_grain.clip_to_restricted_range);
282 debug_printf("film_grain.matrix_coeff_is_identity = %d\n", pPicParams->film_grain.matrix_coeff_is_identity);
283 debug_printf("film_grain.Reserved = %d\n", pPicParams->film_grain.Reserved);
284 debug_printf("film_grain.ControlFlags = %d\n", pPicParams->film_grain.ControlFlags);
285
286 debug_printf("film_grain.grain_seed = %d\n", pPicParams->film_grain.grain_seed);
287
288 for (uint32_t i = 0; i < 14; i++)
289 for (uint32_t j = 0; j < 2; j++)
290 debug_printf("film_grain.scaling_points_y[%d][%d] = %d\n", i, j, pPicParams->film_grain.scaling_points_y[i][j]);
291
292 debug_printf("film_grain.num_y_points = %d\n", pPicParams->film_grain.num_y_points);
293
294 for (uint32_t i = 0; i < 10; i++)
295 for (uint32_t j = 0; j < 2; j++)
296 debug_printf("film_grain.scaling_points_cb[%d][%d] = %d\n", i, j, pPicParams->film_grain.scaling_points_cb[i][j]);
297
298 debug_printf("film_grain.num_cb_points = %d\n", pPicParams->film_grain.num_cb_points);
299
300 for (uint32_t i = 0; i < 10; i++)
301 for (uint32_t j = 0; j < 2; j++)
302 debug_printf("film_grain.scaling_points_cr[%d][%d] = %d\n", i, j, pPicParams->film_grain.scaling_points_cr[i][j]);
303
304 debug_printf("film_grain.num_cr_points = %d\n", pPicParams->film_grain.num_cr_points);
305 for (uint32_t i = 0; i < _countof(pPicParams->film_grain.ar_coeffs_y); i++)
306 debug_printf("film_grain.ar_coeffs_y[%d] = %d\n", i, pPicParams->film_grain.ar_coeffs_y[i]);
307
308 for (uint32_t i = 0; i < _countof(pPicParams->film_grain.ar_coeffs_cb); i++)
309 debug_printf("film_grain.ar_coeffs_cb[%d] = %d\n", i, pPicParams->film_grain.ar_coeffs_cb[i]);
310
311 for (uint32_t i = 0; i < _countof(pPicParams->film_grain.ar_coeffs_cr); i++)
312 debug_printf("film_grain.ar_coeffs_cr[%d] = %d\n", i, pPicParams->film_grain.ar_coeffs_cr[i]);
313
314 debug_printf("film_grain.cb_mult = %d\n", pPicParams->film_grain.cb_mult);
315 debug_printf("film_grain.cb_luma_mult = %d\n", pPicParams->film_grain.cb_luma_mult);
316 debug_printf("film_grain.cr_mult = %d\n", pPicParams->film_grain.cr_mult);
317 debug_printf("film_grain.cr_luma_mult = %d\n", pPicParams->film_grain.cr_luma_mult);
318 debug_printf("film_grain.Reserved8Bits = %d\n", pPicParams->film_grain.Reserved8Bits);
319 debug_printf("film_grain.cb_offset = %d\n", pPicParams->film_grain.cb_offset);
320 debug_printf("film_grain.cr_offset = %d\n", pPicParams->film_grain.cr_offset);
321
322 debug_printf("Reserved32Bits = %d\n", pPicParams->Reserved32Bits);
323 debug_printf("StatusReportFeedbackNumber = %d\n", pPicParams->StatusReportFeedbackNumber);
324 }
325
326 void
d3d12_video_decoder_prepare_dxva_slices_control_av1(struct d3d12_video_decoder * pD3D12Dec,std::vector<uint8_t> & vecOutSliceControlBuffers,struct pipe_av1_picture_desc * picture_av1)327 d3d12_video_decoder_prepare_dxva_slices_control_av1(struct d3d12_video_decoder *pD3D12Dec,
328 std::vector<uint8_t> &vecOutSliceControlBuffers,
329 struct pipe_av1_picture_desc *picture_av1)
330 {
331 uint32_t tileCount = picture_av1->picture_parameter.tile_cols * picture_av1->picture_parameter.tile_rows;
332 debug_printf("[d3d12_video_decoder_av1] Upper layer reported %d tiles for this frame, parsing them below...\n",
333 tileCount);
334
335 uint64_t totalSlicesDXVAArrayByteSize = tileCount * sizeof(DXVA_Tile_AV1);
336 vecOutSliceControlBuffers.resize(totalSlicesDXVAArrayByteSize);
337
338 uint8_t* pData = vecOutSliceControlBuffers.data();
339 for (uint32_t tileIdx = 0; tileIdx < tileCount; tileIdx++)
340 {
341 DXVA_Tile_AV1 currentTileEntry = {};
342 currentTileEntry.DataOffset = picture_av1->slice_parameter.slice_data_offset[tileIdx];
343 currentTileEntry.DataSize = picture_av1->slice_parameter.slice_data_size[tileIdx];
344 currentTileEntry.row = picture_av1->slice_parameter.slice_data_row[tileIdx];
345 currentTileEntry.column = picture_av1->slice_parameter.slice_data_col[tileIdx];
346 // From va_dec_av1.h `anchor_frame_idx` valid only when large_scale_tile equals 1.
347 currentTileEntry.anchor_frame = (picture_av1->picture_parameter.pic_info_fields.large_scale_tile == 1) ? picture_av1->slice_parameter.slice_data_anchor_frame_idx[tileIdx] : 0xFF;
348
349 debug_printf("[d3d12_video_decoder_av1] Detected tile index %" PRIu32
350 " with DataOffset %" PRIu32
351 " - DataSize %" PRIu32
352 " - row: %" PRIu16
353 " - col: %" PRIu16
354 " - large_scale_tile: %" PRIu32
355 " - anchor_frame_idx: %" PRIu8
356 " for frame with "
357 "fenceValue: %d\n",
358 tileIdx,
359 currentTileEntry.DataOffset,
360 currentTileEntry.DataSize,
361 currentTileEntry.row,
362 currentTileEntry.column,
363 picture_av1->picture_parameter.pic_info_fields.large_scale_tile,
364 currentTileEntry.anchor_frame,
365 pD3D12Dec->m_fenceValue);
366
367 memcpy(pData, ¤tTileEntry, sizeof(DXVA_Tile_AV1));
368 pData += sizeof(DXVA_Tile_AV1);
369 }
370 assert(vecOutSliceControlBuffers.size() == totalSlicesDXVAArrayByteSize);
371 }
372
373 DXVA_PicParams_AV1
d3d12_video_decoder_dxva_picparams_from_pipe_picparams_av1(uint32_t frameNum,pipe_video_profile profile,pipe_av1_picture_desc * pipe_av1)374 d3d12_video_decoder_dxva_picparams_from_pipe_picparams_av1(
375 uint32_t frameNum,
376 pipe_video_profile profile,
377 pipe_av1_picture_desc *pipe_av1)
378 {
379 DXVA_PicParams_AV1 dxvaStructure;
380 memset(&dxvaStructure, 0, sizeof(dxvaStructure));
381
382 dxvaStructure.width = pipe_av1->picture_parameter.frame_width;
383 dxvaStructure.height = pipe_av1->picture_parameter.frame_height;
384
385 dxvaStructure.max_width = pipe_av1->picture_parameter.max_width;
386 dxvaStructure.max_height = pipe_av1->picture_parameter.max_height;
387
388 uint8_t bit_depths[] = { 8, 10, 12 };
389
390 // dxvaStructure.CurrPicTextureIndex = is set by d3d12_video_decoder_refresh_dpb_active_references_av1
391 dxvaStructure.superres_denom = pipe_av1->picture_parameter.superres_scale_denominator;
392 dxvaStructure.bitdepth = bit_depths[pipe_av1->picture_parameter.bit_depth_idx];
393 dxvaStructure.seq_profile = pipe_av1->picture_parameter.profile;
394
395 /* Tiling info */
396 dxvaStructure.tiles.cols = pipe_av1->picture_parameter.tile_cols;
397 dxvaStructure.tiles.rows = pipe_av1->picture_parameter.tile_rows;
398 dxvaStructure.tiles.context_update_id = pipe_av1->picture_parameter.context_update_tile_id;
399
400 for (uint32_t i = 0; i < dxvaStructure.tiles.cols; i++)
401 dxvaStructure.tiles.widths[i] = pipe_av1->picture_parameter.width_in_sbs[i];
402
403 for (uint32_t i = 0; i < dxvaStructure.tiles.rows; i++)
404 dxvaStructure.tiles.heights[i] = pipe_av1->picture_parameter.height_in_sbs[i];
405
406 // Fix the last tile rounding when uniform_tile_spacing_flag
407 if (pipe_av1->picture_parameter.pic_info_fields.uniform_tile_spacing_flag) {
408 uint32_t sbPixSize = pipe_av1->picture_parameter.seq_info_fields.use_128x128_superblock ? 128 : 64;
409 if (dxvaStructure.tiles.cols > 1) {
410 uint32_t acumSbWMinusLast = 0;
411 for (uint32_t i = 0; i < dxvaStructure.tiles.cols - 1u; i++)
412 acumSbWMinusLast += dxvaStructure.tiles.widths[i];
413
414 dxvaStructure.tiles.widths[dxvaStructure.tiles.cols-1] =
415 std::ceil(pipe_av1->picture_parameter.frame_width / (float)sbPixSize) - acumSbWMinusLast;
416 }
417
418 if (dxvaStructure.tiles.rows > 1) {
419 uint32_t acumSbHMinusLast = 0;
420 for (uint32_t i = 0; i < dxvaStructure.tiles.rows - 1u; i++)
421 acumSbHMinusLast += dxvaStructure.tiles.heights[i];
422
423 dxvaStructure.tiles.heights[dxvaStructure.tiles.rows-1] =
424 std::ceil(pipe_av1->picture_parameter.frame_width / (float)sbPixSize) - acumSbHMinusLast;
425 }
426 }
427
428 /* Coding tools */
429 dxvaStructure.coding.use_128x128_superblock = pipe_av1->picture_parameter.seq_info_fields.use_128x128_superblock;
430 dxvaStructure.coding.intra_edge_filter = pipe_av1->picture_parameter.seq_info_fields.enable_intra_edge_filter;
431 dxvaStructure.coding.interintra_compound = pipe_av1->picture_parameter.seq_info_fields.enable_interintra_compound;
432 dxvaStructure.coding.masked_compound = pipe_av1->picture_parameter.seq_info_fields.enable_masked_compound;
433 dxvaStructure.coding.warped_motion = pipe_av1->picture_parameter.pic_info_fields.allow_warped_motion;
434 dxvaStructure.coding.dual_filter = pipe_av1->picture_parameter.seq_info_fields.enable_dual_filter;
435 dxvaStructure.coding.jnt_comp = pipe_av1->picture_parameter.seq_info_fields.enable_jnt_comp;
436 dxvaStructure.coding.screen_content_tools = pipe_av1->picture_parameter.pic_info_fields.allow_screen_content_tools;
437 dxvaStructure.coding.integer_mv = pipe_av1->picture_parameter.pic_info_fields.force_integer_mv || !(pipe_av1->picture_parameter.pic_info_fields.frame_type & 1);
438 dxvaStructure.coding.cdef = pipe_av1->picture_parameter.seq_info_fields.enable_cdef;
439 dxvaStructure.coding.restoration = 1; // This indicates the feature MAY be enabled in the sequence
440 dxvaStructure.coding.film_grain = pipe_av1->picture_parameter.seq_info_fields.film_grain_params_present;
441 dxvaStructure.coding.intrabc = pipe_av1->picture_parameter.pic_info_fields.allow_intrabc;
442 dxvaStructure.coding.high_precision_mv = pipe_av1->picture_parameter.pic_info_fields.allow_high_precision_mv;
443 dxvaStructure.coding.switchable_motion_mode = pipe_av1->picture_parameter.pic_info_fields.is_motion_mode_switchable;
444 dxvaStructure.coding.filter_intra = pipe_av1->picture_parameter.seq_info_fields.enable_filter_intra;
445 dxvaStructure.coding.disable_frame_end_update_cdf = pipe_av1->picture_parameter.pic_info_fields.disable_frame_end_update_cdf;
446 dxvaStructure.coding.disable_cdf_update = pipe_av1->picture_parameter.pic_info_fields.disable_cdf_update;
447 dxvaStructure.coding.reference_mode = pipe_av1->picture_parameter.mode_control_fields.reference_select;
448 dxvaStructure.coding.skip_mode = pipe_av1->picture_parameter.mode_control_fields.skip_mode_present;
449 dxvaStructure.coding.reduced_tx_set = pipe_av1->picture_parameter.mode_control_fields.reduced_tx_set_used;
450 dxvaStructure.coding.superres = pipe_av1->picture_parameter.pic_info_fields.use_superres;
451 dxvaStructure.coding.tx_mode = pipe_av1->picture_parameter.mode_control_fields.tx_mode;
452 dxvaStructure.coding.use_ref_frame_mvs = pipe_av1->picture_parameter.pic_info_fields.use_ref_frame_mvs;
453 dxvaStructure.coding.enable_ref_frame_mvs = pipe_av1->picture_parameter.seq_info_fields.ref_frame_mvs;
454 dxvaStructure.coding.reference_frame_update = 1;
455
456 /* Format & Picture Info flags */
457 dxvaStructure.format.frame_type = pipe_av1->picture_parameter.pic_info_fields.frame_type;
458 dxvaStructure.format.show_frame = pipe_av1->picture_parameter.pic_info_fields.show_frame;
459 dxvaStructure.format.showable_frame = pipe_av1->picture_parameter.pic_info_fields.showable_frame;
460 dxvaStructure.format.subsampling_x = 1; // D3D12 Only Supports 4:2:0 (ie. Profile0)
461 dxvaStructure.format.subsampling_y = 1; // D3D12 Only Supports 4:2:0 (ie. Profile0)
462 dxvaStructure.format.mono_chrome = pipe_av1->picture_parameter.seq_info_fields.mono_chrome;
463
464 /* References */
465 dxvaStructure.primary_ref_frame = pipe_av1->picture_parameter.primary_ref_frame;
466 dxvaStructure.order_hint = pipe_av1->picture_parameter.order_hint;
467 dxvaStructure.order_hint_bits = pipe_av1->picture_parameter.seq_info_fields.enable_order_hint ? pipe_av1->picture_parameter.order_hint_bits_minus_1 + 1 : 0;
468
469 // d3d12_video_decoder_refresh_dpb_active_references_av1 will assign the correct Index for
470 // RefFrameMapTextureIndex entries where pipe_av1->ref[i] has a surface
471 memset(dxvaStructure.RefFrameMapTextureIndex, DXVA_AV1_INVALID_PICTURE_INDEX, sizeof(dxvaStructure.RefFrameMapTextureIndex));
472 memset(&dxvaStructure.frame_refs[0], 0, sizeof(dxvaStructure.frame_refs));
473 for (uint32_t i = 0; i < _countof(dxvaStructure.frame_refs); i++) {
474 debug_printf("libva ref[%d] = %p\n", i, pipe_av1->ref[i]);
475 debug_printf("libva ref_frame_idx[%d] = %d\n", i, pipe_av1->picture_parameter.ref_frame_idx[i]);
476
477 uint8_t ref_idx = pipe_av1->picture_parameter.ref_frame_idx[i];
478 struct pipe_video_buffer *ref_frame = (ref_idx <= _countof(pipe_av1->ref)) ? pipe_av1->ref[ref_idx] : NULL;
479 if(ref_frame) {
480 dxvaStructure.frame_refs[i].width = ref_frame->width;
481 dxvaStructure.frame_refs[i].height = ref_frame->height;
482 dxvaStructure.frame_refs[i].Index = ref_idx;
483
484 /* Global Motion */
485 dxvaStructure.frame_refs[i].wminvalid = pipe_av1->picture_parameter.wm[i].invalid;
486 dxvaStructure.frame_refs[i].wmtype = pipe_av1->picture_parameter.wm[i].wmtype;
487 for (uint32_t j = 0; j < 6; ++j) {
488 dxvaStructure.frame_refs[i].wmmat[j] = pipe_av1->picture_parameter.wm[i].wmmat[j];
489 }
490 }
491 else
492 {
493 dxvaStructure.frame_refs[i].Index = DXVA_AV1_INVALID_PICTURE_INDEX;
494 }
495 }
496
497 /* Loop filter parameters */
498 dxvaStructure.loop_filter.filter_level[0] = pipe_av1->picture_parameter.filter_level[0];
499 dxvaStructure.loop_filter.filter_level[1] = pipe_av1->picture_parameter.filter_level[1];
500 dxvaStructure.loop_filter.filter_level_u = pipe_av1->picture_parameter.filter_level_u;
501 dxvaStructure.loop_filter.filter_level_v = pipe_av1->picture_parameter.filter_level_v;
502 dxvaStructure.loop_filter.sharpness_level = pipe_av1->picture_parameter.loop_filter_info_fields.sharpness_level;
503 dxvaStructure.loop_filter.mode_ref_delta_enabled = pipe_av1->picture_parameter.loop_filter_info_fields.mode_ref_delta_enabled;
504 dxvaStructure.loop_filter.mode_ref_delta_update = pipe_av1->picture_parameter.loop_filter_info_fields.mode_ref_delta_update;
505 dxvaStructure.loop_filter.delta_lf_multi = pipe_av1->picture_parameter.mode_control_fields.delta_lf_multi;
506 dxvaStructure.loop_filter.delta_lf_present = pipe_av1->picture_parameter.mode_control_fields.delta_lf_present_flag;
507 if (dxvaStructure.loop_filter.delta_lf_present)
508 dxvaStructure.loop_filter.delta_lf_res = pipe_av1->picture_parameter.mode_control_fields.log2_delta_lf_res; /* no need to convert log2 here */
509
510 for (uint32_t i = 0; i < 8; i++) {
511 dxvaStructure.loop_filter.ref_deltas[i] = pipe_av1->picture_parameter.ref_deltas[i];
512 }
513
514 dxvaStructure.loop_filter.mode_deltas[0] = pipe_av1->picture_parameter.mode_deltas[0];
515 dxvaStructure.loop_filter.mode_deltas[1] = pipe_av1->picture_parameter.mode_deltas[1];
516
517 /* VAAPI already receives *frame_restoration_type after the remap_lr_type conversion */
518 dxvaStructure.loop_filter.frame_restoration_type[0] = pipe_av1->picture_parameter.loop_restoration_fields.yframe_restoration_type;
519 dxvaStructure.loop_filter.frame_restoration_type[1] = pipe_av1->picture_parameter.loop_restoration_fields.cbframe_restoration_type;
520 dxvaStructure.loop_filter.frame_restoration_type[2] = pipe_av1->picture_parameter.loop_restoration_fields.crframe_restoration_type;
521
522 bool lr_enabled = dxvaStructure.loop_filter.frame_restoration_type[0] || dxvaStructure.loop_filter.frame_restoration_type[1] || dxvaStructure.loop_filter.frame_restoration_type[2];
523 dxvaStructure.loop_filter.log2_restoration_unit_size[0] = lr_enabled ? (6 + pipe_av1->picture_parameter.loop_restoration_fields.lr_unit_shift) : 8;
524 dxvaStructure.loop_filter.log2_restoration_unit_size[1] = lr_enabled ? (6 + pipe_av1->picture_parameter.loop_restoration_fields.lr_unit_shift - pipe_av1->picture_parameter.loop_restoration_fields.lr_uv_shift) : 8;
525 dxvaStructure.loop_filter.log2_restoration_unit_size[2] = lr_enabled ? (6 + pipe_av1->picture_parameter.loop_restoration_fields.lr_unit_shift - pipe_av1->picture_parameter.loop_restoration_fields.lr_uv_shift) : 8;
526
527 /* Quantization */
528 dxvaStructure.quantization.delta_q_present = pipe_av1->picture_parameter.mode_control_fields.delta_q_present_flag;
529 if(dxvaStructure.quantization.delta_q_present)
530 dxvaStructure.quantization.delta_q_res = pipe_av1->picture_parameter.mode_control_fields.log2_delta_q_res; /* no need to convert log2 here */
531 dxvaStructure.quantization.base_qindex = pipe_av1->picture_parameter.base_qindex;
532 dxvaStructure.quantization.y_dc_delta_q = pipe_av1->picture_parameter.y_dc_delta_q;
533 dxvaStructure.quantization.u_dc_delta_q = pipe_av1->picture_parameter.u_dc_delta_q;
534 dxvaStructure.quantization.v_dc_delta_q = pipe_av1->picture_parameter.v_dc_delta_q;
535 dxvaStructure.quantization.u_ac_delta_q = pipe_av1->picture_parameter.u_ac_delta_q;
536 dxvaStructure.quantization.v_ac_delta_q = pipe_av1->picture_parameter.v_ac_delta_q;
537
538 if(pipe_av1->picture_parameter.qmatrix_fields.using_qmatrix)
539 {
540 dxvaStructure.quantization.qm_y = pipe_av1->picture_parameter.qmatrix_fields.qm_y;
541 dxvaStructure.quantization.qm_u = pipe_av1->picture_parameter.qmatrix_fields.qm_u;
542 dxvaStructure.quantization.qm_v = pipe_av1->picture_parameter.qmatrix_fields.qm_v;
543 } else {
544 dxvaStructure.quantization.qm_y = 0xFF;
545 dxvaStructure.quantization.qm_u = 0xFF;
546 dxvaStructure.quantization.qm_v = 0xFF;
547 }
548
549 /* Cdef parameters */
550 dxvaStructure.cdef.damping = pipe_av1->picture_parameter.cdef_damping_minus_3;
551 dxvaStructure.cdef.bits = pipe_av1->picture_parameter.cdef_bits;
552 for (uint32_t i = 0; i < 8; i++) {
553 dxvaStructure.cdef.y_strengths[i].primary = (pipe_av1->picture_parameter.cdef_y_strengths[i] >> 2);
554 dxvaStructure.cdef.y_strengths[i].secondary = (pipe_av1->picture_parameter.cdef_y_strengths[i] & 0x03);
555 dxvaStructure.cdef.uv_strengths[i].primary = (pipe_av1->picture_parameter.cdef_uv_strengths[i] >> 2);
556 dxvaStructure.cdef.uv_strengths[i].secondary = (pipe_av1->picture_parameter.cdef_uv_strengths[i] & 0x03);
557 }
558
559 /* Misc flags */
560 dxvaStructure.interp_filter = pipe_av1->picture_parameter.interp_filter;
561
562 /* Segmentation */
563 dxvaStructure.segmentation.enabled = pipe_av1->picture_parameter.seg_info.segment_info_fields.enabled;
564 dxvaStructure.segmentation.update_map = pipe_av1->picture_parameter.seg_info.segment_info_fields.update_map;
565 dxvaStructure.segmentation.update_data = pipe_av1->picture_parameter.seg_info.segment_info_fields.update_data;
566 dxvaStructure.segmentation.temporal_update = pipe_av1->picture_parameter.seg_info.segment_info_fields.temporal_update;
567 for (uint32_t i = 0; i < 8; i++) {
568 dxvaStructure.segmentation.feature_mask[i].mask |= pipe_av1->picture_parameter.seg_info.feature_mask[i];
569 for (uint32_t j = 0; j < 8; j++) {
570 dxvaStructure.segmentation.feature_data[i][j] = pipe_av1->picture_parameter.seg_info.feature_data[i][j];
571 }
572 }
573
574 /* Film grain */
575 if (pipe_av1->picture_parameter.film_grain_info.film_grain_info_fields.apply_grain) {
576 dxvaStructure.film_grain.apply_grain = 1;
577 dxvaStructure.film_grain.scaling_shift_minus8 = pipe_av1->picture_parameter.film_grain_info.film_grain_info_fields.grain_scaling_minus_8;
578 dxvaStructure.film_grain.chroma_scaling_from_luma = pipe_av1->picture_parameter.film_grain_info.film_grain_info_fields.chroma_scaling_from_luma;
579 dxvaStructure.film_grain.ar_coeff_lag = pipe_av1->picture_parameter.film_grain_info.film_grain_info_fields.ar_coeff_lag;
580 dxvaStructure.film_grain.ar_coeff_shift_minus6 = pipe_av1->picture_parameter.film_grain_info.film_grain_info_fields.ar_coeff_shift_minus_6;
581 dxvaStructure.film_grain.grain_scale_shift = pipe_av1->picture_parameter.film_grain_info.film_grain_info_fields.grain_scale_shift;
582 dxvaStructure.film_grain.overlap_flag = pipe_av1->picture_parameter.film_grain_info.film_grain_info_fields.overlap_flag;
583 dxvaStructure.film_grain.clip_to_restricted_range = pipe_av1->picture_parameter.film_grain_info.film_grain_info_fields.clip_to_restricted_range;
584
585 /* order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB) */
586 constexpr uint8_t AVCOL_SPC_RGB = 0;
587 dxvaStructure.film_grain.matrix_coeff_is_identity = (pipe_av1->picture_parameter.matrix_coefficients == AVCOL_SPC_RGB);
588
589 dxvaStructure.film_grain.grain_seed = pipe_av1->picture_parameter.film_grain_info.grain_seed;
590 dxvaStructure.film_grain.num_y_points = pipe_av1->picture_parameter.film_grain_info.num_y_points;
591 for (uint32_t i = 0; i < pipe_av1->picture_parameter.film_grain_info.num_y_points; i++) {
592 dxvaStructure.film_grain.scaling_points_y[i][0] = pipe_av1->picture_parameter.film_grain_info.point_y_value[i];
593 dxvaStructure.film_grain.scaling_points_y[i][1] = pipe_av1->picture_parameter.film_grain_info.point_y_scaling[i];
594 }
595 dxvaStructure.film_grain.num_cb_points = pipe_av1->picture_parameter.film_grain_info.num_cb_points;
596 for (uint32_t i = 0; i < pipe_av1->picture_parameter.film_grain_info.num_cb_points; i++) {
597 dxvaStructure.film_grain.scaling_points_cb[i][0] = pipe_av1->picture_parameter.film_grain_info.point_cb_value[i];
598 dxvaStructure.film_grain.scaling_points_cb[i][1] = pipe_av1->picture_parameter.film_grain_info.point_cb_scaling[i];
599 }
600 dxvaStructure.film_grain.num_cr_points = pipe_av1->picture_parameter.film_grain_info.num_cr_points;
601 for (uint32_t i = 0; i < pipe_av1->picture_parameter.film_grain_info.num_cr_points; i++) {
602 dxvaStructure.film_grain.scaling_points_cr[i][0] = pipe_av1->picture_parameter.film_grain_info.point_cr_value[i];
603 dxvaStructure.film_grain.scaling_points_cr[i][1] = pipe_av1->picture_parameter.film_grain_info.point_cr_scaling[i];
604 }
605 for (uint32_t i = 0; i < 24; i++) {
606 dxvaStructure.film_grain.ar_coeffs_y[i] = pipe_av1->picture_parameter.film_grain_info.ar_coeffs_y[i];
607 }
608 for (uint32_t i = 0; i < 25; i++) {
609 dxvaStructure.film_grain.ar_coeffs_cb[i] = pipe_av1->picture_parameter.film_grain_info.ar_coeffs_cb[i];
610 dxvaStructure.film_grain.ar_coeffs_cr[i] = pipe_av1->picture_parameter.film_grain_info.ar_coeffs_cr[i];
611 }
612 dxvaStructure.film_grain.cb_mult = pipe_av1->picture_parameter.film_grain_info.cb_mult;
613 dxvaStructure.film_grain.cb_luma_mult = pipe_av1->picture_parameter.film_grain_info.cb_luma_mult;
614 dxvaStructure.film_grain.cr_mult = pipe_av1->picture_parameter.film_grain_info.cr_mult;
615 dxvaStructure.film_grain.cr_luma_mult = pipe_av1->picture_parameter.film_grain_info.cr_luma_mult;
616 dxvaStructure.film_grain.cb_offset = pipe_av1->picture_parameter.film_grain_info.cb_offset;
617 dxvaStructure.film_grain.cr_offset = pipe_av1->picture_parameter.film_grain_info.cr_offset;
618 dxvaStructure.film_grain.cr_offset = pipe_av1->picture_parameter.film_grain_info.cr_offset;
619 }
620
621 dxvaStructure.StatusReportFeedbackNumber = frameNum;
622 assert(dxvaStructure.StatusReportFeedbackNumber > 0);
623 return dxvaStructure;
624 }
625