vc1.c
来自「linux下的MPEG1」· C语言 代码 · 共 1,909 行 · 第 1/5 页
C
1,909 行
* @param[in] len Maximum length * @return Unary length/index */static int get_prefix(GetBitContext *gb, int stop, int len){#if 1 int i; for(i = 0; i < len && get_bits1(gb) != stop; i++); return i;/* int i = 0, tmp = !stop; while (i != len && tmp != stop) { tmp = get_bits(gb, 1); i++; } if (i == len && tmp != stop) return len+1; return i;*/#else unsigned int buf; int log; OPEN_READER(re, gb); UPDATE_CACHE(re, gb); buf=GET_CACHE(re, gb); //Still not sure if (stop) buf = ~buf; log= av_log2(-buf); //FIXME: -? if (log < limit){ LAST_SKIP_BITS(re, gb, log+1); CLOSE_READER(re, gb); return log; } LAST_SKIP_BITS(re, gb, limit); CLOSE_READER(re, gb); return limit;#endif}static inline int decode210(GetBitContext *gb){ int n; n = get_bits1(gb); if (n == 1) return 0; else return 2 - get_bits1(gb);}/** * Init VC-1 specific tables and VC1Context members * @param v The VC1Context to initialize * @return Status */static int vc1_init_common(VC1Context *v){ static int done = 0; int i = 0; v->hrd_rate = v->hrd_buffer = NULL; /* VLC tables */ if(!done) { done = 1; init_vlc(&vc1_bfraction_vlc, VC1_BFRACTION_VLC_BITS, 23, vc1_bfraction_bits, 1, 1, vc1_bfraction_codes, 1, 1, 1); init_vlc(&vc1_norm2_vlc, VC1_NORM2_VLC_BITS, 4, vc1_norm2_bits, 1, 1, vc1_norm2_codes, 1, 1, 1); init_vlc(&vc1_norm6_vlc, VC1_NORM6_VLC_BITS, 64, vc1_norm6_bits, 1, 1, vc1_norm6_codes, 2, 2, 1); init_vlc(&vc1_imode_vlc, VC1_IMODE_VLC_BITS, 7, vc1_imode_bits, 1, 1, vc1_imode_codes, 1, 1, 1); for (i=0; i<3; i++) { init_vlc(&vc1_ttmb_vlc[i], VC1_TTMB_VLC_BITS, 16, vc1_ttmb_bits[i], 1, 1, vc1_ttmb_codes[i], 2, 2, 1); init_vlc(&vc1_ttblk_vlc[i], VC1_TTBLK_VLC_BITS, 8, vc1_ttblk_bits[i], 1, 1, vc1_ttblk_codes[i], 1, 1, 1); init_vlc(&vc1_subblkpat_vlc[i], VC1_SUBBLKPAT_VLC_BITS, 15, vc1_subblkpat_bits[i], 1, 1, vc1_subblkpat_codes[i], 1, 1, 1); } for(i=0; i<4; i++) { init_vlc(&vc1_4mv_block_pattern_vlc[i], VC1_4MV_BLOCK_PATTERN_VLC_BITS, 16, vc1_4mv_block_pattern_bits[i], 1, 1, vc1_4mv_block_pattern_codes[i], 1, 1, 1); init_vlc(&vc1_cbpcy_p_vlc[i], VC1_CBPCY_P_VLC_BITS, 64, vc1_cbpcy_p_bits[i], 1, 1, vc1_cbpcy_p_codes[i], 2, 2, 1); init_vlc(&vc1_mv_diff_vlc[i], VC1_MV_DIFF_VLC_BITS, 73, vc1_mv_diff_bits[i], 1, 1, vc1_mv_diff_codes[i], 2, 2, 1); } for(i=0; i<8; i++) init_vlc(&vc1_ac_coeff_table[i], AC_VLC_BITS, vc1_ac_sizes[i], &vc1_ac_tables[i][0][1], 8, 4, &vc1_ac_tables[i][0][0], 8, 4, 1); init_vlc(&ff_msmp4_mb_i_vlc, MB_INTRA_VLC_BITS, 64, &ff_msmp4_mb_i_table[0][1], 4, 2, &ff_msmp4_mb_i_table[0][0], 4, 2, 1); } /* Other defaults */ v->pq = -1; v->mvrange = 0; /* 7.1.1.18, p80 */ return 0;}/***********************************************************************//** * @defgroup bitplane VC9 Bitplane decoding * @see 8.7, p56 * @{ *//** @addtogroup bitplane * Imode types * @{ */enum Imode { IMODE_RAW, IMODE_NORM2, IMODE_DIFF2, IMODE_NORM6, IMODE_DIFF6, IMODE_ROWSKIP, IMODE_COLSKIP};/** @} */ //imode defines/** Decode rows by checking if they are skipped * @param plane Buffer to store decoded bits * @param[in] width Width of this buffer * @param[in] height Height of this buffer * @param[in] stride of this buffer */static void decode_rowskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){ int x, y; for (y=0; y<height; y++){ if (!get_bits(gb, 1)) //rowskip memset(plane, 0, width); else for (x=0; x<width; x++) plane[x] = get_bits(gb, 1); plane += stride; }}/** Decode columns by checking if they are skipped * @param plane Buffer to store decoded bits * @param[in] width Width of this buffer * @param[in] height Height of this buffer * @param[in] stride of this buffer * @fixme FIXME: Optimize */static void decode_colskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){ int x, y; for (x=0; x<width; x++){ if (!get_bits(gb, 1)) //colskip for (y=0; y<height; y++) plane[y*stride] = 0; else for (y=0; y<height; y++) plane[y*stride] = get_bits(gb, 1); plane ++; }}/** Decode a bitplane's bits * @param bp Bitplane where to store the decode bits * @param v VC-1 context for bit reading and logging * @return Status * @fixme FIXME: Optimize */static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v){ GetBitContext *gb = &v->s.gb; int imode, x, y, code, offset; uint8_t invert, *planep = data; int width, height, stride; width = v->s.mb_width; height = v->s.mb_height; stride = v->s.mb_stride; invert = get_bits(gb, 1); imode = get_vlc2(gb, vc1_imode_vlc.table, VC1_IMODE_VLC_BITS, 1); *raw_flag = 0; switch (imode) { case IMODE_RAW: //Data is actually read in the MB layer (same for all tests == "raw") *raw_flag = 1; //invert ignored return invert; case IMODE_DIFF2: case IMODE_NORM2: if ((height * width) & 1) { *planep++ = get_bits(gb, 1); offset = 1; } else offset = 0; // decode bitplane as one long line for (y = offset; y < height * width; y += 2) { code = get_vlc2(gb, vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 1); *planep++ = code & 1; offset++; if(offset == width) { offset = 0; planep += stride - width; } *planep++ = code >> 1; offset++; if(offset == width) { offset = 0; planep += stride - width; } } break; case IMODE_DIFF6: case IMODE_NORM6: if(!(height % 3) && (width % 3)) { // use 2x3 decoding for(y = 0; y < height; y+= 3) { for(x = width & 1; x < width; x += 2) { code = get_vlc2(gb, vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2); if(code < 0){ av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n"); return -1; } planep[x + 0] = (code >> 0) & 1; planep[x + 1] = (code >> 1) & 1; planep[x + 0 + stride] = (code >> 2) & 1; planep[x + 1 + stride] = (code >> 3) & 1; planep[x + 0 + stride * 2] = (code >> 4) & 1; planep[x + 1 + stride * 2] = (code >> 5) & 1; } planep += stride * 3; } if(width & 1) decode_colskip(data, 1, height, stride, &v->s.gb); } else { // 3x2 planep += (height & 1) * stride; for(y = height & 1; y < height; y += 2) { for(x = width % 3; x < width; x += 3) { code = get_vlc2(gb, vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2); if(code < 0){ av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n"); return -1; } planep[x + 0] = (code >> 0) & 1; planep[x + 1] = (code >> 1) & 1; planep[x + 2] = (code >> 2) & 1; planep[x + 0 + stride] = (code >> 3) & 1; planep[x + 1 + stride] = (code >> 4) & 1; planep[x + 2 + stride] = (code >> 5) & 1; } planep += stride * 2; } x = width % 3; if(x) decode_colskip(data , x, height , stride, &v->s.gb); if(height & 1) decode_rowskip(data+x, width - x, 1, stride, &v->s.gb); } break; case IMODE_ROWSKIP: decode_rowskip(data, width, height, stride, &v->s.gb); break; case IMODE_COLSKIP: decode_colskip(data, width, height, stride, &v->s.gb); break; default: break; } /* Applying diff operator */ if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6) { planep = data; planep[0] ^= invert; for (x=1; x<width; x++) planep[x] ^= planep[x-1]; for (y=1; y<height; y++) { planep += stride; planep[0] ^= planep[-stride]; for (x=1; x<width; x++) { if (planep[x-1] != planep[x-stride]) planep[x] ^= invert; else planep[x] ^= planep[x-1]; } } } else if (invert) { planep = data; for (x=0; x<stride*height; x++) planep[x] = !planep[x]; //FIXME stride } return (imode<<1) + invert;}/** @} */ //Bitplane group/***********************************************************************//** VOP Dquant decoding * @param v VC-1 Context */static int vop_dquant_decoding(VC1Context *v){ GetBitContext *gb = &v->s.gb; int pqdiff; //variable size if (v->dquant == 2) { pqdiff = get_bits(gb, 3); if (pqdiff == 7) v->altpq = get_bits(gb, 5); else v->altpq = v->pq + pqdiff + 1; } else { v->dquantfrm = get_bits(gb, 1); if ( v->dquantfrm ) { v->dqprofile = get_bits(gb, 2); switch (v->dqprofile) { case DQPROFILE_SINGLE_EDGE: case DQPROFILE_DOUBLE_EDGES: v->dqsbedge = get_bits(gb, 2); break; case DQPROFILE_ALL_MBS: v->dqbilevel = get_bits(gb, 1); default: break; //Forbidden ? } if (v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS) { pqdiff = get_bits(gb, 3); if (pqdiff == 7) v->altpq = get_bits(gb, 5); else v->altpq = v->pq + pqdiff + 1; } } } return 0;}/** Put block onto picture */static void vc1_put_block(VC1Context *v, DCTELEM block[6][64]){ uint8_t *Y; int ys, us, vs; DSPContext *dsp = &v->s.dsp; if(v->rangeredfrm) { int i, j, k; for(k = 0; k < 6; k++) for(j = 0; j < 8; j++) for(i = 0; i < 8; i++) block[k][i + j*8] = ((block[k][i + j*8] - 128) << 1) + 128; } ys = v->s.current_picture.linesize[0]; us = v->s.current_picture.linesize[1]; vs = v->s.current_picture.linesize[2]; Y = v->s.dest[0]; dsp->put_pixels_clamped(block[0], Y, ys); dsp->put_pixels_clamped(block[1], Y + 8, ys); Y += ys * 8; dsp->put_pixels_clamped(block[2], Y, ys); dsp->put_pixels_clamped(block[3], Y + 8, ys);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?