📄 vp3.c
字号:
/* unpack the list of partially-coded superblocks */ bit = get_bits1(gb); /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; while (current_superblock < s->superblock_count) { if (current_run-- == 0) { bit ^= 1; current_run = get_vlc2(gb, s->superblock_run_length_vlc.table, 6, 2); if (current_run == 33) current_run += get_bits(gb, 12); debug_block_coding(" setting superblocks %d..%d to %s\n", current_superblock, current_superblock + current_run - 1, (bit) ? "partially coded" : "not coded"); /* if any of the superblocks are not partially coded, flag * a boolean to decode the list of fully-coded superblocks */ if (bit == 0) { decode_fully_flags = 1; } else { /* make a note of the fact that there are partially coded * superblocks */ decode_partial_blocks = 1; } } s->superblock_coding[current_superblock++] = bit; } /* unpack the list of fully coded superblocks if any of the blocks were * not marked as partially coded in the previous step */ if (decode_fully_flags) { current_superblock = 0; current_run = 0; bit = get_bits1(gb); /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; while (current_superblock < s->superblock_count) { /* skip any superblocks already marked as partially coded */ if (s->superblock_coding[current_superblock] == SB_NOT_CODED) { if (current_run-- == 0) { bit ^= 1; current_run = get_vlc2(gb, s->superblock_run_length_vlc.table, 6, 2); if (current_run == 33) current_run += get_bits(gb, 12); } debug_block_coding(" setting superblock %d to %s\n", current_superblock, (bit) ? "fully coded" : "not coded"); s->superblock_coding[current_superblock] = 2*bit; } current_superblock++; } } /* if there were partial blocks, initialize bitstream for * unpacking fragment codings */ if (decode_partial_blocks) { current_run = 0; bit = get_bits1(gb); /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; } } /* figure out which fragments are coded; iterate through each * superblock (all planes) */ s->coded_fragment_list_index = 0; s->next_coeff= s->coeffs + s->fragment_count; s->first_coded_y_fragment = s->first_coded_c_fragment = 0; s->last_coded_y_fragment = s->last_coded_c_fragment = -1; first_c_fragment_seen = 0; memset(s->macroblock_coding, MODE_COPY, s->macroblock_count); for (i = 0; i < s->superblock_count; i++) { /* iterate through all 16 fragments in a superblock */ for (j = 0; j < 16; j++) { /* if the fragment is in bounds, check its coding status */ current_fragment = s->superblock_fragments[i * 16 + j]; if (current_fragment >= s->fragment_count) { av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_superblocks(): bad fragment number (%d >= %d)\n", current_fragment, s->fragment_count); return 1; } if (current_fragment != -1) { if (s->superblock_coding[i] == SB_NOT_CODED) { /* copy all the fragments from the prior frame */ s->all_fragments[current_fragment].coding_method = MODE_COPY; } else if (s->superblock_coding[i] == SB_PARTIALLY_CODED) { /* fragment may or may not be coded; this is the case * that cares about the fragment coding runs */ if (current_run-- == 0) { bit ^= 1; current_run = get_vlc2(gb, s->fragment_run_length_vlc.table, 5, 2); } if (bit) { /* default mode; actual mode will be decoded in * the next phase */ s->all_fragments[current_fragment].coding_method = MODE_INTER_NO_MV; s->all_fragments[current_fragment].next_coeff= s->coeffs + current_fragment; s->coded_fragment_list[s->coded_fragment_list_index] = current_fragment; if ((current_fragment >= s->fragment_start[1]) && (s->last_coded_y_fragment == -1) && (!first_c_fragment_seen)) { s->first_coded_c_fragment = s->coded_fragment_list_index; s->last_coded_y_fragment = s->first_coded_c_fragment - 1; first_c_fragment_seen = 1; } s->coded_fragment_list_index++; s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV; debug_block_coding(" superblock %d is partially coded, fragment %d is coded\n", i, current_fragment); } else { /* not coded; copy this fragment from the prior frame */ s->all_fragments[current_fragment].coding_method = MODE_COPY; debug_block_coding(" superblock %d is partially coded, fragment %d is not coded\n", i, current_fragment); } } else { /* fragments are fully coded in this superblock; actual * coding will be determined in next step */ s->all_fragments[current_fragment].coding_method = MODE_INTER_NO_MV; s->all_fragments[current_fragment].next_coeff= s->coeffs + current_fragment; s->coded_fragment_list[s->coded_fragment_list_index] = current_fragment; if ((current_fragment >= s->fragment_start[1]) && (s->last_coded_y_fragment == -1) && (!first_c_fragment_seen)) { s->first_coded_c_fragment = s->coded_fragment_list_index; s->last_coded_y_fragment = s->first_coded_c_fragment - 1; first_c_fragment_seen = 1; } s->coded_fragment_list_index++; s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV; debug_block_coding(" superblock %d is fully coded, fragment %d is coded\n", i, current_fragment); } } } } if (!first_c_fragment_seen) /* only Y fragments coded in this frame */ s->last_coded_y_fragment = s->coded_fragment_list_index - 1; else /* end the list of coded C fragments */ s->last_coded_c_fragment = s->coded_fragment_list_index - 1; debug_block_coding(" %d total coded fragments, y: %d -> %d, c: %d -> %d\n", s->coded_fragment_list_index, s->first_coded_y_fragment, s->last_coded_y_fragment, s->first_coded_c_fragment, s->last_coded_c_fragment); return 0;}/* * This function unpacks all the coding mode data for individual macroblocks * from the bitstream. */static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb){ int i, j, k; int scheme; int current_macroblock; int current_fragment; int coding_mode; int custom_mode_alphabet[CODING_MODE_COUNT]; debug_vp3(" vp3: unpacking encoding modes\n"); if (s->keyframe) { debug_vp3(" keyframe-- all blocks are coded as INTRA\n"); for (i = 0; i < s->fragment_count; i++) s->all_fragments[i].coding_method = MODE_INTRA; } else { /* fetch the mode coding scheme for this frame */ scheme = get_bits(gb, 3); debug_modes(" using mode alphabet %d\n", scheme); /* is it a custom coding scheme? */ if (scheme == 0) { debug_modes(" custom mode alphabet ahead:\n"); for (i = 0; i < 8; i++) custom_mode_alphabet[get_bits(gb, 3)] = i; } for (i = 0; i < 8; i++) { if(scheme) debug_modes(" mode[%d][%d] = %d\n", scheme, i, ModeAlphabet[scheme-1][i]); else debug_modes(" mode[0][%d] = %d\n", i, custom_mode_alphabet[i]); } /* iterate through all of the macroblocks that contain 1 or more * coded fragments */ for (i = 0; i < s->u_superblock_start; i++) { for (j = 0; j < 4; j++) { current_macroblock = s->superblock_macroblocks[i * 4 + j]; if ((current_macroblock == -1) || (s->macroblock_coding[current_macroblock] == MODE_COPY)) continue; if (current_macroblock >= s->macroblock_count) { av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_modes(): bad macroblock number (%d >= %d)\n", current_macroblock, s->macroblock_count); return 1; } /* mode 7 means get 3 bits for each coding mode */ if (scheme == 7) coding_mode = get_bits(gb, 3); else if(scheme == 0) coding_mode = custom_mode_alphabet [get_vlc2(gb, s->mode_code_vlc.table, 3, 3)]; else coding_mode = ModeAlphabet[scheme-1] [get_vlc2(gb, s->mode_code_vlc.table, 3, 3)]; s->macroblock_coding[current_macroblock] = coding_mode; for (k = 0; k < 6; k++) { current_fragment = s->macroblock_fragments[current_macroblock * 6 + k]; if (current_fragment == -1) continue; if (current_fragment >= s->fragment_count) { av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_modes(): bad fragment number (%d >= %d)\n", current_fragment, s->fragment_count); return 1; } if (s->all_fragments[current_fragment].coding_method != MODE_COPY) s->all_fragments[current_fragment].coding_method = coding_mode; } debug_modes(" coding method for macroblock starting @ fragment %d = %d\n", s->macroblock_fragments[current_macroblock * 6], coding_mode); } } } return 0;}/* * This function unpacks all the motion vectors for the individual * macroblocks from the bitstream. */static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb){ int i, j, k; int coding_mode; int motion_x[6]; int motion_y[6]; int last_motion_x = 0; int last_motion_y = 0; int prior_last_motion_x = 0; int prior_last_motion_y = 0; int current_macroblock; int current_fragment; debug_vp3(" vp3: unpacking motion vectors\n"); if (s->keyframe) { debug_vp3(" keyframe-- there are no motion vectors\n"); } else { memset(motion_x, 0, 6 * sizeof(int)); memset(motion_y, 0, 6 * sizeof(int)); /* coding mode 0 is the VLC scheme; 1 is the fixed code scheme */ coding_mode = get_bits1(gb); debug_vectors(" using %s scheme for unpacking motion vectors\n", (coding_mode == 0) ? "VLC" : "fixed-length"); /* iterate through all of the macroblocks that contain 1 or more * coded fragments */ for (i = 0; i < s->u_superblock_start; i++) { for (j = 0; j < 4; j++) { current_macroblock = s->superblock_macroblocks[i * 4 + j]; if ((current_macroblock == -1) || (s->macroblock_coding[current_macroblock] == MODE_COPY)) continue; if (current_macroblock >= s->macroblock_count) { av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_vectors(): bad macroblock number (%d >= %d)\n", current_macroblock, s->macroblock_count); return 1; } current_fragment = s->macroblock_fragments[current_macroblock * 6]; if (current_fragment >= s->fragment_count) { av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_vectors(): bad fragment number (%d >= %d\n", current_fragment, s->fragment_count); return 1; } switch (s->macroblock_coding[current_macroblock]) { case MODE_INTER_PLUS_MV: case MODE_GOLDEN_MV: /* all 6 fragments use the same motion vector */ if (coding_mode == 0) { motion_x[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; motion_y[0] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; } else { motion_x[0] = fixed_motion_vector_table[get_bits(gb, 6)]; motion_y[0] = fixed_motion_vector_table[get_bits(gb, 6)]; } for (k = 1; k < 6; k++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -