⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vopseenc.cpp

📁 此源码是在VC平台下,实现MPEG4编解码的源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
CVideoObjectEncoder::CVideoObjectEncoder (
	UInt uiVOId, 
	VOLMode& volmd, 
	VOPMode& vopmd,
	Int iSessionWidth,
	Int iSessionHeight
) :
	CVideoObject (),
	m_pvopcOrig (NULL),
	m_rgiSubBlkIndx16x16 (NULL),
	m_rgiSSubBlkIndx16x16 (NULL),
	m_rgiSubBlkIndx18x18 (NULL),
	m_rgiSubBlkIndx20x20 (NULL),
	m_rgiPxlIndx12x12 (NULL),
	m_rgiPxlIndx8x8 (NULL)
{

	// sprite stuff
    	m_uiSprite = 0; // sprite off

	m_pchBitsBuffer = NULL;
	m_pbitstrmOut = NULL;
	m_pentrencSet = NULL;

        // shape cache
	m_pchShapeBitsBuffer = NULL;
	m_pbitstrmShape = NULL;
	m_pbitstrmShapeMBOut = NULL;
	
	m_uiVOId = uiVOId;
	m_volmd = volmd;

	m_vopmd = vopmd;
//	decideMVInfo ();
	m_vopmd.iRoundingControl = 0;
	m_vopmd.iRoundingControlEncSwitch = 0;
	Int iMod = iSessionWidth % MB_SIZE;
	Int iSessionWidthRound = (iMod > 0) ? iSessionWidth + MB_SIZE - iMod : iSessionWidth;
	iMod = iSessionHeight % MB_SIZE;
	Int iSessionHeightRound = (iMod > 0) ? iSessionHeight + MB_SIZE - iMod : iSessionHeight;
	m_rctRefFrameY = CRct (
		-EXPANDY_REF_FRAME, -EXPANDY_REF_FRAME, 
		EXPANDY_REF_FRAME + iSessionWidthRound, EXPANDY_REF_FRAME + iSessionHeightRound
	);
	m_rctRefFrameUV = m_rctRefFrameY.downSampleBy2 ();
	m_pvopcOrig = new CVOPU8YUVBA (m_volmd.fAUsage, m_rctRefFrameY);
	m_pvopcRefOrig0 = new CVOPU8YUVBA (m_volmd.fAUsage, m_rctRefFrameY);
	m_pvopcRefOrig1 = new CVOPU8YUVBA (m_volmd.fAUsage, m_rctRefFrameY);
	allocateVOLMembers (iSessionWidth, iSessionHeight);

	CRct rctFrameZoom = m_rctRefFrameY.upSampleBy2 ();
	m_puciRefQZoom0 = new CU8Image (rctFrameZoom);

	m_puciRefQZoom1 = new CU8Image (rctFrameZoom);

	m_pfdct = new CFwdBlockDCT;

	// B-VOP MB buffer
	m_puciDirectPredMB = new CU8Image (CRct (0, 0, MB_SIZE, MB_SIZE));
	m_puciInterpPredMB = new CU8Image (CRct (0, 0, MB_SIZE, MB_SIZE));
	m_ppxlcDirectPredMBY = (PixelC*) m_puciDirectPredMB->pixels (); 
	m_ppxlcInterpPredMBY = (PixelC*) m_puciInterpPredMB->pixels (); 

	m_piiDirectErrorMB = new CIntImage (CRct (0, 0, MB_SIZE, MB_SIZE)); 
	m_piiInterpErrorMB = new CIntImage (CRct (0, 0, MB_SIZE, MB_SIZE)); 
	m_ppxliDirectErrorMBY = (PixelI*) m_piiDirectErrorMB->pixels (); 
	m_ppxliInterpErrorMBY = (PixelI*) m_piiInterpErrorMB->pixels (); 

	// with shape
	if (m_volmd.fAUsage != RECTANGLE) {
		m_rgiSubBlkIndx16x16 = computeShapeSubBlkIndex (4, 16);
		m_rgiSSubBlkIndx16x16 = computeShapeSubBlkIndex (2, 16);
		m_rgiSubBlkIndx18x18 = computeShapeSubBlkIndex (4, 18);
		m_rgiSubBlkIndx20x20 = computeShapeSubBlkIndex (4, 20);
		m_rgiPxlIndx12x12 = new Int [8 * 8];		
		Int* piPxl = m_rgiPxlIndx12x12;
		UInt i, j;
		for (i = 2; i < 10; i++)
			for (j = 2; j < 10; j++)
				*piPxl++ = i * 12 + j;
		m_rgiPxlIndx8x8 = new Int [4 * 4];		
		piPxl = m_rgiPxlIndx8x8;
		for (i = 2; i < 6; i++)
			for (j = 2; j < 6; j++)
				*piPxl++ = i * 8 + j;
	}

	m_statRC.resetSkipMode ();
	m_rgdSNR = (m_volmd.fAUsage == EIGHT_BIT) ? new Double [4] : new Double [3];

	// some fixed variables	
	m_iFrameWidthZoomY = m_iFrameWidthY * 2;
	m_iFrameWidthZoomUV = m_iFrameWidthUV * 2;
	m_iFrameWidthZoomYx2Minus2MB = m_iFrameWidthY * 2 * 2 - 2 * MB_SIZE;
	m_iFrameWidthZoomYx2Minus2Blk = m_iFrameWidthY * 2 * 2 - 2 * BLOCK_SIZE;
	
	if (m_volmd.fAUsage == RECTANGLE) {
		m_rctCurrVOPY = CRct (0, 0, iSessionWidthRound, iSessionHeightRound);
		m_pvopcOrig->setBoundRct (m_rctCurrVOPY);
		m_rctCurrVOPUV = m_rctCurrVOPY.downSampleBy2 ();
		
		m_rctRefVOPY0 = m_rctCurrVOPY;
		m_rctRefVOPY0.expand (EXPANDY_REFVOP);
		m_rctRefVOPUV0 = m_rctRefVOPY0.downSampleBy2 ();
		
		m_rctRefVOPY1 = m_rctRefVOPY0;
		m_rctRefVOPUV1 = m_rctRefVOPUV0;
		
		m_rctRefVOPZoom0 = m_rctRefVOPY0.upSampleBy2 ();
		m_pvopcRefOrig0->setBoundRct (m_rctRefVOPY0);
		m_pvopcRefOrig1->setBoundRct (m_rctRefVOPY1);
		computeVOLConstMembers (); // these VOP members are the same for all frames
	}
}

Bool CVideoObjectEncoder::skipTest(Time t,VOPpredType vopPredType)
{
	if (m_uiRateControl==RC_MPEG4) {
		if (!m_statRC.firstFrame ()) {// test whether we should skip this frame
			if (m_statRC.skipThisFrame ())
				return TRUE;
		} 
		else
			m_statRC.resetFirstFrame ();
	}
	return FALSE;
}

Void CVideoObjectEncoder::encode (
	Bool bVOPVisible, 
	Time t,
	VOPpredType vopPredType,
	const CVOPU8YUVBA* pvopfRefBaseLayer)
{
	m_t = t;
	m_vopmd.vopPredType = vopPredType;
    m_statsVOP.reset ();

	Bool bTemporalScalability = m_volmd.bTemporalScalability; // added by Sharp (98/2/10)
	Bool bPrevRefVopWasCoded = m_bCodedFutureRef;

	//__LOW_LATENCY_SPRITE_
	if (m_uiSprite == 1 && m_sptMode != BASIC_SPRITE && m_vopmd.SpriteXmitMode != STOP)	{
		setRefStartingPointers (); // need to compute the starting pointers of the refVOP's (corresponding to the current Rct)
		computeVOPMembers ();
		m_iNumSptMB = 0;
		encodeVOP ();
	}
	else {
	    if (m_uiSprite == 1 && m_t>=0)
		    m_vopmd.vopPredType = SPRITE;
	
	    m_pbitstrmOut->reset ();
	    cout << "\nVOP " << m_uiVOId << "\n";
	    cout << "\tVOL " << m_volmd.volType << "\n"; // added by Sharp (98/2/10)

		if(m_vopmd.vopPredType==IVOP || m_vopmd.vopPredType==PVOP)
			m_bCodedFutureRef = bVOPVisible; // flag used by bvop prediction

	    if(!bVOPVisible)
	    {
#ifdef __TRACE_AND_STATS_
		    m_pbitstrmOut -> trace (m_t, "VOP_Time");
#endif // __TRACE_AND_STATS_
		    codeNonCodedVOPHead ();
		    cout << "\tTime..." << m_t << " (" << m_t/m_volmd.dFrameHz << " sec)" 
				<< "\n\tNot coded.\n\n";
		    cout.flush ();
		    m_statsVOP.nBitsStuffing += m_pbitstrmOut->flush ();
#ifdef __TRACE_AND_STATS_
		    m_statsVOP.dSNRY = m_statsVOP.dSNRU = m_statsVOP.dSNRV = 0;
		    m_statsVOP.print (TRUE);
		    m_statsVOL += m_statsVOP;
#endif // __TRACE_AND_STATS_
	    }

		if(bPrevRefVopWasCoded) // only swap references if previous vop was coded
		{
			if (m_volmd.volType == BASE_LAYER)
				updateAllRefVOPs ();					// update all reconstructed VOP's
			else if (!bTemporalScalability) { // modified by Sharp (98/2/10)
				if(m_volmd.volType == ENHN_LAYER && m_vopmd.vopPredType == PVOP)
					m_vopmd.iRefSelectCode = 3;
				else if(m_volmd.volType == ENHN_LAYER && m_vopmd.vopPredType == BVOP)
					m_vopmd.iRefSelectCode = 0;
				updateAllRefVOPs (pvopfRefBaseLayer);	// for spatial scalability
			}

    		if (m_volmd.bOriginalForME) {
    			if (m_vopmd.vopPredType == PVOP || 
    				(m_volmd.volType == ENHN_LAYER && m_vopmd.vopPredType == BVOP && m_vopmd.iRefSelectCode == 0))
    				swapVOPU8Pointers (m_pvopcRefOrig0, m_pvopcRefOrig1);
    		}
		}

	    if (m_vopmd.vopPredType != BVOP) {
			if(bPrevRefVopWasCoded)
			{
				// swap zoomed ref images
				CU8Image *puciTmp = m_puciRefQZoom0;
				m_puciRefQZoom0 = m_puciRefQZoom1;
				m_puciRefQZoom1 = puciTmp;
				m_rctRefVOPZoom0 = m_rctRefVOPZoom1;
			}
		    m_vopmd.iSearchRangeBackward = 0;
			if(bPrevRefVopWasCoded)
				if ( !bTemporalScalability || m_volmd.volType == BASE_LAYER ) // added by Sharp (99/1/28)
					m_tPastRef = m_tFutureRef;
		    m_tDistanceBetwIPVOP = (m_t - m_tPastRef) / m_volmd.iTemporalRate;
            m_tFutureRef = m_t;
		    m_iBCount = 0;
			if(m_vopmd.vopPredType == PVOP &&
				m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode ==3)
				m_tPastRef = m_t;
		    if (m_vopmd.vopPredType == PVOP) {
				// swap rounding control 0 <-> 1 every coded PVOP
				if( bPrevRefVopWasCoded && !m_volmd.bRoundingControlDisable)
					m_vopmd.iRoundingControlEncSwitch ^= 0x00000001;
				m_vopmd.iRoundingControl = m_vopmd.iRoundingControlEncSwitch;

				m_rctRefVOPZoom0 = m_rctRefVOPY0.upSampleBy2 ();
				biInterpolateY (m_pvopcRefQ0, m_rctRefVOPY0, m_puciRefQZoom0,
					m_rctRefVOPZoom0, m_vopmd.iRoundingControl);

			    m_vopmd.iSearchRangeForward = 
					checkrange (m_volmd.iMVRadiusPerFrameAwayFromRef * (m_t - m_tPastRef) / m_volmd.iTemporalRate, 1, 1024);
		    } else
			    m_vopmd.iSearchRangeForward = 0;
	    } else {
			// BVOP, set rounding control to zero
			m_vopmd.iRoundingControl = 0;
			if (m_volmd.volType==ENHN_LAYER && m_vopmd.iRefSelectCode==0){
				m_tPastRef = m_tFutureRef;
				m_tFutureRef = m_t;
			}
			m_iBCount++;
			if (m_iBCount == 1 || (m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode==0))
			{
				if(bPrevRefVopWasCoded)
				{
					m_rctRefVOPZoom1 = m_rctRefVOPY1.upSampleBy2 ();
					biInterpolateY (m_pvopcRefQ1,m_rctRefVOPY1,
						m_puciRefQZoom1, m_rctRefVOPZoom1, 0);
				}
				if (m_vopmd.iRoundingControlEncSwitch==1 // modified by Sharp (98/2/10) &&	// Need to re-compute because iRoundingControl was 1
					|| (m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode == 0) || bTemporalScalability) 
				{
					m_rctRefVOPZoom0 = m_rctRefVOPY0.upSampleBy2 ();
					biInterpolateY (m_pvopcRefQ0, m_rctRefVOPY0, m_puciRefQZoom0, m_rctRefVOPZoom0, 0);
				}
			}
//m_vopmd.iSearchRangeForward = 15;
//m_vopmd.iSearchRangeBackward = 15;
			m_vopmd.iSearchRangeForward = 
				checkrange ((m_t - m_tPastRef) * m_volmd.iMVRadiusPerFrameAwayFromRef / m_volmd.iTemporalRate, 1, 1024);
			m_vopmd.iSearchRangeBackward = 
				checkrange ((m_tFutureRef - m_t) * m_volmd.iMVRadiusPerFrameAwayFromRef / m_volmd.iTemporalRate, 1, 1024);
	    }
	    decideMVInfo();
	    m_statsVOP.nVOPs = 1;
    	if (m_volmd.fAUsage != RECTANGLE)
    		resetBYPlane ();

		if(!bVOPVisible)
		{
			if (m_vopmd.vopPredType != BVOP
				&& m_volmd.fAUsage != RECTANGLE && bPrevRefVopWasCoded)
			{
				// give the current object a dummy size
				m_iNumMBX = m_iNumMBY = m_iNumMB = 1;
				saveShapeMode(); // save the previous reference vop shape mode
			}
			return;   // return if not coded
		}

    	// prepare for the current original data
    	// extend the currVOP size to multiples of MBSize, will put zero on extended pixels
    	if (m_volmd.fAUsage != RECTANGLE) {
    		if (m_uiSprite != 1) {		// add by cgu to deal with vop-mc-left-top 12/5
    			findTightBoundingBox ();
    			findBestBoundingBox ();	
			} else if (m_sptMode == BASIC_SPRITE) {
				Int iSpriteWidth =  m_rctSpt.right - m_rctSpt.left;
				if(iSpriteWidth%16)
					iSpriteWidth += 16 - (iSpriteWidth%16);
				Int iSpriteHeight =  m_rctSpt.bottom - m_rctSpt.top;
				if(iSpriteHeight%16)
					iSpriteHeight += 16 - (iSpriteHeight%16);
				m_pvopcOrig->setBoundRct (CRct (0, 0, iSpriteWidth, iSpriteHeight));
			}
			m_rctCurrVOPY = m_pvopcOrig->whereBoundY ();
			m_rctCurrVOPUV = m_pvopcOrig->whereBoundUV ();
			setRefStartingPointers (); // need to compute the starting pointers of the refVOP's (corresponding to the current Rct)
			computeVOPMembers ();
			// Modified for error resilient mode by Toshiba(1998-1-16)
			if (m_volmd.bVPBitTh < 0 || m_volmd.bShapeOnly==TRUE) {
				m_vopmd.bShapeCodingType = (m_vopmd.vopPredType == IVOP) ? 0 : 1;
			} else {
				m_vopmd.bShapeCodingType = (m_volmd.iBinaryAlphaRR<0)?1:((m_t % m_volmd.iBinaryAlphaRR)==0) ? 0 : 1;
			}
	//		printf("vop_shape_coding_type=%d\n",m_vopmd.bShapeCodingType);
			// End Toshiba(1998-1-16)
		}

#ifdef __TRACE_AND_STATS_
	    m_pbitstrmOut -> trace (m_t, "VOP_Time");
#endif // __TRACE_AND_STATS_
	    codeVOPHead ();
	    cout << "\t" << "Time..." << m_t << " (" << m_t/m_volmd.dFrameHz << " sec)";
	    switch(vopPredType)
	    {
	    case IVOP:
		    cout << "\tIVOP";
	    	break;
	    case PVOP:
	    	cout << "\tPVOP (reference: t=" << m_tPastRef <<")";
	    	break;
	    case BVOP:
	    	cout << "\tBVOP (past ref: t=" << m_tPastRef
	    		<< ", future ref: t=" << m_tFutureRef <<")";
	    	break;
	    default:
	    	break;
	    }
	    cout << "\n";
	    cout.flush ();
	
	    encodeVOP ();

	    m_statsVOP.nBitsStuffing += m_pbitstrmOut->flush ();
	}
#ifdef __TRACE_AND_STATS_
	if (m_vopmd.vopPredType == BVOP)
		computeSNRs (m_pvopcCurrQ);
	else
		computeSNRs (m_pvopcRefQ1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -