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
33void 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
95void 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
123static 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
136static 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
147static 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
161static 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
177void 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