[xiph-commits] r10302 - in branches/oggdsf_new_demux/src/lib/codecs/theora: filters/dsfTheoraDecoder libs/libOOTheora

illiminable at svn.xiph.org illiminable at svn.xiph.org
Tue Oct 25 04:51:43 PDT 2005


Author: illiminable
Date: 2005-10-25 04:51:36 -0700 (Tue, 25 Oct 2005)
New Revision: 10302

Modified:
   branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.cpp
   branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.h
   branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeOutputPin.h
   branches/oggdsf_new_demux/src/lib/codecs/theora/libs/libOOTheora/TheoraDecoder.cpp
Log:
* Change all the data flow in theora decoder

Modified: branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.cpp
===================================================================
--- branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.cpp	2005-10-25 10:28:59 UTC (rev 10301)
+++ branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.cpp	2005-10-25 11:51:36 UTC (rev 10302)
@@ -338,106 +338,248 @@
 	return CTransformFilter::NewSegment(inStart, inEnd, inRate);
 
 }
-HRESULT TheoraDecodeFilter::Transform(IMediaSample* inInputSample, IMediaSample* outOutputSample) {
 
+HRESULT TheoraDecodeFilter::Receive(IMediaSample* inInputSample)
+{
 
-	HRESULT locHR;
+
 	BYTE* locBuff = NULL;
 	//Get a source poitner into the input buffer
-	locHR = inInputSample->GetPointer(&locBuff);
+	HRESULT locHR = inInputSample->GetPointer(&locBuff);
 
-	//TODO::: This should be after the return value check !!
-	BYTE* locNewBuff = new unsigned char[inInputSample->GetActualDataLength()];		//This gets put into a packet.
-	memcpy((void*)locNewBuff, (const void*)locBuff, inInputSample->GetActualDataLength());
-
-
 	if (locHR != S_OK) {
 		//debugLog<<"Receive : Get pointer failed..."<<locHR<<endl;	
 		return S_FALSE;
 	} else {
-		//debugLog<<"Receive : Get pointer succeeds..."<<endl;	
-		//New start time hacks
+
+		if ((inInputSample->GetActualDataLength() > 0) && ((locBuff[0] & 128) != 0)) {
+			//inInputSample->Release();
+
+			//This is a header, so ignore it
+			return S_OK;
+		}
+		//Make a copy of the packet buffer
+		BYTE* locNewBuff = new unsigned char[inInputSample->GetActualDataLength()];		//This gets put into a packet.
+		memcpy((void*)locNewBuff, (const void*)locBuff, inInputSample->GetActualDataLength());
+
+
 		REFERENCE_TIME locStart = 0;
 		REFERENCE_TIME locEnd = 0;
 		inInputSample->GetTime(&locStart, &locEnd);
-		//Error chacks needed here
-		//debugLog<<"Input Sample Time - "<<locStart<<" to "<<locEnd<<endl;
-		
-		//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;
-		//
 
-		//debugLog<<"SeekTimeBase = "<<mSeekTimeBase<<endl;
-		
-		if ((mLastSeenStartGranPos != locStart) && (locStart != -1)) {
-			//debugLog<<"Resetting frame count"<<endl;
+		//This packet is given to the decoder or buffered for later
+		StampedOggPacket* locPacket = new StampedOggPacket(locNewBuff, inInputSample->GetActualDataLength(), false, false, locStart, locEnd, StampedOggPacket::OGG_END_ONLY);
 
-			//FIXXX:::
-			//ResetFrameCount();
-			//
+		//Buffer all packets, even if we are about to send them anyway
+		mBufferedPackets.push_back(locPacket);
 
-			mLastSeenStartGranPos = locStart;
-			//debugLog<<"Setting base gran pos to "<<locStart<<endl;
-		}
-		
-		//End of additions
+		if (locEnd < 0) {
 
+			//The packet was ok, but we just aren't going to deliver it yet
+			return S_OK;
+		} else {
+			//Now we have one with a stamp, we can send all the previous ones.
+			TheoraDecodeInputPin* locInputPin = (TheoraDecodeInputPin*)m_pInput;
+			REFERENCE_TIME locGlobalEnd = locInputPin->convertGranuleToTime(locEnd);
+			unsigned long locNumBufferedFrames = mBufferedPackets.size();
+			REFERENCE_TIME locGlobalStart = locGlobalEnd - (locNumBufferedFrames * mFrameDuration);
 
+			locStart = locGlobalStart;
+			
+			for (unsigned long i = 0; i < locNumBufferedFrames; i++) {
+				bool locIsKeyFrame = mTheoraDecoder->isKeyFrame(mBufferedPackets[i]);
+				yuv_buffer* locYUV = mTheoraDecoder->decodeTheora(mBufferedPackets[i]);		//This accept the packet and deletes it
+				locEnd = locStart + mFrameDuration;
+				if (locYUV != NULL) {
+					IMediaSample* locOutSample = NULL;
+					locHR = InitializeOutputSample(inInputSample, &locOutSample);
+					if (locHR != S_OK) {
+						//XTODO::: We need to trash our buffered packets
+						return S_FALSE;
+					}
 
-		AM_MEDIA_TYPE* locMediaType = NULL;
-		inInputSample->GetMediaType(&locMediaType);
-		if (locMediaType == NULL) {
-			//debugLog<<"No dynamic change..."<<endl;
-		} else {
-			//debugLog<<"Attempting dynamic change..."<<endl;
-		}
-		
-		//This packet is given to the decoder.
-		StampedOggPacket* locPacket = new StampedOggPacket(locNewBuff, inInputSample->GetActualDataLength(), false, false, locStart, locEnd, StampedOggPacket::OGG_END_ONLY);
+					//Fill the sample info
+					if (TheoraDecoded(locYUV, locOutSample, locIsKeyFrame, locStart, locEnd) != S_OK) {
+						
+						//XTODO::: We need to trash our buffered packets
+						return S_FALSE;
+					} else {
+						//Deliver the sample
+						
+						locHR = m_pOutput->Deliver(locOutSample);
+						if (locHR != S_OK) {
+							//XTODO::: We need to trash our buffered packets
+							return S_FALSE;
+						}
 
-		bool locIsKeyFrame = mTheoraDecoder->isKeyFrame(locPacket);
-		yuv_buffer* locYUV = mTheoraDecoder->decodeTheora(locPacket);		//This accept the packet and deletes it
-		if (locYUV != NULL) {
-			if (TheoraDecoded(locYUV, outOutputSample, locIsKeyFrame) != 0) {
-				//debugLog<<"Decoded *** FALSE ***"<<endl;
-				return S_FALSE;
+					}
+				} else {
+					//XTODO::: We need to trash our buffered packets
+					return S_FALSE;
+				}	
+				locStart = locEnd;
 			}
-		} else {
-			//debugLog<<"!@&#^()!&@#!()*@#&)!(*@#&()!*@# NULL Decode"<<endl;
-			return S_FALSE;
+
+			mBufferedPackets.clear();
+
+
+
+			return S_OK;
+
 		}
-
-		return S_OK;
 		
 	}
-	
 }
-
-int TheoraDecodeFilter::TheoraDecoded (yuv_buffer* inYUVBuffer, IMediaSample* outSample, bool inIsKeyFrame) 
+HRESULT TheoraDecodeFilter::Transform(IMediaSample* inInputSample, IMediaSample* outOutputSample) 
 {
-	if (!mBegun) {
-		mBegun = true;
-		
-		//How many UNITS does one frame take.
-		mFrameDuration = (UNITS * mTheoraFormatInfo->frameRateDenominator) / (mTheoraFormatInfo->frameRateNumerator);
+	//HRESULT locHR;
+	//BYTE* locBuff = NULL;
+	////Get a source poitner into the input buffer
+	//locHR = inInputSample->GetPointer(&locBuff);
 
-		mFrameSize = (mHeight * mWidth * 3) / 2;
-		mFrameCount = 0;
-	}
+	//if (locHR != S_OK) {
+	//	//debugLog<<"Receive : Get pointer failed..."<<locHR<<endl;	
+	//	return S_FALSE;
+	//} else {
+	//	//Make a copy of the packet buffer
+	//	BYTE* locNewBuff = new unsigned char[inInputSample->GetActualDataLength()];		//This gets put into a packet.
+	//	memcpy((void*)locNewBuff, (const void*)locBuff, inInputSample->GetActualDataLength());
 
 
+	//	REFERENCE_TIME locStart = 0;
+	//	REFERENCE_TIME locEnd = 0;
+	//	inInputSample->GetTime(&locStart, &locEnd);
 
-	REFERENCE_TIME locFrameStart = (mFrameCount * mFrameDuration);
-	mFrameCount++;
-	REFERENCE_TIME locFrameEnd = (mFrameCount * mFrameDuration);
+	//	//This packet is given to the decoder or buffered for later
+	//	StampedOggPacket* locPacket = new StampedOggPacket(locNewBuff, inInputSample->GetActualDataLength(), false, false, locStart, locEnd, StampedOggPacket::OGG_END_ONLY);
 
+	//	//Buffer all packets, even if we are about to send them anyway
+	//	mBufferedPackets.push_back(locPacket);
+
+	//	if (locEnd < 0) {
+
+	//		//S_FALSE is an agreement with CTransform filter, to not deliver the presented output sample
+	//		//XXX::: There may be some problems doing this, since it causes a quality message, and thinks we
+	//		//		are dropping samples. It also may present a problem when we try to dump many frames
+	//		//		downstream in one go.
+	//		return S_FALSE;
+	//	} else {
+	//		//Now we have one with a stamp, we can send all the previous ones.
+	//		TheoraDecodeInputPin* locInputPin = (TheoraDecodeInputPin*)m_pInput;
+	//		REFERENCE_TIME locGlobalEnd = locInputPin->convertGranuleToTime(locEnd);
+	//		unsigned long locNumBufferedFrames = mBufferedPackets.size();
+	//		REFERENCE_TIME locGlobalStart = locGlobalEnd - (locNumBufferedFrames * mFrameDuration);
+
+	//		locStart = locGlobalStart;
+	//		
+	//		for (unsigned long i = 0; i < locNumBufferedFrames; i++) {
+	//			bool locIsKeyFrame = mTheoraDecoder->isKeyFrame(mBufferedPackets[i]);
+	//			yuv_buffer* locYUV = mTheoraDecoder->decodeTheora(mBufferedPackets[i]);		//This accept the packet and deletes it
+	//			locEnd = locStart + mFrameDuration;
+	//			if (locYUV != NULL) {
+	//				if (TheoraDecoded(locYUV, outOutputSample, locIsKeyFrame) != 0) {
+	//					//debugLog<<"Decoded *** FALSE ***"<<endl;
+	//					return S_FALSE;
+	//				}
+	//			} else {
+	//				//debugLog<<"!@&#^()!&@#!()*@#&)!(*@#&()!*@# NULL Decode"<<endl;
+	//				return S_FALSE;
+	//			}					
+	//		}
+
+
+
+	//		return S_OK;
+
+	//	}
+	//	
+	//}
+
+
+
+
+
+
+
+	//HRESULT locHR;
+	//BYTE* locBuff = NULL;
+	////Get a source poitner into the input buffer
+	//locHR = inInputSample->GetPointer(&locBuff);
+
+	////TODO::: This should be after the return value check !!
+	//BYTE* locNewBuff = new unsigned char[inInputSample->GetActualDataLength()];		//This gets put into a packet.
+	//memcpy((void*)locNewBuff, (const void*)locBuff, inInputSample->GetActualDataLength());
+
+
+	//if (locHR != S_OK) {
+	//	//debugLog<<"Receive : Get pointer failed..."<<locHR<<endl;	
+	//	return S_FALSE;
+	//} 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
+	//	//debugLog<<"Input Sample Time - "<<locStart<<" to "<<locEnd<<endl;
+	//	
+	//	//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;
+	//	//
+
+	//	//debugLog<<"SeekTimeBase = "<<mSeekTimeBase<<endl;
+	//	
+	//	if ((mLastSeenStartGranPos != locStart) && (locStart != -1)) {
+	//		//debugLog<<"Resetting frame count"<<endl;
+
+	//		//FIXXX:::
+	//		//ResetFrameCount();
+	//		//
+
+	//		mLastSeenStartGranPos = locStart;
+	//		//debugLog<<"Setting base gran pos to "<<locStart<<endl;
+	//	}
+	//	
+	//	//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;
+	//	}
+	//	
+	//	//This packet is given to the decoder.
+	//	StampedOggPacket* locPacket = new StampedOggPacket(locNewBuff, inInputSample->GetActualDataLength(), false, false, locStart, locEnd, StampedOggPacket::OGG_END_ONLY);
+
+	//	bool locIsKeyFrame = mTheoraDecoder->isKeyFrame(locPacket);
+	//	yuv_buffer* locYUV = mTheoraDecoder->decodeTheora(locPacket);		//This accept the packet and deletes it
+	//	if (locYUV != NULL) {
+	//		if (TheoraDecoded(locYUV, outOutputSample, locIsKeyFrame) != 0) {
+	//			//debugLog<<"Decoded *** FALSE ***"<<endl;
+	//			return S_FALSE;
+	//		}
+	//	} else {
+	//		//debugLog<<"!@&#^()!&@#!()*@#&)!(*@#&()!*@# NULL Decode"<<endl;
+	//		return S_FALSE;
+	//	}
+
+	//	return S_OK;
+	//	
+	//}
+
+	return E_NOTIMPL;
 	
-	debugLog<<"Sample times = "<<locFrameStart<<" to "<<locFrameEnd<<"  frame "<<mFrameCount<<" KF = "<<((inIsKeyFrame) ? "YES" : "NO")<<endl;
-	
+}
 
+HRESULT TheoraDecodeFilter::TheoraDecoded (yuv_buffer* inYUVBuffer, IMediaSample* outSample, bool inIsKeyFrame, REFERENCE_TIME inStart, REFERENCE_TIME inEnd) 
+{
 
 	////Create pointers for the samples buffer to be assigned to
 	BYTE* locBuffer = NULL;
@@ -449,6 +591,8 @@
 	//Fill the buffer with yuv data...
 	//	
 
+	REFERENCE_TIME locStart = inStart;
+	REFERENCE_TIME locEnd = inEnd;
 
 
 	//Set up the pointers
@@ -543,11 +687,11 @@
 	if (inIsKeyFrame) {
 		locIsKeyFrame = TRUE;
 	};
-	SetSampleParams(outSample, mFrameSize, &locFrameStart, &locFrameEnd, locIsKeyFrame);
+	SetSampleParams(outSample, mFrameSize, &locStart, &locEnd, locIsKeyFrame);
 
 	
 	
-	return 0;
+	return S_OK;
 
 
 }
@@ -563,6 +707,12 @@
 			//Set some other stuff here too...
 			mXOffset = mTheoraFormatInfo->xOffset;
 			mYOffset = mTheoraFormatInfo->xOffset;
+
+			//How many UNITS does one frame take.
+			mFrameDuration = (UNITS * mTheoraFormatInfo->frameRateDenominator) / (mTheoraFormatInfo->frameRateNumerator);
+
+			mFrameSize = (mHeight * mWidth * 3) / 2;
+			mFrameCount = 0;
 		} else {
 			//Failed... should never be here !
 			throw 0;

Modified: branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.h
===================================================================
--- branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.h	2005-10-25 10:28:59 UTC (rev 10301)
+++ branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeFilter.h	2005-10-25 11:51:36 UTC (rev 10302)
@@ -62,6 +62,8 @@
 	virtual HRESULT Transform(IMediaSample* inInputSample, IMediaSample* outOutputSample);
 
 	//Overrides
+	virtual HRESULT Receive(IMediaSample* inSample);
+
 	virtual HRESULT SetMediaType(PIN_DIRECTION inDirection, const CMediaType* inMediaType);
 	virtual HRESULT NewSegment(REFERENCE_TIME inStart, REFERENCE_TIME inEnd, double inRate);
 	//virtual BOOL ShouldSkipFrame(IMediaSample* inSample);
@@ -88,7 +90,7 @@
 	
 	vector<StampedOggPacket*> mBufferedPackets;
 
-	int TheoraDecoded (yuv_buffer* inYUVBuffer, IMediaSample* outSample, bool inIsKeyFrame);
+	HRESULT TheoraDecoded (yuv_buffer* inYUVBuffer, IMediaSample* outSample, bool inIsKeyFrame, REFERENCE_TIME inStart, REFERENCE_TIME inEnd);
 
 
 	__int64 mSeekTimeBase;

Modified: branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeOutputPin.h
===================================================================
--- branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeOutputPin.h	2005-10-25 10:28:59 UTC (rev 10301)
+++ branches/oggdsf_new_demux/src/lib/codecs/theora/filters/dsfTheoraDecoder/TheoraDecodeOutputPin.h	2005-10-25 11:51:36 UTC (rev 10302)
@@ -55,5 +55,7 @@
 	//Quality control
 	virtual STDMETHODIMP Notify(IBaseFilter* inMessageSource, Quality inQuality);
 
+	virtual HRESULT Deliver(IMediaSample* inSample)	{	return m_pInputPin->Receive(inSample);	}
+
 	//fstream debugLog;
 };

Modified: branches/oggdsf_new_demux/src/lib/codecs/theora/libs/libOOTheora/TheoraDecoder.cpp
===================================================================
--- branches/oggdsf_new_demux/src/lib/codecs/theora/libs/libOOTheora/TheoraDecoder.cpp	2005-10-25 10:28:59 UTC (rev 10301)
+++ branches/oggdsf_new_demux/src/lib/codecs/theora/libs/libOOTheora/TheoraDecoder.cpp	2005-10-25 11:51:36 UTC (rev 10302)
@@ -64,15 +64,21 @@
 			theora_decode_init(&mTheoraState, &mTheoraInfo);
 			mFirstPacket = false;
 		}
-			ogg_packet* locOldPack = simulateOldOggPacket(inPacket);		//Accepts the packet and deletes it.
-			theora_decode_packetin(&mTheoraState, locOldPack);
-			delete locOldPack->packet;
-			delete locOldPack;
-			
-			//Ignore return value... always returns 0 (or crashes :)
-			theora_decode_YUVout(&mTheoraState, &mYUVBuffer);
-			
-			return &mYUVBuffer;
+		if ((inPacket->packetSize() > 0) && ((inPacket->packetData()[0] & 128) != 0)) {
+			//Ignore header packets
+			delete inPacket;
+			return NULL;
+		}
+
+		ogg_packet* locOldPack = simulateOldOggPacket(inPacket);		//Accepts the packet and deletes it.
+		theora_decode_packetin(&mTheoraState, locOldPack);
+		delete locOldPack->packet;
+		delete locOldPack;
+		
+		//Ignore return value... always returns 0 (or crashes :)
+		theora_decode_YUVout(&mTheoraState, &mYUVBuffer);
+		
+		return &mYUVBuffer;
 	}
 
 }



More information about the commits mailing list