📄 vp3.c
字号:
debug_dequantizers(" %4d,", s->inter_dequant[j]); } debug_dequantizers("\n"); } debug_dequantizers("\n");}/* * This function is used to fetch runs of 1s or 0s from the bitstream for * use in determining which superblocks are fully and partially coded. * * Codeword RunLength * 0 1 * 10x 2-3 * 110x 4-5 * 1110xx 6-9 * 11110xxx 10-17 * 111110xxxx 18-33 * 111111xxxxxxxxxxxx 34-4129 */static int get_superblock_run_length(GetBitContext *gb){ if (get_bits(gb, 1) == 0) return 1; else if (get_bits(gb, 1) == 0) return (2 + get_bits(gb, 1)); else if (get_bits(gb, 1) == 0) return (4 + get_bits(gb, 1)); else if (get_bits(gb, 1) == 0) return (6 + get_bits(gb, 2)); else if (get_bits(gb, 1) == 0) return (10 + get_bits(gb, 3)); else if (get_bits(gb, 1) == 0) return (18 + get_bits(gb, 4)); else return (34 + get_bits(gb, 12));}/* * This function is used to fetch runs of 1s or 0s from the bitstream for * use in determining which particular fragments are coded. * * Codeword RunLength * 0x 1-2 * 10x 3-4 * 110x 5-6 * 1110xx 7-10 * 11110xx 11-14 * 11111xxxx 15-30 */static int get_fragment_run_length(GetBitContext *gb){ if (get_bits(gb, 1) == 0) return (1 + get_bits(gb, 1)); else if (get_bits(gb, 1) == 0) return (3 + get_bits(gb, 1)); else if (get_bits(gb, 1) == 0) return (5 + get_bits(gb, 1)); else if (get_bits(gb, 1) == 0) return (7 + get_bits(gb, 2)); else if (get_bits(gb, 1) == 0) return (11 + get_bits(gb, 2)); else return (15 + get_bits(gb, 4));}/* * This function decodes a VLC from the bitstream and returns a number * that ranges from 0..7. The number indicates which of the 8 coding * modes to use. * * VLC Number * 0 0 * 10 1 * 110 2 * 1110 3 * 11110 4 * 111110 5 * 1111110 6 * 1111111 7 * */static int get_mode_code(GetBitContext *gb){ if (get_bits(gb, 1) == 0) return 0; else if (get_bits(gb, 1) == 0) return 1; else if (get_bits(gb, 1) == 0) return 2; else if (get_bits(gb, 1) == 0) return 3; else if (get_bits(gb, 1) == 0) return 4; else if (get_bits(gb, 1) == 0) return 5; else if (get_bits(gb, 1) == 0) return 6; else return 7;}/* * This function extracts a motion vector from the bitstream using a VLC * scheme. 3 bits are fetched from the bitstream and 1 of 8 actions is * taken depending on the value on those 3 bits: * * 0: return 0 * 1: return 1 * 2: return -1 * 3: if (next bit is 1) return -2, else return 2 * 4: if (next bit is 1) return -3, else return 3 * 5: return 4 + (next 2 bits), next bit is sign * 6: return 8 + (next 3 bits), next bit is sign * 7: return 16 + (next 4 bits), next bit is sign */static int get_motion_vector_vlc(GetBitContext *gb){ int bits; bits = get_bits(gb, 3); switch(bits) { case 0: bits = 0; break; case 1: bits = 1; break; case 2: bits = -1; break; case 3: if (get_bits(gb, 1) == 0) bits = 2; else bits = -2; break; case 4: if (get_bits(gb, 1) == 0) bits = 3; else bits = -3; break; case 5: bits = 4 + get_bits(gb, 2); if (get_bits(gb, 1) == 1) bits = -bits; break; case 6: bits = 8 + get_bits(gb, 3); if (get_bits(gb, 1) == 1) bits = -bits; break; case 7: bits = 16 + get_bits(gb, 4); if (get_bits(gb, 1) == 1) bits = -bits; break; } return bits;}/* * This function fetches a 5-bit number from the stream followed by * a sign and calls it a motion vector. */static int get_motion_vector_fixed(GetBitContext *gb){ int bits; bits = get_bits(gb, 5); if (get_bits(gb, 1) == 1) bits = -bits; return bits;}/* * This function unpacks all of the superblock/macroblock/fragment coding * information from the bitstream. */static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb){ int bit = 0; int current_superblock = 0; int current_run = 0; int decode_fully_flags = 0; int decode_partial_blocks = 0; int first_c_fragment_seen; int i, j; int current_fragment; debug_vp3(" vp3: unpacking superblock coding\n"); if (s->keyframe) { debug_vp3(" keyframe-- all superblocks are fully coded\n"); memset(s->superblock_coding, SB_FULLY_CODED, s->superblock_count); } else { /* unpack the list of partially-coded superblocks */ bit = get_bits(gb, 1); /* 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_superblock_run_length(gb); 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) ? SB_PARTIALLY_CODED : SB_NOT_CODED; current_run--; } /* 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_bits(gb, 1); /* 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_superblock_run_length(gb); } debug_block_coding(" setting superblock %d to %s\n", current_superblock, (bit) ? "fully coded" : "not coded"); s->superblock_coding[current_superblock] = (bit) ? SB_FULLY_CODED : SB_NOT_CODED; current_run--; } current_superblock++; } } /* if there were partial blocks, initialize bitstream for * unpacking fragment codings */ if (decode_partial_blocks) { current_run = 0; bit = get_bits(gb, 1); /* 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->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_fragment_run_length(gb); } 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->coded_fragment_list[s->coded_fragment_list_index] = current_fragment; if ((current_fragment >= s->u_fragment_start) && (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); } current_run--; } 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->coded_fragment_list[s->coded_fragment_list_index] = current_fragment; if ((current_fragment >= s->u_fragment_start) && (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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -