VC1Status Set_Alt_MQUANT(VC1Context* pContext) { Ipp32u MQDIFF; Ipp32s MQUANT = pContext->m_picLayerHeader->PQUANT; Ipp32s HALFQP = pContext->m_picLayerHeader->HALFQP; if (VC1_DQPROFILE_ALLMBLKS == pContext->m_picLayerHeader->m_DQProfile) { if (pContext->m_picLayerHeader->m_DQBILevel) { VC1_GET_BITS(1, MQDIFF); if (MQDIFF) { MQUANT = pContext->m_picLayerHeader->m_AltPQuant; HALFQP = 0; } } else { VC1_GET_BITS(3, MQDIFF); HALFQP = 0; if (7 != MQDIFF) MQUANT = (pContext->m_picLayerHeader->PQUANT + MQDIFF); else VC1_GET_BITS(5, MQUANT); // ABSMQ } //QUANT pContext->CurrDC->DCStepSize = GetDCStepSize(MQUANT); pContext->CurrDC->DoubleQuant = MQUANT *2 + HALFQP; } return VC1_OK; }
void GetMQUANT(VC1Context* pContext) { Ipp32s z; VC1PictureLayerHeader* picLayerHeader = pContext->m_picLayerHeader; Ipp32u MQUANT = picLayerHeader->PQUANT; Ipp32u HALFQP = picLayerHeader->HALFQP; if (picLayerHeader->m_PQuant_mode==VC1_ALTPQUANT_MB_LEVEL) { VC1_GET_BITS(1,z ); MQUANT= (z)? picLayerHeader->m_AltPQuant: picLayerHeader->PQUANT; } else { VM_ASSERT(picLayerHeader->m_PQuant_mode==VC1_ALTPQUANT_ANY_VALUE); VC1_GET_BITS(3,z); HALFQP = 0; if (z!=7) { MQUANT = picLayerHeader->PQUANT + z; } else { VC1_GET_BITS(5,z); MQUANT=z; } }//m_DQBILevel==0 if ((MQUANT == picLayerHeader->m_AltPQuant)) HALFQP=0; pContext->CurrDC->DCStepSize = GetDCStepSize(MQUANT); pContext->CurrDC->DoubleQuant = MQUANT *2 + HALFQP; }
VC1Status DecodePictureLayer_ProgressiveBpicture(VC1Context* pContext) { VC1Status vc1Res = VC1_OK; VC1PictureLayerHeader* picLayerHeader = pContext->m_picLayerHeader; VC1SequenceLayerHeader* seqLayerHeader = pContext->m_seqLayerHeader; picLayerHeader->RNDCTRL = seqLayerHeader->RNDCTRL; //3.2.1.7 //PQINDEX is a 5-bit field that signals the quantizer scale index //for the entire frame. It is present in all picture types. If the //implicit quantizer is used (signaled by sequence field //QUANTIZER = 00, see section 3.1.19) then PQINDEX specifies both //the picture quantizer scale (PQUANT) and the quantizer //(3QP or 5QP deadzone) used for the frame. Table 5 shows how //PQINDEX is translated to PQUANT and the quantizer for implicit mode. //If the quantizer is signaled explicitly at the sequence or frame //level (signaled by sequence field QUANTIZER = 01, 10 or 11 see //section 3.1.19) then PQINDEX is translated to the picture quantizer //stepsize PQUANT as indicated by Table 6. VC1_GET_BITS(5, picLayerHeader->PQINDEX); CalculatePQuant(pContext); ChooseTTMB_TTBLK_SBP(pContext); if(picLayerHeader->PQINDEX <= 8) { //3.2.1.8 //HALFQP is a 1bit field present in all frame types if QPINDEX //is less than or equal to 8. The HALFQP field allows the picture //quantizer to be expressed in half step increments over the low //PQUANT range. If HALFQP = 1 then the picture quantizer stepsize //is PQUANT + ?. If HALFQP = 0 then the picture quantizer //stepize is PQUANT. Therefore, if the 3QP deadzone quantizer //is used then half stepsizes are possible up to PQUANT = 9 //(i.e., PQUANT = 1, 1.5, 2, 2.5 : 8.5, 9) and then only integer //stepsizes are allowable above PQUANT = 9. For the 5QP deadzone //quantizer, half stepsizes are possible up to PQUANT = 7 (i.e., //1, 1.5, 2, 2.5 : 6.5, 7). VC1_GET_BITS(1, picLayerHeader->HALFQP); } if(seqLayerHeader->QUANTIZER == 01) { //3.2.1.9 //PQUANTIZER is a 1 bit field present in all frame types if the //sequence level field QUANTIZER = 01 (see section 3.1.19). //In this case, the quantizer used for the frame is specified by //PQUANTIZER. If PQUANTIZER = 0 then the 5QP deadzone quantizer //is used for the frame. If PQUANTIZER = 1 then the 3QP deadzone //quantizer is used. VC1_GET_BITS(1, picLayerHeader->PQUANTIZER); //PQUANTIZER } MVRangeDecode(pContext); //VC-1 Table 47: B Picture MVMODE codetable //MVMODE VLC Mode //1 1 MV //0 1 MV Half-pel bilinear VC1_GET_BITS(1, picLayerHeader->MVMODE); picLayerHeader->MVMODE =(picLayerHeader->MVMODE==1)? VC1_MVMODE_1MV:VC1_MVMODE_HPELBI_1MV; //3.2.1.15 //The DIRECTMB field is present only present in B pictures. //The DIRECTMB field uses bitplane coding to indicate the //macroblocks in the B picture that are coded in direct mode. //The DIRECTMB field may also signal that the direct mode is //signaled in raw mode in which case the direct mode is signaled //at the macroblock level (see section 3.2.2.11). Refer to section //4.10 for a description of the bitplane coding method. DecodeBitplane(pContext, &picLayerHeader->m_DirectMB, seqLayerHeader->widthMB, seqLayerHeader->heightMB,0); DecodeBitplane(pContext, &picLayerHeader->SKIPMB, seqLayerHeader->widthMB,seqLayerHeader->heightMB,0); VC1_GET_BITS(2, picLayerHeader->MVTAB); //MVTAB picLayerHeader->m_pCurrMVDifftbl = pContext->m_vlcTbl->MVDIFF_PB_TABLES[picLayerHeader->MVTAB]; //MVTAB VC1_GET_BITS(2, picLayerHeader->CBPTAB); //CBPTAB picLayerHeader->m_pCurrCBPCYtbl = pContext->m_vlcTbl->CBPCY_PB_TABLES[picLayerHeader->CBPTAB]; //CBPTAB vc1Res = VOPDQuant(pContext); if (seqLayerHeader->VSTRANSFORM == 1) { VC1_GET_BITS(1, picLayerHeader->TTMBF); if(picLayerHeader->TTMBF) { VC1_GET_BITS(2, picLayerHeader->TTFRM_ORIG); picLayerHeader->TTFRM = 1 << picLayerHeader->TTFRM_ORIG; } else { picLayerHeader->TTFRM = VC1_BLK_INTER; } } else { picLayerHeader->TTFRM = VC1_BLK_INTER8X8; } VC1_GET_BITS(1, picLayerHeader->TRANSACFRM);//TRANSACFRM if(picLayerHeader->TRANSACFRM == 1) { VC1_GET_BITS(1, picLayerHeader->TRANSACFRM); picLayerHeader->TRANSACFRM++; } ChooseACTable(pContext, picLayerHeader->TRANSACFRM, picLayerHeader->TRANSACFRM);//TRANSACFRM VC1_GET_BITS(1, picLayerHeader->TRANSDCTAB); //TRANSDCTAB ChooseDCTable(pContext, picLayerHeader->TRANSDCTAB); //TRANSDCTAB return vc1Res; }
VC1Status DecodePictureHeader_Adv(VC1Context* pContext) { VC1Status vc1Sts = VC1_OK; uint32_t i = 0; uint32_t tempValue; uint32_t RFF = 0; uint32_t number_of_pan_scan_window; uint32_t RPTFRM = 0; VC1PictureLayerHeader* picLayerHeader = pContext->m_picLayerHeader; VC1SequenceLayerHeader* seqLayerHeader = &pContext->m_seqLayerHeader; picLayerHeader->RFF = 0; if(seqLayerHeader->INTERLACE) { //Frame Coding mode //0 - progressive; 10 - Frame-interlace; 11 - Field-interlace VC1_GET_BITS(1, picLayerHeader->FCM); if(picLayerHeader->FCM) { VC1_GET_BITS(1, picLayerHeader->FCM); if(picLayerHeader->FCM) picLayerHeader->FCM = VC1_FieldInterlace; else picLayerHeader->FCM = VC1_FrameInterlace; } else picLayerHeader->FCM = VC1_Progressive; } if(picLayerHeader->FCM != VC1_FieldInterlace) { //picture type //110 - I picture; 0 - P picture; 10 - B picture; 1110 - BI picture; 1111 - skipped VC1_GET_BITS(1, picLayerHeader->PTYPE); if(picLayerHeader->PTYPE) { VC1_GET_BITS(1, picLayerHeader->PTYPE); if(picLayerHeader->PTYPE) { VC1_GET_BITS(1, picLayerHeader->PTYPE); if(picLayerHeader->PTYPE) { VC1_GET_BITS(1, picLayerHeader->PTYPE); if(picLayerHeader->PTYPE) { //1111 picLayerHeader->PTYPE = VC1_SKIPPED_FRAME; } else { //1110 picLayerHeader->PTYPE = VC1_BI_FRAME; } } else { //110 picLayerHeader->PTYPE = VC1_I_FRAME; } } else { //10 picLayerHeader->PTYPE = VC1_B_FRAME; } } else { //0 picLayerHeader->PTYPE = VC1_P_FRAME; } if(!(picLayerHeader->PTYPE == VC1_SKIPPED_FRAME)) { if(seqLayerHeader->TFCNTRFLAG) { //temporal reference frame counter VC1_GET_BITS(8, tempValue); //TFCNTR } } if(seqLayerHeader->PULLDOWN) { if(!(seqLayerHeader->INTERLACE)) { //repeat frame count VC1_GET_BITS(2, RPTFRM); } else { uint32_t tff; //top field first VC1_GET_BITS(1, tff); picLayerHeader->TFF = (uint8_t)tff; //repeat first field VC1_GET_BITS(1, RFF); picLayerHeader->RFF = (uint8_t)RFF; } } if(seqLayerHeader->PANSCAN_FLAG) { //pan scan present flag VC1_GET_BITS(1,tempValue); //PS_PRESENT if(tempValue) //PS_PRESENT { //calculate number ofpan scan window, see standard, p177 if(seqLayerHeader->INTERLACE) { if(seqLayerHeader->PULLDOWN) { number_of_pan_scan_window = 2 + RFF; } else { number_of_pan_scan_window = 2; } } else { if(seqLayerHeader->PULLDOWN) { number_of_pan_scan_window = 1 + RPTFRM; } else { number_of_pan_scan_window = 1; } } //fill in pan scan window struture for (i = 0; i< number_of_pan_scan_window; i++) { //PS_HOFFSET VC1_GET_BITS(18,tempValue); //PS_VOFFSET VC1_GET_BITS(18,tempValue); //PS_WIDTH VC1_GET_BITS(14,tempValue); //PS_HEIGHT VC1_GET_BITS(14,tempValue); } } } if(!(picLayerHeader->PTYPE == VC1_SKIPPED_FRAME)) { //rounding control VC1_GET_BITS(1,picLayerHeader->RNDCTRL); if((seqLayerHeader->INTERLACE) || (picLayerHeader->FCM != VC1_Progressive)) { //UV sampling format VC1_GET_BITS(1,tempValue);//UVSAMP } if(seqLayerHeader->FINTERPFLAG && (picLayerHeader->FCM == VC1_Progressive) ) { //frame interpolation hint VC1_GET_BITS(1,tempValue); } if(picLayerHeader->PTYPE == VC1_B_FRAME && (picLayerHeader->FCM == VC1_Progressive) ) { //B picture fraction int8_t z1; int16_t z2; DecodeHuffmanPair(&pContext->m_bitstream.pBitstream, &pContext->m_bitstream.bitOffset, pContext->m_vlcTbl->BFRACTION, &z1, &z2); VM_ASSERT (z2 != VC1_BRACTION_INVALID); VM_ASSERT (!(z2 == VC1_BRACTION_BI && seqLayerHeader->PROFILE==VC1_PROFILE_ADVANCED)); if(0 == z2) { return VC1_ERR_INVALID_STREAM; } if (z2 == VC1_BRACTION_BI) { picLayerHeader->PTYPE = VC1_BI_FRAME; } picLayerHeader->BFRACTION = (z1*2>=z2)?1:0; picLayerHeader->ScaleFactor = ((256+z2/2)/z2)*z1; picLayerHeader->BFRACTION_orig = VC1_VA_Bfraction_tbl[z1-1][z2-2]; } //picture quantizer index VC1_GET_BITS(5,picLayerHeader->PQINDEX); if(picLayerHeader->PQINDEX<=8) { //half QP step VC1_GET_BITS(1,picLayerHeader->HALFQP); } else picLayerHeader->HALFQP = 0; if(seqLayerHeader->QUANTIZER == 1) { //picture quantizer type VC1_GET_BITS(1,pContext->m_picLayerHeader->PQUANTIZER); //PQUANTIZER } CalculatePQuant(pContext); if(seqLayerHeader->POSTPROCFLAG) { //post processing VC1_GET_BITS(2,tempValue); //POSTPROC } } } else { //FIELD INTERLACE FRAME DecodePictHeaderParams_InterlaceFieldPicture_Adv(pContext); } return vc1Sts; }
VC1Status DecodePictHeaderParams_InterlaceFieldPicture_Adv (VC1Context* pContext) { VC1Status vc1Sts = VC1_OK; uint32_t i = 0; uint32_t tempValue; uint32_t RFF = 0; uint32_t number_of_pan_scan_window; VC1PictureLayerHeader* picLayerHeader = pContext->m_picLayerHeader; VC1SequenceLayerHeader* seqLayerHeader = &pContext->m_seqLayerHeader; picLayerHeader->RFF = 0; VC1_GET_BITS(3, tempValue); switch(tempValue) { case 0: //000 - I,I picLayerHeader->PTypeField1 = VC1_I_FRAME; picLayerHeader->PTypeField2 = VC1_I_FRAME; break; case 1: //001 - I,P picLayerHeader->PTypeField1 = VC1_I_FRAME; picLayerHeader->PTypeField2 = VC1_P_FRAME; break; case 2: //010 - P,I picLayerHeader->PTypeField1 = VC1_P_FRAME; picLayerHeader->PTypeField2 = VC1_I_FRAME; break; case 3: //011 - P,P picLayerHeader->PTypeField1 = VC1_P_FRAME; picLayerHeader->PTypeField2 = VC1_P_FRAME; break; case 4: //100 - B,B picLayerHeader->PTypeField1 = VC1_B_FRAME; picLayerHeader->PTypeField2 = VC1_B_FRAME; break; case 5: //101 - B,BI picLayerHeader->PTypeField1 = VC1_B_FRAME; picLayerHeader->PTypeField2 = VC1_BI_FRAME; break; case 6: //110 - BI,B picLayerHeader->PTypeField1 = VC1_BI_FRAME; picLayerHeader->PTypeField2 = VC1_B_FRAME; break; case 7: //111 - BI,BI picLayerHeader->PTypeField1 = VC1_BI_FRAME; picLayerHeader->PTypeField2 = VC1_BI_FRAME; break; default: VM_ASSERT(0); break; } if(seqLayerHeader->TFCNTRFLAG) { //temporal reference frame counter VC1_GET_BITS(8, tempValue); //TFCNTR } if(seqLayerHeader->PULLDOWN) { if(!(seqLayerHeader->INTERLACE)) { //repeat frame count VC1_GET_BITS(2,tempValue);//RPTFRM } else { uint32_t tff; //top field first VC1_GET_BITS(1, tff); picLayerHeader->TFF = (uint8_t)tff; //repeat first field VC1_GET_BITS(1, RFF); picLayerHeader->RFF = (uint8_t)RFF; } } else picLayerHeader->TFF = 1; if(seqLayerHeader->PANSCAN_FLAG) { //pan scan present flag VC1_GET_BITS(1,tempValue); //PS_PRESENT if(tempValue) //PS_PRESENT { //calculate number ofpan scan window, see standard, p177 if(seqLayerHeader->PULLDOWN) { number_of_pan_scan_window = 2 + RFF; } else { number_of_pan_scan_window = 2; } //fill in pan scan window struture for (i = 0; i<number_of_pan_scan_window; i++) { //PS_HOFFSET VC1_GET_BITS(18,tempValue); //PS_VOFFSET VC1_GET_BITS(18,tempValue); //PS_WIDTH VC1_GET_BITS(14,tempValue); //PS_HEIGHT VC1_GET_BITS(14,tempValue); } } } //rounding control VC1_GET_BITS(1,picLayerHeader->RNDCTRL); //UV sampling format VC1_GET_BITS(1,tempValue);//UVSAMP if(seqLayerHeader->REFDIST_FLAG == 1 && (picLayerHeader->PTypeField1 < VC1_B_FRAME && picLayerHeader->PTypeField2 < VC1_B_FRAME)) { int32_t ret; ret = DecodeHuffmanOne( &pContext->m_bitstream.pBitstream, &pContext->m_bitstream.bitOffset, &picLayerHeader->REFDIST, pContext->m_vlcTbl->REFDIST_TABLE); VM_ASSERT(ret == 0); *pContext->pRefDist = picLayerHeader->REFDIST; } else if(seqLayerHeader->REFDIST_FLAG == 0) { *pContext->pRefDist = 0; picLayerHeader->REFDIST = 0; } else { picLayerHeader->REFDIST = 0; } if( (picLayerHeader->PTypeField1 >= VC1_B_FRAME && picLayerHeader->PTypeField2 >= VC1_B_FRAME) ) { //B picture fraction int8_t z1; int16_t z2; DecodeHuffmanPair(&pContext->m_bitstream.pBitstream, &pContext->m_bitstream.bitOffset, pContext->m_vlcTbl->BFRACTION, &z1, &z2); VM_ASSERT (z2 != VC1_BRACTION_INVALID); VM_ASSERT (!(z2 == VC1_BRACTION_BI && seqLayerHeader->PROFILE==VC1_PROFILE_ADVANCED)); if(0 == z2) return VC1_ERR_INVALID_STREAM; picLayerHeader->BFRACTION = (z1*2>=z2)?1:0; picLayerHeader->ScaleFactor = ((256+z2/2)/z2)*z1; picLayerHeader->BFRACTION_orig = VC1_VA_Bfraction_tbl[z1-1][z2-2]; } if(picLayerHeader->CurrField == 0) { picLayerHeader->PTYPE = picLayerHeader->PTypeField1; picLayerHeader->BottomField = (uint8_t)(1 - picLayerHeader->TFF); } else { picLayerHeader->BottomField = (uint8_t)(picLayerHeader->TFF); picLayerHeader->PTYPE = picLayerHeader->PTypeField2; } return vc1Sts; }
VC1Status MBLayer_ProgressiveIpicture_Adv(VC1Context* pContext) { Ipp32s i; VC1MB* pCurrMB = pContext->m_pCurrMB; VC1SingletonMB* sMB = pContext->m_pSingleMB; VC1PictureLayerHeader* picLayerHeader = pContext->m_picLayerHeader; Ipp32s CBPCY;//decoded_cbpy IppStatus ret; VC1Status vc1Res = VC1_OK; Ipp32u ACPRED; pCurrMB->LeftTopRightPositionFlag = CalculateLeftTopRightPositionFlag(sMB); Set_MQuant(pContext); pContext->m_pCurrMB->mbType = VC1_MB_INTRA; //CBPCY is a variable-length field present in both I picture and P //picture macroblock layers. ret = ippiDecodeHuffmanOne_1u32s( &pContext->m_bitstream.pBitstream, &pContext->m_bitstream.bitOffset, &CBPCY, pContext->m_vlcTbl->m_pCBPCY_Ipic); VM_ASSERT(ret == ippStsNoErr); pCurrMB->m_cbpBits = CalculateCBP(pCurrMB, CBPCY, sMB->widthMB); // Check ACPRED coding mode { if(VC1_IS_BITPLANE_RAW_MODE(&picLayerHeader->ACPRED)) { VC1_GET_BITS(1, ACPRED); } else { ACPRED = picLayerHeader->ACPRED.m_databits [sMB->widthMB * sMB->m_currMBYpos + sMB->m_currMBXpos]; } } // Overlap //for smoothing pCurrMB->Overlap = (Ipp8u)pContext->m_seqLayerHeader->OVERLAP; if(pCurrMB->Overlap) { if(picLayerHeader->PQUANT>=9) { pCurrMB->Overlap=1; } else if(picLayerHeader->CONDOVER == VC1_COND_OVER_FLAG_NONE) { pCurrMB->Overlap=0; } else if( VC1_COND_OVER_FLAG_SOME == picLayerHeader->CONDOVER ) { Ipp32s OverlapVal; if (VC1_IS_BITPLANE_RAW_MODE(&picLayerHeader->OVERFLAGS)) { VC1_GET_BITS(1, OverlapVal); } else { OverlapVal = picLayerHeader->OVERFLAGS.m_databits [sMB->widthMB * sMB->m_currMBYpos + sMB->m_currMBXpos]; } pCurrMB->Overlap = (Ipp8u)OverlapVal; } } if (picLayerHeader->m_DQuantFRM) Set_Alt_MQUANT(pContext); memset(pContext->m_pBlock, 0, sizeof(Ipp16s)*8*8*VC1_NUM_OF_BLOCKS); //all bloks are INTRA pCurrMB->IntraFlag=0x3F; //Y pCurrMB->currYPitch = sMB->currYPitch; pCurrMB->currYPlane = sMB->currYPlane + pCurrMB->currYPitch * (sMB->m_currMBYpos << 4)//*VC1_PIXEL_IN_LUMA + (sMB->m_currMBXpos << 4); //*VC1_PIXEL_IN_LUMA; //U pCurrMB->currUPitch = sMB->currUPitch; pCurrMB->currUPlane = sMB->currUPlane + pCurrMB->currUPitch*(sMB->m_currMBYpos << 3) // * VC1_PIXEL_IN_CHROMA + (sMB->m_currMBXpos << 3); //* VC1_PIXEL_IN_CHROMA; //V pCurrMB->currVPitch = sMB->currVPitch; pCurrMB->currVPlane = sMB->currVPlane + pCurrMB->currVPitch*(sMB->m_currMBYpos << 3) // * VC1_PIXEL_IN_CHROMA + (sMB->m_currMBXpos << 3); //* VC1_PIXEL_IN_CHROMA; IntraPredictionTable[pContext->m_seqLayerHeader->DQUANT](pContext); sMB->ZigzagTable = AdvZigZagTables_IProgressive_luma[ACPRED]; for(i = 0; i < VC1_NUM_OF_LUMA; i++) { //all MB intra in I picture vc1Res = BLKLayer_Intra_Luma_Adv(pContext, i, ACPRED); if(vc1Res != VC1_OK) { VM_ASSERT(0); break; } } sMB->ZigzagTable = AdvZigZagTables_IProgressive_chroma[ACPRED]; for(i = VC1_NUM_OF_LUMA; i < VC1_NUM_OF_BLOCKS; i++) { //all MB intra in I picture vc1Res = BLKLayer_Intra_Chroma_Adv(pContext, i, ACPRED); if(vc1Res != VC1_OK) { VM_ASSERT(0); break; } } pCurrMB->FIELDTX = 0; return vc1Res; }
//Figure 14: Syntax diagram for VOPDQUANT in //(Progressive P, Interlace I and Interlace P) picture header //3.2.1.27 VOPDQUANT Syntax Elements VC1Status VOPDQuant(VC1Context* pContext) { uint32_t tempValue; VC1PictureLayerHeader* picLayerHeader = pContext->m_picLayerHeader; uint32_t DQUANT = pContext->m_seqLayerHeader.DQUANT; picLayerHeader->m_DQuantFRM = 0; picLayerHeader->DQSBEdge = 0; picLayerHeader->m_DQBILevel = 0; //pContext->m_picLayerHeader->bVopdquantCoded = 1; if(DQUANT == 1) { //The DQUANTFRM field is a 1 bit value that is present only //when DQUANT = 1. If DQUANTFRM = 0 then the current picture //is only quantized with PQUANT. VC1_GET_BITS(1, picLayerHeader->m_DQuantFRM); if(picLayerHeader->m_DQuantFRM == 1) { //The DQPROFILE field is a 2 bits value that is present //only when DQUANT = 1 and DQUANTFRM = 1. It indicates //where we are allowed to change quantization step sizes //within the current picture. //Table 15: Macroblock Quantization Profile (DQPROFILE) Code Table //FLC Location //00 All four Edges //01 Double Edges //10 Single Edges //11 All Macroblocks VC1_GET_BITS(2,picLayerHeader->m_DQProfile); switch (picLayerHeader->m_DQProfile) { case VC1_DQPROFILE_ALL4EDGES: picLayerHeader->m_PQuant_mode = VC1_ALTPQUANT_EDGES; break; case VC1_DQPROFILE_SNGLEDGES: { //uint32_t m_DQSBEdge; //The DQSBEDGE field is a 2 bits value that is present //when DQPROFILE = Single Edge. It indicates which edge //will be quantized with ALTPQUANT. //Table 16: Single Boundary Edge Selection (DQSBEDGE) Code Table //FLC Boundary Edge //00 Left //01 Top //10 Right //11 Bottom VC1_GET_BITS(2, picLayerHeader->DQSBEdge); picLayerHeader->m_PQuant_mode = 1<<picLayerHeader->DQSBEdge; break; } case VC1_DQPROFILE_DBLEDGES: { //uint32_t m_DQDBEdge; //The DQSBEDGE field is a 2 bits value that is present //when DQPROFILE = Double Edge. It indicates which two //edges will be quantized with ALTPQUANT. //Table 17: Double Boundary Edges Selection (DQDBEDGE) Code Table //FLC Boundary Edges //00 Left and Top //01 Top and Right //10 Right and Bottom //11 Bottom and Left VC1_GET_BITS(2, picLayerHeader->DQSBEdge); picLayerHeader->m_PQuant_mode = (picLayerHeader->DQSBEdge>1)?VC1_ALTPQUANT_BOTTOM:VC1_ALTPQUANT_TOP; picLayerHeader->m_PQuant_mode |= ((picLayerHeader->DQSBEdge%3)? VC1_ALTPQUANT_RIGTHT:VC1_ALTPQUANT_LEFT); break; } case VC1_DQPROFILE_ALLMBLKS: { //The DQBILEVEL field is a 1 bit value that is present //when DQPROFILE = All Macroblock. If DQBILEVEL = 1, //then each macroblock in the picture can take one of //two possible values (PQUANT or ALTPQUANT). If //DQBILEVEL = 0, then each macroblock in the picture //can take on any quantization step size. VC1_GET_BITS(1, picLayerHeader->m_DQBILevel); picLayerHeader->m_PQuant_mode = (picLayerHeader->m_DQBILevel)? VC1_ALTPQUANT_MB_LEVEL:VC1_ALTPQUANT_ANY_VALUE; break; } } } else picLayerHeader->m_PQuant_mode=VC1_ALTPQUANT_NO; } else if (DQUANT == 2) { picLayerHeader->m_PQuant_mode = VC1_ALTPQUANT_EDGES; picLayerHeader->m_DQuantFRM = 1; } else picLayerHeader->m_PQuant_mode=VC1_ALTPQUANT_NO; //PQDIFF is a 3 bit field that encodes either the PQUANT //differential or encodes an escape code. //If PQDIFF does not equal 7 then PQDIFF encodes the //differential and the ABSPQ field does not follow in //the bitstream. In this case: // ALTPQUANT = PQUANT + PQDIFF + 1 //If PQDIFF equals 7 then the ABSPQ field follows in //the bitstream and ALTPQUANT is decoded as: // ALTPQUANT = ABSPQ if (picLayerHeader->m_DQuantFRM) { if(DQUANT==2 || !(picLayerHeader->m_DQProfile == VC1_DQPROFILE_ALLMBLKS && picLayerHeader->m_DQBILevel == 0)) { VC1_GET_BITS(3, tempValue); //PQDIFF if(tempValue == 7) // escape { //ABSPQ is present in the bitstream if PQDIFF equals 7. //In this case, ABSPQ directly encodes the value of //ALTPQUANT as described above. VC1_GET_BITS(5, tempValue); //m_ABSPQ picLayerHeader->m_AltPQuant = tempValue; //m_ABSPQ } else { picLayerHeader->m_AltPQuant = picLayerHeader->PQUANT + tempValue + 1; } } } return VC1_OK; }