#include <stdio.h> #include <string.h> #include <malloc.h> #include <assert.h> #define _HEAD_LEN_ (16) #define MI_U32VALUE(pu8Data, index) (pu8Data[index]<<24)|(pu8Data[index+1]<<16)|(pu8Data[index+2]<<8)|(pu8Data[index+3]) FILE *g_fread = NULL; unsigned char *g_phead = NULL; unsigned char *g_pbuf = NULL; unsigned int g_u32bitpos = 0; unsigned int g_u32bufsz = 0; int read_one_frame(unsigned int *sz) { if (NULL == sz) { return 0; } memset(g_phead, 0x0, _HEAD_LEN_); int nread = fread(g_phead, 1, _HEAD_LEN_, g_fread); if (0 >= nread) { return 0; } unsigned int pk_sz = 0; pk_sz = MI_U32VALUE(g_phead, 4); if(pk_sz <= 0) { printf("%s(%d) read end of file because of ZERO PKT!\n", __FUNCTION__, __LINE__); return 0; } memset(g_pbuf, 0x0, pk_sz); nread = fread(g_pbuf, 1, pk_sz, g_fread); if (0 >= nread) { return 0; } *sz = nread; return 1; } / uncompressed_header start /// ///REF FRMAE #define KEY_FRAME (0) #define NON_KEY_FRAME (1) ///COLOR SPACE #define CS_UNKNOWN (0) #define CS_BT_601 (1) #define CS_BT_709 (2) #define CS_SMPTE_170 (3) #define CS_SMPTE_240 (4) #define CS_BT_2020 (5) #define CS_BT_RWSERVED (6) #define CS_RGB (7) #define INTRA_FRAME (0) #define LAST_FRAME (1) #define GOLDEN_FRAME (2) #define ALTREF_FRAME (3) #define EIGHTTAP (0) #define EIGHTTAP_SMOOTH (1) #define EIGHTTAP_SHARP (2) #define BILINEAR (3) #define SWITCHABLE (4) #define SEG_LVL_MAX (4) #define MAX_SEGMENTS (8) #define MIN_TILE_WIDTH_B64 (4) #define MAX_TILE_WIDTH_B64 (64) #define NUM_REF_FRAMES (8) int frame_type = 0; int lastFrameType = 0; int profile = 0; int FrameIsIntra = 0; int show_frame = 0; int error_resilient_mode = 0; int frame_parallel_decoding_mode = 0;///1:can parallel decode frame int frame_context_idx = 0; int refresh_frame_context = 0;///0: drop probabilities; 1:save current probabilities int BitDepth = 0; int subsampling_x = 1; int subsampling_y = 1; int color_space = 0; int ref_frame_idx[3]; int FrameWidth = 0; int FrameHeight = 0; int RefFrameWidth[NUM_REF_FRAMES]; int RefFrameHeight[NUM_REF_FRAMES]; int RefSubsamplingX[NUM_REF_FRAMES]; int RefSubsamplingY[NUM_REF_FRAMES]; int RefBitDepth[NUM_REF_FRAMES]; int renderWidth = 0; int renderHeight = 0; int show_existing_frame = 0; int refresh_frame_flags = 0; int literal_to_type[4] = {EIGHTTAP_SMOOTH, EIGHTTAP, EIGHTTAP_SHARP, BILINEAR}; int interpolation_filter = 0; int loop_filter_ref_deltas[20]; int loop_filter_mode_deltas[20]; int segmentation_feature_bits[SEG_LVL_MAX] = {8, 6, 2, 0}; int segmentation_feature_signed[SEG_LVL_MAX] = {1, 1, 0, 0}; int segmentation_tree_probs[7]; int segmentation_pred_prob[3]; int FeatureEnabled[MAX_SEGMENTS][SEG_LVL_MAX]; int FeatureData[MAX_SEGMENTS][SEG_LVL_MAX]; int Sb64Cols = 0; int Sb64Rows = 0; int segmentation_abs_or_delta_update = 0; int MiCols = 0; int MiRows = 0; int PrevSegmentIds[4906][2160]; int loop_filter_delta_enabled = 0; int ref_frame_sign_bias[LAST_FRAME + 3]; int SegmentId[4096][2160]; int UsePrevFrameMvs = 0; int header_size_in_bytes = 0; char chroma_subsampling_forma[4][10] = {"YUV 4:4:4", "YUV 4:4:0", "YUV 4:2:2", "YUV 4:2:0"}; int read_bit() { assert(g_u32bufsz > (g_u32bitpos / 8)); unsigned char value = g_pbuf[g_u32bitpos / 8]; unsigned int offset = 7 - (g_u32bitpos % 8); g_u32bitpos += 1; return ((value >> offset) & 0x1); } void update_bitpos(unsigned int sz) { g_u32bitpos = g_u32bitpos + (sz * 8); } #if (0) #define fn(x) Fn(x);printf("[%s][%d]\n", __FUNCTION__, __LINE__) int Fn(unsigned int n) #else int fn(unsigned int n) #endif { int x = 0; int i = 0; for (i = 0; i < n; ++i) { x = 2 * x + read_bit(); } return x; } int sn(unsigned int n) { int value = fn(n); int sign = fn(1); return sign ? -value : value; } void frame_sync_code() { int frame_sync_byte_0 = fn(8);///shall be 0x49 int frame_sync_byte_1 = fn(8);///shall be 0x83 int frame_sync_byte_2 = fn(8);///shall be 0x42 if ((0x49 != frame_sync_byte_0) || (0x83 != frame_sync_byte_1) || (0x42 != frame_sync_byte_2)) { printf("error frame found, frame sync code must be:0x49,0x83,0x42, current:0x%x 0x%x 0x%x\n", frame_sync_byte_0, frame_sync_byte_1, frame_sync_byte_2); } } void color_config() { if (2 <= profile) { int ten_or_twelve_bit = fn(1); BitDepth = ten_or_twelve_bit ? 12 : 10;/// bit depth 10 or 12 bits } else { BitDepth = 8; } color_space = fn(3); int color_range = 0; int reserved_zero = 0;///shall be 0 if (CS_RGB != color_space) { color_range = fn(1); if ((1 == profile) || (3 == profile)) { subsampling_x = fn(1); subsampling_y = fn(1); reserved_zero = fn(1); } else { subsampling_x = 1; subsampling_y = 1; } } else { color_range = 1; if ((1 == profile) || (3 == profile)) { subsampling_x = 0; subsampling_y = 0; reserved_zero = fn(1); } } ///(subsampling_x, subsampling_y) -> (0,0) YUV 4:4:4; (0,1) YUV 4:4:0; (1,0) YUV 4:2:2; (1,1) YUV 4:2:0; } void compute_image_size() { MiCols = (FrameWidth + 7) >> 3; MiRows = (FrameHeight + 7) >> 3; Sb64Cols = (MiCols + 7) >> 3; Sb64Rows = (MiRows + 7) >> 3; int i = 0, j = 0; for (i = 0; i < MiRows - 1; ++i) { for (j = 0; j < MiCols - 1; ++j) { SegmentId[i][j] = 0x0; } } static int PreFrameWidth = 0; static int PreFrameHeight = 0; if ( (PreFrameWidth == FrameWidth) && (PreFrameHeight == FrameHeight) && (1 == show_frame) && (0 == error_resilient_mode) && (0 == FrameIsIntra) ) { UsePrevFrameMvs = 1; } else { UsePrevFrameMvs = 0; } PreFrameWidth = FrameWidth; PreFrameHeight = FrameHeight; } void frame_size() { int frame_width_minus_1 = fn(16);///width in pixels int frame_height_minus_1 = fn(16);///width in pixels FrameWidth = frame_width_minus_1 + 1; FrameHeight = frame_height_minus_1 + 1; compute_image_size(); } void render_size() { ///this function no effect on the decoding process int render_and_frame_size_different = fn(1); if (1 == render_and_frame_size_different) { int render_width_minus_1 = fn(16); int render_height_minus_1 = fn(16); renderWidth = render_width_minus_1 + 1; renderHeight = render_height_minus_1 + 1; } else { renderWidth = FrameWidth; renderHeight = FrameHeight; } } void frame_size_with_refs() { ///For inter frames, the frame size is either set equal to the size of a reference frame, or can be sent explicitly int i = 0; int found_ref = 0; for (i = 0; i < 3; ++i) { found_ref = fn(1); if (1 == found_ref) { ///from reference frame FrameWidth = RefFrameWidth[ ref_frame_idx[i] ]; FrameHeight = RefFrameHeight[ ref_frame_idx[i] ]; break; } } if (0 == found_ref) { ///be sent explicitly frame_size(); } else { compute_image_size(); } render_size(); } void read_interpolation_filter() { int is_filter_switchable = fn(1);///1: the filter selection is signaled at the block leve ; 0:the filter selection is signaled at the frame level. interpolation_filter = 0;///used to compute interpolation_filte if (1 == is_filter_switchable) { interpolation_filter = SWITCHABLE; } else { int raw_interpolation_filter = fn(2); interpolation_filter = literal_to_type[raw_interpolation_filter]; } } void setup_past_independence() { printf("xx current frame can be decoded without dependence on previous coded frames xx\n"); int i = 0, j = 0; for (i = 0; i < MAX_SEGMENTS; ++i) { for (j = 0; j < SEG_LVL_MAX; ++j) { FeatureEnabled[i][j] = 0; FeatureData[i][j] = 0; } } segmentation_abs_or_delta_update = 0; for (i = 0; i < (MiRows - 1); ++i) { for (j = 0; j < (MiCols - 1); ++j) { PrevSegmentIds[i][j] = 0; } } loop_filter_delta_enabled = 0; loop_filter_ref_deltas[ INTRA_FRAME ] = 1; loop_filter_ref_deltas[ LAST_FRAME ] = 0; loop_filter_ref_deltas[ GOLDEN_FRAME ] = -1; loop_filter_ref_deltas[ ALTREF_FRAME ] = -1; loop_filter_mode_deltas[0] = 0; loop_filter_mode_deltas[1] = 0; ref_frame_sign_bias[0] = 0; ref_frame_sign_bias[1] = 0; ref_frame_sign_bias[2] = 0; ref_frame_sign_bias[3] = 0; ///todo: copy code from chater 10.5 Default probability tables to here } void save_probs(unsigned int n) { } void loop_filter_params() { int loop_filter_level = fn(6); /// loop filter strength int loop_filter_sharpness = fn(3); loop_filter_delta_enabled = fn(1); if (1 == loop_filter_delta_enabled) { int loop_filter_delta_update = fn(1); if (1 == loop_filter_delta_update) { int i = 0; for (i = 0; i < 4; ++i) { int update_ref_delta = fn(1); if (1 == update_ref_delta) { loop_filter_ref_deltas[i] = sn(6); } } for (i = 0; i < 2; ++i) { int update_mode_delta = fn(1); if (1 == update_mode_delta) { loop_filter_mode_deltas[i] = sn(6); } } } } } int read_delta_q() { int delta_coded = fn(1); int delta_q = 0; if (delta_coded) { delta_q = sn(4); } else { delta_q = 0; } return delta_q; } void quantization_params() { int base_q_idx = fn(8); int delta_q_y_dc = read_delta_q(); int delta_q_uv_dc = read_delta_q(); int delta_q_uv_ac = read_delta_q(); int Lossless = (base_q_idx == 0) && (0 == delta_q_y_dc) && (0 == delta_q_uv_dc) && (0 == delta_q_uv_ac); } int read_prob() { int prob_coded = fn(1); int prob = 0; if (prob_coded) { prob = fn(8); } else { prob = 255; } return prob; } void segmentation_params() { int segmentation_enabled = fn(1); if (1 == segmentation_enabled) { int segmetation_update_map = fn(1); if (1 == segmetation_update_map) { int i = 0; for (i = 0; i < 7; ++i) { segmentation_tree_probs[i] == read_prob(); } int segmentation_temporal_update = fn(1); for (i = 0; i < 3; ++i) { segmentation_pred_prob[i] = segmentation_temporal_update ? read_prob() : 255; } } int segmentation_update_data = fn(1); if (1 == segmentation_update_data) { segmentation_abs_or_delta_update = fn(1); int i = 0; for (i = 0; i < MAX_SEGMENTS; ++i) { int j = 0; for (j = 0; j < SEG_LVL_MAX; ++j) { int feature_value = 0; int feature_enabled = fn(1); FeatureEnabled[i][j] = feature_enabled; if (1 == feature_enabled) { int bits_to_read = segmentation_feature_bits[j]; int feature_value = fn(bits_to_read); if (1 == segmentation_feature_signed[j]) { int feature_sign = fn(1); if (1 == feature_sign) { feature_sign *= -1; } } }///feature_enabled FeatureEnabled[i][j] = feature_value; } }///for_i } } } int calc_min_log2_tile_cols() { int minLog2 = 0; while ((MAX_TILE_WIDTH_B64 << minLog2) < Sb64Cols) { minLog2++; } return minLog2; } int calc_max_log2_tile_cols() { int maxLog2 = 1; while ((Sb64Cols >> maxLog2) >= MIN_TILE_WIDTH_B64) { maxLog2++; } return maxLog2 - 1; } void tile_info() { int minLog2TileCols = calc_min_log2_tile_cols(); int maxLog2TileCols = calc_max_log2_tile_cols(); int tile_cols_log2 = minLog2TileCols; while (tile_cols_log2 < maxLog2TileCols) { int increment_tile_cols_log2 = fn(1); if (1 == increment_tile_cols_log2) { tile_cols_log2++; } else { break; } } int tile_rows_log2 = fn(1); if (1 == tile_rows_log2) { int increment_tile_rows_log2 = fn(1); tile_rows_log2 += increment_tile_rows_log2; } } void reference_frame_update_process() { ///This process is invoked as the final step in decoding a frame int i = 0; for (i = 0; i < (NUM_REF_FRAMES - 1); ++i) { if ((refresh_frame_flags >> i) & 1) { RefFrameWidth[i] = FrameWidth; RefFrameHeight[i] = FrameHeight; RefSubsamplingX[i] = subsampling_x; RefSubsamplingY[i] = subsampling_y; RefBitDepth[i] = BitDepth; ///other operation see charter 8.10 } } if (0 == show_existing_frame) { ///other operation see charter 8.10 } } ///page 62 void uncompressed_header() { int frame_marker = fn(2);///shall be 2 int profile_low_bit = fn(1); int profile_high_bit = fn(1); profile = (profile_high_bit << 1) + profile_low_bit; if (3 == profile) { int reserved_zero = fn(1);///shall be 0 } show_existing_frame = fn(1);///1: display frame_to_show_map_idx frame 0:process current frame data if (1 == show_existing_frame) { int frame_to_show_map_idx = fn(3); int header_size_in_bytes = 0; refresh_frame_flags = 0; int loop_filter_level = 0; printf("display:%d frame now\n", frame_to_show_map_idx); return; } lastFrameType = frame_type; frame_type = fn(1); show_frame = fn(1); error_resilient_mode = fn(1); FrameIsIntra = 0; int reset_frame_context = 0; if (KEY_FRAME == frame_type) { ///key frame frame_sync_code();///3 byte color_config(); frame_size(); render_size(); refresh_frame_flags = 0xFF; FrameIsIntra = 1; } else { ///no-key frame:intra-only frame or inter frame ///the stream can start by no-key frame int intra_only = 0 ; if (0 == show_frame) { intra_only = fn(1); } else { intra_only = 0; } FrameIsIntra = intra_only; ///reset_frame_context:whether the frame context should be reset to default values:0 or 1 means don't resest any frame context;2 resets just the context specified in the frame header;3 reset all contexts if (0 == error_resilient_mode) { reset_frame_context = fn(2); } else { /// the frame to be decoded independently of previous frames reset_frame_context = 0; } if (1 == intra_only) { ///intra only frame frame_sync_code(); color_space = 0; if (0 < profile) { color_config(); } else { color_space = CS_BT_601; subsampling_x = 1; subsampling_y = 1; BitDepth = 8; } refresh_frame_flags = fn(8); frame_size(); render_size(); } else { ///inter frame refresh_frame_flags = fn(8); int i = 0; for (i = 0; i < 3; ++i) { ref_frame_idx[i] = fn(3); ref_frame_sign_bias[LAST_FRAME + i] = fn(1);///0:backwards reference 1:forwards reference } frame_size_with_refs(); int allow_high_precision_mv = fn(1);///0:mv 1/4 pel precision; 1:mv 8 pel precision read_interpolation_filter(); }///end of intra_only }/// end of frame_type if (0 == error_resilient_mode) { refresh_frame_context = fn(1); frame_parallel_decoding_mode = fn(1); } else { refresh_frame_context = 0; frame_parallel_decoding_mode = 1; } frame_context_idx = fn(2);///indicates the frame context to use. if (FrameIsIntra || error_resilient_mode) { setup_past_independence(); if ((KEY_FRAME == frame_type) || (1 == error_resilient_mode) || (3 == reset_frame_context)) { int i = 0; for (i = 0; i < 4; ++i) { save_probs(i); } } else if (2 == reset_frame_context) { save_probs(frame_context_idx); } frame_context_idx = 0; } loop_filter_params(); quantization_params(); segmentation_params(); tile_info(); header_size_in_bytes = fn(16);///indicates the size of the compressed header in bytes. } / uncompressed_header end /// / compressed_header start /// #define ONLY_4X4 (0) #define ALLOW_8X8 (1) #define ALLOW_16X16 (2) #define ALLOW_32X32 (3) #define TX_MODE_SELECT (4) #define TX_SIZE_CONTEXTS (2) #define TX_SIZES (4) #define MAX_PROB (255) #define TX_MODES (5) #define TX_4X4 (0) #define TX_8X8 (1) #define TX_16X16 (2) #define TX_32X32 (3) #define SKIP_CONTEXTS (3) #define INTER_MODE_CONTEXTS (7) #define INTER_MODES (4) #define INTERP_FILTER_CONTEXTS (4) #define SWITCHABLE_FILTERS (3) #define IS_INTER_CONTEXTS (4) #define MV_JOINTS (4) #define MV_CLASSES (11) #define MV_OFFSET_BITS (10) #define CLASS0_SIZE (2) #define MV_FR_SIZE (4) #define PARTITION_CONTEXTS (16) #define PARTITION_TYPES (4) #define BLOCK_SIZE_GROUPS (4) #define INTRA_MODES (10) #define COMP_MODE_CONTEXTS (5) #define REF_CONTEXTS (5) #define REFS_PER_FRAME (5) #define SINGLE_REFERENCE (0) #define COMPOUND_REFERENCE (1) #define REFERENCE_MODE_SELECT (2) #define BLOCK_TYPES (2) #define REF_TYPES (2) #define COEF_BANDS (6) #define PREV_COEF_CONTEXTS (6) #define UNCONSTRAINED_NODES (3) int counts_intra_mode[BLOCK_SIZE_GROUPS][INTRA_MODES]; int counts_uv_mode[INTRA_MODES][INTRA_MODES]; int counts_partition[PARTITION_CONTEXTS][PARTITION_TYPES]; int counts_interp_filter[INTERP_FILTER_CONTEXTS][SWITCHABLE_FILTERS]; int counts_inter_mode[INTER_MODE_CONTEXTS][INTER_MODES]; int counts_tx_size[TX_SIZES][TX_SIZE_CONTEXTS][TX_SIZES]; int counts_is_inter[IS_INTER_CONTEXTS][2]; int counts_comp_mode[COMP_MODE_CONTEXTS][2]; int counts_single_ref[REF_CONTEXTS][2][2]; int counts_comp_ref[REF_CONTEXTS][2]; int counts_skip[SKIP_CONTEXTS][2]; int counts_mv_joint[MV_JOINTS]; int counts_mv_sign[2][2]; int counts_mv_class[2][MV_CLASSES]; int counts_mv_class0_bit[2][CLASS0_SIZE]; int counts_mv_class0_fr[2][CLASS0_SIZE][MV_FR_SIZE]; int counts_mv_class0_hp[2][2]; int counts_mv_bits[2][MV_OFFSET_BITS][2]; int counts_mv_fr[2][ MV_FR_SIZE]; int counts_mv_hp[2][2]; int counts_token[TX_SIZES][BLOCK_TYPES][REF_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][UNCONSTRAINED_NODES]; int counts_more_coefs[TX_SIZES][BLOCK_TYPES][REF_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][2]; int tx_probs_8x8[TX_SIZE_CONTEXTS][TX_SIZES]; int tx_probs_16x16[TX_SIZE_CONTEXTS][TX_SIZES]; int tx_probs_32x32[TX_SIZE_CONTEXTS][TX_SIZES]; int tx_mode = 0; int Lossless = 0; int inv_map_table[MAX_PROB] = { 7, 20, 33, 46, 59, 72, 85, 98, 111, 124, 137, 150, 163, 176, 189, 202, 215, 228, 241, 254, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 86 , 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 253 }; int update_prob = 0; int tx_mode_to_biggest_tx_size[TX_MODES] = { TX_4X4, TX_8X8, TX_16X16, TX_32X32, TX_32X32 }; int coef_probs[ TX_SIZES ][ BLOCK_TYPES ][ REF_TYPES ][ COEF_BANDS ] [ PREV_COEF_CONTEXTS ][ UNCONSTRAINED_NODES ] = { { { /* block Type 0 */ { /* Intra */ { /* Coeff Band 0 */ { 195, 29, 183 }, { 84, 49, 136 }, { 8, 42, 71 }, { 0, 0, 0 }, // unused { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Band 1 */ { 31, 107, 169 }, { 35, 99, 159 }, { 17, 82, 140 }, { 8, 66, 114 }, { 2, 44, 76 }, { 1, 19, 32 } }, { /* Coeff Band 2 */ { 40, 132, 201 }, { 29, 114, 187 }, { 13, 91, 157 }, { 7, 75, 127 }, { 3, 58, 95 }, { 1, 28, 47 } }, { /* Coeff Band 3 */ { 69, 142, 221 }, { 42, 122, 201 }, { 15, 91, 159 }, { 6, 67, 121 }, { 1, 42, 77 }, { 1, 17, 31 } }, { /* Coeff Band 4 */ { 102, 148, 228 }, { 67, 117, 204 }, { 17, 82, 154 }, { 6, 59, 114 }, { 2, 39, 75 }, { 1, 15, 29 } }, { /* Coeff Band 5 */ { 156, 57, 233 }, { 119, 57, 212 }, { 58, 48, 163 }, { 29, 40, 124 }, { 12, 30, 81 }, { 3, 12, 31 } } }, { /* Inter */ { /* Coeff Band 0 */ { 191, 107, 226 }, { 124, 117, 204 }, { 25, 99, 155 }, { 0, 0, 0 }, // unused { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Band 1 */ { 29, 148, 210 }, { 37, 126, 194 }, { 8, 93, 157 }, { 2, 68, 118 }, { 1, 39, 69 }, { 1, 17, 33 } }, { /* Coeff Band 2 */ { 41, 151, 213 }, { 27, 123, 193 }, { 3, 82, 144 }, { 1, 58, 105 } , { 1, 32, 60 }, { 1, 13, 26 } }, { /* Coeff Band 3 */ { 59, 159, 220 }, { 23, 126, 198 }, { 4, 88, 151 }, { 1, 66, 114 }, { 1, 38, 71 }, { 1, 18, 34 } }, { /* Coeff Band 4 */ { 114, 136, 232 }, { 51, 114, 207 }, { 11, 83, 155 }, { 3, 56, 105 }, { 1, 33, 65 }, { 1, 17, 34 } }, { /* Coeff Band 5 */ { 149, 65, 234 }, { 121, 57, 215 }, { 61, 49, 166 }, { 28, 36, 114 }, { 12, 25, 76 }, { 3, 16, 42 } } } }, { /* block Type 1 */ { /* Intra */ { /* Coeff Band 0 */ { 214, 49, 220 }, { 132, 63, 188 }, { 42, 65, 137 }, { 0, 0, 0 }, // unused { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Band 1 */ { 85, 137, 221 }, { 104, 131, 216 }, { 49, 111, 192 }, { 21, 87, 155 }, { 2, 49, 87 }, { 1, 16, 28 } }, { /* Coeff Band 2 */ { 89, 163, 230 }, { 90, 137, 220 }, { 29, 100, 183 }, { 10, 70, 135 }, { 2, 42, 81 }, { 1, 17, 33 } }, { /* Coeff Band 3 */ { 108, 167, 237 }, { 55, 133, 222 }, { 15, 97, 179 }, { 4, 72, 135 }, { 1, 45, 85 }, { 1, 19, 38 } }, { /* Coeff Band 4 */ { 124, 146, 240 }, { 66, 124, 224 }, { 17, 88, 175 }, { 4, 58, 122 }, { 1, 36, 75 }, { 1, 18, 37 } }, { /* Coeff Band 5 */ { 141, 79, 241 }, { 126, 70, 227 }, { 66, 58, 182 }, { 30, 44, 136 }, { 12, 34, 96 }, { 2, 20, 47 } } }, { /* Inter */ { /* Coeff Band 0 */ { 229, 99, 249 }, { 143, 111, 235 }, { 46, 109, 192 }, { 0, 0, 0 }, // unused { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Band 1 */ { 82, 158, 236 }, { 94, 146, 224 }, { 25, 117, 191 }, { 9, 87, 149 }, { 3, 56, 99 }, { 1, 33, 57 } }, { /* Coeff Band 2 */ { 83, 167, 237 }, { 68, 145, 222 }, { 10, 103, 177 }, { 2, 72, 131 }, { 1, 41, 79 }, { 1, 20, 39 } }, { /* Coeff Band 3 */ { 99, 167, 239 }, { 47, 141, 224 }, { 10, 104, 178 }, { 2, 73, 133 }, { 1, 44, 85 }, { 1, 22, 47 } }, { /* Coeff Band 4 */ { 127, 145, 243 }, { 71, 129, 228 }, { 17, 93, 177 }, { 3, 61, 124 }, { 1, 41, 84 }, { 1, 21, 52 } }, { /* Coeff Band 5 */ { 157, 78, 244 }, { 140, 72, 231 }, { 69, 58, 184 }, { 31, 44, 137 }, { 14, 38, 105 }, { 8, 23, 61 } } } } }, / { { /* block Type 0 */ { /* Intra */ { /* Coeff Band 0 */ { 125, 34, 187 }, { 52, 41, 133 }, { 6, 31, 56 }, { 0, 0, 0 }, // unused { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Band 1 */ { 37, 109, 153 }, { 51, 102, 147 }, { 23, 87, 128 }, { 8, 67, 101 }, { 1, 41, 63 }, { 1, 19, 29 } }, { /* Coeff Band 2 */ { 31, 154, 185 }, { 17, 127, 175 }, { 6, 96, 145 }, { 2, 73, 114 }, { 1, 51, 82 }, { 1, 28, 45 } }, { /* Coeff Band 3 */ { 23, 163, 200 }, { 10, 131, 185 }, { 2, 93, 148 }, { 1, 67, 111 }, { 1, 41, 69 }, { 1, 14 , 24 } }, { /* Coeff Band 4 */ { 29, 176, 217 }, { 12, 145, 201 }, { 3, 101, 156 }, { 1, 69, 111 }, { 1, 39, 63 }, { 1, 14, 23 } }, { /* Coeff Band 5 */ { 57, 192, 233 }, { 25, 154, 215 }, { 6, 109, 167 }, { 3, 78, 118 }, { 1, 48, 69 }, { 1, 21, 29 } } }, { /* Inter */ { {202, 105, 245 }, { 108, 106, 216 }, { 18, 90, 144 }, { 0, 0, 0 }, // unused { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Band 1 */ { 33, 172, 219 }, { 64, 149, 206 }, { 14, 117, 177 }, { 5, 90, 141 }, { 2, 61, 95 }, { 1, 37, 57 } }, { /* Coeff Band 2 */ { 33, 179, 220 }, { 11, 140, 198 }, { 1, 89, 148 }, { 1, 60, 104 }, { 1, 33, 57 }, { 1, 12, 21 } }, { /* Coeff Band 3 */ { 30, 181, 221 }, { 8, 141, 198 }, { 1, 87, 145 }, { 1, 58, 100 }, { 1, 31, 55 }, { 1, 12, 20 } }, { /* Coeff Band 4 */ { 32, 186, 224 }, { 7, 142, 198 }, { 1, 86, 143 }, { 1, 58, 100 }, { 1, 31, 55 }, { 1, 12, 22 } }, { /* Coeff Band 5 */ { 57, 192, 227 }, { 20, 143, 204 }, { 3, 96, 154 }, { 1, 68, 112 }, { 1, 42, 69 }, { 1, 19, 32 } } } } , { /* block Type 1 */ { /* Intra */ { /* Coeff Band 0 */ { 212, 35, 215 }, { 113, 47, 169 }, { 29, 48, 105 }, { 0, 0, 0 }, // unused { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Band 1 */ { 74, 129, 203 }, { 106, 120, 203 }, { 49, 107, 178 }, { 19, 84, 144 }, { 4, 50, 84 }, { 1, 15, 25 } }, { /* Coeff Band 2 */ { 71, 172, 217 }, { 44, 141, 209 }, { 15, 102, 173 }, { 6, 76, 133 }, { 2, 51, 89 }, { 1, 24, 42 } }, { /* Coeff Band 3 */ { 64, 185, 231 }, { 31, 148, 216 }, { 8, 103, 175 }, { 3, 74, 131 }, { 1, 46, 81 }, { 1, 18, 30 } }, { /* Coeff Band 4 */ { 65, 196, 235 }, { 25, 157, 221 }, { 5, 105, 174 }, { 1, 67, 120 }, { 1, 38, 69 }, { 1, 15, 30 } }, { /* Coeff Band 5 */ { 65, 204, 238 }, { 30, 156, 224 }, { 7, 107, 177 }, { 2, 70, 124 }, { 1, 42, 73 }, { 1, 18, 34 } } }, { /* Inter */ { /* Coeff Band 0 */ { 225, 86, 251 }, { 144, 104, 235 }, { 42, 99, 181 }, { 0, 0, 0 }, // unuse d { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Band 1 */ { 85, 175, 239 }, { 112, 165, 229 }, { 29, 136, 200 }, { 12, 103, 162 }, { 6, 77, 123 }, { 2, 53, 84 } }, { /* Coeff Band 2 */ { 75, 183, 239 }, { 30, 155, 221 }, { 3, 106, 171 }, { 1, 74, 128 }, { 1, 44, 76 }, { 1, 17, 28 } }, { /* Coeff Band 3 */ { 73, 185, 240 }, { 27, 159, 222 }, { 2, 107, 172 }, { 1, 75, 127 }, { 1, 42, 73 }, { 1, 17, 29 } }, { /* Coeff Band 4 */ { 62, 190, 238 }, { 21, 159, 222 }, { 2, 107, 172 }, { 1, 72, 122 }, { 1, 40, 71 }, { 1, 18, 32 } }, { /* Coeff Band 5 */ { 61, 199, 240 }, { 27, 161, 226 }, { 4, 113, 180 }, { 1, 76, 129 }, { 1, 46, 80 }, { 1, 23, 41 } } } } }, { { /* block Type 0 */ { /* Intra */ { /* Coeff Band 0 */ { 7, 27, 153 }, { 5, 30, 95 }, { 1, 16, 30 }, { 0, 0, 0 }, // unused { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Band 1 */ { 50, 75, 127 }, { 57, 75, 124 }, { 27, 67, 108 }, { 10, 54, 86 }, { 1, 33, 52 }, { 1, 12, 18 } }, { /* Coeff Band 2 */ { 43, 125, 151 }, { 26, 108, 148 }, { 7, 83, 122 }, { 2, 59, 89 }, { 1, 38, 60 }, { 1, 17, 27 } }, { /* Coeff Band 3 */ { 23, 144, 163 }, { 13, 112, 154 }, { 2, 75, 117 }, { 1, 50, 81 }, { 1, 31, 51 }, { 1, 14, 23 } }, { /* Coeff Band 4 */ { 18, 162, 185 }, { 6, 123, 171 }, { 1, 78, 125 }, { 1, 51, 86 }, { 1, 31, 54 }, { 1, 14, 23 } }, { /* Coeff Band 5 */ { 15, 199, 227 }, { 3, 150, 204 }, { 1, 91, 146 }, { 1, 55, 95 }, { 1, 30, 53 }, { 1, 11, 20 } } }, { /* Inter */ { /* Coeff Band 0 */ { 19, 55, 240 }, { 19, 59, 196 }, { 3, 52, 105 }, { 0, 0, 0 }, // unused { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Band 1 */ { 41, 166, 207 }, { 104, 153, 199 }, { 31, 123, 181 }, { 14, 101, 152 }, { 5, 72, 106 }, { 1, 36, 52 } }, { /* Coeff Band 2 */ { 35, 176, 211 }, { 12, 131, 190 }, { 2, 88, 144 }, { 1, 60, 101 }, { 1, 36, 60 }, { 1, 16, 28 } }, { /* Coeff Band 3 */ { 28, 183, 213 }, { 8, 134, 191 }, { 1, 86, 142 }, { 1, 56, 96 }, { 1, 30, 53 }, { 1, 12, 20 } }, { /* Coeff Band 4 */ { 20, 190, 215 }, { 4, 135, 192 }, { 1, 84, 139 }, { 1, 53, 91 }, { 1, 28, 49 }, { 1, 11, 20 } }, { /* Coeff Band 5 */ { 13, 196, 216 }, { 2, 137, 192 }, { 1, 86, 143 }, { 1, 57, 99 }, { 1, 32, 56 }, { 1, 13, 24 } } } }, { /* block Type 1 */ { /* Intra */ { /* Coeff Band 0 */ { 211, 29, 217 }, { 96, 47, 156 }, { 22, 43, 87 }, { 0, 0, 0 }, // unused { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Band 1 */ { 78, 120, 193 }, { 111, 116, 186 }, { 46, 102, 164 }, { 15, 80, 128 }, { 2, 49, 76 }, { 1, 18, 28 } }, { /* Coeff Band 2 */ { 71, 161, 203 }, { 42, 132, 192 }, { 10, 98, 150 }, { 3, 69, 109 }, { 1, 44, 70 }, { 1, 18, 29 } }, { /* Coeff Band 3 */ { 57, 186, 211 }, { 30, 140, 196 }, { 4, 93, 146 }, { 1, 62, 102 }, { 1, 38, 65 }, { 1, 16, 27 } }, { /* Coeff Band 4 */ { 47, 199, 217 }, { 14, 145, 196 }, { 1, 88, 142 }, { 1, 57, 98 }, { 1, 36, 62 }, { 1, 15, 26 } }, { /* Coeff Band 5 */ { 26, 219, 229 }, { 5, 155, 207 }, { 1, 94, 151 }, { 1, 60, 104 }, { 1, 36, 62 }, { 1, 16, 28 } } }, { /* Inter */ { /* Coeff Band 0 */ { 233, 29, 248 }, { 146, 47, 220 }, { 43, 52, 140}, { 0, 0, 0 }, // unused { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Band 1 */ { 100, 163, 232 }, { 179, 161, 222 }, { 63, 142, 204 }, { 37, 113, 174}, { 26, 89, 137 }, { 18, 68, 97 } }, { /* Coeff Band 2 */ { 85, 181, 230 }, { 32, 146, 209 }, { 7, 100, 164 }, { 3, 71, 121 }, { 1, 45, 77 }, { 1, 18, 30 } }, { /* Coeff Band 3 */ { 65, 187, 230 }, { 20, 148, 207 }, { 2, 97, 159 }, { 1, 68, 116 }, { 1, 40, 70 }, { 1, 14, 29 } }, { /* Coeff Band 4 */ { 40, 194, 227 }, { 8, 147, 204 }, { 1, 94, 155 }, { 1, 65, 112 }, { 1, 39, 66 }, { 1, 14, 26 } }, { /* Coeff Band 5 */ { 16, 208, 228 }, { 3, 151, 207 }, { 1, 98, 160 }, { 1, 67, 117 }, { 1, 41, 74 }, { 1, 17, 31 } } } } }, { { /* block Type 0 */ { /* Intra */ { /* Coeff Band 0 */ { 17, 38, 140 }, { 7, 34, 80 }, { 1, 17, 29 }, { 0, 0, 0 }, // unused { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Ba nd 1 */ { 37, 75, 128 }, { 41, 76, 128 }, { 26, 66, 116 }, { 12, 52, 94 }, { 2, 32, 55 }, { 1, 10, 16 } }, { /* Coeff Band 2 */ { 50, 127, 154 }, { 37, 109, 152 }, { 16, 82, 121 }, { 5, 59, 85 }, { 1, 35, 54 }, { 1, 13, 20 } }, { /* Coeff Band 3 */ { 40, 142, 167 }, { 17, 110, 157 }, { 2, 71, 112 }, { 1, 44, 72 }, { 1, 27, 45 }, { 1, 11, 17 } }, { /* Coeff Band 4 */ { 30, 175, 188 }, { 9, 124, 169 }, { 1, 74, 116 }, { 1, 48, 78 }, { 1, 30, 49}, { 1, 11, 18 } }, { /* Coeff Band 5 */ { 10, 222, 223 }, { 2, 150, 194 }, { 1, 83, 128 }, { 1, 48, 79 }, { 1, 27, 45 }, { 1, 11, 17} } }, { /* Inter */ { /* Coeff Band 0 */ { 36, 41, 235 }, { 29, 36, 193 }, { 10, 27, 111 }, { 0, 0, 0 }, // unused { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Band 1 */ { 85, 165, 222 }, { 177, 162, 215 }, { 110, 135, 195 }, { 57, 113, 168 }, { 23, 83, 120 }, { 10, 49, 61 } }, { /*Coeff Band 2 */ { 85, 190, 223 }, { 36, 139, 200 }, { 5, 90, 146 }, { 1, 60, 103 }, { 1, 38, 65 }, { 1, 18, 30 } }, { /* Coeff Band 3 */ { 72, 202, 223 }, { 23, 141, 199 }, { 2, 86, 140 }, { 1, 56, 97 }, { 1, 36, 61 }, { 1, 16, 27 } }, { /* Coeff Band 4 */ { 55, 218, 225 }, { 13, 145, 200 }, { 1, 86, 141}, { 1, 57, 99 }, { 1, 35, 61 }, { 1, 13, 22 } }, { /* Coeff Band 5 */ { 15, 235, 212 }, { 1, 132, 184 }, { 1, 84, 139 }, { 1, 57, 97}, { 1, 34, 56 }, { 1, 14, 23 } } } }, { /* block Type 1 */ { /* Intra */ { /* Coeff Band 0 */ { 181, 21, 201 }, { 61, 37, 123 }, { 10, 38, 71 }, { 0, 0, 0 }, // unused { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Band 1 */ { 47, 106, 172 }, { 95, 104, 173 }, { 42, 93, 159 }, { 18, 77, 131}, { 4, 50, 81 }, { 1, 17, 23 } }, { /* Coeff Band 2 */ { 62, 147, 199 }, { 44, 130, 189 }, { 28, 102, 154 }, { 18, 75, 115 }, { 2, 44, 65 }, { 1, 12, 19 } }, { /* Coeff Band 3 */ { 55, 153, 210 }, { 24, 130, 194 }, { 3, 93, 146 }, { 1, 61, 97 }, { 1, 31, 50 }, { 1, 10, 16 } }, { /* Coeff Band 4 */ { 49, 186, 223 }, { 17, 148, 204 }, { 1, 96, 142 }, { 1, 53, 83 }, { 1, 26, 44 }, { 1, 11, 17 } }, { /* Coeff Band 5 */ { 13, 217, 212 }, { 2, 136, 180 }, { 1, 78, 124 }, { 1, 50, 83 }, { 1, 29, 49 }, { 1, 14, 23 } } }, { /* Inter */ { /* Coeff Band 0 */ { 197, 13, 247 }, { 82, 17, 222 }, { 25, 17, 162 }, { 0, 0, 0 }, // unused { 0, 0, 0 }, // unused { 0, 0, 0 } // unused }, { /* Coeff Band 1 */ { 126, 186, 247 }, { 234, 191 , 243 }, { 176, 177, 234 }, { 104, 158, 220 }, { 66, 128, 186 }, { 55, 90, 137 } }, { /* Coeff Band 2 */ { 111, 197, 242 }, { 46, 158, 219 }, { 9, 104, 171 }, { 2, 65, 125 }, { 1, 44, 80 }, { 1, 17, 91 } }, { /* Coeff Band 3 */ { 104, 208, 245 }, { 39, 168, 224 }, { 3, 109, 162 }, { 1, 79, 124 }, { 1, 50, 102 }, { 1, 43, 102 } }, { /* Coeff Band 4 */ { 84, 220, 246 }, { 31, 177, 231 }, { 2, 115, 180 }, { 1, 79, 134 }, { 1, 55, 77 }, { 1, 60, 79 } }, { /* Coeff Band 5 */ { 43, 243, 240 }, { 8, 180, 217 }, { 1, 115, 166 }, { 1, 84, 121 }, { 1, 51, 67 }, { 1, 16, 6 } } } } } }; /// int skip_prob[SKIP_CONTEXTS]; int inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES]; int inter_filter_probs[INTER_MODE_CONTEXTS][SWITCHABLE_FILTERS]; int is_inter_prob[IS_INTER_CONTEXTS]; int CompVarRef[2]; int CompFixedRef = 0; int mv_joint_probs[MV_JOINTS]; int mv_sign_probs[2]; int mv_class_probs[2][MV_CLASSES]; int mv_class0_bit_prob[2]; int mv_bits_prob[2][MV_OFFSET_BITS]; int mv_class0_fr_probs[2][CLASS0_SIZE][MV_FR_SIZE]; int mv_fr_probs[2][MV_FR_SIZE]; int allow_high_precision_mv = 0; int mv_class0_hp_prob[2]; int mv_hp_prob[2]; int partition_probs[PARTITION_CONTEXTS][PARTITION_TYPES]; int y_mode_probs[BLOCK_SIZE_GROUPS][INTRA_MODES]; int comp_mode_prob[COMP_MODE_CONTEXTS]; int single_ref_prob[REF_CONTEXTS][REF_CONTEXTS]; int comp_ref_prob[REF_CONTEXTS]; int reference_mode = 0; int BoolValue = 0; int BoolRange = 0; int BoolMaxBits = 0; void init_bool(unsigned int sz) { assert(0 == (g_u32bitpos % 8));///shall be aligned 8 bit BoolValue = fn(8); BoolRange = 255; BoolMaxBits = (8 * sz) - 8; } void exit_bool() { int padding_value = fn(BoolMaxBits); } int read_bool(unsigned int p) { int split = 1 + (((BoolRange - 1) * p) >> 8); int bit = 0; if (BoolValue < split) { BoolRange = split; bit = 0; } else { BoolRange -= split; BoolValue -= split; bit = 1; } if (BoolRange < 128) { int newBit = 0; if (BoolMaxBits > 0) { newBit = fn(1); BoolMaxBits -= 1; } else { newBit = 0; } BoolRange = BoolRange << 1; BoolValue = (BoolValue << 1) + newBit; } return bit; } int read_literal(unsigned int n) { int x = 0; int i = 0; for (i = 0; i < n; ++i) { x = 2 * x + read_bool(128); } return x; } int Bn(unsigned int p) { return read_bool(p); } int Ln(unsigned int n) { return read_literal(n); } int Tn(unsigned int n) { return 0; } void read_tx_mode() { if (1 == Lossless) { tx_mode = ONLY_4X4; } else { tx_mode = Ln(2); if (ALLOW_32X32) { int tx_mode_select = Ln(1); tx_mode += tx_mode_select; } } } int decode_term_subexp() { int bit = Ln(1); if (0 == bit) { int sub_exp_val = Ln(4); return sub_exp_val; } bit = Ln(1); if (0 == bit) { int sub_exp_val_minus_16 = Ln(4); return sub_exp_val_minus_16 + 16; } bit = Ln(1); if (0 == bit) { int sub_exp_val_minus_32 = Ln(4); return sub_exp_val_minus_32 + 32; } int v = Ln(7); if (65 > v) { return v + 64; } bit = Ln(1); return ((v << 1) - 1 + bit); } int inv_recenter_nonneg(int v, int m) { if (v > 2 * m) { return v; } if (v & 1) { return (m - ((v + 1) >> 1)); } return (m + (v >> 1)); } int inv_remap_prob(int deltaProb, int prob) { int m = prob; int v = deltaProb; v = inv_map_table[v]; m--; if (255 >= (m << 1)) { m = 1 + inv_recenter_nonneg(v, m); } else { m = 255 + inv_recenter_nonneg(v, 255 -1 - m); } return m; } int diff_update_prob(int prob) { update_prob = Bn(252); if (1 == update_prob) { int deltaProb = decode_term_subexp(); prob = inv_remap_prob(deltaProb, prob); } return prob; } void tx_mode_probs() { int i = 0, j = 0; for (i = 0; i < TX_SIZE_CONTEXTS; ++i) { for (j = 0; j < TX_SIZES - 3; j++) { tx_probs_8x8[i][j] = diff_update_prob(tx_probs_8x8[i][j]); } } for (i = 0; i < TX_SIZE_CONTEXTS; ++i) { for (j = 0; j < TX_SIZES - 2; j++) { tx_probs_16x16[i][j] = diff_update_prob(tx_probs_16x16[i][j]); } } for (i = 0; i < TX_SIZE_CONTEXTS; ++i) { for (j = 0; j < TX_SIZES - 1; j++) { tx_probs_32x32[i][j] = diff_update_prob(tx_probs_32x32[i][j]); } } } void read_coef_probs() { int maxTxSize = tx_mode_to_biggest_tx_size[tx_mode]; int txSz = 0; for (txSz = TX_4X4; txSz <= maxTxSize; ++txSz) { update_prob = Ln(1); if (1 == update_prob) { int i = 0; for (i = 0; i < 2; ++i) { int j = 0; for (j = 0; j < 2; ++j) { int k = 0; for (k = 0; k < 6; ++k) { int maxL = (0 == k) ? 3 : 6; int l = 0; for (l = 0; l < maxL; ++l) { int m = 0; for (m = 0; m < 3; ++m) { coef_probs[txSz][i][j][k][l][m] = diff_update_prob(coef_probs[txSz][i][j][k][l][m]); } } } } } } } } void read_skip_prob() { int i = 0; for (i = 0; i < SKIP_CONTEXTS; ++i) { skip_prob[i] = diff_update_prob(skip_prob[i]); } } void read_inter_mode_probs() { int i = 0; int j = 0; for (i = 0; i < INTER_MODE_CONTEXTS; ++i) { for (j = 0; j < INTER_MODES - 1; ++j) { inter_mode_probs[i][j] = diff_update_prob(inter_mode_probs[i][j]); } } } void read_interp_filter_probs() { int i = 0, j = 0; for (j = 0; j < INTER_MODE_CONTEXTS; ++j) { for (i = 0; i < SWITCHABLE_FILTERS - 1; ++i) { inter_filter_probs[j][i] = diff_update_prob(inter_filter_probs[j][i]); } } } void read_is_inter_probs() { int i = 0; for (i = 0; i < IS_INTER_CONTEXTS; ++i) { is_inter_prob[i] = diff_update_prob(is_inter_prob[i]); } } void setup_compound_reference_mode() { if (ref_frame_sign_bias[LAST_FRAME] == ref_frame_sign_bias[GOLDEN_FRAME]) { CompFixedRef = ALTREF_FRAME; CompVarRef[0] = LAST_FRAME; CompVarRef[1] = GOLDEN_FRAME; } else if (ref_frame_sign_bias[LAST_FRAME] == ref_frame_sign_bias[ALTREF_FRAME]) { CompFixedRef = GOLDEN_FRAME; CompVarRef[0] = LAST_FRAME; CompVarRef[1] = ALTREF_FRAME; } else { CompFixedRef = LAST_FRAME; CompVarRef[0] = GOLDEN_FRAME; CompVarRef[1] = ALTREF_FRAME; } } void frame_reference_mode() { int compoundReferenceAllowed = 0; int i = 0; for (i = 0; i < REFS_PER_FRAME; ++i) { if (ref_frame_sign_bias[i + 1] != ref_frame_sign_bias[1]) { compoundReferenceAllowed = 1; } } if (1 == compoundReferenceAllowed) { int non_single_reference = Ln(1); if (0 == non_single_reference) { reference_mode = SINGLE_REFERENCE; } else { int reference_select = Ln(1); if (0 == reference_select) { reference_mode = COMPOUND_REFERENCE; } else { reference_mode = REFERENCE_MODE_SELECT; } setup_compound_reference_mode(); } } else { reference_mode = SINGLE_REFERENCE; } } void frame_reference_mode_probs() { if (reference_mode == REFERENCE_MODE_SELECT) { int i = 0; for (i = 0; i < COMP_MODE_CONTEXTS; ++i) { comp_mode_prob[i] = diff_update_prob(comp_mode_prob[i]); } } if (reference_mode != COMPOUND_REFERENCE) { int i = 0; for (i = 0; i < REF_CONTEXTS; ++i) { single_ref_prob[i][0] = diff_update_prob(single_ref_prob[i][0]); single_ref_prob[i][1] = diff_update_prob(single_ref_prob[i][1]); } } if (reference_mode != SINGLE_REFERENCE) { int i = 0; for (i = 0; i < REF_CONTEXTS; ++i) { comp_ref_prob[i] = diff_update_prob(comp_ref_prob[i]); } } } void read_y_mode_probs() { int i = 0; for (i = 0; i < BLOCK_SIZE_GROUPS; ++i) { int j = 0; for (j = 0; j < INTRA_MODES - 1; ++j) { y_mode_probs[i][j] = diff_update_prob(y_mode_probs[i][j]); } } } void read_partition_probs() { int i = 0; for (i = 0; i < PARTITION_CONTEXTS; ++i) { int j = 0; for (j = 0; j < PARTITION_TYPES - 1; ++j) { partition_probs[i][j] = diff_update_prob(partition_probs[i][j]); } } } int update_mv_prob(int mv) { int update_mv_prob_value = Bn(252); int prob = 0; if (1 == update_mv_prob_value) { int mv_prob = Ln(7); prob = (mv_prob << 1) | 1; } return prob; } void mv_probs() { int i = 0, j = 0; for (j = 0; j < MV_JOINTS - 1; ++j) { mv_joint_probs[j] = update_mv_prob(mv_joint_probs[j]); } for (i = 0; i < 2; ++i) { mv_sign_probs[i] = update_mv_prob(mv_sign_probs[i]); for (j = 0; j < MV_CLASSES - 1; ++j) { mv_class_probs[i][j] = update_mv_prob(mv_class_probs[i][j]); } mv_class0_bit_prob[i] = update_mv_prob(mv_class0_bit_prob[i]); for (j = 0; j < MV_OFFSET_BITS; ++j) { mv_bits_prob[i][j] = update_mv_prob(mv_bits_prob[i][j]); } } for (i = 0; i < 2; ++i) { for (j = 0; j < CLASS0_SIZE; ++j) { int k = 0; for (k = 0; k < MV_FR_SIZE - 1; ++k) { mv_class0_fr_probs[i][j][k] = update_mv_prob(mv_class0_fr_probs[i][j][k]); } } for (j = 0; j < MV_FR_SIZE - 1; ++j) { mv_fr_probs[i][j] = update_mv_prob(mv_fr_probs[i][j]); } } if (allow_high_precision_mv) { for (i = 0; i < 2; ++i) { mv_class0_hp_prob[i] = update_mv_prob(mv_class0_hp_prob[i]); mv_hp_prob[i] = update_mv_prob(mv_hp_prob[i]); } } } void compressed_header() { read_tx_mode(); if (TX_MODE_SELECT == tx_mode) { tx_mode_probs(); } read_coef_probs(); read_skip_prob(); if (0 == FrameIsIntra) { read_inter_mode_probs(); if (SWITCHABLE == interpolation_filter) { read_interp_filter_probs(); } read_is_inter_probs(); frame_reference_mode(); frame_reference_mode_probs(); read_y_mode_probs(); read_partition_probs(); mv_probs(); } } / compressed_header end /// / decode_one frame start /// int updateFactor = 0; int get_position() { return g_u32bitpos; } void trailing_bits() { while (get_position() & 0x7) { int zero_bit = fn(1); } } void load_probs(unsigned int frame_context_idx) { } void load_probs2(unsigned int frame_context_idx) { } void clear_counts() { #define _CLEAR_COUNTS_(x) memset(x, 0x0, sizeof(x)) _CLEAR_COUNTS_(counts_intra_mode); _CLEAR_COUNTS_(counts_uv_mode); _CLEAR_COUNTS_(counts_partition); _CLEAR_COUNTS_(counts_interp_filter); _CLEAR_COUNTS_(counts_inter_mode); _CLEAR_COUNTS_(counts_tx_size); _CLEAR_COUNTS_(counts_is_inter); _CLEAR_COUNTS_(counts_comp_mode); _CLEAR_COUNTS_(counts_single_ref); _CLEAR_COUNTS_(counts_comp_ref); _CLEAR_COUNTS_(counts_skip); _CLEAR_COUNTS_(counts_mv_joint); _CLEAR_COUNTS_(counts_mv_sign); _CLEAR_COUNTS_(counts_mv_class); _CLEAR_COUNTS_(counts_mv_class0_bit); _CLEAR_COUNTS_(counts_mv_class0_fr); _CLEAR_COUNTS_(counts_mv_class0_hp); _CLEAR_COUNTS_(counts_mv_bits); _CLEAR_COUNTS_(counts_mv_fr); _CLEAR_COUNTS_(counts_mv_hp); _CLEAR_COUNTS_(counts_token); _CLEAR_COUNTS_(counts_more_coefs); #undef _CLEAR_COUNTS_ } void decode_tiles(unsigned int sz) { } int Clip3(int x, int y, int z) { if (z < x) { return x; } if (z > y) { return y; } return z; } int Min(int x, int y) { if (x <= y) { return x; } return y; } int Round2(int x, int n) { return ((x + (1 << (n - 1))) >> n); } int merge_prob(int preProb, int ct0, int ct1, int countSat, int maxUpdateFactor) { int outProb = 0; int den = ct0 + ct1; int prob = (den == 0) ? 128 : Clip3(1, 255, (ct0 * 256 + (den >> 1)) / den); int count = Min(ct0 + ct1, countSat); int factor = maxUpdateFactor * count / countSat; outProb = Round2(preProb * (256 - factor) + prob * factor, 8); return outProb; } int merge_probs(int *tree, int i, int *probs, int *counts, int countSat, int maxUpdateFactor) { int s = tree[i]; int leftCount = (s <= 0) ? counts[-s] : merge_probs(tree, s, probs, counts, countSat, maxUpdateFactor); int r = tree[i + 1]; int rightCount = (r <= 0) ? counts[-r] : merge_probs(tree, r, probs, counts, countSat, maxUpdateFactor); probs[i >> 1] = merge_prob(probs[i >> 1], leftCount, rightCount, countSat, maxUpdateFactor); return leftCount + rightCount; } #define ZERO_TOKEN (0) #define ONE_TOKEN (1) #define TWO_TOKEN (2) #define THREE_TOKEN (3) #define FOUR_TOKEN (4) #define DCT_VAL_CAT1 (5) #define DCT_VAL_CAT2 (6) #define DCT_VAL_CAT3 (7) #define DCT_VAL_CAT4 (8) #define DCT_VAL_CAT5 (9) #define DCT_VAL_CAT6 (10) int binary_tree[2] = {0,-1}; int small_token_tree[6] = { 0, 0, // Unused -ZERO_TOKEN, 4, -ONE_TOKEN, -TWO_TOKEN }; void adapt_coef_probs() { if (1 == FrameIsIntra) { updateFactor = 112; } else { if (KEY_FRAME == lastFrameType) { updateFactor = 128; } else { updateFactor = 112; } } int t = 0, i = 0, j = 0, k = 0, l = 0, maxL = 0; for (t = 0; t < 4; ++t) { for (i = 0; i < 2; ++i) { for (k = 0; k < 6; ++k) { maxL = (0 == k) ? 3 : 6; for (l = 0; l < maxL; ++l) { merge_probs(small_token_tree, 2, coef_probs[t][i][j][k][l], counts_token[t][i][j][k][l], 24, updateFactor); merge_probs(binary_tree, 0, coef_probs[t][i][j][k][l], counts_more_coefs[t][i][j][k][l], 24, updateFactor); } } } } } #define COUNT_SAT (20) #define MAX_UPDATE_FACTOR (128) int adapt_prob(int prob, int *counts) { return merge_prob(prob, counts[0], counts[1], COUNT_SAT, MAX_UPDATE_FACTOR); } void adapt_probs(int *tree, int *probs, int *counts) { merge_probs(tree, 0, probs, counts, COUNT_SAT, MAX_UPDATE_FACTOR); } #define NEARESTMV (0) #define NEARMV (1) #define ZEROMV (2) #define NEWMV (3) int inter_mode_tree[6] = { -(ZEROMV - NEARESTMV), 2, -(NEARESTMV - NEARESTMV), 4, -(NEARMV - NEARESTMV), -(NEWMV - NEARESTMV) }; #define DC_PRED (0) #define V_PRED (1) #define H_PRED (2) #define D45_PRED (3) #define D135_PRED (4) #define D117_PRED (5) #define D153_PRED (6) #define D207_PRED (7) #define D63_PRED (8) #define TM_PRED (9) int intra_mode_tree[18] = { -DC_PRED, 2 , -TM_PRED, 4, -V_PRED, 6, 8, 12, -H_PRED, 10, -D135_PRED, -D117_PRED, -D45_PRED, 14, -D63_PRED, 16, -D153_PRED, -D207_PRED }; #define PARTITION_NONE (0) #define PARTITION_HORZ (0) #define PARTITION_VERT (0) #define PARTITION_SPLIT (0) int partition_tree[6] = { -PARTITION_NONE, 2, -PARTITION_HORZ, 4, -PARTITION_VERT, -PARTITION_SPLIT }; int tx_size_32_tree[ 6 ] = { -TX_4X4, 2, -TX_8X8, 4, -TX_16X16, -TX_32X32 }; int tx_size_16_tree[ 4 ] = { -TX_4X4, 2, -TX_8X8, -TX_16X16, }; int tx_size_8_tree[ 2 ] = { -TX_4X4, -TX_8X8 }; #define MV_CLASS_0 (0) #define MV_CLASS_1 (1) #define MV_CLASS_2 (2) #define MV_CLASS_3 (3) #define MV_CLASS_4 (4) #define MV_CLASS_5 (5) #define MV_CLASS_6 (6) #define MV_CLASS_7 (7) #define MV_CLASS_8 (8) #define MV_CLASS_9 (9) #define MV_CLASS_10 (10) int mv_class_tree[ 20 ] = { -MV_CLASS_0, 2, -MV_CLASS_1, 4, 6, 8, -MV_CLASS_2, -MV_CLASS_3, 10, 12, -MV_CLASS_4, -MV_CLASS_5, -MV_CLASS_6, 14, 16, 18, -MV_CLASS_7, -MV_CLASS_8, -MV_CLASS_9, -MV_CLASS_10, }; int mv_fr_tree[ 6 ] = { -0, 2, -1, 4, -2, -3 }; int default_tx_probs[ TX_SIZES ] [ TX_SIZE_CONTEXTS ][ TX_SIZES - 1 ] = { { {0,0,0}, {0,0,0} }, { {100,0,0}, {66,0,0} }, { { 20, 152, 0 },{ 15, 101, 0 } }, { { 3, 136, 37 } ,{ 5, 52, 13 } } }; int kf_uv_mode_probs[ INTRA_MODES ][ INTRA_MODES - 1 ] = { { 144, 11, 54, 157, 195, 130, 46, 58, 108 }, // y = dc { 118, 15, 123, 148, 131, 101, 44, 93, 131 }, // y = v { 113, 12, 23, 188, 226, 142, 26, 32, 125 }, // y = h { 120, 11, 50, 123, 163, 135, 64, 77, 103 }, // y = d45 { 113, 9, 36, 155, 111, 157, 32, 44, 161 }, // y = d135 { 116, 9, 55, 176, 76, 96, 37, 61, 149 }, // y = d117 { 115, 9, 28, 141, 161, 167, 21, 25, 193 }, // y = d153 { 120, 12, 32, 145, 195, 142, 32, 38, 86 }, // y = d207 { 116, 12, 64, 120, 140, 125, 49, 115, 121 }, // y = d63 { 102, 19, 66, 162, 182, 122, 35, 59, 128 } // y = tm }; int default_interp_filter_probs[ INTERP_FILTER_CONTEXTS ][ SWITCHABLE_FILTERS - 1 ] = { { 235, 162 }, { 36, 255 }, { 34, 3 }, { 149, 144 } }; int default_mv_sign_prob[ 2 ] = { 128, 128 }; #define MV_JOINT_ZERO (0) #define MV_JOINT_HNZVZ (1) #define MV_JOINT_HZVNZ (2) #define MV_JOINT_HNZVNZ (3) int mv_joint_tree[ 6 ] = { -MV_JOINT_ZERO, 2, -MV_JOINT_HNZVZ, 4, -MV_JOINT_HZVNZ, -MV_JOINT_HNZVNZ }; int interp_filter_tree[ 4 ] = { - EIGHTTAP, 2, - EIGHTTAP_SMOOTH, -EIGHTTAP_SHARP }; void adapt_noncoef_probs() { int i = 0, j = 0; for (i = 0; i < IS_INTER_CONTEXTS; i++) { is_inter_prob[i] = adapt_prob(is_inter_prob[i], counts_is_inter[i]); } for (i = 0; i < COMP_MODE_CONTEXTS; i++) { comp_mode_prob[i] = adapt_prob(comp_mode_prob[i], counts_comp_mode[i]); } for (i = 0; i < REF_CONTEXTS; i++) { comp_ref_prob[i] = adapt_prob(comp_ref_prob[i], counts_comp_ref[i]); } for (i = 0; i < REF_CONTEXTS; i++) { for (j = 0; j < 2; j++) { single_ref_prob[i][j] = adapt_prob(single_ref_prob[i][j], counts_single_ref[i][j]); } } for (i = 0; i < INTER_MODE_CONTEXTS; i++) { adapt_probs(inter_mode_tree, inter_mode_probs[i], counts_inter_mode[i]); } for (i = 0; i < BLOCK_SIZE_GROUPS; i++) { adapt_probs(intra_mode_tree, y_mode_probs[i], counts_intra_mode[i]); } for (i = 0; i < INTRA_MODES; i++) { adapt_probs(intra_mode_tree, kf_uv_mode_probs[i], counts_uv_mode[i]); } for (i = 0; i < PARTITION_CONTEXTS; i++) { adapt_probs(partition_tree, partition_probs[i], counts_partition[i]); } for (i = 0; i < SKIP_CONTEXTS; i++) { skip_prob[i] = adapt_prob(skip_prob[i], counts_skip[i]); } if (interpolation_filter == SWITCHABLE ) { for (i = 0; i < INTERP_FILTER_CONTEXTS; i++) { adapt_probs(interp_filter_tree, default_interp_filter_probs[i], counts_interp_filter[i]); } } if (tx_mode == TX_MODE_SELECT){ for (i = 0; i < TX_SIZE_CONTEXTS; i++ ) { adapt_probs(tx_size_8_tree, default_tx_probs[TX_8X8][i], counts_tx_size[TX_8X8][i]); adapt_probs(tx_size_16_tree, default_tx_probs[TX_16X16][i], counts_tx_size[TX_16X16][i]); adapt_probs(tx_size_32_tree, default_tx_probs[TX_32X32][i], counts_tx_size[TX_32X32][i]); } } adapt_probs(mv_joint_tree, mv_joint_probs, counts_mv_joint); for (i = 0; i < 2; i++) { default_mv_sign_prob[i] = adapt_prob(default_mv_sign_prob[i], counts_mv_sign[i]); adapt_probs(mv_class_tree, mv_class_probs[i], counts_mv_class[i]); mv_class0_bit_prob[i] = adapt_prob(mv_class0_bit_prob[i ], counts_mv_class0_bit[i]); for (j = 0; j < MV_OFFSET_BITS; j++) { mv_bits_prob[i][j] = adapt_prob(mv_bits_prob[i][j], counts_mv_bits[i][j]); } for (j = 0; j < CLASS0_SIZE; j++) { adapt_probs(mv_fr_tree, mv_class0_fr_probs[i][j], counts_mv_class0_fr [i][j]); } adapt_probs(mv_fr_tree, mv_fr_probs[i], counts_mv_fr[i]); if (allow_high_precision_mv) { mv_class0_hp_prob[i] = adapt_prob(mv_class0_hp_prob[i], counts_mv_class0_hp[i]) ; mv_hp_prob[i] = adapt_prob(mv_hp_prob[i], counts_mv_hp[i]); } } } void refresh_probs() { if ((0 == error_resilient_mode) && (0 == frame_parallel_decoding_mode)) { load_probs(frame_context_idx); adapt_coef_probs(); if (0 == FrameIsIntra) { load_probs2(frame_context_idx); adapt_noncoef_probs(); } } if (refresh_frame_context) { save_probs(frame_context_idx); } } void parser_one_frame(unsigned int sz) { int startBitPos = get_position(); uncompressed_header(); trailing_bits(); if (0 == header_size_in_bytes) { while (get_position() < startBitPos + 8 * sz) { int padding_bit = fn(1); } return; } load_probs(frame_context_idx); load_probs2(frame_context_idx); clear_counts(); init_bool(header_size_in_bytes); compressed_header(); exit_bool(); int endBitPos = get_position(); int headerBytes = (endBitPos - startBitPos) / 8; decode_tiles(sz - headerBytes); refresh_probs(); ///after decoder one frame reference_frame_update_process(); } / decorder one frame start /// void show_current_frame_info() { printf("profile:%d key_frame:%s(%s) frame size(%d x %d), render size(%d x %d)\n", profile, (frame_type ? "NO" : "YES"), FrameIsIntra ? "intra_only" : "inter", FrameWidth, FrameHeight, renderWidth, renderHeight); printf("comepressed header size:%d Byte\n", header_size_in_bytes); printf("chroma format:%s\n", chroma_subsampling_forma[subsampling_x*2+subsampling_y]); } int main(int argc, char *argv[]) { g_u32bitpos = 0; #if (0) g_fread = fopen(argv[1], "r+"); #else g_fread = fopen("vp9ng.es", "r+"); #endif g_phead = (unsigned char *)malloc(_HEAD_LEN_); g_pbuf = (unsigned char *)malloc(5*1024*1024); #if (1) int count = 0; if (g_fread && g_phead && g_pbuf) { while (read_one_frame(&g_u32bufsz)) { g_u32bitpos = 0; parser_one_frame(g_u32bufsz); show_current_frame_info(); #if (0) static int count = 0; if (2 <= count++) break; #endif printf("parser count:%d xx\n", count++); } } #else ///function test g_u32bufsz = 4; g_pbuf[0] = 0xF4; g_pbuf[1] = 0x01; g_pbuf[2] = 0xC5; g_pbuf[3] = 0x7A; int i = 0, j = 0; for (i = 0; i < 4; ++i) { for (j = 0; j < 2; ++j) { printf("%d ", fn(4)); } printf("\n"); } #endif if (g_fread) { fclose(g_fread); g_fread = NULL; } if (g_phead) { free(g_phead); g_phead = NULL; } if (g_pbuf) { free(g_pbuf); g_pbuf = NULL; } return 0; } #if (0) if (1) { ///dump es if (0 < stBufInfo.u32BufSize) { if (NULL == g_fpdump) { g_fpdump = fopen("/mnt/usb/sda1/dump_injvp9.es", "w+"); } if (g_fpdump) { char buf[8]; memset(buf, 0x0, sizeof(buf)); char *p = (char *)(&(stBufInfo.u32BufSize)); buf[7] = p[0]; buf[6] = p[1]; buf[5] = p[2]; buf[4] = p[3]; fwrite(buf, 8, 1, g_fpdump); memset(buf, 0x0, sizeof(buf)); p = (char *)(&(stBufInfo.u64Pts)); buf[7] = p[0]; buf[6] = p[1]; buf[5] = p[2]; buf[4] = p[3]; buf[3] = p[4]; buf[2] = p[5]; buf[1] = p[6]; buf[0] = p[7]; fwrite(buf, 8, 1, g_fpdump); fwrite(stBufInfo.pu8BufAddr, stBufInfo.u32BufSize, 1, g_fpdump); printf("[bz]write size:0x%x done ....\n", stBufInfo.u32BufSize); } } } #endif
vp9 header parser
最新推荐文章于 2024-01-29 22:13:10 发布