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 #include "StdAfx.h"
00032 #include ".\OggDemuxPacketsourcepin.h"
00033
00034 OggDemuxPacketSourcePin:: OggDemuxPacketSourcePin( TCHAR* inObjectName
00035 , OggDemuxPacketSourceFilter* inParentFilter
00036 , CCritSec* inFilterLock
00037 , OggPacket* inIdentHeader
00038 , unsigned long inSerialNo)
00039 : CBaseOutputPin( NAME("Ogg Demux Output Pin")
00040 , inParentFilter
00041 , inFilterLock
00042 , &mFilterHR
00043 , L"Ogg Stream" )
00044 , mIdentHeader(inIdentHeader)
00045 , mSerialNo(inSerialNo)
00046 , mIsStreamReady(false)
00047 , mAcceptingData(false)
00048 , mNumBuffers(0)
00049 , mDataQueue(NULL)
00050 , mFilterHR(S_OK)
00051 {
00052
00053 mPacketiserLock = new CCritSec;
00054
00055
00056 mPacketiser.setPacketSink(this);
00057
00058
00059
00060
00061 IMediaSeeking* locSeeker = NULL;
00062 locSeeker = (IMediaSeeking*)inParentFilter;
00063 SetDelegate(locSeeker);
00064 }
00065 STDMETHODIMP OggDemuxPacketSourcePin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00066 {
00067 if (riid == IID_IMediaSeeking) {
00068
00069 *ppv = (IMediaSeeking*)this;
00070 ((IUnknown*)*ppv)->AddRef();
00071 return NOERROR;
00072 } else if (riid == IID_IOggOutputPin) {
00073 *ppv = (IOggOutputPin*)this;
00074
00075 return NOERROR;
00076 }
00077
00078 return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv);
00079 }
00080 OggDemuxPacketSourcePin::~OggDemuxPacketSourcePin(void)
00081 {
00082
00083
00084 SetDelegate(NULL);
00085
00086
00087 delete mIdentHeader;
00088 delete mDataQueue;
00089
00090 delete mPacketiserLock;
00091
00092
00093 }
00094
00095 bool OggDemuxPacketSourcePin::acceptOggPage(OggPage* inOggPage)
00096 {
00097 CAutoLock locPackLock(mPacketiserLock);
00098 if (mIsStreamReady) {
00099 mAcceptingData = true;
00100 return mPacketiser.acceptOggPage(inOggPage);
00101 } else {
00102 delete inOggPage;
00103 }
00104 return false;
00105 }
00106 BYTE* OggDemuxPacketSourcePin::getIdentAsFormatBlock()
00107 {
00108 return (BYTE*)mIdentHeader->packetData();
00109 }
00110
00111 unsigned long OggDemuxPacketSourcePin::getIdentSize()
00112 {
00113 return mIdentHeader->packetSize();
00114 }
00115
00116 unsigned long OggDemuxPacketSourcePin::getSerialNo()
00117 {
00118 return mSerialNo;
00119 }
00120
00121 IOggDecoder* OggDemuxPacketSourcePin::getDecoderInterface()
00122 {
00123 if (mDecoderInterface == NULL) {
00124 IOggDecoder* locDecoder = NULL;
00125 if (IsConnected()) {
00126 IPin* locPin = GetConnected();
00127 if (locPin != NULL) {
00128 locPin->QueryInterface(IID_IOggDecoder, (void**)&locDecoder);
00129 }
00130 }
00131
00132 mDecoderInterface = locDecoder;
00133 }
00134 return mDecoderInterface;
00135
00136 }
00137 HRESULT OggDemuxPacketSourcePin::GetMediaType(int inPosition, CMediaType* outMediaType)
00138 {
00139
00140 if (inPosition == 0) {
00141 AM_MEDIA_TYPE locAMMediaType;
00142 locAMMediaType.majortype = MEDIATYPE_OggPacketStream;
00143
00144 locAMMediaType.subtype = MEDIASUBTYPE_None;
00145 locAMMediaType.formattype = FORMAT_OggIdentHeader;
00146 locAMMediaType.cbFormat = getIdentSize();
00147 locAMMediaType.pbFormat = getIdentAsFormatBlock();
00148 locAMMediaType.pUnk = NULL;
00149
00150
00151
00152 CMediaType locMediaType(locAMMediaType);
00153 *outMediaType = locMediaType;
00154 return S_OK;
00155 } else {
00156 return VFW_S_NO_MORE_ITEMS;
00157 }
00158 }
00159 HRESULT OggDemuxPacketSourcePin::CheckMediaType(const CMediaType* inMediaType) {
00160 if ( (inMediaType->majortype == MEDIATYPE_OggPacketStream)
00161 && (inMediaType->subtype == MEDIASUBTYPE_None)
00162 && (inMediaType->formattype == FORMAT_OggIdentHeader)) {
00163
00164
00165 return S_OK;
00166 } else {
00167 return E_FAIL;
00168 }
00169 }
00170 HRESULT OggDemuxPacketSourcePin::DecideBufferSize(IMemAllocator* inoutAllocator, ALLOCATOR_PROPERTIES* inoutInputRequest)
00171 {
00172 HRESULT locHR = S_OK;
00173
00174 ALLOCATOR_PROPERTIES locReqAlloc = *inoutInputRequest;
00175 ALLOCATOR_PROPERTIES locActualAlloc;
00176
00177
00178
00179
00180
00181
00182 locHR = inoutAllocator->SetProperties(&locReqAlloc, &locActualAlloc);
00183
00184 if (locHR != S_OK) {
00185 return locHR;
00186 }
00187
00188 mNumBuffers = locActualAlloc.cBuffers;
00189
00190 locHR = inoutAllocator->Commit();
00191
00192 return locHR;
00193
00194 }
00195
00196
00197
00198 HRESULT OggDemuxPacketSourcePin::BreakConnect()
00199 {
00200 delete mDataQueue;
00201 mDataQueue = NULL;
00202 return CBaseOutputPin::BreakConnect();
00203 }
00204 HRESULT OggDemuxPacketSourcePin::CompleteConnect(IPin *inReceivePin)
00205 {
00206 IOggDecoder* locDecoder = NULL;
00207 inReceivePin->QueryInterface(IID_IOggDecoder, (void**)&locDecoder);
00208 if (locDecoder != NULL) {
00209 mDecoderInterface = locDecoder;
00210
00211 IOggDecoder::eAcceptHeaderResult locResult = mDecoderInterface->showHeaderPacket(mIdentHeader->clone());
00212 if (locResult == IOggDecoder::AHR_ALL_HEADERS_RECEIVED) {
00213 mIsStreamReady = true;
00214
00215 } else {
00216 OggPacketiser locPacketiser;
00217 locPacketiser.setPacketSink(this);
00218 OggDemuxPacketSourceFilter* locParent = (OggDemuxPacketSourceFilter*)m_pFilter;
00219 vector<OggPage*> locList = locParent->getMatchingBufferedPages(mSerialNo);
00220
00221 for (size_t i = 0; i < locList.size(); i++) {
00222 locPacketiser.acceptOggPage(locList[i]);
00223 }
00224
00225 locParent->removeMatchingBufferedPages(mSerialNo);
00226
00227
00228 }
00229
00230 if (mIsStreamReady) {
00231 HRESULT locHR = CBaseOutputPin::CompleteConnect(inReceivePin);
00232 if (locHR == S_OK) {
00233 ((OggDemuxPacketSourceFilter*)m_pFilter)->notifyPinConnected();
00234 mDataQueue = new COutputQueue (inReceivePin, &mFilterHR, FALSE, TRUE,1,TRUE, mNumBuffers);
00235 return S_OK;
00236 } else {
00237 return locHR;
00238 }
00239
00240 }
00241
00242
00243 }
00244 return E_FAIL;
00245
00246 }
00247
00248 bool OggDemuxPacketSourcePin::dispatchPacket(StampedOggPacket* inPacket)
00249 {
00250 CAutoLock locStreamLock(((OggDemuxPacketSourceFilter*)m_pFilter)->streamLock());
00251
00252
00253
00254 IMediaSample* locSample = NULL;
00255 REFERENCE_TIME locStart = inPacket->startTime();
00256 REFERENCE_TIME locStop = inPacket->endTime();
00257
00258
00259 HRESULT locHR = GetDeliveryBuffer(&locSample, &locStart, &locStop, NULL);
00260
00261
00262 if (locHR != S_OK) {
00263
00264
00265 delete inPacket;
00266 return false;
00267 }
00268
00269
00270 locSample->SetTime(&locStart, &locStop);
00271
00272 locSample->SetMediaTime(&locStart, &locStop);
00273 locSample->SetSyncPoint(TRUE);
00274
00275
00276
00277 BYTE* locBuffer = NULL;
00278 locSample->GetPointer(&locBuffer);
00279
00280 if (locSample->GetSize() >= inPacket->packetSize()) {
00281
00282 memcpy((void*)locBuffer, (const void*)inPacket->packetData(), inPacket->packetSize());
00283 locSample->SetActualDataLength(inPacket->packetSize());
00284
00285 locHR = mDataQueue->Receive(locSample);
00286
00287 if (locHR != S_OK) {
00288
00289
00290
00291 delete inPacket;
00292 return false;
00293 } else {
00294 delete inPacket;
00295 return true;
00296 }
00297 } else {
00298
00299 throw 0;
00300 }
00301 }
00302 bool OggDemuxPacketSourcePin::acceptStampedOggPacket(StampedOggPacket* inPacket)
00303 {
00304 if (mAcceptingData) {
00305 return dispatchPacket(inPacket);
00306 } else {
00307
00308 IOggDecoder::eAcceptHeaderResult locResult;
00309 if ((mDecoderInterface != NULL) && (!mIsStreamReady)) {
00310 locResult = mDecoderInterface->showHeaderPacket(inPacket);
00311 if (locResult == IOggDecoder::AHR_ALL_HEADERS_RECEIVED) {
00312 mIsStreamReady = true;
00313 }
00314 }
00315 delete inPacket;
00316 return true;
00317 }
00318 }
00319
00320
00321 HRESULT OggDemuxPacketSourcePin::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
00322 {
00323 NewSegment(tStart, tStop, dRate);
00324
00325 if (mDataQueue != NULL) {
00326 mDataQueue->NewSegment(tStart, tStop, dRate);
00327 }
00328
00329 return S_OK;
00330 }
00331 HRESULT OggDemuxPacketSourcePin::DeliverEndOfStream(void)
00332 {
00333 if (mDataQueue != NULL) {
00334 mDataQueue->EOS();
00335 }
00336 return S_OK;
00337 }
00338
00339 HRESULT OggDemuxPacketSourcePin::DeliverEndFlush(void)
00340 {
00341 CAutoLock locPackLock(mPacketiserLock);
00342
00343 if (mDataQueue != NULL) {
00344 mDataQueue->EndFlush();
00345 }
00346
00347 mPacketiser.reset();
00348 return S_OK;
00349 }
00350
00351 HRESULT OggDemuxPacketSourcePin::DeliverBeginFlush(void)
00352 {
00353 if (mDataQueue != NULL) {
00354 mDataQueue->BeginFlush();
00355 }
00356
00357 return S_OK;
00358 }
00359
00360 bool OggDemuxPacketSourcePin::notifyStreamBaseTime(__int64 inStreamTime)
00361 {
00362 return ((OggDemuxPacketSourceFilter*)m_pFilter)->notifyStreamBaseTime(inStreamTime);
00363 }
00364 __int64 OggDemuxPacketSourcePin::getGlobalBaseTime()
00365 {
00366 return ((OggDemuxPacketSourceFilter*)m_pFilter)->getGlobalBaseTime();
00367 }