📄 vp3.c
字号:
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; 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++) ModeAlphabet[scheme][get_bits(gb, 3)] = i; } for (i = 0; i < 8; i++) debug_modes(" mode[%d][%d] = %d\n", scheme, i, ModeAlphabet[scheme][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 coding_mode = ModeAlphabet[scheme][get_mode_code(gb)]; 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_bits(gb, 1); 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] = get_motion_vector_vlc(gb); motion_y[0] = get_motion_vector_vlc(gb); } else { motion_x[0] = get_motion_vector_fixed(gb); motion_y[0] = get_motion_vector_fixed(gb); } for (k = 1; k < 6; k++) { motion_x[k] = motion_x[0]; motion_y[k] = motion_y[0]; } /* vector maintenance, only on MODE_INTER_PLUS_MV */ if (s->macroblock_coding[current_macroblock] == MODE_INTER_PLUS_MV) { prior_last_motion_x = last_motion_x; prior_last_motion_y = last_motion_y; last_motion_x = motion_x[0]; last_motion_y = motion_y[0]; } break; case MODE_INTER_FOURMV: /* fetch 4 vectors from the bitstream, one for each * Y fragment, then average for the C fragment vectors */ motion_x[4] = motion_y[4] = 0; for (k = 0; k < 4; k++) { if (coding_mode == 0) { motion_x[k] = get_motion_vector_vlc(gb); motion_y[k] = get_motion_vector_vlc(gb); } else { motion_x[k] = get_motion_vector_fixed(gb); motion_y[k] = get_motion_vector_fixed(gb); } motion_x[4] += motion_x[k]; motion_y[4] += motion_y[k]; } if (motion_x[4] >= 0) motion_x[4] = (motion_x[4] + 2) / 4; else motion_x[4] = (motion_x[4] - 2) / 4; motion_x[5] = motion_x[4]; if (motion_y[4] >= 0) motion_y[4] = (motion_y[4] + 2) / 4; else motion_y[4] = (motion_y[4] - 2) / 4; motion_y[5] = motion_y[4]; /* vector maintenance; vector[3] is treated as the * last vector in this case */ prior_last_motion_x = last_motion_x; prior_last_motion_y = last_motion_y; last_motion_x = motion_x[3]; last_motion_y = motion_y[3]; break; case MODE_INTER_LAST_MV: /* all 6 fragments use the last motion vector */ motion_x[0] = last_motion_x; motion_y[0] = last_motion_y; for (k = 1; k < 6; k++) { motion_x[k] = motion_x[0]; motion_y[k] = motion_y[0]; } /* no vector maintenance (last vector remains the * last vector) */ break; case MODE_INTER_PRIOR_LAST: /* all 6 fragments use the motion vector prior to the * last motion vector */ motion_x[0] = prior_last_motion_x; motion_y[0] = prior_last_motion_y; for (k = 1; k < 6; k++) { motion_x[k] = motion_x[0]; motion_y[k] = motion_y[0]; } /* vector maintenance */ prior_last_motion_x = last_motion_x; prior_last_motion_y = last_motion_y; last_motion_x = motion_x[0]; last_motion_y = motion_y[0]; break; default: /* covers intra, inter without MV, golden without MV */ memset(motion_x, 0, 6 * sizeof(int)); memset(motion_y, 0, 6 * sizeof(int)); /* no vector maintenance */ break; } /* assign the motion vectors to the correct fragments */ debug_vectors(" vectors for macroblock starting @ fragment %d (coding method %d):\n", current_fragment, s->macroblock_coding[current_macroblock]); 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_vectors(): bad fragment number (%d >= %d)\n", current_fragment, s->fragment_count); return 1; } s->all_fragments[current_fragment].motion_x = motion_x[k]; s->all_fragments[current_fragment].motion_y = motion_y[k]; debug_vectors(" vector %d: fragment %d = (%d, %d)\n", k, current_fragment, motion_x[k], motion_y[k]); } } } } return 0;}/* * This function is called by unpack_dct_coeffs() to extract the VLCs from * the bitstream. The VLCs encode tokens which are used to unpack DCT * data. This function unpacks all the VLCs for either the Y plane or both * C planes, and is called for DC coefficients or different AC coefficient * levels (since different coefficient types require different VLC tables. * * This function returns a residual eob run. E.g, if a particular token gave * instructions to EOB the next 5 fragments and there were only 2 fragments * left in the current fragment range, 3 would be returned so that it could * be passed into the next call to this same function. */static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, VLC *table, int coeff_index, int first_fragment, int last_fragment, int eob_run){ int i; int token; int zero_run; DCTELEM coeff; Vp3Fragment *fragment; if ((first_fragment >= s->fragment_count) || (last_fragment >= s->fragment_count)) { av_log(s->avctx, AV_LOG_ERROR, " vp3:unpack_vlcs(): bad fragment number (%d -> %d ?)\n", first_fragment, last_fragment); return 0; } for (i = first_fragment; i <= last_fragment; i++) { fragment = &s->all_fragments[s->coded_fragment_list[i]]; if (fragment->coeff_count > coeff_index) continue; if (!eob_run) { /* decode a VLC into a token */ token = get_vlc2(gb, table->table, 5, 3); debug_vlc(" token = %2d, ", token); /* use the token to get a zero run, a coefficient, and an eob run */ unpack_token(gb, token, &zero_run, &coeff, &eob_run); } if (!eob_run) { fragment->coeff_count += zero_run; if (fragment->coeff_count < 64) fragment->coeffs[fragment->coeff_count++] = coeff; debug_vlc(" fragment %d coeff = %d\n", s->coded_fragment_list[i], fragment->coeffs[coeff_index]); } else { fragment->last_coeff = fragment->coeff_count; fragment->coeff_count = 64; debug_vlc(" fragment %d eob with %d coefficients\n", s->coded_fragment_list[i], fragment->last_coeff); eob_run--; } } return eob_run;}/* * This function unpacks all of the DCT coefficient data from the * bitstream. */static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb){ int i; int dc_y_table; int dc_c_table; int ac_y_table; int ac_c_table; int residual_eob_run = 0; /* fetch the DC table indices */ dc_y_table = get_bits(gb, 4); dc_c_table = get_bits(gb, 4); /* unpack the Y plane DC coefficients */ debug_vp3(" vp3: unpacking Y plane DC coefficients using table %d\n", dc_y_table); residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_y_table], 0, s->first_coded_y_fragment, s->last_coded_y_fragment, residual_eob_run); /* unpack the C plane DC coefficients */ debug_vp3(" vp3: unpacking C plane DC coefficients using table %d\n", dc_c_table); residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_c_table], 0, s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run); /* fetch the AC table indices */ ac_y_table = get_bits(gb, 4); ac_c_table = get_bits(gb, 4); /* unpack the group 1 AC coefficients (coeffs 1-5) */ for (i = 1; i <= 5; i++) { debug_vp3(" vp3: unpacking level %d Y plane AC coefficients using table %d\n", i, ac_y_table); residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_1[ac_y_table], i, s->first_coded_y_fragment, s->last_coded_y_fragment, residual_eob_run); debug_vp3(" vp3: unpacking level %d C plane AC coefficients using table %d\n", i, ac_c_table); residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_1[ac_c_table], i, s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run); } /* unpack the group 2 AC coefficients (coeffs 6-14) */ for (i = 6; i <= 14; i++) { debug_vp3(" vp3: unpacking level %d Y plane AC coefficients using table %d\n", i, ac_y_table); residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_2[ac_y_table], i, s->first_coded_y_fragment, s->last_coded_y_fragment, residual_eob_run); debug_vp3(" vp3: unpacking level %d C plane AC coefficients using table %d\n", i, ac_c_table); residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_2[ac_c_table], i, s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run); } /* unpack the group 3 AC coefficients (coeffs 15-27) */ for (i = 15; i <= 27; i++) { debug_vp3(" vp3: unpacking level %d Y plane AC coefficients using table %d\n", i, ac_y_table); residual_eob_run = unpack_vlcs(s, gb, &s->ac_vlc_3[ac_y_table], i, s->first_coded_y_fragment, s->last_coded_y_fragment, residual_eob_run
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -