📄 vp3.c
字号:
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] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; motion_y[k] = motion_vector_table[get_vlc2(gb, s->motion_vector_vlc.table, 6, 2)]; } else { motion_x[k] = fixed_motion_vector_table[get_bits(gb, 6)]; motion_y[k] = fixed_motion_vector_table[get_bits(gb, 6)]; } motion_x[4] += motion_x[k]; motion_y[4] += motion_y[k]; } motion_x[5]= motion_x[4]= RSHIFT(motion_x[4], 2); motion_y[5]= motion_y[4]= RSHIFT(motion_y[4], 2); /* 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 = 0; DCTELEM coeff = 0; Vp3Fragment *fragment; uint8_t *perm= s->scantable.permutated; int bits_to_get; 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++) { int fragment_num = s->coded_fragment_list[i]; if (s->coeff_counts[fragment_num] > coeff_index) continue; fragment = &s->all_fragments[fragment_num]; 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 */ if (token <= 6) { eob_run = eob_run_base[token]; if (eob_run_get_bits[token]) eob_run += get_bits(gb, eob_run_get_bits[token]); coeff = zero_run = 0; } else { bits_to_get = coeff_get_bits[token]; if (!bits_to_get) coeff = coeff_tables[token][0]; else coeff = coeff_tables[token][get_bits(gb, bits_to_get)]; zero_run = zero_run_base[token]; if (zero_run_get_bits[token]) zero_run += get_bits(gb, zero_run_get_bits[token]); } } if (!eob_run) { s->coeff_counts[fragment_num] += zero_run; if (s->coeff_counts[fragment_num] < 64){ fragment->next_coeff->coeff= coeff; fragment->next_coeff->index= perm[s->coeff_counts[fragment_num]++]; //FIXME perm here already? fragment->next_coeff->next= s->next_coeff; s->next_coeff->next=NULL; fragment->next_coeff= s->next_coeff++; } debug_vlc(" fragment %d coeff = %d\n", s->coded_fragment_list[i], fragment->next_coeff[coeff_index]); } else { s->coeff_counts[fragment_num] |= 128; debug_vlc(" fragment %d eob with %d coefficients\n", s->coded_fragment_list[i], s->coeff_counts[fragment_num]&127); 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 indexes */ 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 indexes */ 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); 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_3[ac_c_table], i, s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run); } /* unpack the group 4 AC coefficients (coeffs 28-63) */ for (i = 28; i <= 63; 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_4[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_4[ac_c_table], i, s->first_coded_c_fragment, s->last_coded_c_fragment, residual_eob_run); } return 0;}/* * This function reverses the DC prediction for each coded fragment in * the frame. Much of this function is adapted directly from the original * VP3 source code. */#define COMPATIBLE_FRAME(x) \ (compatible_frame[s->all_fragments[x].coding_method] == current_frame_type)#define FRAME_CODED(x) (s->all_fragments[x].coding_method != MODE_COPY)#define DC_COEFF(u) (s->coeffs[u].index ? 0 : s->coeffs[u].coeff) //FIXME do somethin to simplify thisstatic void reverse_dc_prediction(Vp3DecodeContext *s, int first_fragment, int fragment_width, int fragment_height){#define PUL 8#define PU 4#define PUR 2#define PL 1 int x, y; int i = first_fragment; int predicted_dc; /* DC values for the left, up-left, up, and up-right fragments */ int vl, vul, vu, vur; /* indexes for the left, up-left, up, and up-right fragments */ int l, ul, u, ur; /* * The 6 fields mean: * 0: up-left multiplier * 1: up multiplier * 2: up-right multiplier * 3: left multiplier */ int predictor_transform[16][4] = { { 0, 0, 0, 0}, { 0, 0, 0,128}, // PL { 0, 0,128, 0}, // PUR { 0, 0, 53, 75}, // PUR|PL { 0,128, 0, 0}, // PU { 0, 64, 0, 64}, // PU|PL { 0,128, 0, 0}, // PU|PUR { 0, 0, 53, 75}, // PU|PUR|PL {128, 0, 0, 0}, // PUL { 0, 0, 0,128}, // PUL|PL { 64, 0, 64, 0}, // PUL|PUR { 0, 0, 53, 75}, // PUL|PUR|PL { 0,128, 0, 0}, // PUL|PU {-104,116, 0,116}, // PUL|PU|PL { 24, 80, 24, 0}, // PUL|PU|PUR {-104,116, 0,116} // PUL|PU|PUR|PL };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -