- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# Copy (2) 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_pImageGWorld(NULL)
    00101         , m_hImageDesc(NULL)
    00102         , m_cinst(NULL)
    00103 {
    00104         if(phr) *phr = S_OK;
    00105
    00106         m_fQtInitialized = false;
    00107         if(InitializeQTML(0) != 0) {if(phr) *phr = E_FAIL; return;}
    00108 //      if(EnterMovies() != 0) {TerminateQTML(); if(phr) *phr = E_FAIL; return;}
    00109         m_fQtInitialized = true;
    00110 }
    00111
    00112 CQTDec::~CQTDec()
    00113 {
    00114         if(m_cinst)
    00115                 CloseComponent(m_cinst),
    00116                 m_cinst = NULL;
    00117
    00118         if(m_hImageDesc)
    00119                 DisposeHandle((Handle)m_hImageDesc),
    00120                 m_hImageDesc = NULL;
    00121
    00122         FreeGWorld(m_pImageGWorld);
    00123
    00124         if(m_fQtInitialized)
    00125         {
    00126 //              ExitMovies();
    00127                 TerminateQTML();
    00128         }
    00129 }
    00130
    00131 //
    00132
    00133 GWorldPtr CQTDec::MakeGWorld()
    00134 {
    00135         if(!m_pOutput->IsConnected())
    00136                 return NULL;
    00137
    00138         const CMediaType& mt = m_pOutput->CurrentMediaType();
    00139         VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)mt.pbFormat;
    00140         BITMAPINFOHEADER& bih = vih->bmiHeader;
    00141
    00142         GWorldPtr pImageWorld = NULL;
    00143         Rect rect = {0, 0, (short)abs(bih.biHeight), (short)bih.biWidth};
    00144
    00145         OSType PixelFormat =
    00146                 mt.subtype == MEDIASUBTYPE_YUY2 ? kYUVSPixelFormat : // 'yuvs'
    00147                 mt.subtype == MEDIASUBTYPE_UYVY ? k2vuyPixelFormat : // '2vuy'
    00148                 mt.subtype == MEDIASUBTYPE_RGB32 ? k32BGRAPixelFormat : // 'BGRA'
    00149                 mt.subtype == MEDIASUBTYPE_RGB565 ? k16LE565PixelFormat : // 'L565'
    00150                 mt.subtype == MEDIASUBTYPE_RGB555 ? k16LE555PixelFormat : // 'L555'
    00151                 0;
    00152
    00153         if(!PixelFormat || noErr != QTNewGWorld(&pImageWorld, PixelFormat, &rect, NULL, NULL, 0))
    00154                 pImageWorld = NULL;
    00155
    00156         if(pImageWorld)
    00157         LockPixels(GetGWorldPixMap(pImageWorld));
    00158
    00159         return pImageWorld;
    00160 }
    00161
    00162 void CQTDec::FreeGWorld(GWorldPtr& pImageGWorld)
    00163 {
    00164         if(pImageGWorld)
    00165         {
    00166         UnlockPixels(GetGWorldPixMap(pImageGWorld));
    00167                 DisposeGWorld(pImageGWorld);
    00168                 pImageGWorld = NULL;
    00169         }
    00170 }
    00171
    00172 bool CQTDec::InitComponent()
    00173 {
    00174         if(m_cinst)
    00175                 CloseComponent(m_cinst),
    00176                 m_cinst = NULL;
    00177
    00178         if(m_hImageDesc)
    00179                 DisposeHandle((Handle)m_hImageDesc),
    00180                 m_hImageDesc = NULL;
    00181
    00182         if(!m_pInput->IsConnected())
    00183                 return NULL;
    00184
    00185         BITMAPINFOHEADER& bih = ((VIDEOINFOHEADER*)m_pInput->CurrentMediaType().pbFormat)->bmiHeader;
    00186
    00187         ComponentDescription cd = {decompressorComponentType, DWSWAP(bih.biCompression), 0, 0, 0};
    00188         Component c = FindNextComponent(0, &cd);
    00189         if(!c) return(false);
    00190
    00191         m_cinst = OpenComponent(c);
    00192         if(!m_cinst) return(false);
    00193
    00194         ComponentResult cres;
    00195
    00196     ImageSubCodecDecompressCapabilities icap;
    00197     memset(&icap, 0, sizeof(icap));
    00198     cres = ImageCodecInitialize(m_cinst, &icap);
    00199
    00200     CodecInfo cinfo;
    00201     memset(&cinfo, 0, sizeof(cinfo));
    00202     cres = ImageCodecGetCodecInfo(m_cinst, &cinfo);
    00203
    00204         m_hImageDesc = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription));
    00205         if(!m_hImageDesc)
    00206                 return(false);
    00207
    00208     (**m_hImageDesc).idSize = sizeof(ImageDescription);
    00209         (**m_hImageDesc).cType = DWSWAP(bih.biCompression);
    00210     (**m_hImageDesc).temporalQuality = 0;
    00211     (**m_hImageDesc).spatialQuality = codecNormalQuality;
    00212         (**m_hImageDesc).width = (short)bih.biWidth;
    00213     (**m_hImageDesc).height = (short)abs(bih.biHeight);
    00214     (**m_hImageDesc).hRes = 72 << 16;
    00215     (**m_hImageDesc).vRes = 72 << 16;
    00216     (**m_hImageDesc).frameCount = 1; // ?
    00217         (**m_hImageDesc).depth = bih.biBitCount; // should be 24 for unknown/compressed types
    00218     (**m_hImageDesc).clutID = -1;
    00219
    00220         memset(&m_cdpar, 0, sizeof(m_cdpar));
    00221     m_cdpar.imageDescription = m_hImageDesc;
    00222     m_cdpar.startLine = 0;
    00223     m_cdpar.stopLine = (**m_hImageDesc).height;
    00224     m_cdpar.frameNumber = 1;
    00225     m_cdpar.matrixFlags = 0;
    00226     m_cdpar.matrixType = 0;
    00227     m_cdpar.matrix = 0;
    00228     m_cdpar.capabilities = &m_ccap;
    00229         memset(&m_ccap, 0, sizeof(m_ccap));
    00230     m_cdpar.accuracy = codecNormalQuality;
    00231     m_cdpar.port = m_pImageGWorld;
    00232         Rect rect = {0, 0, (**m_hImageDesc).height, (**m_hImageDesc).width};
    00233         m_cdpar.srcRect = rect;
    00234     m_cdpar.transferMode = srcCopy;
    00235     m_cdpar.dstPixMap = **GetGWorldPixMap(m_pImageGWorld);
    00236
    00237     cres = ImageCodecPreDecompress(m_cinst, &m_cdpar);
    00238
    00239         return(true);
    00240 }
    00241
    00242 //
    00243
    00244 HRESULT CQTDec::BreakConnect(PIN_DIRECTION dir)
    00245 {
    00246         if(dir == PINDIR_INPUT)
    00247         {
    00248                 m_mts.RemoveAll();
    00249         }
    00250         else if(dir == PINDIR_OUTPUT)
    00251         {
    00252                 FreeGWorld(m_pImageGWorld);
    00253         }
    00254
    00255         return __super::BreakConnect(dir);
    00256 }
    00257
    00258 HRESULT CQTDec::CompleteConnect(PIN_DIRECTION dir, IPin* pReceivePin)
    00259 {
    00260         if(dir == PINDIR_INPUT)
    00261         {
    00262                 m_mts.RemoveAll();
    00263
    00264                 VIDEOINFOHEADER* vihin = (VIDEOINFOHEADER*)m_pInput->CurrentMediaType().pbFormat;
    00265                 BITMAPINFOHEADER& bihin = vihin->bmiHeader;
    00266
    00267                 CMediaType mt;
    00268                 mt.majortype = MEDIATYPE_Video;
    00269                 mt.subtype = MEDIASUBTYPE_None;
    00270                 mt.formattype = FORMAT_VideoInfo;
    00271                 mt.bFixedSizeSamples = TRUE;
    00272                 mt.bTemporalCompression = FALSE;
    00273                 mt.lSampleSize = 0;
    00274                 mt.pUnk = NULL;
    00275
    00276                 VIDEOINFOHEADER vih;
    00277                 memset(&vih, 0, sizeof(vih));
    00278                 vih.AvgTimePerFrame = vihin->AvgTimePerFrame;
    00279                 vih.rcSource = vihin->rcSource;
    00280                 vih.rcTarget = vihin->rcTarget;
    00281                 vih.dwBitRate = vihin->dwBitRate;
    00282                 vih.dwBitErrorRate = vihin->dwBitErrorRate;
    00283
    00284                 BITMAPINFOHEADER& bih = vih.bmiHeader;
    00285                 bih.biSize = sizeof(bih);
    00286                 bih.biWidth = bihin.biWidth;
    00287                 bih.biHeight = abs(bihin.biHeight);
    00288                 bih.biPlanes = 1;
    00289                 bih.biXPelsPerMeter = bih.biYPelsPerMeter = 0;
    00290                 bih.biClrUsed = bih.biClrImportant = 0;
    00291
    00292 //              if(fRGB32) // always can decompress to (?)
    00293                 {
    00294                         VIDEOINFOHEADER* vihout = (VIDEOINFOHEADER*)mt.AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
    00295                         memcpy(vihout, &vih, sizeof(vih));
    00296
    00297                         BITMAPINFOHEADER& bihout = vihout->bmiHeader;
    00298                         bihout.biBitCount = 32;
    00299                         bihout.biSizeImage = bihout.biWidth*abs(bihout.biHeight)*bihout.biBitCount>>3;
    00300
    00301                         mt.subtype = MEDIASUBTYPE_RGB32;
    00302
    00303                         ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_BITFIELDS;
    00304                         ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = -bih.biHeight;
    00305                         CorrectMediaType(&mt);
    00306                         m_mts.Add(mt);
    00307
    00308                         ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_RGB;
    00309                         ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = bih.biHeight;
    00310                         CorrectMediaType(&mt);
    00311                         m_mts.Add(mt);
    00312                 }
    00313
    00314 //              if(fRGB16) // always can decompress to (?)
    00315                 {
    00316                         VIDEOINFOHEADER* vihout = (VIDEOINFOHEADER*)mt.AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
    00317                         memcpy(vihout, &vih, sizeof(vih));
    00318
    00319                         BITMAPINFOHEADER& bihout = vihout->bmiHeader;
    00320                         bihout.biBitCount = 16;
    00321                         bihout.biSizeImage = bihout.biWidth*abs(bihout.biHeight)*bihout.biBitCount>>3;
    00322
    00323                         mt.subtype = MEDIASUBTYPE_RGB565;
    00324
    00325                         ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_BITFIELDS;
    00326                         ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = -bih.biHeight;
    00327                         CorrectMediaType(&mt);
    00328                         m_mts.Add(mt);
    00329
    00330                         ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_RGB;
    00331                         ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = bih.biHeight;
    00332                         CorrectMediaType(&mt);
    00333                         m_mts.Add(mt);
    00334
    00335                         mt.subtype = MEDIASUBTYPE_RGB555;
    00336
    00337                         ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_BITFIELDS;
    00338                         ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = -bih.biHeight;
    00339                         CorrectMediaType(&mt);
    00340                         m_mts.Add(mt);
    00341
    00342                         ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_RGB;
    00343                         ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = bih.biHeight;
    00344                         CorrectMediaType(&mt);
    00345                         m_mts.Add(mt);
    00346                 }
    00347         }
    00348         else if(dir == PINDIR_OUTPUT)
    00349         {
    00350                 FreeGWorld(m_pImageGWorld);
    00351                 m_pImageGWorld = MakeGWorld();
    00352         }
    00353
    00354         return __super::CompleteConnect(dir, pReceivePin);
    00355 }
    00356
    00357 HRESULT CQTDec::Transform(IMediaSample* pSample, IMediaSample* pOutSample)
    00358 {
    00359         HRESULT hr;
    00360
    00361         BYTE* pIn = NULL;
    00362         if(FAILED(hr = pSample->GetPointer(&pIn))) return hr;
    00363         long len = pSample->GetActualDataLength();
    00364         if(len <= 0) return S_FALSE;
    00365
    00366         BYTE* pOut = NULL;
    00367         if(FAILED(hr = pOutSample->GetPointer(&pOut))) return hr;
    00368         int size = pOutSample->GetSize();
    00369
    00370         VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)m_pOutput->CurrentMediaType().pbFormat;
    00371         BITMAPINFOHEADER& bih = vih->bmiHeader;
    00372
    00373         bool fInitialized = true;
    00374
    00375         if(m_cinst)
    00376         {
    00377                 AM_MEDIA_TYPE* pmt = NULL;
    00378                 if(S_OK == pSample->GetMediaType((AM_MEDIA_TYPE**)&pmt) && pmt)
    00379                 {
    00380                         CMediaType mt(*pmt);
    00381                         DeleteMediaType(pmt), pmt = NULL;
    00382
    00383                         if(mt != m_pInput->CurrentMediaType())
    00384                         {
    00385                                 m_pInput->SetMediaType(&mt);
    00386                                 fInitialized = InitComponent();
    00387                         }
    00388                 }
    00389         }
    00390         else
    00391         {
    00392                 fInitialized = InitComponent();
    00393         }
    00394
    00395         if(!fInitialized)
    00396                 return E_FAIL;
    00397
    00398         m_cdpar.data = (Ptr)pIn;
    00399         m_cdpar.bufferSize = len;
    00400         (**m_cdpar.imageDescription).dataSize = len;
    00401     ComponentResult cres = ImageCodecBandDecompress(m_cinst, &m_cdpar);
    00402     m_cdpar.frameNumber++;
    00403
    00404         if(cres == noErr)
    00405         {
    00406                 PixMapHandle hPixMap = GetGWorldPixMap(m_pImageGWorld);
    00407                 Ptr pPixels = GetPixBaseAddr(hPixMap);
    00408                 long theRowBytes = QTGetPixMapHandleRowBytes(hPixMap);
    00409
    00410                 DWORD pitch = bih.biWidth*bih.biBitCount>>3;
    00411
    00412                 for(int i = 0, h = abs(bih.biHeight); i < h; i++)
    00413                 {
    00414                         memcpy(pOut + i*pitch, (BYTE*)pPixels + i*theRowBytes, min(pitch, theRowBytes));
    00415                 }
    00416         }
    00417
    00418         return S_OK;
    00419 }
    00420
    00421 HRESULT CQTDec::CheckInputType(const CMediaType* mtIn)
    00422 {
    00423         if(mtIn->majortype != MEDIATYPE_Video || mtIn->formattype != FORMAT_VideoInfo)
    00424                 return VFW_E_TYPE_NOT_ACCEPTED;
    00425
    00426         VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)mtIn->pbFormat;
    00427         BITMAPINFOHEADER& bih = vih->bmiHeader;
    00428
    00429         OSErr err;
    00430         ComponentInstance ci;
    00431         if(noErr == (err = OpenADefaultComponent('imdc', DWSWAP(bih.biCompression), &ci)))
    00432         {
    00433                 err = CloseComponent(ci);
    00434                 return S_OK;
    00435         }
    00436
    00437         return VFW_E_TYPE_NOT_ACCEPTED;
    00438 }
    00439
    00440 HRESULT CQTDec::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
    00441 {
    00442         return S_OK;
    00443         // TODO
    00444         return VFW_E_TYPE_NOT_ACCEPTED;
    00445 }
    00446
    00447 HRESULT CQTDec::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
    00448 {
    00449         if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
    00450
    00451         CComPtr<IMemAllocator> pAllocatorIn;
    00452         m_pInput->GetAllocator(&pAllocatorIn);
    00453         if(!pAllocatorIn) return E_UNEXPECTED;
    00454
    00455         pAllocatorIn->GetProperties(pProperties);
    00456
    00457         VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)m_pInput->CurrentMediaType().pbFormat;
    00458         BITMAPINFOHEADER& bih = vih->bmiHeader;
    00459
    00460         pProperties->cBuffers = 1;
    00461         pProperties->cbBuffer = bih.biWidth*abs(bih.biHeight)*4; // TODO
    00462         pProperties->cbAlign = 1;
    00463         pProperties->cbPrefix = 0;
    00464
    00465         HRESULT hr;
    00466         ALLOCATOR_PROPERTIES Actual;
    00467     if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual)))
    00468                 return hr;
    00469
    00470     return(pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
    00471                 ? E_FAIL
    00472                 : NOERROR);
    00473 }
    00474
    00475 HRESULT CQTDec::GetMediaType(int iPosition, CMediaType* pmt)
    00476 {
    00477     if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
    00478
    00479         if(iPosition < 0) return E_INVALIDARG;
    00480         if(iPosition >= m_mts.GetCount()) return VFW_S_NO_MORE_ITEMS;
    00481
    00482         *pmt = m_mts[iPosition];
    00483
    00484         return S_OK;
    00485 }