• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2018 Advanced Micro Devices, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 #include "vl/vl_vlc.h"
29 #include "va_private.h"
30 
31 #define NUM_VP9_REFS 8
32 
vlVaHandlePictureParameterBufferVP9(vlVaDriver * drv,vlVaContext * context,vlVaBuffer * buf)33 void vlVaHandlePictureParameterBufferVP9(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
34 {
35    VADecPictureParameterBufferVP9 *vp9 = buf->data;
36    int i;
37 
38    assert(buf->size >= sizeof(VADecPictureParameterBufferVP9) && buf->num_elements == 1);
39 
40    context->desc.vp9.picture_parameter.frame_width = vp9->frame_width;
41    context->desc.vp9.picture_parameter.frame_height = vp9->frame_height;
42 
43    context->desc.vp9.picture_parameter.pic_fields.subsampling_x = vp9->pic_fields.bits.subsampling_x;
44    context->desc.vp9.picture_parameter.pic_fields.subsampling_y = vp9->pic_fields.bits.subsampling_y;
45    context->desc.vp9.picture_parameter.pic_fields.frame_type = vp9->pic_fields.bits.frame_type;
46    context->desc.vp9.picture_parameter.pic_fields.show_frame = vp9->pic_fields.bits.show_frame;
47    context->desc.vp9.picture_parameter.pic_fields.error_resilient_mode = vp9->pic_fields.bits.error_resilient_mode;
48    context->desc.vp9.picture_parameter.pic_fields.intra_only = vp9->pic_fields.bits.intra_only;
49    context->desc.vp9.picture_parameter.pic_fields.allow_high_precision_mv = vp9->pic_fields.bits.allow_high_precision_mv;
50    context->desc.vp9.picture_parameter.pic_fields.mcomp_filter_type = vp9->pic_fields.bits.mcomp_filter_type;
51    context->desc.vp9.picture_parameter.pic_fields.frame_parallel_decoding_mode = vp9->pic_fields.bits.frame_parallel_decoding_mode;
52    context->desc.vp9.picture_parameter.pic_fields.reset_frame_context = vp9->pic_fields.bits.reset_frame_context;
53    context->desc.vp9.picture_parameter.pic_fields.refresh_frame_context = vp9->pic_fields.bits.refresh_frame_context;
54    context->desc.vp9.picture_parameter.pic_fields.frame_context_idx = vp9->pic_fields.bits.frame_context_idx;
55    context->desc.vp9.picture_parameter.pic_fields.segmentation_enabled = vp9->pic_fields.bits.segmentation_enabled;
56    context->desc.vp9.picture_parameter.pic_fields.segmentation_temporal_update = vp9->pic_fields.bits.segmentation_temporal_update;
57    context->desc.vp9.picture_parameter.pic_fields.segmentation_update_map = vp9->pic_fields.bits.segmentation_update_map;
58    context->desc.vp9.picture_parameter.pic_fields.last_ref_frame = vp9->pic_fields.bits.last_ref_frame;
59    context->desc.vp9.picture_parameter.pic_fields.last_ref_frame_sign_bias = vp9->pic_fields.bits.last_ref_frame_sign_bias;
60    context->desc.vp9.picture_parameter.pic_fields.golden_ref_frame = vp9->pic_fields.bits.golden_ref_frame;
61    context->desc.vp9.picture_parameter.pic_fields.golden_ref_frame_sign_bias = vp9->pic_fields.bits.golden_ref_frame_sign_bias;
62    context->desc.vp9.picture_parameter.pic_fields.alt_ref_frame = vp9->pic_fields.bits.alt_ref_frame;
63    context->desc.vp9.picture_parameter.pic_fields.alt_ref_frame_sign_bias = vp9->pic_fields.bits.alt_ref_frame_sign_bias;
64    context->desc.vp9.picture_parameter.pic_fields.lossless_flag = vp9->pic_fields.bits.lossless_flag;
65 
66    context->desc.vp9.picture_parameter.filter_level = vp9->filter_level;
67    context->desc.vp9.picture_parameter.sharpness_level = vp9->sharpness_level;
68 
69    context->desc.vp9.picture_parameter.log2_tile_rows = vp9->log2_tile_rows;
70    context->desc.vp9.picture_parameter.log2_tile_columns = vp9->log2_tile_columns;
71 
72    context->desc.vp9.picture_parameter.frame_header_length_in_bytes = vp9->frame_header_length_in_bytes;
73    context->desc.vp9.picture_parameter.first_partition_size = vp9->first_partition_size;
74 
75    for (i = 0; i < 7; ++i)
76       context->desc.vp9.picture_parameter.mb_segment_tree_probs[i] = vp9->mb_segment_tree_probs[i];
77    for (i = 0; i < 3; ++i)
78       context->desc.vp9.picture_parameter.segment_pred_probs[i] = vp9->segment_pred_probs[i];
79 
80    context->desc.vp9.picture_parameter.profile = vp9->profile;
81 
82    context->desc.vp9.picture_parameter.bit_depth = vp9->bit_depth;
83 
84    for (i = 0 ; i < NUM_VP9_REFS ; i++) {
85       if (vp9->pic_fields.bits.frame_type == 0)
86          context->desc.vp9.ref[i] = NULL;
87       else
88          vlVaGetReferenceFrame(drv, vp9->reference_frames[i], &context->desc.vp9.ref[i]);
89    }
90 
91    if (!context->decoder && !context->templat.max_references)
92       context->templat.max_references = NUM_VP9_REFS;
93 }
94 
vlVaHandleSliceParameterBufferVP9(vlVaContext * context,vlVaBuffer * buf)95 void vlVaHandleSliceParameterBufferVP9(vlVaContext *context, vlVaBuffer *buf)
96 {
97    VASliceParameterBufferVP9 *vp9 = buf->data;
98    int i;
99 
100    assert(buf->size >= sizeof(VASliceParameterBufferVP9) && buf->num_elements == 1);
101 
102    context->desc.vp9.slice_parameter.slice_data_size = vp9->slice_data_size;
103    context->desc.vp9.slice_parameter.slice_data_offset = vp9->slice_data_offset;
104    context->desc.vp9.slice_parameter.slice_data_flag = vp9->slice_data_flag;
105 
106    for (i = 0; i < 8; ++i) {
107       context->desc.vp9.slice_parameter.seg_param[i].segment_flags.segment_reference_enabled =
108          vp9->seg_param[i].segment_flags.fields.segment_reference_enabled;
109       context->desc.vp9.slice_parameter.seg_param[i].segment_flags.segment_reference =
110          vp9->seg_param[i].segment_flags.fields.segment_reference;
111       context->desc.vp9.slice_parameter.seg_param[i].segment_flags.segment_reference_skipped =
112          vp9->seg_param[i].segment_flags.fields.segment_reference_skipped;
113 
114       memcpy(context->desc.vp9.slice_parameter.seg_param[i].filter_level, vp9->seg_param[i].filter_level, 4 * 2);
115 
116       context->desc.vp9.slice_parameter.seg_param[i].luma_ac_quant_scale = vp9->seg_param[i].luma_ac_quant_scale;
117       context->desc.vp9.slice_parameter.seg_param[i].luma_dc_quant_scale = vp9->seg_param[i].luma_dc_quant_scale;
118       context->desc.vp9.slice_parameter.seg_param[i].chroma_ac_quant_scale = vp9->seg_param[i].chroma_ac_quant_scale;
119       context->desc.vp9.slice_parameter.seg_param[i].chroma_dc_quant_scale = vp9->seg_param[i].chroma_dc_quant_scale;
120    }
121 }
122 
vp9_u(struct vl_vlc * vlc,unsigned n)123 static unsigned vp9_u(struct vl_vlc *vlc, unsigned n)
124 {
125    unsigned valid = vl_vlc_valid_bits(vlc);
126 
127    if (n == 0)
128       return 0;
129 
130    if (valid < 32)
131       vl_vlc_fillbits(vlc);
132 
133    return vl_vlc_get_uimsbf(vlc, n);
134 }
135 
vp9_s(struct vl_vlc * vlc,unsigned n)136 static signed vp9_s(struct vl_vlc *vlc, unsigned n)
137 {
138    unsigned v;
139    bool s;
140 
141    v = vp9_u(vlc, n);
142    s = vp9_u(vlc, 1);
143 
144    return s ? -v : v;
145 }
146 
bitdepth_colorspace_sampling(struct vl_vlc * vlc,unsigned profile)147 static void bitdepth_colorspace_sampling(struct vl_vlc *vlc, unsigned profile)
148 {
149    unsigned cs;
150 
151    if (profile == 2)
152       /* bit_depth */
153       vp9_u(vlc, 1);
154 
155    cs = vp9_u(vlc, 3);
156    if (cs != 7)
157       /* yuv_range_flag */
158       vp9_u(vlc, 1);
159 }
160 
frame_size(struct vl_vlc * vlc)161 static void frame_size(struct vl_vlc *vlc)
162 {
163       /* width_minus_one */
164       vp9_u(vlc, 16);
165       /* height_minus_one */
166       vp9_u(vlc, 16);
167 
168       /* has_scaling */
169       if (vp9_u(vlc, 1)) {
170          /* render_width_minus_one */
171          vp9_u(vlc, 16);
172          /* render_height_minus_one */
173          vp9_u(vlc, 16);
174       }
175 }
176 
vlVaDecoderVP9BitstreamHeader(vlVaContext * context,vlVaBuffer * buf)177 void vlVaDecoderVP9BitstreamHeader(vlVaContext *context, vlVaBuffer *buf)
178 {
179    struct vl_vlc vlc;
180    unsigned profile;
181    bool frame_type, show_frame, error_resilient_mode;
182    bool mode_ref_delta_enabled, mode_ref_delta_update = false;
183    int i;
184 
185    vl_vlc_init(&vlc, 1, (const void * const*)&buf->data,
186       (const unsigned *)&context->desc.vp9.picture_parameter.frame_header_length_in_bytes);
187 
188    /* frame_marker */
189    if (vp9_u(&vlc, 2) != 0x2)
190       return;
191 
192    profile = vp9_u(&vlc, 1) | vp9_u(&vlc, 1) << 1;
193 
194    if (profile == 3)
195       profile += vp9_u(&vlc, 1);
196 
197    if (profile != 0 && profile != 2)
198       return;
199 
200    /* show_existing_frame */
201    if (vp9_u(&vlc, 1))
202       return;
203 
204    frame_type = vp9_u(&vlc, 1);
205    show_frame = vp9_u(&vlc, 1);
206    error_resilient_mode = vp9_u(&vlc, 1);
207 
208    if (frame_type == 0) {
209       /* sync_code */
210       if (vp9_u(&vlc, 24) != 0x498342)
211          return;
212 
213       bitdepth_colorspace_sampling(&vlc, profile);
214       frame_size(&vlc);
215    } else {
216       bool intra_only, size_in_refs = false;
217 
218       intra_only = show_frame ? 0 : vp9_u(&vlc, 1);
219       if (!error_resilient_mode)
220          /* reset_frame_context */
221          vp9_u(&vlc, 2);
222 
223       if (intra_only) {
224          /* sync_code */
225          if (vp9_u(&vlc, 24) != 0x498342)
226             return;
227 
228          bitdepth_colorspace_sampling(&vlc, profile);
229          /* refresh_frame_flags */
230          vp9_u(&vlc, 8);
231          frame_size(&vlc);
232       } else {
233          /* refresh_frame_flags */
234          vp9_u(&vlc, 8);
235 
236          for (i = 0; i < 3; ++i) {
237             /* frame refs */
238             vp9_u(&vlc, 3);
239             vp9_u(&vlc, 1);
240          }
241 
242          for (i = 0; i < 3; ++i) {
243             size_in_refs = vp9_u(&vlc, 1);
244             if (size_in_refs)
245                break;
246          }
247 
248          if (!size_in_refs) {
249             /* width/height_minus_one */
250             vp9_u(&vlc, 16);
251             vp9_u(&vlc, 16);
252          }
253 
254          if (vp9_u(&vlc, 1)) {
255             /* render_width/height_minus_one */
256             vp9_u(&vlc, 16);
257             vp9_u(&vlc, 16);
258          }
259 
260          /* high_precision_mv */
261          vp9_u(&vlc, 1);
262          /* filter_switchable */
263          if (!vp9_u(&vlc, 1))
264             /* filter_index */
265             vp9_u(&vlc, 2);
266       }
267    }
268    if (!error_resilient_mode) {
269       /* refresh_frame_context */
270       vp9_u(&vlc, 1);
271       /* frame_parallel_decoding_mode */
272       vp9_u(&vlc, 1);
273    }
274    /* frame_context_index */
275    vp9_u(&vlc, 2);
276 
277    /* loop filter */
278 
279    /* filter_level */
280    vp9_u(&vlc, 6);
281    /* sharpness_level */
282    vp9_u(&vlc, 3);
283 
284    mode_ref_delta_enabled = vp9_u(&vlc, 1);
285    if (mode_ref_delta_enabled) {
286       mode_ref_delta_update = vp9_u(&vlc, 1);
287       if (mode_ref_delta_update) {
288          for (i = 0; i < 4; ++i) {
289             /* update_ref_delta */
290             if (vp9_u(&vlc, 1))
291                /* ref_deltas */
292                vp9_s(&vlc, 6);
293          }
294          for (i = 0; i < 2; ++i) {
295             /* update_mode_delta */
296             if (vp9_u(&vlc, 1))
297                /* mode_deltas */
298                vp9_s(&vlc, 6);
299          }
300       }
301    }
302    context->desc.vp9.picture_parameter.mode_ref_delta_enabled = mode_ref_delta_enabled;
303    context->desc.vp9.picture_parameter.mode_ref_delta_update = mode_ref_delta_update;
304 
305    /* quantization */
306 
307    context->desc.vp9.picture_parameter.base_qindex = vp9_u(&vlc, 8);
308    context->desc.vp9.picture_parameter.y_dc_delta_q = vp9_u(&vlc, 1) ? vp9_s(&vlc, 4) : 0;
309    context->desc.vp9.picture_parameter.uv_ac_delta_q = vp9_u(&vlc, 1) ? vp9_s(&vlc, 4) : 0;
310    context->desc.vp9.picture_parameter.uv_dc_delta_q = vp9_u(&vlc, 1) ? vp9_s(&vlc, 4) : 0;
311 
312    /* segmentation */
313 
314    /* enabled */
315    if (!vp9_u(&vlc, 1))
316       return;
317 
318    /* update_map */
319    if (vp9_u(&vlc, 1)) {
320       for (i = 0; i < 7; ++i) {
321          /* tree_probs_set */
322          if (vp9_u(&vlc, 1)) {
323             /* tree_probs */
324             vp9_u(&vlc, 8);
325          }
326       }
327 
328       /* temporal_update */
329       if (vp9_u(&vlc, 1)) {
330          for (i = 0; i < 3; ++i) {
331             /* pred_probs_set */
332             if (vp9_u(&vlc, 1))
333                /* pred_probs */
334                vp9_u(&vlc, 8);
335          }
336       }
337    }
338 
339    /* update_data */
340    if (vp9_u(&vlc, 1)) {
341       /* abs_delta */
342       context->desc.vp9.picture_parameter.abs_delta = vp9_u(&vlc, 1);
343       for (i = 0; i < 8; ++i) {
344          /* Use alternate quantizer */
345          if ((context->desc.vp9.slice_parameter.seg_param[i].alt_quant_enabled = vp9_u(&vlc, 1)))
346             context->desc.vp9.slice_parameter.seg_param[i].alt_quant = vp9_s(&vlc, 8);
347          /* Use alternate loop filter value */
348          if ((context->desc.vp9.slice_parameter.seg_param[i].alt_lf_enabled = vp9_u(&vlc, 1)))
349             context->desc.vp9.slice_parameter.seg_param[i].alt_lf = vp9_s(&vlc, 6);
350          /* Optional Segment reference frame */
351          if (vp9_u(&vlc, 1))
352             vp9_u(&vlc, 2);
353          /* Optional Segment skip mode */
354          vp9_u(&vlc, 1);
355       }
356    }
357 }
358