[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