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_vp9.h"
26 #include <cmath>
27
28 void
d3d12_video_decoder_refresh_dpb_active_references_vp9(struct d3d12_video_decoder * pD3D12Dec)29 d3d12_video_decoder_refresh_dpb_active_references_vp9(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_VP9 *pCurrPicParams = d3d12_video_decoder_get_current_dxva_picparams<DXVA_PicParams_VP9>(pD3D12Dec);
40
41 for (uint8_t i = 0; i < _countof(pCurrPicParams->ref_frame_map); i++) {
42 if (pD3D12Dec->m_pCurrentReferenceTargets[i]) {
43 pCurrPicParams->ref_frame_map[i].Index7Bits =
44 pD3D12Dec->m_spDPBManager->get_index7bits(pD3D12Dec->m_pCurrentReferenceTargets[i]);
45 }
46 }
47
48 for (uint8_t i = 0; i < _countof(pCurrPicParams->frame_refs); i++) {
49 if(!pCurrPicParams->frame_refs[i].AssociatedFlag)
50 pCurrPicParams->frame_refs[i].Index7Bits = pCurrPicParams->ref_frame_map[pCurrPicParams->frame_refs[i].Index7Bits].Index7Bits;
51 }
52
53 pD3D12Dec->m_spDPBManager->mark_all_references_as_unused();
54 pD3D12Dec->m_spDPBManager->mark_references_in_use(pCurrPicParams->ref_frame_map);
55
56 // Releases the underlying reference picture texture objects of all references that were not marked as used in this
57 // method.
58 pD3D12Dec->m_spDPBManager->release_unused_references_texture_memory();
59
60 pCurrPicParams->CurrPic.Index7Bits = pD3D12Dec->m_spDPBManager->get_index7bits(pD3D12Dec->m_pCurrentDecodeTarget);
61 }
62
63 void
d3d12_video_decoder_get_frame_info_vp9(struct d3d12_video_decoder * pD3D12Dec,uint32_t * pWidth,uint32_t * pHeight,uint16_t * pMaxDPB)64 d3d12_video_decoder_get_frame_info_vp9(
65 struct d3d12_video_decoder *pD3D12Dec, uint32_t *pWidth, uint32_t *pHeight, uint16_t *pMaxDPB)
66 {
67 auto pPicParams = d3d12_video_decoder_get_current_dxva_picparams<DXVA_PicParams_VP9>(pD3D12Dec);
68 *pWidth = pPicParams->width;
69 *pHeight = pPicParams->height;
70
71 /*
72 – The VP9 decoder maintains a pool (ref_frame_map[]) of 8 reference pictures at all times. Each
73 frame picks 3 reference frames (frame_refs[]) from the pool to use for inter prediction (known as Last,
74 Golden, and AltRef) of the current frame.
75 */
76 *pMaxDPB = 8 + 1 /*current picture*/;
77 }
78
79 void
d3d12_video_decoder_prepare_current_frame_references_vp9(struct d3d12_video_decoder * pD3D12Dec,ID3D12Resource * pTexture2D,uint32_t subresourceIndex)80 d3d12_video_decoder_prepare_current_frame_references_vp9(struct d3d12_video_decoder *pD3D12Dec,
81 ID3D12Resource *pTexture2D,
82 uint32_t subresourceIndex)
83 {
84 DXVA_PicParams_VP9 *pPicParams = d3d12_video_decoder_get_current_dxva_picparams<DXVA_PicParams_VP9>(pD3D12Dec);
85 pPicParams->CurrPic.Index7Bits = pD3D12Dec->m_spDPBManager->store_future_reference(pPicParams->CurrPic.Index7Bits,
86 pD3D12Dec->m_spVideoDecoderHeap,
87 pTexture2D,
88 subresourceIndex);
89 pD3D12Dec->m_spDPBManager->update_entries(
90 d3d12_video_decoder_get_current_dxva_picparams<DXVA_PicParams_VP9>(pD3D12Dec)->frame_refs,
91 pD3D12Dec->m_transitionsStorage);
92
93 pD3D12Dec->m_spDPBManager->update_entries(
94 d3d12_video_decoder_get_current_dxva_picparams<DXVA_PicParams_VP9>(pD3D12Dec)->ref_frame_map,
95 pD3D12Dec->m_transitionsStorage);
96
97 pD3D12Dec->m_spDecodeCommandList->ResourceBarrier(pD3D12Dec->m_transitionsStorage.size(), pD3D12Dec->m_transitionsStorage.data());
98
99 // Schedule reverse (back to common) transitions before command list closes for current frame
100 for (auto BarrierDesc : pD3D12Dec->m_transitionsStorage) {
101 std::swap(BarrierDesc.Transition.StateBefore, BarrierDesc.Transition.StateAfter);
102 pD3D12Dec->m_transitionsBeforeCloseCmdList.push_back(BarrierDesc);
103 }
104
105 debug_printf(
106 "[d3d12_video_decoder_prepare_current_frame_references_vp9] DXVA_PicParams_VP9 after index remapping)\n");
107 d3d12_video_decoder_log_pic_params_vp9(
108 d3d12_video_decoder_get_current_dxva_picparams<DXVA_PicParams_VP9>(pD3D12Dec));
109 }
110
111 void
d3d12_video_decoder_log_pic_params_vp9(DXVA_PicParams_VP9 * pPicParams)112 d3d12_video_decoder_log_pic_params_vp9(DXVA_PicParams_VP9 *pPicParams)
113 {
114 debug_printf("\n=============================================\n");
115 debug_printf("[D3D12 Video Decoder VP9 DXVA PicParams info]\n");
116
117 debug_printf("CurrPic.Index7Bits = %d\n", pPicParams->CurrPic.Index7Bits);
118 debug_printf("CurrPic.AssociatedFlag = %d\n", pPicParams->CurrPic.AssociatedFlag);
119 debug_printf("profile = %d\n", pPicParams->profile);
120 debug_printf("frame_type = %d\n", pPicParams->frame_type);
121 debug_printf("show_frame = %d\n", pPicParams->show_frame);
122 debug_printf("error_resilient_mode = %d\n", pPicParams->error_resilient_mode);
123 debug_printf("subsampling_x = %d\n", pPicParams->subsampling_x);
124 debug_printf("subsampling_y = %d\n", pPicParams->subsampling_y);
125 debug_printf("extra_plane = %d\n", pPicParams->extra_plane);
126 debug_printf("refresh_frame_context = %d\n", pPicParams->refresh_frame_context);
127 debug_printf("frame_parallel_decoding_mode = %d\n", pPicParams->frame_parallel_decoding_mode);
128 debug_printf("intra_only = %d\n", pPicParams->intra_only);
129 debug_printf("frame_context_idx = %d\n", pPicParams->frame_context_idx);
130 debug_printf("reset_frame_context = %d\n", pPicParams->reset_frame_context);
131 debug_printf("allow_high_precision_mv = %d\n", pPicParams->allow_high_precision_mv);
132 debug_printf("ReservedFormatInfo2Bits = %d\n", pPicParams->ReservedFormatInfo2Bits);
133 debug_printf("wFormatAndPictureInfoFlags = %d\n", pPicParams->wFormatAndPictureInfoFlags);
134 debug_printf("width = %d\n", pPicParams->width);
135 debug_printf("height = %d\n", pPicParams->height);
136 debug_printf("BitDepthMinus8Luma = %d\n", pPicParams->BitDepthMinus8Luma);
137 debug_printf("BitDepthMinus8Chroma = %d\n", pPicParams->BitDepthMinus8Chroma);
138 debug_printf("interp_filter = %d\n", pPicParams->interp_filter);
139 debug_printf("Reserved8Bits = %d\n", pPicParams->Reserved8Bits);
140
141 for (uint32_t i = 0; i < _countof(pPicParams->ref_frame_map); i++) {
142 debug_printf("ref_frame_map[%d].Index7Bits = %d\n", i, pPicParams->ref_frame_map[i].Index7Bits);
143 debug_printf("ref_frame_map[%d].AssociatedFlag = %d\n", i, pPicParams->ref_frame_map[i].AssociatedFlag);
144 }
145
146 for (uint32_t i = 0; i < _countof(pPicParams->ref_frame_coded_width); i++)
147 debug_printf("ref_frame_coded_width[%d] = %d\n", i, pPicParams->ref_frame_coded_width[i]);
148
149 for (uint32_t i = 0; i < _countof(pPicParams->ref_frame_coded_height); i++)
150 debug_printf("ref_frame_coded_height[%d] = %d\n", i, pPicParams->ref_frame_coded_height[i]);
151
152 for (uint32_t i = 0; i < _countof(pPicParams->frame_refs); i++) {
153 debug_printf("frame_refs[%d].Index7Bits = %d\n", i, pPicParams->frame_refs[i].Index7Bits);
154 debug_printf("frame_refs[%d].AssociatedFlag = %d\n", i, pPicParams->frame_refs[i].AssociatedFlag);
155 }
156
157 for (uint32_t i = 0; i < _countof(pPicParams->ref_frame_sign_bias); i++)
158 debug_printf("ref_frame_sign_bias[%d] = %d\n", i, pPicParams->ref_frame_sign_bias[i]);
159
160 debug_printf("filter_level = %d\n", pPicParams->filter_level);
161 debug_printf("sharpness_level = %d\n", pPicParams->sharpness_level);
162 debug_printf("mode_ref_delta_enabled = %d\n", pPicParams->mode_ref_delta_enabled);
163 debug_printf("mode_ref_delta_update = %d\n", pPicParams->mode_ref_delta_update);
164 debug_printf("use_prev_in_find_mv_refs = %d\n", pPicParams->use_prev_in_find_mv_refs);
165 debug_printf("ReservedControlInfo5Bits = %d\n", pPicParams->ReservedControlInfo5Bits);
166 debug_printf("wControlInfoFlags; = %d\n", pPicParams->wControlInfoFlags);
167
168 for (uint32_t i = 0; i < _countof(pPicParams->ref_deltas); i++)
169 debug_printf("ref_deltas[%d] = %d\n", i, pPicParams->ref_deltas[i]);
170 for (uint32_t i = 0; i < _countof(pPicParams->mode_deltas); i++)
171 debug_printf("mode_deltas[%d] = %d\n", i, pPicParams->mode_deltas[i]);
172
173 debug_printf("base_qindex = %d\n", pPicParams->base_qindex);
174 debug_printf("y_dc_delta_q = %d\n", pPicParams->y_dc_delta_q);
175 debug_printf("uv_dc_delta_q = %d\n", pPicParams->uv_dc_delta_q);
176 debug_printf("uv_ac_delta_q = %d\n", pPicParams->uv_ac_delta_q);
177
178 debug_printf("stVP9Segments.enabled = %d\n", pPicParams->stVP9Segments.enabled);
179 debug_printf("stVP9Segments.update_map = %d\n", pPicParams->stVP9Segments.update_map);
180 debug_printf("stVP9Segments.temporal_update = %d\n", pPicParams->stVP9Segments.temporal_update);
181 debug_printf("stVP9Segments.abs_delta = %d\n", pPicParams->stVP9Segments.abs_delta);
182 debug_printf("stVP9Segments.ReservedSegmentFlags4Bits = %d\n", pPicParams->stVP9Segments.ReservedSegmentFlags4Bits);
183 debug_printf("stVP9Segments.wSegmentInfoFlags = %d\n", pPicParams->stVP9Segments.wSegmentInfoFlags);
184
185 for (uint32_t i = 0; i < _countof(pPicParams->stVP9Segments.tree_probs); i++)
186 debug_printf("tree_probs[%d] = %d\n", i, pPicParams->stVP9Segments.tree_probs[i]);
187
188 for (uint32_t i = 0; i < _countof(pPicParams->stVP9Segments.pred_probs); i++)
189 debug_printf("pred_probs[%d] = %d\n", i, pPicParams->stVP9Segments.pred_probs[i]);
190
191 for (uint32_t i = 0; i < _countof(pPicParams->stVP9Segments.feature_data); i++)
192 for (uint32_t j = 0; j < _countof(pPicParams->stVP9Segments.feature_data[0]); j++)
193 debug_printf("feature_data[%d][%d] = %d\n", i, j, pPicParams->stVP9Segments.feature_data[i][j]);
194
195 for (uint32_t i = 0; i < _countof(pPicParams->stVP9Segments.feature_mask); i++)
196 debug_printf("feature_mask[%d] = %d\n", i, pPicParams->stVP9Segments.feature_mask[i]);
197
198 debug_printf("log2_tile_cols = %d\n", pPicParams->log2_tile_cols);
199 debug_printf("log2_tile_rows = %d\n", pPicParams->log2_tile_rows);
200 debug_printf("uncompressed_header_size_byte_aligned = %d\n", pPicParams->uncompressed_header_size_byte_aligned);
201 debug_printf("first_partition_size = %d\n", pPicParams->first_partition_size);
202 debug_printf("Reserved16Bits = %d\n", pPicParams->Reserved16Bits);
203 debug_printf("Reserved32Bits = %d\n", pPicParams->Reserved32Bits);
204 debug_printf("StatusReportFeedbackNumber = %d\n", pPicParams->StatusReportFeedbackNumber);
205 }
206
207 void
d3d12_video_decoder_prepare_dxva_slices_control_vp9(struct d3d12_video_decoder * pD3D12Dec,std::vector<uint8_t> & vecOutSliceControlBuffers,struct pipe_vp9_picture_desc * picture_vp9)208 d3d12_video_decoder_prepare_dxva_slices_control_vp9(struct d3d12_video_decoder *pD3D12Dec,
209 std::vector<uint8_t> &vecOutSliceControlBuffers,
210 struct pipe_vp9_picture_desc *picture_vp9)
211 {
212 if(!picture_vp9->slice_parameter.slice_info_present)
213 {
214 unreachable("Unsupported - need pipe_vp9_picture_desc.slice_parameter.slice_info_present");
215 }
216
217 debug_printf("[d3d12_video_decoder_vp9] Upper layer reported %d slices for this frame, parsing them below...\n",
218 picture_vp9->slice_parameter.slice_count);
219
220 uint64_t TotalSlicesDXVAArrayByteSize = picture_vp9->slice_parameter.slice_count * sizeof(DXVA_Slice_VPx_Short);
221 vecOutSliceControlBuffers.resize(TotalSlicesDXVAArrayByteSize);
222
223 uint8_t* pData = vecOutSliceControlBuffers.data();
224 for (uint32_t sliceIdx = 0; sliceIdx < picture_vp9->slice_parameter.slice_count; sliceIdx++)
225 {
226 DXVA_Slice_VPx_Short currentSliceEntry = {};
227 // From DXVA Spec
228 // wBadSliceChopping
229 // 0 All bits for the slice are located within the corresponding bitstream data buffer.
230 // 1 The bitstream data buffer contains the start of the slice, but not the entire slice, because the buffer is full.
231 // 2 The bitstream data buffer contains the end of the slice. It does not contain the start of the slice, because the start of the slice was located in the previous bitstream data buffer.
232 // 3 The bitstream data buffer does not contain the start of the slice (because the start of the slice was located in the previous bitstream data buffer),
233 // and it does not contain the end of the slice (because the current bitstream data buffer is also full).
234
235 switch (picture_vp9->slice_parameter.slice_data_flag[sliceIdx]) {
236 /* whole slice is in the buffer */
237 case PIPE_SLICE_BUFFER_PLACEMENT_TYPE_WHOLE:
238 currentSliceEntry.wBadSliceChopping = 0u;
239 break;
240 /* The beginning of the slice is in the buffer but the end is not */
241 case PIPE_SLICE_BUFFER_PLACEMENT_TYPE_BEGIN:
242 currentSliceEntry.wBadSliceChopping = 1u;
243 break;
244 /* Neither beginning nor end of the slice is in the buffer */
245 case PIPE_SLICE_BUFFER_PLACEMENT_TYPE_MIDDLE:
246 currentSliceEntry.wBadSliceChopping = 3u;
247 break;
248 /* end of the slice is in the buffer */
249 case PIPE_SLICE_BUFFER_PLACEMENT_TYPE_END:
250 currentSliceEntry.wBadSliceChopping = 2u;
251 break;
252 default:
253 {
254 unreachable("Unsupported pipe_slice_buffer_placement_type");
255 } break;
256 }
257
258 currentSliceEntry.SliceBytesInBuffer = picture_vp9->slice_parameter.slice_data_size[sliceIdx];
259 currentSliceEntry.BSNALunitDataLocation = picture_vp9->slice_parameter.slice_data_offset[sliceIdx];
260
261 debug_printf("[d3d12_video_decoder_vp9] Detected slice index %" PRIu32 " with SliceBytesInBuffer %d - BSNALunitDataLocation %d - wBadSliceChopping: %" PRIu16
262 " for frame with "
263 "fenceValue: %d\n",
264 sliceIdx,
265 currentSliceEntry.SliceBytesInBuffer,
266 currentSliceEntry.BSNALunitDataLocation,
267 currentSliceEntry.wBadSliceChopping,
268 pD3D12Dec->m_fenceValue);
269
270 memcpy(pData, ¤tSliceEntry, sizeof(DXVA_Slice_VPx_Short));
271 pData += sizeof(DXVA_Slice_VPx_Short);
272 }
273 assert(vecOutSliceControlBuffers.size() == TotalSlicesDXVAArrayByteSize);
274 }
275
276 DXVA_PicParams_VP9
d3d12_video_decoder_dxva_picparams_from_pipe_picparams_vp9(struct d3d12_video_decoder * pD3D12Dec,pipe_video_profile profile,pipe_vp9_picture_desc * pipe_vp9)277 d3d12_video_decoder_dxva_picparams_from_pipe_picparams_vp9(
278 struct d3d12_video_decoder *pD3D12Dec,
279 pipe_video_profile profile,
280 pipe_vp9_picture_desc *pipe_vp9)
281 {
282 uint32_t frameNum = pD3D12Dec->m_fenceValue;
283 DXVA_PicParams_VP9 dxvaStructure;
284 memset(&dxvaStructure, 0, sizeof(dxvaStructure));
285
286 dxvaStructure.profile = pipe_vp9->picture_parameter.profile;
287 dxvaStructure.wFormatAndPictureInfoFlags = ((pipe_vp9->picture_parameter.pic_fields.frame_type != 0) << 0) |
288 ((pipe_vp9->picture_parameter.pic_fields.show_frame != 0) << 1) |
289 (pipe_vp9->picture_parameter.pic_fields.error_resilient_mode << 2) |
290 (pipe_vp9->picture_parameter.pic_fields.subsampling_x << 3) |
291 (pipe_vp9->picture_parameter.pic_fields.subsampling_y << 4) |
292 (0 << 5) |
293 (pipe_vp9->picture_parameter.pic_fields.refresh_frame_context << 6) |
294 (pipe_vp9->picture_parameter.pic_fields.frame_parallel_decoding_mode << 7) |
295 (pipe_vp9->picture_parameter.pic_fields.intra_only << 8) |
296 (pipe_vp9->picture_parameter.pic_fields.frame_context_idx << 9) |
297 (pipe_vp9->picture_parameter.pic_fields.reset_frame_context << 11) |
298 ((pipe_vp9->picture_parameter.pic_fields.allow_high_precision_mv) << 13) |
299 (0 << 14);
300
301 dxvaStructure.width = pipe_vp9->picture_parameter.frame_width;
302 dxvaStructure.height = pipe_vp9->picture_parameter.frame_height;
303 dxvaStructure.BitDepthMinus8Luma = pipe_vp9->picture_parameter.bit_depth - 8;
304 dxvaStructure.BitDepthMinus8Chroma = pipe_vp9->picture_parameter.bit_depth - 8;
305 dxvaStructure.interp_filter = pipe_vp9->picture_parameter.pic_fields.mcomp_filter_type;
306 dxvaStructure.Reserved8Bits = 0;
307 for (uint32_t i = 0; i < 8; i++) {
308 if (pipe_vp9->ref[i]) {
309 dxvaStructure.ref_frame_coded_width[i] = pipe_vp9->ref[i]->width;
310 dxvaStructure.ref_frame_coded_height[i] = pipe_vp9->ref[i]->height;
311 } else
312 dxvaStructure.ref_frame_map[i].bPicEntry = DXVA_VP9_INVALID_PICTURE_ENTRY;
313 }
314
315 /* DXVA spec The enums and indices for ref_frame_sign_bias[] are defined */
316 const uint8_t signbias_last_index = 1;
317 const uint8_t signbias_golden_index = 2;
318 const uint8_t signbias_alt_index = 3;
319
320 /* AssociatedFlag When Index7Bits does not contain an index to a valid uncompressed surface, the value shall be set to 127, to indicate that the index is invalid. */
321 memset(&dxvaStructure.frame_refs[0], DXVA_VP9_INVALID_PICTURE_ENTRY, sizeof(dxvaStructure.frame_refs));
322
323 if (pipe_vp9->ref[pipe_vp9->picture_parameter.pic_fields.last_ref_frame]) {
324 /* AssociatedFlag When Index7Bits does not contain an index to a valid uncompressed surface, the value shall be set to 127, to indicate that the index is invalid. */
325 /* Mark AssociatedFlag = 0 so last_ref_frame will be replaced with the correct reference index in d3d12_video_decoder_refresh_dpb_active_references_vp9 */
326 dxvaStructure.frame_refs[0].AssociatedFlag = 0;
327 dxvaStructure.frame_refs[0].Index7Bits = pipe_vp9->picture_parameter.pic_fields.last_ref_frame;
328 dxvaStructure.ref_frame_sign_bias[signbias_last_index] = pipe_vp9->picture_parameter.pic_fields.last_ref_frame_sign_bias;
329 }
330
331 if (pipe_vp9->ref[pipe_vp9->picture_parameter.pic_fields.golden_ref_frame]) {
332 /* AssociatedFlag When Index7Bits does not contain an index to a valid uncompressed surface, the value shall be set to 127, to indicate that the index is invalid. */
333 /* Mark AssociatedFlag = 0 so golden_ref_frame will be replaced with the correct reference index in d3d12_video_decoder_refresh_dpb_active_references_vp9 */
334 dxvaStructure.frame_refs[1].AssociatedFlag = 0;
335 dxvaStructure.frame_refs[1].Index7Bits = pipe_vp9->picture_parameter.pic_fields.golden_ref_frame;
336 dxvaStructure.ref_frame_sign_bias[signbias_golden_index] = pipe_vp9->picture_parameter.pic_fields.golden_ref_frame_sign_bias;
337 }
338
339 if (pipe_vp9->ref[pipe_vp9->picture_parameter.pic_fields.alt_ref_frame]) {
340 /* AssociatedFlag When Index7Bits does not contain an index to a valid uncompressed surface, the value shall be set to 127, to indicate that the index is invalid. */
341 /* Mark AssociatedFlag = 0 so alt_ref_frame will be replaced with the correct reference index in d3d12_video_decoder_refresh_dpb_active_references_vp9 */
342 dxvaStructure.frame_refs[2].AssociatedFlag = 0;
343 dxvaStructure.frame_refs[2].Index7Bits = pipe_vp9->picture_parameter.pic_fields.alt_ref_frame;
344 dxvaStructure.ref_frame_sign_bias[signbias_alt_index] = pipe_vp9->picture_parameter.pic_fields.alt_ref_frame_sign_bias;
345 }
346
347 dxvaStructure.filter_level = pipe_vp9->picture_parameter.filter_level;
348 dxvaStructure.sharpness_level = pipe_vp9->picture_parameter.sharpness_level;
349
350 bool use_prev_in_find_mv_refs =
351 !pipe_vp9->picture_parameter.pic_fields.error_resilient_mode &&
352 !(pipe_vp9->picture_parameter.pic_fields.frame_type == 0 /*KEY_FRAME*/ || pipe_vp9->picture_parameter.pic_fields.intra_only) &&
353 pipe_vp9->picture_parameter.pic_fields.prev_show_frame &&
354 pipe_vp9->picture_parameter.frame_width == pipe_vp9->picture_parameter.prev_frame_width &&
355 pipe_vp9->picture_parameter.frame_height == pipe_vp9->picture_parameter.prev_frame_height;
356
357 dxvaStructure.wControlInfoFlags = (pipe_vp9->picture_parameter.mode_ref_delta_enabled << 0) |
358 (pipe_vp9->picture_parameter.mode_ref_delta_update << 1) |
359 (use_prev_in_find_mv_refs << 2) |
360 (0 << 3);
361
362 for (uint32_t i = 0; i < 4; i++)
363 dxvaStructure.ref_deltas[i] = pipe_vp9->picture_parameter.ref_deltas[i];
364
365 for (uint32_t i = 0; i < 2; i++)
366 dxvaStructure.mode_deltas[i] = pipe_vp9->picture_parameter.mode_deltas[i];
367
368 dxvaStructure.base_qindex = pipe_vp9->picture_parameter.base_qindex;
369 dxvaStructure.y_dc_delta_q = pipe_vp9->picture_parameter.y_dc_delta_q;
370 dxvaStructure.uv_dc_delta_q = pipe_vp9->picture_parameter.uv_ac_delta_q;
371 dxvaStructure.uv_ac_delta_q = pipe_vp9->picture_parameter.uv_dc_delta_q;
372
373 /* segmentation data */
374 dxvaStructure.stVP9Segments.wSegmentInfoFlags = (pipe_vp9->picture_parameter.pic_fields.segmentation_enabled << 0) |
375 (pipe_vp9->picture_parameter.pic_fields.segmentation_update_map << 1) |
376 (pipe_vp9->picture_parameter.pic_fields.segmentation_temporal_update << 2) |
377 (pipe_vp9->picture_parameter.abs_delta << 3) |
378 (0 << 4);
379
380 for (uint32_t i = 0; i < 7; i++)
381 dxvaStructure.stVP9Segments.tree_probs[i] = pipe_vp9->picture_parameter.mb_segment_tree_probs[i];
382
383 if (pipe_vp9->picture_parameter.pic_fields.segmentation_temporal_update)
384 for (uint32_t i = 0; i < 3; i++)
385 dxvaStructure.stVP9Segments.pred_probs[i] = pipe_vp9->picture_parameter.segment_pred_probs[i];
386 else
387 memset(dxvaStructure.stVP9Segments.pred_probs, 255, sizeof(dxvaStructure.stVP9Segments.pred_probs));
388
389 for (uint32_t i = 0; i < 8; i++) {
390 dxvaStructure.stVP9Segments.feature_mask[i] = (pipe_vp9->slice_parameter.seg_param[i].alt_quant_enabled << 0) |
391 (pipe_vp9->slice_parameter.seg_param[i].alt_lf_enabled << 1) |
392 (pipe_vp9->slice_parameter.seg_param[i].segment_flags.segment_reference_enabled << 2) |
393 (pipe_vp9->slice_parameter.seg_param[i].segment_flags.segment_reference_skipped << 3);
394
395 dxvaStructure.stVP9Segments.feature_data[i][0] = pipe_vp9->slice_parameter.seg_param[i].alt_quant;
396 dxvaStructure.stVP9Segments.feature_data[i][1] = pipe_vp9->slice_parameter.seg_param[i].alt_lf;
397 dxvaStructure.stVP9Segments.feature_data[i][2] = pipe_vp9->slice_parameter.seg_param[i].segment_flags.segment_reference;
398 dxvaStructure.stVP9Segments.feature_data[i][3] = 0;
399 }
400
401 dxvaStructure.log2_tile_cols = pipe_vp9->picture_parameter.log2_tile_columns;
402 dxvaStructure.log2_tile_rows = pipe_vp9->picture_parameter.log2_tile_rows;
403 dxvaStructure.uncompressed_header_size_byte_aligned = pipe_vp9->picture_parameter.frame_header_length_in_bytes;
404 dxvaStructure.first_partition_size = pipe_vp9->picture_parameter.first_partition_size;
405 dxvaStructure.StatusReportFeedbackNumber = frameNum;
406 assert(dxvaStructure.StatusReportFeedbackNumber > 0);
407 return dxvaStructure;
408 }
409