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