00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "stdafx.h"
00033 #include "theoradecodeinputpin.h"
00034
00035
00036 TheoraDecodeInputPin::TheoraDecodeInputPin(CTransformFilter* inParentFilter, HRESULT* outHR)
00037 : CTransformInputPin(NAME("Theora Input Pin"), inParentFilter, outHR, L"Theora In")
00038 , mSetupState(VSS_SEEN_NOTHING)
00039 , mOggOutputPinInterface(NULL)
00040 , mSentStreamOffset(false)
00041 {
00042
00043 }
00044 TheoraDecodeInputPin::~TheoraDecodeInputPin() {
00045
00046 }
00047
00048 STDMETHODIMP TheoraDecodeInputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00049 {
00050
00051
00052
00053 if (riid == IID_IMediaSeeking) {
00054
00055 *ppv = (IMediaSeeking*)this;
00056 ((IUnknown*)*ppv)->AddRef();
00057
00058 return NOERROR;
00059 } else if (riid == IID_IOggDecoder) {
00060 *ppv = (IOggDecoder*)this;
00061
00062 return NOERROR;
00063
00064 }
00065
00066 return CBaseInputPin::NonDelegatingQueryInterface(riid, ppv);
00067 }
00068 HRESULT TheoraDecodeInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *outRequestedProps)
00069 {
00070 TheoraDecodeFilter* locParent = (TheoraDecodeFilter*)m_pFilter;
00071 unsigned long locBuffSize = ((unsigned long)locParent->mTheoraFormatInfo->outerFrameHeight * (unsigned long)locParent->mTheoraFormatInfo->outerFrameWidth * 3) >> 3;
00072 if (locBuffSize < 65536) {
00073 locBuffSize = 65536;
00074 }
00075 outRequestedProps->cbBuffer = locBuffSize;
00076 outRequestedProps->cBuffers = THEORA_NUM_BUFFERS;
00077 outRequestedProps->cbAlign = 1;
00078 outRequestedProps->cbPrefix = 0;
00079
00080 return S_OK;
00081 }
00082 HRESULT TheoraDecodeInputPin::BreakConnect() {
00083 CAutoLock locLock(m_pLock);
00084
00085
00086 ReleaseDelegate();
00087 return CTransformInputPin::BreakConnect();
00088 }
00089 HRESULT TheoraDecodeInputPin::CompleteConnect (IPin *inReceivePin) {
00090 CAutoLock locLock(m_pLock);
00091
00092
00093 IOggOutputPin* locOggOutput = NULL;
00094 mSentStreamOffset = false;
00095 HRESULT locHR = inReceivePin->QueryInterface(IID_IOggOutputPin, (void**)&locOggOutput);
00096 if (locHR == S_OK) {
00097 mOggOutputPinInterface = locOggOutput;
00098
00099 } else {
00100 mOggOutputPinInterface = NULL;
00101 }
00102
00103
00104
00105 IMediaSeeking* locSeeker = NULL;
00106 inReceivePin->QueryInterface(IID_IMediaSeeking, (void**)&locSeeker);
00107 if (locSeeker == NULL) {
00108
00109 }
00110 SetDelegate(locSeeker);
00111 return CTransformInputPin::CompleteConnect(inReceivePin);
00112 }
00113
00114 LOOG_INT64 TheoraDecodeInputPin::convertGranuleToTime(LOOG_INT64 inGranule)
00115 {
00116
00117
00118
00119
00120
00121 TheoraDecodeFilter* locParent = (TheoraDecodeFilter*)m_pFilter;
00122
00123
00124 LOOG_INT64 locMod = ((LOOG_INT64)1)<<locParent->getTheoraFormatBlock()->maxKeyframeInterval;
00125 LOOG_INT64 locInterFrameNo = (LOOG_INT64) ( inGranule % locMod );
00126
00127
00128
00129
00130 LOOG_INT64 retTime = inGranule >> locParent->getTheoraFormatBlock()->maxKeyframeInterval;
00131 retTime += locInterFrameNo + 1;
00132 retTime *= UNITS;
00133 retTime *= locParent->getTheoraFormatBlock()->frameRateDenominator;
00134 retTime /= locParent->getTheoraFormatBlock()->frameRateNumerator;
00135 return retTime;
00136
00137 }
00138
00139 LOOG_INT64 TheoraDecodeInputPin::mustSeekBefore(LOOG_INT64 inGranule)
00140 {
00141 TheoraDecodeFilter* locParent = (TheoraDecodeFilter*)m_pFilter;
00142 LOOG_INT64 locShift = locParent->getTheoraFormatBlock()->maxKeyframeInterval;
00143 return (inGranule >> locShift) << locShift;
00144 }
00145 IOggDecoder::eAcceptHeaderResult TheoraDecodeInputPin::showHeaderPacket(OggPacket* inCodecHeaderPacket)
00146 {
00147 unsigned char* locPacketData = new unsigned char[inCodecHeaderPacket->packetSize()];
00148 memcpy((void*)locPacketData, (const void**)inCodecHeaderPacket->packetData(), inCodecHeaderPacket->packetSize());
00149 StampedOggPacket* locStamped = new StampedOggPacket(locPacketData, inCodecHeaderPacket->packetSize(), false, false, 0,0, StampedOggPacket::NONE);
00150
00151 TheoraDecodeFilter* locParent = (TheoraDecodeFilter*)m_pFilter;
00152
00153 IOggDecoder::eAcceptHeaderResult retResult = IOggDecoder::AHR_INVALID_HEADER;
00154 switch (mSetupState) {
00155 case VSS_SEEN_NOTHING:
00156 if (strncmp((char*)inCodecHeaderPacket->packetData(), "\200theora", 7) == 0) {
00157
00158 if (locParent->mTheoraDecoder->decodeTheora(locStamped) == NULL) {
00159 mSetupState = VSS_SEEN_BOS;
00160 retResult = IOggDecoder::AHR_MORE_HEADERS_TO_COME;
00161 }
00162 }
00163
00164 break;
00165
00166
00167 case VSS_SEEN_BOS:
00168 if (strncmp((char*)inCodecHeaderPacket->packetData(), "\201theora", 7) == 0) {
00169 if (locParent->mTheoraDecoder->decodeTheora(locStamped) == NULL) {
00170 mSetupState = VSS_SEEN_COMMENT;
00171 retResult = IOggDecoder::AHR_MORE_HEADERS_TO_COME;
00172 }
00173
00174
00175 }
00176
00177 break;
00178
00179
00180 case VSS_SEEN_COMMENT:
00181 if (strncmp((char*)inCodecHeaderPacket->packetData(), "\202theora", 7) == 0) {
00182 if (locParent->mTheoraDecoder->decodeTheora(locStamped) == NULL) {
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 mSetupState = VSS_ALL_HEADERS_SEEN;
00194 retResult = IOggDecoder::AHR_ALL_HEADERS_RECEIVED;
00195 }
00196
00197 }
00198
00199 break;
00200
00201 case VSS_ALL_HEADERS_SEEN:
00202 case VSS_ERROR:
00203 default:
00204 delete locStamped;
00205 retResult = IOggDecoder::AHR_UNEXPECTED;
00206 }
00207
00208 return retResult;
00209 }
00210 string TheoraDecodeInputPin::getCodecShortName()
00211 {
00212 return "theora";
00213 }
00214 string TheoraDecodeInputPin::getCodecIdentString()
00215 {
00216
00217 return "theora";
00218 }