📄 vdecoder.cc
字号:
case Macroblock::FRMT_FieldBased: MC_Frame_FieldBased(mb,mb_mode); break; case Macroblock::FRMT_DualPrime: cout << "Frame: DualPrime\n"; break; default: cout << "UNIMPLEMENTED FRAME MOTION\n"; break; } } else // MV-Format: Field { switch (mb.m_field_motion_type) { case Macroblock::FIMT_FieldBased: MC_Field_FieldBased(mb,mb_mode); break; case Macroblock::FIMT_16x8MC: MC_Field_16x8(mb,mb_mode); //cout << "Fld 16x8\n"; break; case Macroblock::FIMT_DualPrime: cout << "Field: DualPrime\n"; break; default: cout << "UNIMPLEMENTED FIELD MOTION\n"; break; } } } // ------- begin of coded_block_pattern() ----------- uint16 cbp = 0; if (mb_mode & MBMODE_PATTERN) { cbp=GetCBP(bs)<<6; if (d_ChromaFormat==CHROMA_422) { cbp |= bs.GetBits(2)<<4; } else if (d_ChromaFormat==CHROMA_444) { cbp |= bs.GetBits(6); } } else if (mb_mode & MBMODE_INTRA) { cbp = d_intra_cbp; } // ------- end of coded_block_pattern() -----------#ifndef NDEBUG if (d_options.Trace_MB) { cout << "MBHdr (pos: " << mb_row << ',' << mb_addr << '=' << mb_row*d_MBWidth+mb_addr << ")\n" << " modes: "; if (mb_mode & MBMODE_QUANT) cout << "Quant "; else cout << "..... "; if (mb_mode & MBMODE_MVFWD) cout << "MVFwd "; else cout << "..... "; if (mb_mode & MBMODE_MVBKW) cout << "MVBkw "; else cout << "..... "; if (mb_mode & MBMODE_PATTERN) cout << "Pattern "; else cout << "....... "; if (mb_mode & MBMODE_INTRA) cout << "Intra\n"; else cout << ".....\n"; if (mb_mode & MBMODE_QUANT) cout << " qcode: " << qcode << endl; cout << " nBlks: " << d_dctblks << endl; cout << " CBP: 0x" << hex << cbp << dec << endl; if (!(mb_mode & MBMODE_INTRA)) { cout << " Prediction: "; if (mb.m_mv_format==Macroblock::MVFormat_Frame) { switch (mb.m_frame_motion_type) { case Macroblock::FRMT_FieldBased: cout << " frame, field based\n"; break; case Macroblock::FRMT_FrameBased: cout << " frame, frame based\n"; break; case Macroblock::FRMT_DualPrime: cout << " frame, dual prime\n"; break; } } else { switch (mb.m_field_motion_type) { case Macroblock::FIMT_FieldBased: cout << " field, field based\n"; break; case Macroblock::FIMT_16x8MC: cout << " field, 16x8MC\n"; break; case Macroblock::FIMT_DualPrime: cout << " field, dual prime\n"; break; } } cout << "fwd1 field select: " << (mb.m_forward1.m_vertical_field_select==0 ? "t\n" : "b\n"); cout << "fwd2 field select: " << (mb.m_forward2.m_vertical_field_select==0 ? "t\n" : "b\n"); cout << "bkw1 field select: " << (mb.m_backward1.m_vertical_field_select==0 ? "t\n" : "b\n"); cout << "bkw2 field select: " << (mb.m_backward2.m_vertical_field_select==0 ? "t\n" : "b\n"); } if (mb_mode & (MBMODE_INTRA|MBMODE_PATTERN)) { cout << "DCT: " << (mb.m_FieldDCT ? "field":"frame") << endl; } }#endif // Decode DCT blocks. int cbp_bit=0x800; int qscale = qcode2qscale[d_pichdr.m_q_scale_type][mb.m_quantiser_scale_code]; int scanid = (d_pichdr.m_alternate_scan ? 1 : 0); bool b15 = (d_pichdr.m_intra_vlc_format && (mb_mode & MBMODE_INTRA)); for (int b=0 ; b<d_dctblks ; b++,cbp_bit>>=1) { int* matrix; int mismatch_sum; // Sum of all coefficients to calculate mismatch. if (mb_mode & MBMODE_INTRA) { if (b<4) matrix=d_quant_bs.m_LumIntra; else matrix=d_quant_bs.m_ChrIntra; } else { if (b<4) matrix=d_quant_bs.m_LumInter; else matrix=d_quant_bs.m_ChrInter; } int nextcoeff; if ((cbp & cbp_bit)==0) {#ifndef NDEBUG if (d_options.Trace_DCTCoeff) cout << "all DCT-Coeff. = 0\n";#endif continue; }#ifndef NDEBUG if (d_options.Trace_DCTCoeff) cout << "DCT (" << b << "): ";#endif bzero(&mb.m_blks[b].m_coeff[0],64*sizeof(short)); int run,value; // Decode first coefficient. if (mb_mode & MBMODE_INTRA) { if (b<4) { int diff = get_luma_dc_dct_diff(bs); dcpred_y += diff; mb.m_blks[b].m_coeff[0] = mismatch_sum = (dcpred_y << d_pichdr.m_intra_dc_precision_shift); } else { int diff =get_chroma_dc_dct_diff(bs); int val; if (cbblks[b]) { dcpred_cb+=diff; val = dcpred_cb; } else { dcpred_cr+=diff; val = dcpred_cr; } mb.m_blks[b].m_coeff[0] = mismatch_sum = (val << d_pichdr.m_intra_dc_precision_shift); } nextcoeff=1; } if (mb_mode & MBMODE_INTRA) { if (b15) { get_intra_block_B15(bs,&mb.m_blks[b].m_coeff[0],d_scan[scanid],qscale,matrix); } else { if (d_IsMPEG2) { get_intra_block_B14(bs,&mb.m_blks[b].m_coeff[0],d_scan[scanid],qscale,matrix); } else { get_mpeg1_intra_block(bs,&mb.m_blks[b].m_coeff[0],d_scan[scanid],qscale,matrix); } } } else { if (d_IsMPEG2) { get_non_intra_block(bs,&mb.m_blks[b].m_coeff[0],d_scan[scanid],qscale,matrix); } else { get_mpeg1_non_intra_block(bs,&mb.m_blks[b].m_coeff[0],d_scan[scanid],qscale,matrix); } } // Apply iDCT bool add_dct = !mb.m_IsIntra; if (b<4) { int lineskip; Pixel* blkstart; if (mb.m_FieldDCT) { blkstart = &dp_y[blk_yoffs_field[b]*lineskip_lum+blk_xoffs_field[b]]; lineskip=lineskip_lum*2; } else { blkstart = &dp_y[blk_yoffs[b]*lineskip_lum+blk_xoffs[b]]; lineskip=lineskip_lum; }#if MMX_DCT if (add_dct) { IDCT_mmx(&mb.m_blks[b].m_coeff[0], &mb.m_blks[b].m_coeff[0]); IDCT_16bit8bit_add(&mb.m_blks[b].m_coeff[0],blkstart,lineskip); } else { mb.m_blks[b].m_coeff[0] <<= 4; mb.m_blks[b].m_coeff[0] |= 0x8; IDCT_mmx(&mb.m_blks[b].m_coeff[0], &mb.m_blks[b].m_coeff[0]); IDCT_16bit8bit(&mb.m_blks[b].m_coeff[0],blkstart,lineskip); }#else Pixel* op[8]; op[0] = blkstart; for (int i=1;i<8;i++) op[i]=op[i-1]+lineskip; IDCT_Int2b(&mb.m_blks[b].m_coeff[0], op, add_dct);#endif } else { Pixel* p; if (cbblks[b]) p=dp_cr; else p=dp_cb; int lineskip; if (mb.m_FieldDCT && d_ChromaFormat!=CHROMA_420) { p += blk_yoffs_field[b]*lineskip_chr+blk_xoffs_field[b]; lineskip = lineskip_chr*2; } else { p += blk_yoffs[b]*lineskip_chr+blk_xoffs[b]; lineskip = lineskip_chr; } // if (mb.m_blks[b].m_hasdata) {#if MMX_DCT Pixel* blkstart = p; if (add_dct) { IDCT_mmx(&mb.m_blks[b].m_coeff[0], &mb.m_blks[b].m_coeff[0]); IDCT_16bit8bit_add(&mb.m_blks[b].m_coeff[0],blkstart,lineskip); } else { mb.m_blks[b].m_coeff[0] <<= 4; mb.m_blks[b].m_coeff[0] |= 0x8; IDCT_mmx(&mb.m_blks[b].m_coeff[0], &mb.m_blks[b].m_coeff[0]); IDCT_16bit8bit(&mb.m_blks[b].m_coeff[0],blkstart,lineskip); }#else Pixel* op[8]; op[0] = p; for (int i=1;i<8;i++) op[i]=op[i-1]+lineskip; IDCT_Int2b(&mb.m_blks[b].m_coeff[0], op, add_dct);#endif } } } if (d_pichdr.m_picture_coding_type == PICTYPE_D) { // D-picture requires final '1' bit (end of macroblock) int n = bs.GetBits(1); if (n != 1) { throw Excpt_StreamError(ErrSev_Error, "Invalid MPEG stream, 'end of macroblock'-bit missing in D-picture."); } } lastmb = &mb; last_mb_mode = mb_mode; } if (IsBPicture && mb_addr==d_MBWidth-1) { FlushBSlice(mb_row); } } catch(Excpt_StreamError& err) { MessageDisplay::Show(err); MessageDisplay::Show(ErrSev_Note,"continuing anyway..."); }}void VideoDecoder::motion_vector(struct MotionVector& mv,int s,bool dmv, class FastBitBuf& bs){ // horizontal component { const int motcode = GetMotionCode(bs); const int fcode = d_pichdr.m_fcode[s][0]; const int rsize = fcode-1; int delta; int res; if (motcode!=0 && fcode !=1) { res = bs.GetBits(rsize); if (motcode>0) delta = (( motcode-1)<<rsize) + res+1; else delta = -(((-motcode-1)<<rsize) + res+1); } else delta = motcode; mv.m_habs += delta; if (mv.m_habs < (-16 << rsize)) mv.m_habs += 32<<rsize; else if (mv.m_habs > ( 16 << rsize)-1) mv.m_habs -= 32<<rsize;#ifndef NDEBUG if (d_options.Trace_MB) cout << "H (" << motcode << " " << res << ") -> " << delta << " " << mv.m_habs << endl;#endif } if (dmv) { int bits = bs.PeekBits(2); switch (bits) { case 0: case 1: mv.m_dmvector[0]= 0; bs.SkipBits(1); break; case 2: mv.m_dmvector[0]= 1; bs.SkipBits(2); break; case 3: mv.m_dmvector[0]=-1; bs.SkipBits(2); break; } } // vertical component { const int motcode = GetMotionCode(bs); const int fcode = d_pichdr.m_fcode[s][1]; const int rsize = fcode-1; int delta; int res; if (motcode!=0 && fcode !=1) { res = bs.GetBits(rsize); if (motcode>0) delta = (( motcode-1)<<rsize) + res+1; else delta = -(((-motcode-1)<<rsize) + res+1); } else delta = motcode; mv.m_vabs += delta; if (mv.m_vabs < (-16 << rsize)) mv.m_vabs += 32<<rsize; else if (mv.m_vabs > ( 16 << rsize)-1) mv.m_vabs -= 32<<rsize;#ifndef NDEBUG if (d_options.Trace_MB) cout << "V (" << motcode << " " << res << ") -> " << delta << " " << mv.m_vabs << endl;#endif } if (dmv) { int bits = bs.PeekBits(2); switch (bits) { case 0: case 1: mv.m_dmvector[0]= 0; bs.SkipBits(1); break; case 2: mv.m_dmvector[0]= 1; bs.SkipBits(2); break; case 3: mv.m_dmvector[0]=-1; bs.SkipBits(2); break; } }#ifndef NDEBUG if (d_options.Trace_MB) cout << "MV: " << mv.m_habs << " " << mv.m_vabs << endl;#endif}#if 0 { ImageParam_YUV param; d_outbuf[d_outbuf_len-1].m_image.GetParam(param); Pixel*const* p = ((Image_YUV<Pixel>*)&d_outbuf[d_outbuf_len-1].m_image)->AskFrameY(); for (int y=0;y<param.height;y+=16) for (int x=0;x<param.width;x++) p[y][x]= (((y%160)==0) ? 255 : (((y%80)==0) ? 200 : 150)); for (int y=0;y<param.height;y++) for (int x=0;x<param.width;x+=16) p[y][x]= (((x%160)==0) ? 255 : (((x%80)==0) ? 200 : 150)); }#endif#if 0 { ImageParam_YUV param; d_outbuf[d_outbuf_len-1].m_image.GetParam(param); Pixel*const* p = ((Image_YUV<Pixel>*)&d_outbuf[d_outbuf_len-1].m_image)->AskFrameU(); for (int y=0;y<param.height/2;y++) for (int x=0;x<param.width/2;x++) p[y][x]=128; } { ImageParam_YUV param; d_outbuf[d_outbuf_len-1].m_image.GetParam(param); Pixel*const* p = ((Image_YUV<Pixel>*)&d_outbuf[d_outbuf_len-1].m_image)->AskFrameV(); for (int y=0;y<param.height/2;y++) for (int x=0;x<param.width/2;x++) p[y][x]=128; }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -