[xiph-commits] r7723 - trunk/oggdsf/src/lib/codecs/theora/filters/dsfTheoraDecoder

illiminable at motherfish-iii.xiph.org illiminable at motherfish-iii.xiph.org
Thu Sep 9 07:58:12 PDT 2004


Author: illiminable
Date: 2004-09-09 07:58:11 -0700 (Thu, 09 Sep 2004)
New Revision: 7723

Modified:
   trunk/oggdsf/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.cpp
   trunk/oggdsf/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.h
Log:
* Added decoding code.

Modified: trunk/oggdsf/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.cpp	2004-09-09 14:27:04 UTC (rev 7722)
+++ trunk/oggdsf/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.cpp	2004-09-09 14:58:11 UTC (rev 7723)
@@ -57,9 +57,15 @@
 	:	CVideoTransformFilter( NAME("Theora Decode Filter"), NULL, CLSID_TheoraDecodeFilter)
 {
 	debugLog.open("G:\\logs\\newtheofilter.log", ios_base::out);
+
+	mTheoraDecoder = new TheoraDecoder;
+	mTheoraDecoder->initCodec();
+
 }
 
 TheoraDecodeFilter::~TheoraDecodeFilter() {
+	delete mTheoraDecoder;
+	mTheoraDecoder = NULL;
 	debugLog.close();
 
 }
@@ -288,13 +294,308 @@
 		return VFW_S_NO_MORE_ITEMS;
 	}
 }
+
+void TheoraDecodeFilter::ResetFrameCount() {
+	mFrameCount = 0;
+	
+}
 HRESULT TheoraDecodeFilter::Transform(IMediaSample* inInputSample, IMediaSample* outOutputSample) {
 
-	return S_OK;
+	//CAutoLock locLock(mStreamLock);
+	debugLog<<"Transform "<<endl;
+	
+	HRESULT locHR;
+	BYTE* locBuff = NULL;
+	locHR = inInputSample->GetPointer(&locBuff);
+
+
+	if (FAILED(locHR)) {
+		debugLog<<"Receive : Get pointer failed..."<<locHR<<endl;	
+		return locHR;
+	} else {
+		debugLog<<"Receive : Get pointer succeeds..."<<endl;	
+		//New start time hacks
+		REFERENCE_TIME locStart = 0;
+		REFERENCE_TIME locEnd = 0;
+		inInputSample->GetTime(&locStart, &locEnd);
+		//Error chacks needed here
+		
+		//More work arounds for that stupid granule pos scheme in theora!
+		REFERENCE_TIME locTimeBase = 0;
+		REFERENCE_TIME locDummy = 0;
+		inInputSample->GetMediaTime(&locTimeBase, &locDummy);
+		mSeekTimeBase = locTimeBase;
+		//
+		
+		if ((mLastSeenStartGranPos != locStart) && (locStart != -1)) {
+			ResetFrameCount();
+			mLastSeenStartGranPos = locStart;
+		}
+		
+		//End of additions
+
+
+
+		AM_MEDIA_TYPE* locMediaType = NULL;
+		inInputSample->GetMediaType(&locMediaType);
+		if (locMediaType == NULL) {
+			debugLog<<"No dynamic change..."<<endl;
+		} else {
+			debugLog<<"Attempting dynamic change..."<<endl;
+		}
+				
+		StampedOggPacket* locPacket = new StampedOggPacket(locBuff, inInputSample->GetActualDataLength(), false, false, locStart, locEnd, StampedOggPacket::OGG_END_ONLY);
+		yuv_buffer* locYUV = mTheoraDecoder->decodeTheora(locPacket);
+		if (locYUV != NULL) {
+			if (TheoraDecoded(locYUV, outOutputSample) != 0) {
+				return S_FALSE;
+			}
+		}
+
+		return S_OK;
+		
+	}
+	
 }
 
+int TheoraDecodeFilter::TheoraDecoded (yuv_buffer* inYUVBuffer, IMediaSample* outSample) 
+{
+	debugLog<<"TheoraDecoded... "<<endl;
+	
+		
+	if (!mBegun) {
+	
+		mBegun = true;
+		
+		//How many UNITS does one frame take.
+		mFrameDuration = (UNITS * mTheoraFormatInfo->frameRateDenominator) / (mTheoraFormatInfo->frameRateNumerator);
+		mFrameSize = (mHeight * mWidth * 3) / 2;
+		mFrameCount = 0;
+	}
 
 
+
+	////FIX::: Most of this will be obselete... the demux does it all.
+	//
+
+	////TO DO::: Fix this up... needs to move around order and some only needs to be done once, move it into the block aboce and use member data
+
+	////Make the start timestamp
+	////FIX:::Abstract this calculation
+	DbgLog((LOG_TRACE,1,TEXT("Frame Count = %d"), mFrameCount));
+	//REFERENCE_TIME locFrameStart = CurrentStartTime() + (mFrameCount * mFrameDuration);
+
+	//Timestamp hacks start here...
+	unsigned long locMod = (unsigned long)pow(2, mTheoraFormatInfo->maxKeyframeInterval);
+	
+	DbgLog((LOG_TRACE,1,TEXT("locSeenGranPos = %d"), mLastSeenStartGranPos));
+	DbgLog((LOG_TRACE,1,TEXT("locMod = %d"), locMod));
+	
+	unsigned long locInterFrameNo = (mLastSeenStartGranPos) % locMod;
+	
+	DbgLog((LOG_TRACE,1,TEXT("InterFrameNo = %d"), locInterFrameNo));
+	
+	LONGLONG locAbsFramePos = ((mLastSeenStartGranPos >> mTheoraFormatInfo->maxKeyframeInterval)) + locInterFrameNo;
+	
+	DbgLog((LOG_TRACE,1,TEXT("AbsFrameNo = %d"), locAbsFramePos));
+	DbgLog((LOG_TRACE,1,TEXT("mSeekTimeBase = %d"), mSeekTimeBase));
+	
+	REFERENCE_TIME locTimeBase = (locAbsFramePos * mFrameDuration) - mSeekTimeBase;
+	
+	DbgLog((LOG_TRACE,1,TEXT("locTimeBase = %d"), locTimeBase));
+	//
+	//
+
+	REFERENCE_TIME locFrameStart = locTimeBase + (mFrameCount * mFrameDuration);
+	//Increment the frame counter
+	mFrameCount++;
+	
+	//Make the end frame counter
+	//REFERENCE_TIME locFrameEnd = CurrentStartTime() + (mFrameCount * mFrameDuration);
+	REFERENCE_TIME locFrameEnd = locTimeBase + (mFrameCount * mFrameDuration);
+
+	DbgLog((LOG_TRACE,1,TEXT("Frame Runs From %d"), locFrameStart));
+	DbgLog((LOG_TRACE,1,TEXT("Frame Runs To %d"), locFrameEnd));
+
+	
+	debugLog<<"Sample times = "<<locFrameStart<<" to "<<locFrameEnd<<endl;
+	
+	FILTER_STATE locFS;
+	GetState(0, &locFS);
+	debugLog<<"State Before = "<<locFS<<endl;
+	//HRESULT locHR = mOutputPin->GetDeliveryBuffer(&locSample, &locFrameStart, &locFrameEnd, locFlags);
+	GetState(0, &locFS);
+	debugLog<<"State After = "<<locFS<<endl;
+	//if (locHR != S_OK) {
+	//	debugLog<<"Get DeliveryBuffer FAILED with "<<locHR<<endl;
+	//	debugLog<<"locSample is "<<(unsigned long)locSample<<endl;
+	//	//We get here when the application goes into stop mode usually.
+
+	//	switch (locHR) {
+	//		case VFW_E_SIZENOTSET:
+	//			debugLog<<"SIZE NOT SET"<<endl;
+	//			break;
+	//		case VFW_E_NOT_COMMITTED:
+	//			debugLog<<"NOT COMMITTED"<<endl;
+	//			break;
+	//		case VFW_E_TIMEOUT:
+	//			debugLog<<"TIMEOUT"<<endl;
+	//			break;
+	//		case VFW_E_STATE_CHANGED:
+	//			debugLog<<"STATE CHANGED"<<endl;
+	//			return S_OK;
+	//		default:
+	//			debugLog<<"SOMETHING ELSE !!!"<<endl;
+	//			break;
+	//	}
+	//	return locHR;
+	//}	
+	
+	
+
+	//Debuggin code
+	AM_MEDIA_TYPE* locMediaType = NULL;
+	outSample->GetMediaType(&locMediaType);
+	if (locMediaType == NULL) {
+		debugLog<<"No dynamic change..."<<endl;
+	} else {
+		debugLog<<"Attempting dynamic change..."<<endl;
+		if (locMediaType->majortype == MEDIATYPE_Video) {
+			debugLog<<"Still MEDIATYPE_Video"<<endl;
+		}
+
+		if (locMediaType->subtype == MEDIASUBTYPE_YV12) {
+			debugLog<<"Still MEDIASUBTYPE_YV12"<<endl;
+		}
+
+		if (locMediaType->formattype == FORMAT_VideoInfo) {
+			debugLog<<"Still FORMAT_VideoInfo"<<endl;
+			VIDEOINFOHEADER* locVF = (VIDEOINFOHEADER*)locMediaType->pbFormat;
+			debugLog<<"Size = "<<locVF->bmiHeader.biSizeImage<<endl;
+			debugLog<<"Dim   = "<<locVF->bmiHeader.biWidth<<" x " <<locVF->bmiHeader.biHeight<<endl;
+		}
+
+		debugLog<<"Major  : "<<DSStringer::GUID2String(&locMediaType->majortype);
+		debugLog<<"Minor  : "<<DSStringer::GUID2String(&locMediaType->subtype);
+		debugLog<<"Format : "<<DSStringer::GUID2String(&locMediaType->formattype);
+		debugLog<<"Form Sz: "<<locMediaType->cbFormat;
+
+
+	}
+	//
+
+	////Create pointers for the samples buffer to be assigned to
+	BYTE* locBuffer = NULL;
+	
+	//
+	////Make our pointers set to point to the samples buffer
+	outSample->GetPointer(&locBuffer);
+	
+
+
+	//Fill the buffer with yuv data...
+	//	
+
+
+
+	//Set up the pointers
+	unsigned char* locDestUptoPtr = locBuffer;
+	char* locSourceUptoPtr = inYUVBuffer->y;
+
+	//
+	//Y DATA
+	//
+
+	//NEW WAY with offsets Y Data
+	long locTopPad = inYUVBuffer->y_height - mHeight - mYOffset;
+	ASSERT(locTopPad >= 0);
+	if (locTopPad < 0) {
+		locTopPad = 0;
+	}
+
+	//Skip the top padding
+	locSourceUptoPtr += (locTopPad * inYUVBuffer->y_stride);
+
+	for (long line = 0; line < mHeight; line++) {
+		memcpy((void*)(locDestUptoPtr), (const void*)(locSourceUptoPtr + mXOffset), mWidth);
+		locSourceUptoPtr += inYUVBuffer->y_stride;
+		locDestUptoPtr += mWidth;
+	}
+
+	locSourceUptoPtr += (mYOffset * inYUVBuffer->y_stride);
+
+	//Source advances by (y_height * y_stride)
+	//Dest advances by (mHeight * mWidth)
+
+	//
+	//V DATA
+	//
+
+	//Half the padding for uv planes... is this correct ? 
+	locTopPad = locTopPad /2;
+	
+	locSourceUptoPtr = inYUVBuffer->v;
+
+	//Skip the top padding
+	locSourceUptoPtr += (locTopPad * inYUVBuffer->y_stride);
+
+	for (long line = 0; line < mHeight / 2; line++) {
+		memcpy((void*)(locDestUptoPtr), (const void*)(locSourceUptoPtr + (mXOffset / 2)), mWidth / 2);
+		locSourceUptoPtr += inYUVBuffer->uv_stride;
+		locDestUptoPtr += (mWidth / 2);
+	}
+	locSourceUptoPtr += ((mYOffset/2) * inYUVBuffer->uv_stride);
+
+	//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
+
+
+	//
+	//U DATA
+	//
+
+	locSourceUptoPtr = inYUVBuffer->u;
+
+	//Skip the top padding
+	locSourceUptoPtr += (locTopPad * inYUVBuffer->y_stride);
+
+	for (long line = 0; line < mHeight / 2; line++) {
+		memcpy((void*)(locDestUptoPtr), (const void*)(locSourceUptoPtr + (mXOffset / 2)), mWidth / 2);
+		locSourceUptoPtr += inYUVBuffer->uv_stride;
+		locDestUptoPtr += (mWidth / 2);
+	}
+	locSourceUptoPtr += ((mYOffset/2) * inYUVBuffer->uv_stride);
+
+
+
+	//Set the sample parameters.
+	BOOL locIsKeyFrame = TRUE;
+	SetSampleParams(outSample, mFrameSize, &locFrameStart, &locFrameEnd, locIsKeyFrame);
+
+	
+	
+	return 0;
+
+
+}
+
+
+
+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;
+}
+
+
 //---------------------------------------
 //OLD IMPLOEMENTATION....
 //---------------------------------------

Modified: trunk/oggdsf/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.h	2004-09-09 14:27:04 UTC (rev 7722)
+++ trunk/oggdsf/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.h	2004-09-09 14:58:11 UTC (rev 7723)
@@ -32,7 +32,9 @@
 #pragma once
 
 #include "Theoradecoderdllstuff.h"
-
+#include <math.h>
+#include "DSStringer.h"
+#include "TheoraDecoder.h"
 #include <fstream>
 using namespace std;
 class TheoraDecodeFilter 
@@ -54,11 +56,26 @@
 	virtual HRESULT Transform(IMediaSample* inInputSample, IMediaSample* outOutputSample);
 
 protected:
+	virtual void ResetFrameCount();
 	void FillMediaType(CMediaType* outMediaType, unsigned long inSampleSize);
 	bool FillVideoInfoHeader(VIDEOINFOHEADER* inFormatBuffer);
+	bool SetSampleParams(IMediaSample* outMediaSample, unsigned long inDataSize, REFERENCE_TIME* inStartTime, REFERENCE_TIME* inEndTime, BOOL inIsSync);
 	unsigned long mHeight;
 	unsigned long mWidth;
 	unsigned long mFrameSize;
+	unsigned long mFrameCount;
+	unsigned long mYOffset;
+	unsigned long mXOffset;
+	__int64 mFrameDuration;
+	bool mBegun;
+	TheoraDecoder* mTheoraDecoder;
+	
+
+	int TheoraDecoded (yuv_buffer* inYUVBuffer, IMediaSample* outSample);
+
+
+	__int64 mSeekTimeBase;
+	__int64 mLastSeenStartGranPos;
 	//Format Block
 	sTheoraFormatBlock* mTheoraFormatInfo;
 	fstream debugLog;



More information about the commits mailing list