- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# Copy of QTDec.cpp

    00001 #include "StdAfx.h"
    00002 #include <atlbase.h>
    00003 #include "..\..\..\DSUtil\MediaTypes.h"
    00004 #include <initguid.h>
    00005 #include "qtdec.h"
    00006
    00007 using namespace QT;
    00008
    00009 static DWORD DWSWAP(DWORD dw) {return(((dw&0xff)<<24)|((dw&0xff00)<<8)|((dw&0xff0000)>>8)|((dw&0xff000000)>>24));}
    00010
    00011 #ifdef REGISTER_FILTER
    00012
    00013 const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
    00014 {
    00015         {&MEDIATYPE_Video, &MEDIASUBTYPE_NULL},
    00016 };
    00017
    00018 const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
    00019 {
    00020         {&MEDIATYPE_Video, &MEDIASUBTYPE_NULL},
    00021 };
    00022
    00023 const AMOVIESETUP_PIN sudpPins[] =
    00024 {
    00025     { L"Input",             // Pins string name
    00026       FALSE,                // Is it rendered
    00027       FALSE,                // Is it an output
    00028       FALSE,                // Are we allowed none
    00029       FALSE,                // And allowed many
    00030       &CLSID_NULL,          // Connects to filter
    00031       NULL,                 // Connects to pin
    00032       countof(sudPinTypesIn),   // Number of types
    00033       sudPinTypesIn                     // Pin information
    00034     },
    00035     { L"Output",            // Pins string name
    00036       FALSE,                // Is it rendered
    00037       TRUE,                 // Is it an output
    00038       FALSE,                // Are we allowed none
    00039       FALSE,                // And allowed many
    00040       &CLSID_NULL,          // Connects to filter
    00041       NULL,                 // Connects to pin
    00042       countof(sudPinTypesOut),  // Number of types
    00043       sudPinTypesOut            // Pin information
    00044     }
    00045 };
    00046
    00047 const AMOVIESETUP_FILTER sudFilter =
    00048 {
    00049     &CLSID_QTDec,                       // Filter CLSID
    00050     L"QuickTime Decoder",       // String name
    00051     MERIT_DO_NOT_USE/*MERIT_NORMAL*/,                   // Filter merit
    00052     countof(sudpPins),  // Number of pins
    00053     sudpPins                // Pin information
    00054 };
    00055
    00056 CFactoryTemplate g_Templates[] =
    00057 {
    00058     { L"QuickTime Decoder"
    00059     , &CLSID_QTDec
    00060     , CQTDec::CreateInstance
    00061     , NULL
    00062     , &sudFilter }
    00063 };
    00064
    00065 int g_cTemplates = countof(g_Templates);
    00066
    00067 STDAPI DllRegisterServer()
    00068 {
    00069         return AMovieDllRegisterServer2(TRUE);
    00070 }
    00071
    00072 STDAPI DllUnregisterServer()
    00073 {
    00074         return AMovieDllRegisterServer2(FALSE);
    00075 }
    00076
    00077 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
    00078
    00079 BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
    00080 {
    00081     return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
    00082 }
    00083
    00084 //
    00085 // CQTDec
    00086 //
    00087
    00088 CUnknown* WINAPI CQTDec::CreateInstance(LPUNKNOWN lpunk, HRESULT* phr)
    00089 {
    00090     CUnknown* punk = new CQTDec(lpunk, phr);
    00091     if(punk == NULL) *phr = E_OUTOFMEMORY;
    00092         return punk;
    00093 }
    00094
    00095 #endif
    00096
    00097 CQTDec::CQTDec(LPUNKNOWN lpunk, HRESULT* phr)
    00098         : CTransformFilter(NAME("CQTDec"), lpunk, CLSID_QTDec)
    00099         , m_fQtInitialized(false)
    00100         , m_hImageDescription(NULL)
    00101         , m_pImageGWorld(NULL)
    00102 {
    00103         if(phr) *phr = S_OK;
    00104
    00105         m_fQtInitialized = false;
    00106         if(InitializeQTML(0) != 0) {if(phr) *phr = E_FAIL; return;}
    00107 //      if(EnterMovies() != 0) {TerminateQTML(); if(phr) *phr = E_FAIL; return;}
    00108         m_fQtInitialized = true;
    00109 }
    00110
    00111 CQTDec::~CQTDec()
    00112 {
    00113         FreeImageDescription(m_hImageDescription);
    00114         FreeGWorld(m_pImageGWorld);
    00115
    00116         if(m_fQtInitialized)
    00117         {
    00118 //              ExitMovies();
    00119                 TerminateQTML();
    00120         }
    00121 }
    00122
    00123 //
    00124
    00125 bool CQTDec::CanDecompress(OSType fourcc, bool& fYUY2, bool& fUYVY)
    00126 {
    00127         fYUY2 = fUYVY = false;
    00128
    00129         ComponentDescription cd = {decompressorComponentType, fourcc, 0, 0, cmpIsMissing};
    00130
    00131         if(Component decompressor = FindNextComponent(0, &cd))
    00132         {
    00133                 do
    00134                 {
    00135                         OSErr err;
    00136                         Handle cpix = NULL;
    00137                         if(noErr == (err = GetComponentPublicResource(decompressor, FOUR_CHAR_CODE('cpix'), 1, &cpix)))
    00138                         {
    00139                                 int cpixFormatCount = GetHandleSize(cpix) / sizeof(OSType);
    00140                                 for(int i = 0; i < cpixFormatCount; i++)
    00141                                 {
    00142                                         switch((*(OSType**)cpix)[i])
    00143                                         {
    00144                                         case 'yuvs': fYUY2 = true; break; // yuy2
    00145                                         case '2vuy': fUYVY = true; break; // uyvy
    00146                                         default: break;
    00147                                         }
    00148                                 }
    00149
    00150                                 DisposeHandle(cpix);
    00151                         }
    00152
    00153                         decompressor = FindNextComponent(decompressor, &cd);
    00154                 }
    00155                 while(decompressor && !(fYUY2 && fUYVY));
    00156
    00157                 return(true);
    00158         }
    00159
    00160         return(false);
    00161 }
    00162
    00163 ImageDescriptionHandle CQTDec::MakeImageDescription()
    00164 {
    00165         if(!m_pInput->IsConnected())
    00166                 return NULL;
    00167
    00168         VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)m_pInput->CurrentMediaType().pbFormat;
    00169         BITMAPINFOHEADER& bih = vih->bmiHeader;
    00170
    00171         ImageDescriptionHandle h = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription));
    00172
    00173     if(h)
    00174         {
    00175         (**h).idSize = sizeof(ImageDescription);
    00176                 (**h).cType = DWSWAP(bih.biCompression);
    00177         (**h).temporalQuality = 0;
    00178         (**h).spatialQuality = codecNormalQuality;
    00179                 (**h).width = (short)bih.biWidth;
    00180         (**h).height = (short)abs(bih.biHeight);
    00181         (**h).hRes = 72 << 16;
    00182         (**h).vRes = 72 << 16;
    00183         (**h).frameCount = 1; // ?
    00184                 (**h).depth = bih.biBitCount; // should be 24 for unknown/compressed types
    00185         (**h).clutID = -1;
    00186     }
    00187
    00188     return h;
    00189 }
    00190
    00191 GWorldPtr CQTDec::MakeGWorld()
    00192 {
    00193         if(!m_pOutput->IsConnected())
    00194                 return NULL;
    00195
    00196         const CMediaType& mt = m_pOutput->CurrentMediaType();
    00197         VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)mt.pbFormat;
    00198         BITMAPINFOHEADER& bih = vih->bmiHeader;
    00199
    00200         GWorldPtr pImageWorld = NULL;
    00201         Rect rect = {0, 0, (short)abs(bih.biHeight), (short)bih.biWidth};
    00202
    00203         OSType PixelFormat =
    00204                 mt.subtype == MEDIASUBTYPE_YUY2 ? kYUVSPixelFormat : // 'yuvs'
    00205                 mt.subtype == MEDIASUBTYPE_UYVY ? k2vuyPixelFormat : // '2vuy'
    00206                 mt.subtype == MEDIASUBTYPE_RGB32 ? k32BGRAPixelFormat : // 'BGRA'
    00207                 mt.subtype == MEDIASUBTYPE_RGB565 ? k16LE565PixelFormat : // 'L565'
    00208                 mt.subtype == MEDIASUBTYPE_RGB555 ? k16LE555PixelFormat : // 'L555'
    00209                 0;
    00210
    00211         if(!PixelFormat || noErr != QTNewGWorld(&pImageWorld, PixelFormat, &rect, NULL, NULL, 0))
    00212                 pImageWorld = NULL;
    00213
    00214         if(pImageWorld)
    00215         LockPixels(GetGWorldPixMap(pImageWorld));
    00216
    00217         return pImageWorld;
    00218 }
    00219
    00220 void CQTDec::FreeImageDescription(ImageDescriptionHandle& hImageDescription)
    00221 {
    00222         if(hImageDescription)
    00223         {
    00224                 DisposeHandle((Handle)hImageDescription);
    00225                 hImageDescription = NULL;
    00226         }
    00227 }
    00228
    00229 void CQTDec::FreeGWorld(GWorldPtr& pImageGWorld)
    00230 {
    00231         if(pImageGWorld)
    00232         {
    00233         UnlockPixels(GetGWorldPixMap(pImageGWorld));
    00234                 DisposeGWorld(pImageGWorld);
    00235                 pImageGWorld = NULL;
    00236         }
    00237 }
    00238
    00239 //
    00240
    00241 HRESULT CQTDec::BreakConnect(PIN_DIRECTION dir)
    00242 {
    00243         if(dir == PINDIR_INPUT)
    00244         {
    00245                 m_mts.RemoveAll();
    00246         }
    00247         else if(dir == PINDIR_OUTPUT)
    00248         {
    00249                 FreeImageDescription(m_hImageDescription);
    00250                 FreeGWorld(m_pImageGWorld);
    00251         }
    00252
    00253         return __super::BreakConnect(dir);
    00254 }
    00255
    00256 HRESULT CQTDec::CompleteConnect(PIN_DIRECTION dir, IPin* pReceivePin)
    00257 {
    00258         if(dir == PINDIR_INPUT)
    00259         {
    00260                 m_mts.RemoveAll();
    00261
    00262                 VIDEOINFOHEADER* vihin = (VIDEOINFOHEADER*)m_pInput->CurrentMediaType().pbFormat;
    00263                 BITMAPINFOHEADER& bihin = vihin->bmiHeader;
    00264
    00265                 bool fYUY2 = false, fUYVY = false;
    00266                 if(CanDecompress(DWSWAP(bihin.biCompression), fYUY2, fUYVY))
    00267                 {
    00268                         CMediaType mt;
    00269                         mt.majortype = MEDIATYPE_Video;
    00270                         mt.subtype = MEDIASUBTYPE_None;
    00271                         mt.formattype = FORMAT_VideoInfo;
    00272                         mt.bFixedSizeSamples = TRUE;
    00273                         mt.bTemporalCompression = FALSE;
    00274                         mt.lSampleSize = 0;
    00275                         mt.pUnk = NULL;
    00276
    00277                         VIDEOINFOHEADER vih;
    00278                         memset(&vih, 0, sizeof(vih));
    00279                         vih.AvgTimePerFrame = vihin->AvgTimePerFrame;
    00280                         vih.rcSource = vihin->rcSource;
    00281                         vih.rcTarget = vihin->rcTarget;
    00282                         vih.dwBitRate = vihin->dwBitRate;
    00283                         vih.dwBitErrorRate = vihin->dwBitErrorRate;
    00284
    00285                         BITMAPINFOHEADER& bih = vih.bmiHeader;
    00286                         bih.biSize = sizeof(bih);
    00287                         bih.biWidth = bihin.biWidth;
    00288                         bih.biHeight = abs(bihin.biHeight);
    00289                         bih.biPlanes = 1;
    00290                         bih.biXPelsPerMeter = bih.biYPelsPerMeter = 0;
    00291                         bih.biClrUsed = bih.biClrImportant = 0;
    00292 /*
    00293                         if(fYUY2 || fUYVY)
    00294                         {
    00295                                 VIDEOINFOHEADER* vihout = (VIDEOINFOHEADER*)mt.AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
    00296                                 memcpy(vihout, &vih, sizeof(vih));
    00297
    00298                                 BITMAPINFOHEADER& bihout = vihout->bmiHeader;
    00299                                 bihout.biBitCount = 16;
    00300                                 bihout.biSizeImage = bihout.biWidth*abs(bihout.biHeight)*bihout.biBitCount>>3;
    00301
    00302                                 if(fYUY2)
    00303                                 {
    00304                                         mt.subtype = MEDIASUBTYPE_YUY2;
    00305                                         bihout.biCompression = '2YUY';
    00306                                         m_mts.Add(mt);
    00307                                 }
    00308
    00309                                 if(fUYVY)
    00310                                 {
    00311                                         mt.subtype = MEDIASUBTYPE_UYVY;
    00312                                         bihout.biCompression = 'YVYU';
    00313                     m_mts.Add(mt);
    00314                                 }
    00315                         }
    00316 */
    00317 //                      if(fRGB32) // always can decompress to (?)
    00318                         {
    00319                                 VIDEOINFOHEADER* vihout = (VIDEOINFOHEADER*)mt.AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
    00320                                 memcpy(vihout, &vih, sizeof(vih));
    00321
    00322                                 BITMAPINFOHEADER& bihout = vihout->bmiHeader;
    00323                                 bihout.biBitCount = 32;
    00324                                 bihout.biSizeImage = bihout.biWidth*abs(bihout.biHeight)*bihout.biBitCount>>3;
    00325
    00326                                 mt.subtype = MEDIASUBTYPE_RGB32;
    00327
    00328                                 ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_BITFIELDS;
    00329                                 ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = -bih.biHeight;
    00330                                 CorrectMediaType(&mt);
    00331                                 m_mts.Add(mt);
    00332
    00333                                 ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_RGB;
    00334                                 ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = bih.biHeight;
    00335                                 CorrectMediaType(&mt);
    00336                                 m_mts.Add(mt);
    00337                         }
    00338
    00339 //                      if(fRGB16) // always can decompress to (?)
    00340                         {
    00341                                 VIDEOINFOHEADER* vihout = (VIDEOINFOHEADER*)mt.AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
    00342                                 memcpy(vihout, &vih, sizeof(vih));
    00343
    00344                                 BITMAPINFOHEADER& bihout = vihout->bmiHeader;
    00345                                 bihout.biBitCount = 16;
    00346                                 bihout.biSizeImage = bihout.biWidth*abs(bihout.biHeight)*bihout.biBitCount>>3;
    00347
    00348                                 mt.subtype = MEDIASUBTYPE_RGB565;
    00349
    00350                                 ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_BITFIELDS;
    00351                                 ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = -bih.biHeight;
    00352                                 CorrectMediaType(&mt);
    00353                                 m_mts.Add(mt);
    00354
    00355                                 ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_RGB;
    00356                                 ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = bih.biHeight;
    00357                                 CorrectMediaType(&mt);
    00358                                 m_mts.Add(mt);
    00359
    00360                                 mt.subtype = MEDIASUBTYPE_RGB555;
    00361
    00362                                 ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_BITFIELDS;
    00363                                 ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = -bih.biHeight;
    00364                                 CorrectMediaType(&mt);
    00365                                 m_mts.Add(mt);
    00366
    00367                                 ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_RGB;
    00368                                 ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = bih.biHeight;
    00369                                 CorrectMediaType(&mt);
    00370                                 m_mts.Add(mt);
    00371                         }
    00372                 }
    00373         }
    00374         else if(dir == PINDIR_OUTPUT)
    00375         {
    00376                 FreeGWorld(m_pImageGWorld);
    00377                 m_pImageGWorld = MakeGWorld();
    00378         }
    00379
    00380         return __super::CompleteConnect(dir, pReceivePin);
    00381 }
    00382
    00383 HRESULT CQTDec::StartStreaming()
    00384 {
    00385         FreeImageDescription(m_hImageDescription);
    00386         m_hImageDescription = MakeImageDescription();
    00387
    00388         if(!m_hImageDescription)
    00389                 return E_FAIL;
    00390 /*
    00391     Rect theSrcBounds = {0, 0};
    00392     Rect theDestBounds;
    00393     GetPortBounds((CGrafPtr)m_pImageGWorld, &theDestBounds);
    00394     theSrcBounds.right  = (*m_hImageDescription)->width;
    00395     theSrcBounds.bottom = (*m_hImageDescription)->height;
    00396
    00397     MatrixRecord rMatrix;
    00398     RectMatrix(&rMatrix, &theSrcBounds, &theDestBounds);
    00399 */
    00400     m_outSeqID = 0;
    00401
    00402         OSErr err;
    00403
    00404         DecompressorComponent decompressor = NULL;
    00405
    00406         err = FindCodec((*m_hImageDescription)->cType, anyCodec, NULL, &decompressor);
    00407
    00408         CodecInfo info;
    00409         err = GetCodecInfo(&info, (*m_hImageDescription)->cType, decompressor);
    00410
    00411     err = DecompressSequenceBeginS(
    00412                 &m_outSeqID, m_hImageDescription,
    00413                 NULL, 0,
    00414                 m_pImageGWorld, NULL,
    00415                 NULL, NULL/*&rMatrix*/, srcCopy, (RgnHandle)NULL,
    00416                 codecFlagUseImageBuffer, codecNormalQuality, anyCodec);
    00417
    00418         if(noErr != err || m_outSeqID == 0)
    00419                 return E_FAIL;
    00420
    00421         return __super::StartStreaming();
    00422 }
    00423
    00424
    00425 HRESULT CQTDec::StopStreaming()
    00426 {
    00427         if(m_outSeqID)
    00428         {
    00429         OSErr err = CDSequenceEnd(m_outSeqID);
    00430         m_outSeqID = 0;
    00431     }
    00432
    00433         FreeImageDescription(m_hImageDescription);
    00434
    00435         return __super::StopStreaming();
    00436 }
    00437
    00438 HRESULT CQTDec::Transform(IMediaSample* pSample, IMediaSample* pOutSample)
    00439 {
    00440         HRESULT hr;
    00441
    00442         BYTE* pIn = NULL;
    00443         if(FAILED(hr = pSample->GetPointer(&pIn))) return hr;
    00444         long len = pSample->GetActualDataLength();
    00445         if(len <= 0) return S_FALSE;
    00446
    00447         BYTE* pOut = NULL;
    00448         if(FAILED(hr = pOutSample->GetPointer(&pOut))) return hr;
    00449         int size = pOutSample->GetSize();
    00450
    00451         VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)m_pOutput->CurrentMediaType().pbFormat;
    00452         BITMAPINFOHEADER& bih = vih->bmiHeader;
    00453
    00454         OSErr err;
    00455
    00456         {
    00457                 AM_MEDIA_TYPE* pmt = NULL;
    00458                 if(S_OK == pSample->GetMediaType((AM_MEDIA_TYPE**)&pmt) && pmt)
    00459                 {
    00460                         CMediaType mt(*pmt);
    00461                         DeleteMediaType(pmt), pmt = NULL;
    00462
    00463                         if(mt != m_pInput->CurrentMediaType())
    00464                         {
    00465                                 StopStreaming();
    00466                                 m_pInput->SetMediaType(&mt);
    00467                                 StartStreaming();
    00468                         }
    00469                 }
    00470         }
    00471
    00472         CodecFlags inf = codecFlagNoScreenUpdate, outf = 0;
    00473
    00474         err = DecompressSequenceFrameWhen(m_outSeqID, (Ptr)pIn, len, inf, &outf, NULL, NULL);
    00475 //      if(err == noErr)
    00476         {
    00477                 PixMapHandle hPixMap = GetGWorldPixMap(m_pImageGWorld);
    00478                 Ptr pPixels = GetPixBaseAddr(hPixMap);
    00479                 long theRowBytes = QTGetPixMapHandleRowBytes(hPixMap);
    00480
    00481                 DWORD pitch = bih.biWidth*bih.biBitCount>>3;
    00482
    00483                 for(int i = 0, h = abs(bih.biHeight); i < h; i++)
    00484                 {
    00485                         memcpy(pOut + i*pitch, (BYTE*)pPixels + i*theRowBytes, min(pitch, theRowBytes));
    00486                 }
    00487         }
    00488
    00489 /*
    00490         VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)m_pOutput->CurrentMediaType().pbFormat;
    00491         BITMAPINFOHEADER& bih = vih->bmiHeader;
    00492
    00493         Rect                                            myRect = {0, 0, (short)abs(bih.biHeight), (short)bih.biWidth};
    00494 //      GraphicsImportComponent         myImporter = NULL;
    00495 //      ComponentInstance                       myComponent = NULL;
    00496         GWorldPtr                                       myImageWorld = NULL;
    00497         PixMapHandle                            myPixMap = NULL;
    00498         ImageDescriptionHandle          myDesc = NULL;
    00499         Handle                                          myHandle = NULL;
    00500         OSErr                                           myErr = noErr;
    00501
    00502         myErr = QTNewGWorld(&myImageWorld, 0, &myRect, NULL, NULL, noNewDevice|keepLocal);
    00503 //      myErr = QTNewGWorldFromPtr(&myImageWorld, k422YpCbCr8PixelFormat, &myRect, NULL, NULL, 0, pOut, bih.biWidth*bih.biBitCount>>3);
    00504         if(myErr == noErr)
    00505         {
    00506                 myPixMap = GetGWorldPixMap(myImageWorld);
    00507
    00508                 if(myDesc = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription)))
    00509                 {
    00510                         ImageDescription& id = *(ImageDescription*)*myDesc;
    00511                         memset(&id, 0, sizeof(id));
    00512                         id.idSize = sizeof(id);
    00513                         id.cType = DWSWAP(((VIDEOINFOHEADER*)m_pInput->CurrentMediaType().pbFormat)->bmiHeader.biCompression);
    00514                         id.temporalQuality = codecNormalQuality; // ?
    00515                         id.spatialQuality = codecNormalQuality; // ?
    00516                         id.width = (short)bih.biWidth;
    00517                         id.height = (short)bih.biHeight;
    00518                         id.depth = ((VIDEOINFOHEADER*)m_pInput->CurrentMediaType().pbFormat)->bmiHeader.biBitCount;
    00519                         id.dataSize = len;
    00520                         id.hRes = 0;
    00521                         id.vRes = 0;
    00522                         id.frameCount = 1;
    00523                         id.clutID = -1; // TODO
    00524
    00525                         myErr = DecompressImage((Ptr)pIn, myDesc, myPixMap, NULL, &myRect, srcCopy, NULL);
    00526
    00527                         DisposeHandle((Handle)myDesc);
    00528                 }
    00529         }
    00530
    00531         if(myImageWorld) DisposeGWorld(myImageWorld);
    00532 */
    00533 /*
    00534         // TODO
    00535         pOutSample->SetActualDataLength(0);
    00536         return S_FALSE;
    00537 */
    00538
    00539         return S_OK;
    00540 }
    00541
    00542 HRESULT CQTDec::CheckInputType(const CMediaType* mtIn)
    00543 {
    00544         if(mtIn->majortype != MEDIATYPE_Video || mtIn->formattype != FORMAT_VideoInfo)
    00545                 return VFW_E_TYPE_NOT_ACCEPTED;
    00546
    00547         VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)mtIn->pbFormat;
    00548         BITMAPINFOHEADER& bih = vih->bmiHeader;
    00549
    00550         OSErr err;
    00551         ComponentInstance ci;
    00552         if(noErr == (err = OpenADefaultComponent('imdc', DWSWAP(bih.biCompression), &ci)))
    00553         {
    00554                 err = CloseComponent(ci);
    00555                 return S_OK;
    00556         }
    00557
    00558         return VFW_E_TYPE_NOT_ACCEPTED;
    00559 }
    00560
    00561 HRESULT CQTDec::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
    00562 {
    00563         return S_OK;
    00564         // TODO
    00565         return VFW_E_TYPE_NOT_ACCEPTED;
    00566 }
    00567
    00568 HRESULT CQTDec::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
    00569 {
    00570         if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
    00571
    00572         CComPtr<IMemAllocator> pAllocatorIn;
    00573         m_pInput->GetAllocator(&pAllocatorIn);
    00574         if(!pAllocatorIn) return E_UNEXPECTED;
    00575
    00576         pAllocatorIn->GetProperties(pProperties);
    00577
    00578         VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)m_pInput->CurrentMediaType().pbFormat;
    00579         BITMAPINFOHEADER& bih = vih->bmiHeader;
    00580
    00581         pProperties->cBuffers = 1;
    00582         pProperties->cbBuffer = bih.biWidth*abs(bih.biHeight)*4; // TODO
    00583         pProperties->cbAlign = 1;
    00584         pProperties->cbPrefix = 0;
    00585
    00586         HRESULT hr;
    00587         ALLOCATOR_PROPERTIES Actual;
    00588     if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual)))
    00589                 return hr;
    00590
    00591     return(pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
    00592                 ? E_FAIL
    00593                 : NOERROR);
    00594 }
    00595
    00596 HRESULT CQTDec::GetMediaType(int iPosition, CMediaType* pmt)
    00597 {
    00598     if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
    00599
    00600         if(iPosition < 0) return E_INVALIDARG;
    00601         if(iPosition >= m_mts.GetCount()) return VFW_S_NO_MORE_ITEMS;
    00602
    00603         *pmt = m_mts[iPosition];
    00604
    00605         return S_OK;
    00606 }