17ec681f3Smrg/************************************************************************** 27ec681f3Smrg * 37ec681f3Smrg * Copyright 2018 Advanced Micro Devices, Inc. 47ec681f3Smrg * All Rights Reserved. 57ec681f3Smrg * 67ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 77ec681f3Smrg * copy of this software and associated documentation files (the 87ec681f3Smrg * "Software"), to deal in the Software without restriction, including 97ec681f3Smrg * without limitation the rights to use, copy, modify, merge, publish, 107ec681f3Smrg * distribute, sub license, and/or sell copies of the Software, and to 117ec681f3Smrg * permit persons to whom the Software is furnished to do so, subject to 127ec681f3Smrg * the following conditions: 137ec681f3Smrg * 147ec681f3Smrg * The above copyright notice and this permission notice (including the 157ec681f3Smrg * next paragraph) shall be included in all copies or substantial portions 167ec681f3Smrg * of the Software. 177ec681f3Smrg * 187ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 197ec681f3Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 207ec681f3Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 217ec681f3Smrg * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR 227ec681f3Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 237ec681f3Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 247ec681f3Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 257ec681f3Smrg * 267ec681f3Smrg **************************************************************************/ 277ec681f3Smrg 287ec681f3Smrg#include "vl/vl_vlc.h" 297ec681f3Smrg#include "va_private.h" 307ec681f3Smrg 317ec681f3Smrg#define NUM_VP9_REFS 8 327ec681f3Smrg 337ec681f3Smrgvoid vlVaHandlePictureParameterBufferVP9(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) 347ec681f3Smrg{ 357ec681f3Smrg VADecPictureParameterBufferVP9 *vp9 = buf->data; 367ec681f3Smrg int i; 377ec681f3Smrg 387ec681f3Smrg assert(buf->size >= sizeof(VADecPictureParameterBufferVP9) && buf->num_elements == 1); 397ec681f3Smrg 407ec681f3Smrg context->desc.vp9.picture_parameter.frame_width = vp9->frame_width; 417ec681f3Smrg context->desc.vp9.picture_parameter.frame_height = vp9->frame_height; 427ec681f3Smrg 437ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.subsampling_x = vp9->pic_fields.bits.subsampling_x; 447ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.subsampling_y = vp9->pic_fields.bits.subsampling_y; 457ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.frame_type = vp9->pic_fields.bits.frame_type; 467ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.show_frame = vp9->pic_fields.bits.show_frame; 477ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.error_resilient_mode = vp9->pic_fields.bits.error_resilient_mode; 487ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.intra_only = vp9->pic_fields.bits.intra_only; 497ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.allow_high_precision_mv = vp9->pic_fields.bits.allow_high_precision_mv; 507ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.mcomp_filter_type = vp9->pic_fields.bits.mcomp_filter_type; 517ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.frame_parallel_decoding_mode = vp9->pic_fields.bits.frame_parallel_decoding_mode; 527ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.reset_frame_context = vp9->pic_fields.bits.reset_frame_context; 537ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.refresh_frame_context = vp9->pic_fields.bits.refresh_frame_context; 547ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.frame_context_idx = vp9->pic_fields.bits.frame_context_idx; 557ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.segmentation_enabled = vp9->pic_fields.bits.segmentation_enabled; 567ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.segmentation_temporal_update = vp9->pic_fields.bits.segmentation_temporal_update; 577ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.segmentation_update_map = vp9->pic_fields.bits.segmentation_update_map; 587ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.last_ref_frame = vp9->pic_fields.bits.last_ref_frame; 597ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.last_ref_frame_sign_bias = vp9->pic_fields.bits.last_ref_frame_sign_bias; 607ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.golden_ref_frame = vp9->pic_fields.bits.golden_ref_frame; 617ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.golden_ref_frame_sign_bias = vp9->pic_fields.bits.golden_ref_frame_sign_bias; 627ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.alt_ref_frame = vp9->pic_fields.bits.alt_ref_frame; 637ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.alt_ref_frame_sign_bias = vp9->pic_fields.bits.alt_ref_frame_sign_bias; 647ec681f3Smrg context->desc.vp9.picture_parameter.pic_fields.lossless_flag = vp9->pic_fields.bits.lossless_flag; 657ec681f3Smrg 667ec681f3Smrg context->desc.vp9.picture_parameter.filter_level = vp9->filter_level; 677ec681f3Smrg context->desc.vp9.picture_parameter.sharpness_level = vp9->sharpness_level; 687ec681f3Smrg 697ec681f3Smrg context->desc.vp9.picture_parameter.log2_tile_rows = vp9->log2_tile_rows; 707ec681f3Smrg context->desc.vp9.picture_parameter.log2_tile_columns = vp9->log2_tile_columns; 717ec681f3Smrg 727ec681f3Smrg context->desc.vp9.picture_parameter.frame_header_length_in_bytes = vp9->frame_header_length_in_bytes; 737ec681f3Smrg context->desc.vp9.picture_parameter.first_partition_size = vp9->first_partition_size; 747ec681f3Smrg 757ec681f3Smrg for (i = 0; i < 7; ++i) 767ec681f3Smrg context->desc.vp9.picture_parameter.mb_segment_tree_probs[i] = vp9->mb_segment_tree_probs[i]; 777ec681f3Smrg for (i = 0; i < 3; ++i) 787ec681f3Smrg context->desc.vp9.picture_parameter.segment_pred_probs[i] = vp9->segment_pred_probs[i]; 797ec681f3Smrg 807ec681f3Smrg context->desc.vp9.picture_parameter.profile = vp9->profile; 817ec681f3Smrg 827ec681f3Smrg context->desc.vp9.picture_parameter.bit_depth = vp9->bit_depth; 837ec681f3Smrg 847ec681f3Smrg for (i = 0 ; i < NUM_VP9_REFS ; i++) { 857ec681f3Smrg if (vp9->pic_fields.bits.frame_type == 0) 867ec681f3Smrg context->desc.vp9.ref[i] = NULL; 877ec681f3Smrg else 887ec681f3Smrg vlVaGetReferenceFrame(drv, vp9->reference_frames[i], &context->desc.vp9.ref[i]); 897ec681f3Smrg } 907ec681f3Smrg 917ec681f3Smrg if (!context->decoder && !context->templat.max_references) 927ec681f3Smrg context->templat.max_references = NUM_VP9_REFS; 937ec681f3Smrg} 947ec681f3Smrg 957ec681f3Smrgvoid vlVaHandleSliceParameterBufferVP9(vlVaContext *context, vlVaBuffer *buf) 967ec681f3Smrg{ 977ec681f3Smrg VASliceParameterBufferVP9 *vp9 = buf->data; 987ec681f3Smrg int i; 997ec681f3Smrg 1007ec681f3Smrg assert(buf->size >= sizeof(VASliceParameterBufferVP9) && buf->num_elements == 1); 1017ec681f3Smrg 1027ec681f3Smrg context->desc.vp9.slice_parameter.slice_data_size = vp9->slice_data_size; 1037ec681f3Smrg context->desc.vp9.slice_parameter.slice_data_offset = vp9->slice_data_offset; 1047ec681f3Smrg context->desc.vp9.slice_parameter.slice_data_flag = vp9->slice_data_flag; 1057ec681f3Smrg 1067ec681f3Smrg for (i = 0; i < 8; ++i) { 1077ec681f3Smrg context->desc.vp9.slice_parameter.seg_param[i].segment_flags.segment_reference_enabled = 1087ec681f3Smrg vp9->seg_param[i].segment_flags.fields.segment_reference_enabled; 1097ec681f3Smrg context->desc.vp9.slice_parameter.seg_param[i].segment_flags.segment_reference = 1107ec681f3Smrg vp9->seg_param[i].segment_flags.fields.segment_reference; 1117ec681f3Smrg context->desc.vp9.slice_parameter.seg_param[i].segment_flags.segment_reference_skipped = 1127ec681f3Smrg vp9->seg_param[i].segment_flags.fields.segment_reference_skipped; 1137ec681f3Smrg 1147ec681f3Smrg memcpy(context->desc.vp9.slice_parameter.seg_param[i].filter_level, vp9->seg_param[i].filter_level, 4 * 2); 1157ec681f3Smrg 1167ec681f3Smrg context->desc.vp9.slice_parameter.seg_param[i].luma_ac_quant_scale = vp9->seg_param[i].luma_ac_quant_scale; 1177ec681f3Smrg context->desc.vp9.slice_parameter.seg_param[i].luma_dc_quant_scale = vp9->seg_param[i].luma_dc_quant_scale; 1187ec681f3Smrg context->desc.vp9.slice_parameter.seg_param[i].chroma_ac_quant_scale = vp9->seg_param[i].chroma_ac_quant_scale; 1197ec681f3Smrg context->desc.vp9.slice_parameter.seg_param[i].chroma_dc_quant_scale = vp9->seg_param[i].chroma_dc_quant_scale; 1207ec681f3Smrg } 1217ec681f3Smrg} 1227ec681f3Smrg 1237ec681f3Smrgstatic unsigned vp9_u(struct vl_vlc *vlc, unsigned n) 1247ec681f3Smrg{ 1257ec681f3Smrg unsigned valid = vl_vlc_valid_bits(vlc); 1267ec681f3Smrg 1277ec681f3Smrg if (n == 0) 1287ec681f3Smrg return 0; 1297ec681f3Smrg 1307ec681f3Smrg if (valid < 32) 1317ec681f3Smrg vl_vlc_fillbits(vlc); 1327ec681f3Smrg 1337ec681f3Smrg return vl_vlc_get_uimsbf(vlc, n); 1347ec681f3Smrg} 1357ec681f3Smrg 1367ec681f3Smrgstatic signed vp9_s(struct vl_vlc *vlc, unsigned n) 1377ec681f3Smrg{ 1387ec681f3Smrg unsigned v; 1397ec681f3Smrg bool s; 1407ec681f3Smrg 1417ec681f3Smrg v = vp9_u(vlc, n); 1427ec681f3Smrg s = vp9_u(vlc, 1); 1437ec681f3Smrg 1447ec681f3Smrg return s ? -v : v; 1457ec681f3Smrg} 1467ec681f3Smrg 1477ec681f3Smrgstatic void bitdepth_colorspace_sampling(struct vl_vlc *vlc, unsigned profile) 1487ec681f3Smrg{ 1497ec681f3Smrg unsigned cs; 1507ec681f3Smrg 1517ec681f3Smrg if (profile == 2) 1527ec681f3Smrg /* bit_depth */ 1537ec681f3Smrg vp9_u(vlc, 1); 1547ec681f3Smrg 1557ec681f3Smrg cs = vp9_u(vlc, 3); 1567ec681f3Smrg if (cs != 7) 1577ec681f3Smrg /* yuv_range_flag */ 1587ec681f3Smrg vp9_u(vlc, 1); 1597ec681f3Smrg} 1607ec681f3Smrg 1617ec681f3Smrgstatic void frame_size(struct vl_vlc *vlc) 1627ec681f3Smrg{ 1637ec681f3Smrg /* width_minus_one */ 1647ec681f3Smrg vp9_u(vlc, 16); 1657ec681f3Smrg /* height_minus_one */ 1667ec681f3Smrg vp9_u(vlc, 16); 1677ec681f3Smrg 1687ec681f3Smrg /* has_scaling */ 1697ec681f3Smrg if (vp9_u(vlc, 1)) { 1707ec681f3Smrg /* render_width_minus_one */ 1717ec681f3Smrg vp9_u(vlc, 16); 1727ec681f3Smrg /* render_height_minus_one */ 1737ec681f3Smrg vp9_u(vlc, 16); 1747ec681f3Smrg } 1757ec681f3Smrg} 1767ec681f3Smrg 1777ec681f3Smrgvoid vlVaDecoderVP9BitstreamHeader(vlVaContext *context, vlVaBuffer *buf) 1787ec681f3Smrg{ 1797ec681f3Smrg struct vl_vlc vlc; 1807ec681f3Smrg unsigned profile; 1817ec681f3Smrg bool frame_type, show_frame, error_resilient_mode; 1827ec681f3Smrg bool mode_ref_delta_enabled, mode_ref_delta_update = false; 1837ec681f3Smrg int i; 1847ec681f3Smrg 1857ec681f3Smrg vl_vlc_init(&vlc, 1, (const void * const*)&buf->data, 1867ec681f3Smrg (const unsigned *)&context->desc.vp9.picture_parameter.frame_header_length_in_bytes); 1877ec681f3Smrg 1887ec681f3Smrg /* frame_marker */ 1897ec681f3Smrg if (vp9_u(&vlc, 2) != 0x2) 1907ec681f3Smrg return; 1917ec681f3Smrg 1927ec681f3Smrg profile = vp9_u(&vlc, 1) | vp9_u(&vlc, 1) << 1; 1937ec681f3Smrg 1947ec681f3Smrg if (profile == 3) 1957ec681f3Smrg profile += vp9_u(&vlc, 1); 1967ec681f3Smrg 1977ec681f3Smrg if (profile != 0 && profile != 2) 1987ec681f3Smrg return; 1997ec681f3Smrg 2007ec681f3Smrg /* show_existing_frame */ 2017ec681f3Smrg if (vp9_u(&vlc, 1)) 2027ec681f3Smrg return; 2037ec681f3Smrg 2047ec681f3Smrg frame_type = vp9_u(&vlc, 1); 2057ec681f3Smrg show_frame = vp9_u(&vlc, 1); 2067ec681f3Smrg error_resilient_mode = vp9_u(&vlc, 1); 2077ec681f3Smrg 2087ec681f3Smrg if (frame_type == 0) { 2097ec681f3Smrg /* sync_code */ 2107ec681f3Smrg if (vp9_u(&vlc, 24) != 0x498342) 2117ec681f3Smrg return; 2127ec681f3Smrg 2137ec681f3Smrg bitdepth_colorspace_sampling(&vlc, profile); 2147ec681f3Smrg frame_size(&vlc); 2157ec681f3Smrg } else { 2167ec681f3Smrg bool intra_only, size_in_refs = false; 2177ec681f3Smrg 2187ec681f3Smrg intra_only = show_frame ? 0 : vp9_u(&vlc, 1); 2197ec681f3Smrg if (!error_resilient_mode) 2207ec681f3Smrg /* reset_frame_context */ 2217ec681f3Smrg vp9_u(&vlc, 2); 2227ec681f3Smrg 2237ec681f3Smrg if (intra_only) { 2247ec681f3Smrg /* sync_code */ 2257ec681f3Smrg if (vp9_u(&vlc, 24) != 0x498342) 2267ec681f3Smrg return; 2277ec681f3Smrg 2287ec681f3Smrg bitdepth_colorspace_sampling(&vlc, profile); 2297ec681f3Smrg /* refresh_frame_flags */ 2307ec681f3Smrg vp9_u(&vlc, 8); 2317ec681f3Smrg frame_size(&vlc); 2327ec681f3Smrg } else { 2337ec681f3Smrg /* refresh_frame_flags */ 2347ec681f3Smrg vp9_u(&vlc, 8); 2357ec681f3Smrg 2367ec681f3Smrg for (i = 0; i < 3; ++i) { 2377ec681f3Smrg /* frame refs */ 2387ec681f3Smrg vp9_u(&vlc, 3); 2397ec681f3Smrg vp9_u(&vlc, 1); 2407ec681f3Smrg } 2417ec681f3Smrg 2427ec681f3Smrg for (i = 0; i < 3; ++i) { 2437ec681f3Smrg size_in_refs = vp9_u(&vlc, 1); 2447ec681f3Smrg if (size_in_refs) 2457ec681f3Smrg break; 2467ec681f3Smrg } 2477ec681f3Smrg 2487ec681f3Smrg if (!size_in_refs) { 2497ec681f3Smrg /* width/height_minus_one */ 2507ec681f3Smrg vp9_u(&vlc, 16); 2517ec681f3Smrg vp9_u(&vlc, 16); 2527ec681f3Smrg } 2537ec681f3Smrg 2547ec681f3Smrg if (vp9_u(&vlc, 1)) { 2557ec681f3Smrg /* render_width/height_minus_one */ 2567ec681f3Smrg vp9_u(&vlc, 16); 2577ec681f3Smrg vp9_u(&vlc, 16); 2587ec681f3Smrg } 2597ec681f3Smrg 2607ec681f3Smrg /* high_precision_mv */ 2617ec681f3Smrg vp9_u(&vlc, 1); 2627ec681f3Smrg /* filter_switchable */ 2637ec681f3Smrg if (!vp9_u(&vlc, 1)) 2647ec681f3Smrg /* filter_index */ 2657ec681f3Smrg vp9_u(&vlc, 2); 2667ec681f3Smrg } 2677ec681f3Smrg } 2687ec681f3Smrg if (!error_resilient_mode) { 2697ec681f3Smrg /* refresh_frame_context */ 2707ec681f3Smrg vp9_u(&vlc, 1); 2717ec681f3Smrg /* frame_parallel_decoding_mode */ 2727ec681f3Smrg vp9_u(&vlc, 1); 2737ec681f3Smrg } 2747ec681f3Smrg /* frame_context_index */ 2757ec681f3Smrg vp9_u(&vlc, 2); 2767ec681f3Smrg 2777ec681f3Smrg /* loop filter */ 2787ec681f3Smrg 2797ec681f3Smrg /* filter_level */ 2807ec681f3Smrg vp9_u(&vlc, 6); 2817ec681f3Smrg /* sharpness_level */ 2827ec681f3Smrg vp9_u(&vlc, 3); 2837ec681f3Smrg 2847ec681f3Smrg mode_ref_delta_enabled = vp9_u(&vlc, 1); 2857ec681f3Smrg if (mode_ref_delta_enabled) { 2867ec681f3Smrg mode_ref_delta_update = vp9_u(&vlc, 1); 2877ec681f3Smrg if (mode_ref_delta_update) { 2887ec681f3Smrg for (i = 0; i < 4; ++i) { 2897ec681f3Smrg /* update_ref_delta */ 2907ec681f3Smrg if (vp9_u(&vlc, 1)) 2917ec681f3Smrg /* ref_deltas */ 2927ec681f3Smrg vp9_s(&vlc, 6); 2937ec681f3Smrg } 2947ec681f3Smrg for (i = 0; i < 2; ++i) { 2957ec681f3Smrg /* update_mode_delta */ 2967ec681f3Smrg if (vp9_u(&vlc, 1)) 2977ec681f3Smrg /* mode_deltas */ 2987ec681f3Smrg vp9_s(&vlc, 6); 2997ec681f3Smrg } 3007ec681f3Smrg } 3017ec681f3Smrg } 3027ec681f3Smrg context->desc.vp9.picture_parameter.mode_ref_delta_enabled = mode_ref_delta_enabled; 3037ec681f3Smrg context->desc.vp9.picture_parameter.mode_ref_delta_update = mode_ref_delta_update; 3047ec681f3Smrg 3057ec681f3Smrg /* quantization */ 3067ec681f3Smrg 3077ec681f3Smrg context->desc.vp9.picture_parameter.base_qindex = vp9_u(&vlc, 8); 3087ec681f3Smrg context->desc.vp9.picture_parameter.y_dc_delta_q = vp9_u(&vlc, 1) ? vp9_s(&vlc, 4) : 0; 3097ec681f3Smrg context->desc.vp9.picture_parameter.uv_ac_delta_q = vp9_u(&vlc, 1) ? vp9_s(&vlc, 4) : 0; 3107ec681f3Smrg context->desc.vp9.picture_parameter.uv_dc_delta_q = vp9_u(&vlc, 1) ? vp9_s(&vlc, 4) : 0; 3117ec681f3Smrg 3127ec681f3Smrg /* segmentation */ 3137ec681f3Smrg 3147ec681f3Smrg /* enabled */ 3157ec681f3Smrg if (!vp9_u(&vlc, 1)) 3167ec681f3Smrg return; 3177ec681f3Smrg 3187ec681f3Smrg /* update_map */ 3197ec681f3Smrg if (vp9_u(&vlc, 1)) { 3207ec681f3Smrg for (i = 0; i < 7; ++i) { 3217ec681f3Smrg /* tree_probs_set */ 3227ec681f3Smrg if (vp9_u(&vlc, 1)) { 3237ec681f3Smrg /* tree_probs */ 3247ec681f3Smrg vp9_u(&vlc, 8); 3257ec681f3Smrg } 3267ec681f3Smrg } 3277ec681f3Smrg 3287ec681f3Smrg /* temporal_update */ 3297ec681f3Smrg if (vp9_u(&vlc, 1)) { 3307ec681f3Smrg for (i = 0; i < 3; ++i) { 3317ec681f3Smrg /* pred_probs_set */ 3327ec681f3Smrg if (vp9_u(&vlc, 1)) 3337ec681f3Smrg /* pred_probs */ 3347ec681f3Smrg vp9_u(&vlc, 8); 3357ec681f3Smrg } 3367ec681f3Smrg } 3377ec681f3Smrg } 3387ec681f3Smrg 3397ec681f3Smrg /* update_data */ 3407ec681f3Smrg if (vp9_u(&vlc, 1)) { 3417ec681f3Smrg /* abs_delta */ 3427ec681f3Smrg context->desc.vp9.picture_parameter.abs_delta = vp9_u(&vlc, 1); 3437ec681f3Smrg for (i = 0; i < 8; ++i) { 3447ec681f3Smrg /* Use alternate quantizer */ 3457ec681f3Smrg if ((context->desc.vp9.slice_parameter.seg_param[i].alt_quant_enabled = vp9_u(&vlc, 1))) 3467ec681f3Smrg context->desc.vp9.slice_parameter.seg_param[i].alt_quant = vp9_s(&vlc, 8); 3477ec681f3Smrg /* Use alternate loop filter value */ 3487ec681f3Smrg if ((context->desc.vp9.slice_parameter.seg_param[i].alt_lf_enabled = vp9_u(&vlc, 1))) 3497ec681f3Smrg context->desc.vp9.slice_parameter.seg_param[i].alt_lf = vp9_s(&vlc, 6); 3507ec681f3Smrg /* Optional Segment reference frame */ 3517ec681f3Smrg if (vp9_u(&vlc, 1)) 3527ec681f3Smrg vp9_u(&vlc, 2); 3537ec681f3Smrg /* Optional Segment skip mode */ 3547ec681f3Smrg vp9_u(&vlc, 1); 3557ec681f3Smrg } 3567ec681f3Smrg } 3577ec681f3Smrg} 358