TheoraDecodeInputPin.cpp

Go to the documentation of this file.
00001 //===========================================================================
00002 //Copyright (C) 2003, 2004 Zentaro Kavanagh
00003 //
00004 //Redistribution and use in source and binary forms, with or without
00005 //modification, are permitted provided that the following conditions
00006 //are met:
00007 //
00008 //- Redistributions of source code must retain the above copyright
00009 //  notice, this list of conditions and the following disclaimer.
00010 //
00011 //- Redistributions in binary form must reproduce the above copyright
00012 //  notice, this list of conditions and the following disclaimer in the
00013 //  documentation and/or other materials provided with the distribution.
00014 //
00015 //- Neither the name of Zentaro Kavanagh nor the names of contributors 
00016 //  may be used to endorse or promote products derived from this software 
00017 //  without specific prior written permission.
00018 //
00019 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020 //``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00022 //PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
00023 //CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00024 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00025 //PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00026 //PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00027 //LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00028 //NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 {
00039         //debugLog.open("G:\\logs\\theoinput.log", ios_base::out);
00040 }
00041 TheoraDecodeInputPin::~TheoraDecodeInputPin() {
00042         //debugLog.close();
00043 }
00044 
00045 STDMETHODIMP TheoraDecodeInputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv) {
00046         //debugLog<<"Querying interface"<<endl;
00047         if (riid == IID_IMediaSeeking) {
00048                 //debugLog<<"Got Seeker"<<endl;
00049                 *ppv = (IMediaSeeking*)this;
00050                 ((IUnknown*)*ppv)->AddRef();
00051                 
00052                 return NOERROR;
00053         }
00054 
00055         return CBaseInputPin::NonDelegatingQueryInterface(riid, ppv); 
00056 }
00057 
00058 HRESULT TheoraDecodeInputPin::BreakConnect() {
00059         CAutoLock locLock(m_pLock);
00060         //debugLog<<"Break conenct"<<endl;
00061         //Need a lock ??
00062         ReleaseDelegate();
00063         return CTransformInputPin::BreakConnect();
00064 }
00065 HRESULT TheoraDecodeInputPin::CompleteConnect (IPin *inReceivePin) {
00066         CAutoLock locLock(m_pLock);
00067         //debugLog<<"Complete conenct"<<endl;
00068         IMediaSeeking* locSeeker = NULL;
00069         inReceivePin->QueryInterface(IID_IMediaSeeking, (void**)&locSeeker);
00070         if (locSeeker == NULL) {
00071                 //debugLog<<"Seeker is null"<<endl;
00072         }
00073         SetDelegate(locSeeker);
00074         return CTransformInputPin::CompleteConnect(inReceivePin);
00075 }
00076 
00077 //----------------------
00078 //OLD IMPLEMENTATION
00079 //----------------------
00080 //TheoraDecodeInputPin::TheoraDecodeInputPin(AbstractVideoDecodeFilter* inFilter, CCritSec* inFilterLock, AbstractVideoDecodeOutputPin* inOutputPin, CMediaType* inAcceptMediaType)
00081 //      :       AbstractVideoDecodeInputPin(inFilter, inFilterLock, inOutputPin, NAME("TheoraDecodeInputPin"), L"Theora In", inAcceptMediaType)
00082 //      ,       mXOffset(0)
00083 //      ,       mYOffset(0)
00084 //
00085 //{
00086 //      debugLog.open("G:\\logs\\theoInputPin.log", ios_base::out);
00087 //      ConstructCodec();
00088 //}
00089 //
00090 //STDMETHODIMP TheoraDecodeInputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00091 //{
00092 //      if (riid == IID_IMediaSeeking) {
00093 //              *ppv = (IMediaSeeking*)this;
00094 //              ((IUnknown*)*ppv)->AddRef();
00095 //              return NOERROR;
00096 //      }
00097 //
00098 //      return CBaseInputPin::NonDelegatingQueryInterface(riid, ppv); 
00099 //}
00100 //bool TheoraDecodeInputPin::ConstructCodec() {
00101 //
00102 //
00103 //      mTheoraDecoder = new TheoraDecoder;
00104 //      mTheoraDecoder->initCodec();
00105 //      return true;
00106 //}
00107 //void TheoraDecodeInputPin::DestroyCodec() {
00108 //      delete mTheoraDecoder;
00109 //}
00110 //TheoraDecodeInputPin::~TheoraDecodeInputPin(void)
00111 //{
00112 //      debugLog.close();
00113 //      DestroyCodec();
00114 //      
00115 //}
00116 //
00117 //
00118 //
00119 //int TheoraDecodeInputPin::TheoraDecoded (yuv_buffer* inYUVBuffer) 
00120 //{
00121 //      DbgLog((LOG_TRACE,1,TEXT("Decoded... Sending...")));
00122 //      
00123 //      debugLog<<"TheoraDecoded... "<<endl;
00124 //      
00125 //      TheoraDecodeFilter* locFilter = reinterpret_cast<TheoraDecodeFilter*>(m_pFilter);
00126 //      //
00127 //      if (!mBegun) {
00128 //      
00129 //      
00130 //      
00131 //              mBegun = true;
00132 //              
00133 //              //How many UNITS does one frame take.
00134 //              mFrameDuration = (UNITS * locFilter->mTheoraFormatInfo->frameRateDenominator) / (locFilter->mTheoraFormatInfo->frameRateNumerator);
00135 //              mFrameSize = (mHeight * mWidth * 3) / 2;
00136 //              mFrameCount = 0;
00137 //      }
00138 //
00139 //
00140 //
00141 //      ////FIX::: Most of this will be obselete... the demux does it all.
00142 //      //
00143 //
00144 //      ////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
00145 //
00146 //      ////Make the start timestamp
00147 //      ////FIX:::Abstract this calculation
00148 //      DbgLog((LOG_TRACE,1,TEXT("Frame Count = %d"), mFrameCount));
00149 //      //REFERENCE_TIME locFrameStart = CurrentStartTime() + (mFrameCount * mFrameDuration);
00150 //
00151 //      //Timestamp hacks start here...
00152 //      unsigned long locMod = (unsigned long)pow(2, locFilter->mTheoraFormatInfo->maxKeyframeInterval);
00153 //      DbgLog((LOG_TRACE,1,TEXT("locSeenGranPos = %d"), mLastSeenStartGranPos));
00154 //      DbgLog((LOG_TRACE,1,TEXT("locMod = %d"), locMod));
00155 //      unsigned long locInterFrameNo = (mLastSeenStartGranPos) % locMod;
00156 //      DbgLog((LOG_TRACE,1,TEXT("InterFrameNo = %d"), locInterFrameNo));
00157 //      LONGLONG locAbsFramePos = ((mLastSeenStartGranPos >> locFilter->mTheoraFormatInfo->maxKeyframeInterval)) + locInterFrameNo;
00158 //      DbgLog((LOG_TRACE,1,TEXT("AbsFrameNo = %d"), locAbsFramePos));
00159 //      DbgLog((LOG_TRACE,1,TEXT("mSeekTimeBase = %d"), mSeekTimeBase));
00160 //      REFERENCE_TIME locTimeBase = (locAbsFramePos * mFrameDuration) - mSeekTimeBase;
00161 //      DbgLog((LOG_TRACE,1,TEXT("locTimeBase = %d"), locTimeBase));
00162 //      //
00163 //      //
00164 //
00165 //      REFERENCE_TIME locFrameStart = locTimeBase + (mFrameCount * mFrameDuration);
00166 //      //Increment the frame counter
00167 //      mFrameCount++;
00168 //      
00169 //      //Make the end frame counter
00170 //      //REFERENCE_TIME locFrameEnd = CurrentStartTime() + (mFrameCount * mFrameDuration);
00171 //      REFERENCE_TIME locFrameEnd = locTimeBase + (mFrameCount * mFrameDuration);
00172 //
00173 //      DbgLog((LOG_TRACE,1,TEXT("Frame Runs From %d"), locFrameStart));
00174 //      DbgLog((LOG_TRACE,1,TEXT("Frame Runs To %d"), locFrameEnd));
00175 //
00176 //      IMediaSample* locSample = NULL;
00177 //      debugLog<<"Sample times = "<<locFrameStart<<" to "<<locFrameEnd<<endl;
00178 //      DWORD locFlags = 0;//AM_GBF_PREVFRAMESKIPPED | AM_GBF_NOTASYNCPOINT;
00179 //
00180 //      FILTER_STATE locFS;
00181 //      mParentFilter->GetState(0, &locFS);
00182 //      debugLog<<"State Before = "<<locFS<<endl;
00183 //      HRESULT locHR = mOutputPin->GetDeliveryBuffer(&locSample, &locFrameStart, &locFrameEnd, locFlags);
00184 //      mParentFilter->GetState(0, &locFS);
00185 //      debugLog<<"State After = "<<locFS<<endl;
00186 //      if (locHR != S_OK) {
00187 //              debugLog<<"Get DeliveryBuffer FAILED with "<<locHR<<endl;
00188 //              debugLog<<"locSample is "<<(unsigned long)locSample<<endl;
00189 //              //We get here when the application goes into stop mode usually.
00190 //
00191 //              switch (locHR) {
00192 //                      case VFW_E_SIZENOTSET:
00193 //                              debugLog<<"SIZE NOT SET"<<endl;
00194 //                              break;
00195 //                      case VFW_E_NOT_COMMITTED:
00196 //                              debugLog<<"NOT COMMITTED"<<endl;
00197 //                              break;
00198 //                      case VFW_E_TIMEOUT:
00199 //                              debugLog<<"TIMEOUT"<<endl;
00200 //                              break;
00201 //                      case VFW_E_STATE_CHANGED:
00202 //                              debugLog<<"STATE CHANGED"<<endl;
00203 //                              return S_OK;
00204 //                      default:
00205 //                              debugLog<<"SOMETHING ELSE !!!"<<endl;
00206 //                              break;
00207 //              }
00208 //              return locHR;
00209 //      }       
00210 //      
00211 //      debugLog<<"GetDeliveryBuffer &** SUCCEEDED **"<<endl;
00212 //
00213 //      //Debuggin code
00214 //      AM_MEDIA_TYPE* locMediaType = NULL;
00215 //      locSample->GetMediaType(&locMediaType);
00216 //      if (locMediaType == NULL) {
00217 //              debugLog<<"No dynamic change..."<<endl;
00218 //      } else {
00219 //              debugLog<<"Attempting dynamic change..."<<endl;
00220 //              if (locMediaType->majortype == MEDIATYPE_Video) {
00221 //                      debugLog<<"Still MEDIATYPE_Video"<<endl;
00222 //              }
00223 //
00224 //              if (locMediaType->subtype == MEDIASUBTYPE_YV12) {
00225 //                      debugLog<<"Still MEDIASUBTYPE_YV12"<<endl;
00226 //              }
00227 //
00228 //              if (locMediaType->formattype == FORMAT_VideoInfo) {
00229 //                      debugLog<<"Still FORMAT_VideoInfo"<<endl;
00230 //                      VIDEOINFOHEADER* locVF = (VIDEOINFOHEADER*)locMediaType->pbFormat;
00231 //                      debugLog<<"Size = "<<locVF->bmiHeader.biSizeImage<<endl;
00232 //                      debugLog<<"Dim   = "<<locVF->bmiHeader.biWidth<<" x " <<locVF->bmiHeader.biHeight<<endl;
00233 //              }
00234 //
00235 //              debugLog<<"Major  : "<<DSStringer::GUID2String(&locMediaType->majortype);
00236 //              debugLog<<"Minor  : "<<DSStringer::GUID2String(&locMediaType->subtype);
00237 //              debugLog<<"Format : "<<DSStringer::GUID2String(&locMediaType->formattype);
00238 //              debugLog<<"Form Sz: "<<locMediaType->cbFormat;
00239 //
00240 //
00241 //      }
00242 //      //
00243 //
00244 //      ////Create pointers for the samples buffer to be assigned to
00245 //      BYTE* locBuffer = NULL;
00246 //      
00247 //      //
00248 //      ////Make our pointers set to point to the samples buffer
00249 //      locSample->GetPointer(&locBuffer);
00250 //      
00251 //
00252 //
00253 //      //Fill the buffer with yuv data...
00254 //      //      
00255 //
00256 //
00257 //
00258 //      //Set up the pointers
00259 //      unsigned char* locDestUptoPtr = locBuffer;
00260 //      char* locSourceUptoPtr = inYUVBuffer->y;
00261 //
00262 //      //
00263 //      //Y DATA
00264 //      //
00265 //
00266 //      //NEW WAY with offsets Y Data
00267 //      long locTopPad = inYUVBuffer->y_height - mHeight - mYOffset;
00268 //      ASSERT(locTopPad >= 0);
00269 //      if (locTopPad < 0) {
00270 //              locTopPad = 0;
00271 //      }
00272 //
00273 //      //Skip the top padding
00274 //      locSourceUptoPtr += (locTopPad * inYUVBuffer->y_stride);
00275 //
00276 //      for (long line = 0; line < mHeight; line++) {
00277 //              memcpy((void*)(locDestUptoPtr), (const void*)(locSourceUptoPtr + mXOffset), mWidth);
00278 //              locSourceUptoPtr += inYUVBuffer->y_stride;
00279 //              locDestUptoPtr += mWidth;
00280 //      }
00281 //
00282 //      locSourceUptoPtr += (mYOffset * inYUVBuffer->y_stride);
00283 //
00284 //      //Source advances by (y_height * y_stride)
00285 //      //Dest advances by (mHeight * mWidth)
00286 //
00287 //      //
00288 //      //V DATA
00289 //      //
00290 //
00291 //      //Half the padding for uv planes... is this correct ? 
00292 //      locTopPad = locTopPad /2;
00293 //      
00294 //      locSourceUptoPtr = inYUVBuffer->v;
00295 //
00296 //      //Skip the top padding
00297 //      locSourceUptoPtr += (locTopPad * inYUVBuffer->y_stride);
00298 //
00299 //      for (long line = 0; line < mHeight / 2; line++) {
00300 //              memcpy((void*)(locDestUptoPtr), (const void*)(locSourceUptoPtr + (mXOffset / 2)), mWidth / 2);
00301 //              locSourceUptoPtr += inYUVBuffer->uv_stride;
00302 //              locDestUptoPtr += (mWidth / 2);
00303 //      }
00304 //      locSourceUptoPtr += ((mYOffset/2) * inYUVBuffer->uv_stride);
00305 //
00306 //      //Source advances by (locTopPad + mYOffset/2 + mHeight /2) * uv_stride
00307 //      //where locTopPad for uv = (inYUVBuffer->y_height - mHeight - mYOffset) / 2
00308 //      //                                              =       (inYUVBuffer->yheight/2 - mHeight/2 - mYOffset/2)
00309 //      // so source advances by (y_height/2) * uv_stride
00310 //      //Dest advances by (mHeight * mWidth) /4
00311 //
00312 //
00313 //      //
00314 //      //U DATA
00315 //      //
00316 //
00317 //      locSourceUptoPtr = inYUVBuffer->u;
00318 //
00319 //      //Skip the top padding
00320 //      locSourceUptoPtr += (locTopPad * inYUVBuffer->y_stride);
00321 //
00322 //      for (long line = 0; line < mHeight / 2; line++) {
00323 //              memcpy((void*)(locDestUptoPtr), (const void*)(locSourceUptoPtr + (mXOffset / 2)), mWidth / 2);
00324 //              locSourceUptoPtr += inYUVBuffer->uv_stride;
00325 //              locDestUptoPtr += (mWidth / 2);
00326 //      }
00327 //      locSourceUptoPtr += ((mYOffset/2) * inYUVBuffer->uv_stride);
00328 //
00329 //
00330 //      ////Y Data.
00331 //      //for ( long line = 0; line < inYUVBuffer->y_height; line++) {
00332 //      //      memcpy((void*)locBuffer, (const void*)(inYUVBuffer->y + (inYUVBuffer->y_stride * (line))), inYUVBuffer->y_width);
00333 //      //      locBuffer += inYUVBuffer->y_width;
00334 //
00335 //      //      if (mWidth > inYUVBuffer->y_width) {
00336 //      //              memset((void*)locBuffer, 0, mWidth - inYUVBuffer->y_width);
00337 //      //      }
00338 //      //      locBuffer += mWidth - inYUVBuffer->y_width;
00339 //      //}
00340 //
00341 //      ////Pad height...
00342 //      //for ( long line = 0; line < mHeight - inYUVBuffer->y_height; line++) {
00343 //      //      memset((void*)locBuffer, 0, mWidth);
00344 //      //      locBuffer += mWidth;
00345 //      //}
00346 //
00347 //      ////V Data
00348 //      //for ( long line = 0; line < inYUVBuffer->uv_height; line++) {
00349 //      //      memcpy((void*)locBuffer, (const void*)(inYUVBuffer->v + (inYUVBuffer->uv_stride * (line))), inYUVBuffer->uv_width);
00350 //      //      locBuffer += inYUVBuffer->uv_width;
00351 //
00352 //      //      if (mWidth/2 > inYUVBuffer->uv_width) {
00353 //      //              memset((void*)locBuffer, 0, (mWidth/2) - inYUVBuffer->uv_width);
00354 //      //      }
00355 //      //      locBuffer += (mWidth/2) - inYUVBuffer->uv_width;
00356 //      //}
00357 //
00358 //      ////Pad height...
00359 //      //for ( long line = 0; line < (mHeight/2) - inYUVBuffer->uv_height; line++) {
00360 //      //      memset((void*)locBuffer, 0, mWidth/2);
00361 //      //      locBuffer += mWidth/2;
00362 //      //}
00363 //
00364 //      ////U Data
00365 //      //for (long line = 0; line < inYUVBuffer->uv_height; line++) {
00366 //      //      memcpy((void*)locBuffer, (const void*)(inYUVBuffer->u + (inYUVBuffer->uv_stride * (line))), inYUVBuffer->uv_width);
00367 //      //      locBuffer += inYUVBuffer->uv_width;
00368 //
00369 //      //      if (mWidth/2 > inYUVBuffer->uv_width) {
00370 //      //              memset((void*)locBuffer, 0, (mWidth/2) - inYUVBuffer->uv_width);
00371 //      //      }
00372 //      //      locBuffer += (mWidth/2) - inYUVBuffer->uv_width;
00373 //      //}
00374 //
00375 //      ////Pad height...
00376 //      //for ( long line = 0; line < (mHeight/2) - inYUVBuffer->uv_height; line++) {
00377 //      //      memset((void*)locBuffer, 0, mWidth/2);
00378 //      //      locBuffer += mWidth/2;
00379 //      //}
00380 //
00381 //
00382 //
00383 //
00384 //
00385 //      //Set the sample parameters.
00386 //      SetSampleParams(locSample, mFrameSize, &locFrameStart, &locFrameEnd);
00387 //
00388 //      {
00389 //
00390 //              //Add a reerence to the sample so it isn't deleted in the queue.
00391 //              //locSample->AddRef();
00392 //              HRESULT locHR = mOutputPin->mDataQueue->Receive(locSample);                                             //->DownstreamFilter()->Receive(locSample);
00393 //              if (locHR != S_OK) {
00394 //                      debugLog<<"Data Q rejects sample... with "<<locHR<<endl;
00395 //                      return -1;
00396 //
00397 //              }
00398 //      }
00399 //
00400 //      
00401 //      return 0;
00402 //
00403 //
00404 //}
00405 //
00406 //
00407 //
00408 //long TheoraDecodeInputPin::decodeData(BYTE* inBuf, long inNumBytes, LONGLONG inStart, LONGLONG inEnd) 
00409 //{
00410 //      DbgLog((LOG_TRACE,1,TEXT("decodeData")));
00411 //                                                                                                                                      //Not truncated or continued... it's a full packet
00412 //      StampedOggPacket* locPacket = new StampedOggPacket(inBuf, inNumBytes, false, false, inStart, inEnd, StampedOggPacket::OGG_END_ONLY);
00413 //      yuv_buffer* locYUV = mTheoraDecoder->decodeTheora(locPacket);
00414 //      if (locYUV != NULL) {
00415 //              if (TheoraDecoded(locYUV) != 0) {
00416 //                      return -1;
00417 //              }
00418 //      }
00419 //
00420 //      return 0;
00421 //}
00422 //
00423 //
00424 //
00425 //HRESULT TheoraDecodeInputPin::SetMediaType(const CMediaType* inMediaType) {
00426 //
00427 //      if (inMediaType->subtype == MEDIASUBTYPE_Theora) {
00428 //              ((TheoraDecodeFilter*)mParentFilter)->setTheoraFormat((sTheoraFormatBlock*)inMediaType->pbFormat);
00429 //              mParentFilter->mVideoFormat = AbstractVideoDecodeFilter::THEORA;
00430 //              //Set some other stuff here too...
00431 //              mXOffset = ((sTheoraFormatBlock*)inMediaType->pbFormat)->xOffset;
00432 //              mYOffset = ((sTheoraFormatBlock*)inMediaType->pbFormat)->yOffset;
00433 //
00434 //      } else {
00435 //              //Failed... should never be here !
00436 //              throw 0;
00437 //      }
00438 //      return CBaseInputPin::SetMediaType(inMediaType);
00439 //}
00440 //

Generated on Tue Feb 15 14:54:16 2005 for oggdsf by  doxygen 1.3.9