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 vlVaGetReferenceFrame(drv, vp9->reference_frames[i], &context->desc.vp9.ref[i]); 86 87 if (!context->decoder && !context->templat.max_references) 88 context->templat.max_references = NUM_VP9_REFS; 89} 90 91void vlVaHandleSliceParameterBufferVP9(vlVaContext *context, vlVaBuffer *buf) 92{ 93 VASliceParameterBufferVP9 *vp9 = buf->data; 94 int i; 95 96 assert(buf->size >= sizeof(VASliceParameterBufferVP9) && buf->num_elements == 1); 97 98 context->desc.vp9.slice_parameter.slice_data_size = vp9->slice_data_size; 99 context->desc.vp9.slice_parameter.slice_data_offset = vp9->slice_data_offset; 100 context->desc.vp9.slice_parameter.slice_data_flag = vp9->slice_data_flag; 101 102 for (i = 0; i < 8; ++i) { 103 context->desc.vp9.slice_parameter.seg_param[i].segment_flags.segment_reference_enabled = 104 vp9->seg_param[i].segment_flags.fields.segment_reference_enabled; 105 context->desc.vp9.slice_parameter.seg_param[i].segment_flags.segment_reference = 106 vp9->seg_param[i].segment_flags.fields.segment_reference; 107 context->desc.vp9.slice_parameter.seg_param[i].segment_flags.segment_reference_skipped = 108 vp9->seg_param[i].segment_flags.fields.segment_reference_skipped; 109 110 memcpy(context->desc.vp9.slice_parameter.seg_param[i].filter_level, vp9->seg_param[i].filter_level, 4 * 2); 111 112 context->desc.vp9.slice_parameter.seg_param[i].luma_ac_quant_scale = vp9->seg_param[i].luma_ac_quant_scale; 113 context->desc.vp9.slice_parameter.seg_param[i].luma_dc_quant_scale = vp9->seg_param[i].luma_dc_quant_scale; 114 context->desc.vp9.slice_parameter.seg_param[i].chroma_ac_quant_scale = vp9->seg_param[i].chroma_ac_quant_scale; 115 context->desc.vp9.slice_parameter.seg_param[i].chroma_dc_quant_scale = vp9->seg_param[i].chroma_dc_quant_scale; 116 } 117} 118 119static unsigned vp9_u(struct vl_vlc *vlc, unsigned n) 120{ 121 unsigned valid = vl_vlc_valid_bits(vlc); 122 123 if (n == 0) 124 return 0; 125 126 if (valid < 32) 127 vl_vlc_fillbits(vlc); 128 129 return vl_vlc_get_uimsbf(vlc, n); 130} 131 132static signed vp9_s(struct vl_vlc *vlc, unsigned n) 133{ 134 unsigned v; 135 bool s; 136 137 v = vp9_u(vlc, n); 138 s = vp9_u(vlc, 1); 139 140 return s ? -v : v; 141} 142 143static void bitdepth_colorspace_sampling(struct vl_vlc *vlc, unsigned profile) 144{ 145 unsigned cs; 146 147 if (profile == 2) 148 /* bit_depth */ 149 vp9_u(vlc, 1); 150 151 cs = vp9_u(vlc, 3); 152 if (cs != 7) 153 /* yuv_range_flag */ 154 vp9_u(vlc, 1); 155} 156 157static void frame_size(struct vl_vlc *vlc) 158{ 159 /* width_minus_one */ 160 vp9_u(vlc, 16); 161 /* height_minus_one */ 162 vp9_u(vlc, 16); 163 164 /* has_scaling */ 165 if (vp9_u(vlc, 1)) { 166 /* render_width_minus_one */ 167 vp9_u(vlc, 16); 168 /* render_height_minus_one */ 169 vp9_u(vlc, 16); 170 } 171} 172 173void vlVaDecoderVP9BitstreamHeader(vlVaContext *context, vlVaBuffer *buf) 174{ 175 struct vl_vlc vlc; 176 unsigned profile; 177 bool frame_type, show_frame, error_resilient_mode; 178 bool mode_ref_delta_enabled, mode_ref_delta_update = false; 179 int i; 180 181 vl_vlc_init(&vlc, 1, (const void * const*)&buf->data, 182 (const unsigned *)&context->desc.vp9.picture_parameter.frame_header_length_in_bytes); 183 184 /* frame_marker */ 185 if (vp9_u(&vlc, 2) != 0x2) 186 return; 187 188 profile = vp9_u(&vlc, 1) | vp9_u(&vlc, 1) << 1; 189 190 if (profile == 3) 191 profile += vp9_u(&vlc, 1); 192 193 if (profile != 0 && profile != 2) 194 return; 195 196 /* show_existing_frame */ 197 if (vp9_u(&vlc, 1)) 198 return; 199 200 frame_type = vp9_u(&vlc, 1); 201 show_frame = vp9_u(&vlc, 1); 202 error_resilient_mode = vp9_u(&vlc, 1); 203 204 if (frame_type == 0) { 205 /* sync_code */ 206 if (vp9_u(&vlc, 24) != 0x498342) 207 return; 208 209 bitdepth_colorspace_sampling(&vlc, profile); 210 frame_size(&vlc); 211 } else { 212 bool intra_only, size_in_refs = false; 213 214 intra_only = show_frame ? 0 : vp9_u(&vlc, 1); 215 if (!error_resilient_mode) 216 /* reset_frame_context */ 217 vp9_u(&vlc, 2); 218 219 if (intra_only) { 220 /* sync_code */ 221 if (vp9_u(&vlc, 24) != 0x498342) 222 return; 223 224 bitdepth_colorspace_sampling(&vlc, profile); 225 /* refresh_frame_flags */ 226 vp9_u(&vlc, 8); 227 frame_size(&vlc); 228 } else { 229 /* refresh_frame_flags */ 230 vp9_u(&vlc, 8); 231 232 for (i = 0; i < 3; ++i) { 233 /* frame refs */ 234 vp9_u(&vlc, 3); 235 vp9_u(&vlc, 1); 236 } 237 238 for (i = 0; i < 3; ++i) { 239 size_in_refs = vp9_u(&vlc, 1); 240 if (size_in_refs) 241 break; 242 } 243 244 if (!size_in_refs) { 245 /* width/height_minus_one */ 246 vp9_u(&vlc, 16); 247 vp9_u(&vlc, 16); 248 } 249 250 if (vp9_u(&vlc, 1)) { 251 /* render_width/height_minus_one */ 252 vp9_u(&vlc, 16); 253 vp9_u(&vlc, 16); 254 } 255 256 /* high_precision_mv */ 257 vp9_u(&vlc, 1); 258 /* filter_switchable */ 259 if (!vp9_u(&vlc, 1)) 260 /* filter_index */ 261 vp9_u(&vlc, 2); 262 } 263 } 264 if (!error_resilient_mode) { 265 /* refresh_frame_context */ 266 vp9_u(&vlc, 1); 267 /* frame_parallel_decoding_mode */ 268 vp9_u(&vlc, 1); 269 } 270 /* frame_context_index */ 271 vp9_u(&vlc, 2); 272 273 /* loop filter */ 274 275 /* filter_level */ 276 vp9_u(&vlc, 6); 277 /* sharpness_level */ 278 vp9_u(&vlc, 3); 279 280 mode_ref_delta_enabled = vp9_u(&vlc, 1); 281 if (mode_ref_delta_enabled) { 282 mode_ref_delta_update = vp9_u(&vlc, 1); 283 if (mode_ref_delta_update) { 284 for (i = 0; i < 4; ++i) { 285 /* update_ref_delta */ 286 if (vp9_u(&vlc, 1)) 287 /* ref_deltas */ 288 vp9_s(&vlc, 6); 289 } 290 for (i = 0; i < 2; ++i) { 291 /* update_mode_delta */ 292 if (vp9_u(&vlc, 1)) 293 /* mode_deltas */ 294 vp9_s(&vlc, 6); 295 } 296 } 297 } 298 context->desc.vp9.picture_parameter.mode_ref_delta_enabled = mode_ref_delta_enabled; 299 context->desc.vp9.picture_parameter.mode_ref_delta_update = mode_ref_delta_update; 300 301 /* quantization */ 302 303 context->desc.vp9.picture_parameter.base_qindex = vp9_u(&vlc, 8); 304 context->desc.vp9.picture_parameter.y_dc_delta_q = vp9_u(&vlc, 1) ? vp9_s(&vlc, 4) : 0; 305 context->desc.vp9.picture_parameter.uv_ac_delta_q = vp9_u(&vlc, 1) ? vp9_s(&vlc, 4) : 0; 306 context->desc.vp9.picture_parameter.uv_dc_delta_q = vp9_u(&vlc, 1) ? vp9_s(&vlc, 4) : 0; 307 308 /* segmentation */ 309 310 /* enabled */ 311 if (!vp9_u(&vlc, 1)) 312 return; 313 314 /* update_map */ 315 if (vp9_u(&vlc, 1)) { 316 for (i = 0; i < 7; ++i) { 317 /* tree_probs_set */ 318 if (vp9_u(&vlc, 1)) { 319 /* tree_probs */ 320 vp9_u(&vlc, 8); 321 } 322 } 323 324 /* temporal_update */ 325 if (vp9_u(&vlc, 1)) { 326 for (i = 0; i < 3; ++i) { 327 /* pred_probs_set */ 328 if (vp9_u(&vlc, 1)) 329 /* pred_probs */ 330 vp9_u(&vlc, 8); 331 } 332 } 333 } 334 335 /* update_data */ 336 if (vp9_u(&vlc, 1)) { 337 /* abs_delta */ 338 vp9_u(&vlc, 1); 339 for (i = 0; i < 8; ++i) { 340 /* Use alternate quantizer */ 341 if ((context->desc.vp9.slice_parameter.seg_param[i].alt_quant_enabled = vp9_u(&vlc, 1))) 342 context->desc.vp9.slice_parameter.seg_param[i].alt_quant = vp9_s(&vlc, 8); 343 /* Use alternate loop filter value */ 344 if ((context->desc.vp9.slice_parameter.seg_param[i].alt_lf_enabled = vp9_u(&vlc, 1))) 345 context->desc.vp9.slice_parameter.seg_param[i].alt_lf = vp9_s(&vlc, 6); 346 /* Optional Segment reference frame */ 347 if (vp9_u(&vlc, 1)) 348 vp9_u(&vlc, 2); 349 /* Optional Segment skip mode */ 350 vp9_u(&vlc, 1); 351 } 352 } 353} 354