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

📄 theoradecodefilter.cpp

📁 Window Mobile Capture with DirectDraw
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	long locDestPad = (mBMIWidth - mPictureWidth) * 2;
	long locSourceYPad = (locYStride - mPictureWidth);
	long locSourceUVPad = (locUVStride - (mPictureWidth/2));//locSourceYPad>>1;
	
	//Setup the source pointers into the planar data
	unsigned char* locSourceY = (unsigned char*)inYUVBuffer->y;
	unsigned char* locSourceU = (unsigned char*)inYUVBuffer->u;
	unsigned char* locSourceV = (unsigned char*)inYUVBuffer->v;

	//Skip over the Y Offset at the top of the picture and the X offset into the line
	locSourceY += (mYOffset * locYStride) + mXOffset;
	locSourceU += ((mYOffset/2) * locUVStride) + mXOffset/2;
	locSourceV += ((mYOffset/2) * locUVStride) + mXOffset/2;

	unsigned char* locSecondLineBuffer;

	for (int line = 0; line < mPictureHeight; line+= 2) {
		locSecondLineBuffer = mScratchBuffer;
		for (int col = 0; col < mPictureWidth; col+=2) {
			//Line 1
			*(locBuffer) = *(locSourceY);
			*(locBuffer+1) = *(locSourceU);
			*(locBuffer+2) = *(locSourceY+1);
			*(locBuffer+3) = *(locSourceV);

			//Line 2
			*(locSecondLineBuffer) = *(locSourceY+locYStride);
			*(locSecondLineBuffer+1) = *(locSourceU);
			*(locSecondLineBuffer+2) = *(locSourceY+locYStride+1);
			*(locSecondLineBuffer+3) = *(locSourceV);

			//Advance the pointers for this chunk of columns
			locBuffer += 4;
			locSecondLineBuffer += 4;
			locSourceY += 2;
			locSourceU++;
			locSourceV++;
		}

		//Advance the pointers for the line and copy the second line into the buffer
		locBuffer += locDestPad;
		memcpy((void*)locBuffer, (const void*)mScratchBuffer, mPictureWidth*2);
		locBuffer += mBMIWidth*2;
		locSourceY += locSourceYPad + locYStride;
		locSourceU += locSourceUVPad; //+ locUVStride;
		locSourceV += locSourceUVPad; //+ locUVStride;
	}

	REFERENCE_TIME locStart = inStart;
	REFERENCE_TIME locEnd = inEnd;

	BOOL locIsKeyFrame = FALSE;
	if (inIsKeyFrame) {
		locIsKeyFrame = TRUE;
	};
	SetSampleParams(outSample, mBMIFrameSize, &locStart, &locEnd, locIsKeyFrame);

	return S_OK;
}

HRESULT TheoraDecodeFilter::DecodeToYV12(yuv_buffer* inYUVBuffer, IMediaSample* outSample, bool inIsKeyFrame, REFERENCE_TIME inStart, REFERENCE_TIME inEnd) 
{
	BYTE* locBuffer = NULL;
	outSample->GetPointer(&locBuffer);

	//Set up the pointers
	unsigned char* locDestUptoPtr = locBuffer;
	unsigned char* locSourceUptoPtr = inYUVBuffer->y;

	//Strides from theora are generally -'ve
	long locYStride = inYUVBuffer->y_stride;
	long locUVStride = inYUVBuffer->uv_stride;



	debugLog<<"Y Stride = "<<locYStride<<endl;
	debugLog<<"UV Stride = "<<locUVStride<<endl;

	debugLog<<"PictureHeight = "<<mPictureHeight<<endl;
	debugLog<<"PictureWidth = "<<mPictureWidth<<endl;

	debugLog<<"BMIHeight = "<<mBMIHeight<<endl;
	debugLog<<"BMIWidth = "<<mBMIWidth<<endl;

	//
	//Y DATA
	//

	//Offsets Y Data
	long locTopPad = inYUVBuffer->y_height - mPictureHeight - mYOffset;
	debugLog<<"--------- TOP PAD = "<<locTopPad<<endl;


	//ASSERT(locTopPad >= 0);
	if (locTopPad < 0) {
		locTopPad = 0;
	} else {
		
	}

	//Skip the offset padding
	locSourceUptoPtr += (mYOffset * locYStride);

	for (unsigned long line = 0; line < mPictureHeight; line++) {
		//Ignore the x offset, and copy mPictureWidth bytes onto the destination
		memcpy((void*)(locDestUptoPtr), (const void*)(locSourceUptoPtr + mXOffset), mPictureWidth);

		//Advance the source pointer by the stride
		locSourceUptoPtr += locYStride;

		//Advance the destination pointer by the BMI Width
		locDestUptoPtr += mBMIWidth;
	}

	//Skip the other padding
	locSourceUptoPtr += (locTopPad * locYStride);

	//Advance the destination to pad to the size the video renderer wants
	locDestUptoPtr += ((mBMIHeight - mPictureHeight) * mBMIWidth);

	//debugLog<<"Dest Distance(y) = "<<(unsigned long)(locDestUptoPtr - locBuffer)<<endl;

	//Source advances by (y_height * y_stride)
	//Dest advances by (mHeight * mWidth)

	//
	//V DATA
	//

	//TODO::: May be issue here with odd numbers

	//Half the padding for uv planes... is this correct ? 
	locTopPad = locTopPad /2;
	
	locSourceUptoPtr = inYUVBuffer->v;

	//Skip the top padding
	locSourceUptoPtr += ((mYOffset/2) * locYStride);

	for (unsigned long line = 0; line < mPictureHeight / 2; line++) {
		//Ignore the x offset and copy mPictureWidth/2 bytes to the destination
		memcpy((void*)(locDestUptoPtr), (const void*)(locSourceUptoPtr + (mXOffset / 2)), mPictureWidth / 2);
		locSourceUptoPtr += locUVStride;
		locDestUptoPtr += (mBMIWidth / 2);
	}
	locSourceUptoPtr += (locTopPad * locUVStride);
	locDestUptoPtr += (((mBMIHeight/2) - (mPictureHeight/2)) * (mBMIWidth/2));

	//Source advances by (locTopPad + mYOffset/2 + mHeight /2) * uv_stride
	//where locTopPad for uv = (inYUVBuffer->y_height - mHeight - mYOffset) / 2
	//						=	(inYUVBuffer->yheight/2 - mHeight/2 - mYOffset/2)
	// so source advances by (y_height/2) * uv_stride
	//Dest advances by (mHeight * mWidth) /4


	//debugLog<<"Dest Distance(V) = "<<(unsigned long)(locDestUptoPtr - locBuffer)<<endl;
	//
	//U DATA
	//

	locSourceUptoPtr = inYUVBuffer->u;

	//Skip the top padding
	locSourceUptoPtr += ((mYOffset/2) * locYStride);

	for (unsigned long line = 0; line < mPictureHeight / 2; line++) {
		memcpy((void*)(locDestUptoPtr), (const void*)(locSourceUptoPtr + (mXOffset / 2)), mPictureWidth / 2);
		locSourceUptoPtr += locUVStride;
		locDestUptoPtr += (mBMIWidth / 2);
	}

	//Redundant
	locSourceUptoPtr += (locTopPad * locUVStride);
	locDestUptoPtr += (((mBMIHeight/2) - (mPictureHeight/2)) * (mBMIWidth/2));

	//debugLog<<"Dest Distance(U) = "<<(unsigned long)(locDestUptoPtr - locBuffer)<<endl;
	//debugLog<<"Frame Size = "<<mFrameSize<<endl;

	//Set the sample parameters.
	//BOOL locIsKeyFrame = (locInterFrameNo == 0);
	BOOL locIsKeyFrame = FALSE;
	if (inIsKeyFrame) {
		locIsKeyFrame = TRUE;
	};

	REFERENCE_TIME locStart = inStart;
	REFERENCE_TIME locEnd = inEnd;

	SetSampleParams(outSample, mBMIFrameSize, &locStart, &locEnd, locIsKeyFrame);
	
	return S_OK;
}
HRESULT TheoraDecodeFilter::TheoraDecoded (yuv_buffer* inYUVBuffer, IMediaSample* outSample, bool inIsKeyFrame, REFERENCE_TIME inStart, REFERENCE_TIME inEnd) 
{

	if (mCurrentOutputSubType == MEDIASUBTYPE_YV12) {
		debugLog<<"Decoding to YV12"<<endl;
		return DecodeToYV12(inYUVBuffer, outSample, inIsKeyFrame, inStart, inEnd);
	} else if (mCurrentOutputSubType == MEDIASUBTYPE_YUY2) {
		debugLog<<"Decoding to YUY2"<<endl;
		return DecodeToYUY2(inYUVBuffer, outSample, inIsKeyFrame, inStart, inEnd);
	//} else if (mCurrentOutputSubType == MEDIASUBTYPE_RGB565) {
	//	debugLog<<"Decoding to RGB565"<<endl;
	//	return DecodeToRGB565(inYUVBuffer, outSample, inIsKeyFrame, inStart, inEnd);
	//} else if (mCurrentOutputSubType == MEDIASUBTYPE_RGB24) {
	//	debugLog<<"Decoding to RGB24"<<endl;
	//	return DecodeToRGB24(inYUVBuffer, outSample, inIsKeyFrame, inStart, inEnd);
	} else {
		debugLog<<"Decoding to unknown type - failure"<<endl;
		return E_FAIL;
	}

}


HRESULT TheoraDecodeFilter::SetMediaType(PIN_DIRECTION inDirection, const CMediaType* inMediaType) 
{
	if (inDirection == PINDIR_INPUT) {
		if (CheckInputType(inMediaType) == S_OK) {
			//debugLog<<"Setting format block"<<endl;
			setTheoraFormat(inMediaType->pbFormat);
			
			//Set some other stuff here too...
			mXOffset = mTheoraFormatInfo->xOffset;
			mYOffset = mTheoraFormatInfo->yOffset;

			mPictureWidth = mTheoraFormatInfo->pictureWidth;
			mPictureHeight = mTheoraFormatInfo->pictureHeight;

			//How many UNITS does one frame take.
			mFrameDuration = (UNITS * mTheoraFormatInfo->frameRateDenominator) / (mTheoraFormatInfo->frameRateNumerator);

			mFrameCount = 0;
		} else {
			//Failed... should never be here !
			throw 0;
		}
		debugLog<<"SETTING input type"<<endl;
		return CTransformFilter::SetMediaType(PINDIR_INPUT, inMediaType);//CVideoTransformFilter::SetMediaType(PINDIR_INPUT, inMediaType);
	} else {

		mCurrentOutputSubType = inMediaType->subtype;
		debugLog<<"SETTING output type"<<endl;
		return CTransformFilter::SetMediaType(PINDIR_OUTPUT, inMediaType);//CVideoTransformFilter::SetMediaType(PINDIR_OUTPUT, inMediaType);
	}
}


bool TheoraDecodeFilter::SetSampleParams(IMediaSample* outMediaSample, unsigned long inDataSize, REFERENCE_TIME* inStartTime, REFERENCE_TIME* inEndTime, BOOL inIsSync) 
{
	outMediaSample->SetTime(inStartTime, inEndTime);
	outMediaSample->SetMediaTime(NULL, NULL);
	outMediaSample->SetActualDataLength(inDataSize);
	outMediaSample->SetPreroll(FALSE);
	outMediaSample->SetDiscontinuity(FALSE);
	outMediaSample->SetSyncPoint(inIsSync);
	return true;
}
//BOOL TheoraDecodeFilter::ShouldSkipFrame(IMediaSample* inSample) {
//	//m_bSkipping = FALSE;
//	debugLog<<"Don't skip"<<endl;
//	return FALSE;
//}

sTheoraFormatBlock* TheoraDecodeFilter::getTheoraFormatBlock() 
{
	return mTheoraFormatInfo;
}
void TheoraDecodeFilter::setTheoraFormat(BYTE* inFormatBlock) 
{

	delete mTheoraFormatInfo;
	mTheoraFormatInfo = new sTheoraFormatBlock;			//Deelted in destructor.

	//0		-	55			theora ident						0	-	6
	//56	-	63			ver major							7	-	7
	//64	-	71			ver minor							8	-	8
	//72	-	79			ver subversion						9	=	9
	//80	-	95			width/16							10	-	11
	//96	-	111			height/16							12	-	13
	//112	-	135			framewidth							14	-	16
	//136	-	159			frameheight							17	-	19
	//160	-	167			xoffset								20	-	20
	//168	-	175			yoffset								21	-	21
	//176	-	207			framerateNum						22	-	25
	//208	-	239			frameratedenom						26	-	29
	//240	-	263			aspectNum							30	-	32
	//264	-	287			aspectdenom							33	-	35
	//288	-	295			colourspace							36	-	36
	//296	-	319			targetbitrate						37	-	39
	//320	-	325			targetqual							40	-	40.75
	//326	-	330			keyframintlog						40.75-  41.375

	unsigned char* locIdentHeader = inFormatBlock;
	mTheoraFormatInfo->theoraVersion = (iBE_Math::charArrToULong(locIdentHeader + 7)) >>8;
	mTheoraFormatInfo->outerFrameWidth = (iBE_Math::charArrToUShort(locIdentHeader + 10)) * 16;
	mTheoraFormatInfo->outerFrameHeight = (iBE_Math::charArrToUShort(locIdentHeader + 12)) * 16;
	mTheoraFormatInfo->pictureWidth = (iBE_Math::charArrToULong(locIdentHeader + 14)) >>8;
	mTheoraFormatInfo->pictureHeight = (iBE_Math::charArrToULong(locIdentHeader + 17)) >>8;
	mTheoraFormatInfo->xOffset = locIdentHeader[20];
	mTheoraFormatInfo->yOffset = locIdentHeader[21];
	mTheoraFormatInfo->frameRateNumerator = iBE_Math::charArrToULong(locIdentHeader + 22);
	mTheoraFormatInfo->frameRateDenominator = iBE_Math::charArrToULong(locIdentHeader + 26);
	mTheoraFormatInfo->aspectNumerator = (iBE_Math::charArrToULong(locIdentHeader + 30)) >>8;
	mTheoraFormatInfo->aspectDenominator = (iBE_Math::charArrToULong(locIdentHeader + 33)) >>8;
	mTheoraFormatInfo->colourSpace = locIdentHeader[36];
	mTheoraFormatInfo->targetBitrate = (iBE_Math::charArrToULong(locIdentHeader + 37)) >>8;
	mTheoraFormatInfo->targetQuality = (locIdentHeader[40]) >> 2;

	mTheoraFormatInfo->maxKeyframeInterval= (((locIdentHeader[40]) % 4) << 3) + (locIdentHeader[41] >> 5);
}

CBasePin* TheoraDecodeFilter::GetPin(int inPinNo)
{
    HRESULT locHR = S_OK;

    // Create an input pin if necessary

    if (m_pInput == NULL) {

        m_pInput = new TheoraDecodeInputPin(this, &locHR);		//Deleted in base destructor

        
        if (m_pInput == NULL) {
            return NULL;
        }
        m_pOutput = new TheoraDecodeOutputPin(this, &locHR);	//Deleted in base destructor
			

        if (m_pOutput == NULL) {
            delete m_pInput;
            m_pInput = NULL;
        }
    }

    // Return the pin

    if (inPinNo == 0) {
        return m_pInput;
    } else if (inPinNo == 1) {
        return m_pOutput;
    } else {
        return NULL;
    }
}

⌨️ 快捷键说明

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