////////////////////////////////////////////////////////////////////////////// // // CGargle::Clone // HRESULT CGargle::Clone(IMediaObjectInPlace **ppCloned) { if (!ppCloned) return E_POINTER; HRESULT hr = S_OK; CGargle * pNewGargle = new CComObject<CGargle>; if( !pNewGargle ) hr = E_OUTOFMEMORY; hr = pNewGargle->Init(); IMediaObject * pCloned = NULL; if( SUCCEEDED( hr ) ) { IUnknown *pUnk; hr = pNewGargle->QueryInterface( IID_IUnknown, (void **) &pUnk ); if( SUCCEEDED( hr ) ) { hr = pUnk->QueryInterface( IID_IMediaObject, (void **) &pCloned ); pUnk->Release(); } } else { return hr; } // // Copy parameter control information // if (SUCCEEDED(hr)) hr = pNewGargle->CopyParamsFromSource((CParamsManager *) this); // Copy current parameter values GargleFX params; if (SUCCEEDED(hr)) hr = GetAllParameters(¶ms); if (SUCCEEDED(hr)) hr = pNewGargle->SetAllParameters(¶ms); if (SUCCEEDED(hr)) { // Copy the input and output types DMO_MEDIA_TYPE mt; DWORD cInputStreams = 0; DWORD cOutputStreams = 0; GetStreamCount(&cInputStreams, &cOutputStreams); for (DWORD i = 0; i < cInputStreams && SUCCEEDED(hr); ++i) { hr = GetInputCurrentType(i, &mt); if (hr == DMO_E_TYPE_NOT_SET) { hr = S_OK; // great, don't need to set the cloned DMO } else if (SUCCEEDED(hr)) { hr = pCloned->SetInputType(i, &mt, 0); MoFreeMediaType( &mt ); } } for (i = 0; i < cOutputStreams && SUCCEEDED(hr); ++i) { hr = GetOutputCurrentType(i, &mt); if (hr == DMO_E_TYPE_NOT_SET) { hr = S_OK; // great, don't need to set the cloned DMO } else if (SUCCEEDED(hr)) { hr = pCloned->SetOutputType(i, &mt, 0); MoFreeMediaType( &mt ); } } if (SUCCEEDED(hr)) hr = pCloned->QueryInterface(IID_IMediaObjectInPlace, (void**)ppCloned); // Release the object's original ref. If clone succeeded (made it through QI) then returned pointer // has one ref. If we failed, refs drop to zero, freeing the object. pCloned->Release(); } return hr; }
///////////////////// // // IMediaObjectInPlace::Clone // // The Clone method creates a copy of the DMO in its current state. // // Parameters // // ppMediaObject // [out] Address of a pointer to receive the new DMO's // IMediaObjectInPlace interface. // // Return Value // Returns S_OK if successful. Otherwise, returns an HRESULT value // indicating the cause of the error. // // If the method succeeds, the IMediaObjectInPlace interface that it returns // has an outstanding reference count. Be sure to release the interface when // you are finished using it. // HRESULT CHXAudioDeviceHookBase::Clone(IMediaObjectInPlace **ppMediaObject) { // Check the input pointer if (!ppMediaObject) { return E_POINTER; } // This will be cleaned up when client releases the newly created object // or if there's some error along the way CHXAudioDeviceHookBase * pNewHXAudioDeviceHook = new CComObject<CHXAudioDeviceHookBase>; if( !pNewHXAudioDeviceHook ) { return E_OUTOFMEMORY; } HRESULT hr = S_OK; hr = pNewHXAudioDeviceHook->UpdateStatesInternal(); IMediaObject * pCloned = NULL; if( SUCCEEDED( hr ) ) { IUnknown *pUnk; hr = pNewHXAudioDeviceHook->QueryInterface( IID_IUnknown, (void **) &pUnk ); if( SUCCEEDED( hr ) ) { hr = pUnk->QueryInterface( IID_IMediaObject, (void **) &pCloned ); HX_RELEASE(pUnk); } } // Copy the input and output types if (SUCCEEDED(hr)) { DMO_MEDIA_TYPE mt; DWORD cInputStreams = 0; DWORD cOutputStreams = 0; GetStreamCount(&cInputStreams, &cOutputStreams); for (DWORD i = 0; i < cInputStreams && SUCCEEDED(hr); ++i) { hr = GetInputCurrentType(i, &mt); if (hr == DMO_E_TYPE_NOT_SET) { hr = S_OK; // great, don't need to set the cloned DMO } else if (SUCCEEDED(hr)) { hr = pCloned->SetInputType(i, &mt, 0); MoFreeMediaType( &mt ); } } for (DWORD i = 0; i < cOutputStreams && SUCCEEDED(hr); ++i) { hr = GetOutputCurrentType(i, &mt); if (hr == DMO_E_TYPE_NOT_SET) { hr = S_OK; // great, don't need to set the cloned DMO } else if (SUCCEEDED(hr)) { hr = pCloned->SetOutputType(i, &mt, 0); MoFreeMediaType( &mt ); } } if (SUCCEEDED(hr)) { hr = pCloned->QueryInterface(IID_IMediaObjectInPlace, (void**)ppMediaObject); } // Release the object's original ref. If clone succeeded (made it through QI) then returned pointer // has one ref. If we failed, refs drop to zero, freeing the object. HX_RELEASE(pCloned); } // Something went wrong, clean up for client if (FAILED(hr)) { delete pNewHXAudioDeviceHook; } return hr; }
void dmo_GetOutputType_decoder_inset_(REFGUID clsidEnc, REFGUID clsidDec, REFGUID guidRaw, const vector<GUID> &expected) { HRESULT hr; IMediaObject *pObj; vector<GUID> outTypes; DMO_MEDIA_TYPE mt; VIDEOINFOHEADER *pvih; DWORD fccIn = DirectShowFormatToVCMFormat(guidRaw); hr = CoCreateInstance(clsidEnc, NULL, CLSCTX_INPROC_SERVER, IID_IMediaObject, (LPVOID*)&pObj); BOOST_REQUIRE(hr == S_OK); BOOST_REQUIRE(pObj != NULL); memset(&mt, 0, sizeof(mt)); MoInitMediaType(&mt, sizeof(VIDEOINFOHEADER)); pvih = (VIDEOINFOHEADER*)mt.pbFormat; memset(pvih, 0, sizeof(VIDEOINFOHEADER)); mt.majortype = MEDIATYPE_Video; mt.subtype = guidRaw; mt.bFixedSizeSamples = TRUE; mt.bTemporalCompression = FALSE; mt.lSampleSize = 10000000; /* XXX */ mt.formattype = FORMAT_VideoInfo; pvih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pvih->bmiHeader.biWidth = TEST_WIDTH; pvih->bmiHeader.biHeight = TEST_HEIGHT; pvih->bmiHeader.biPlanes = 1; pvih->bmiHeader.biBitCount = FCC2BitCount(fccIn); pvih->bmiHeader.biCompression = FCC2Compression(fccIn); pvih->bmiHeader.biSizeImage = 10000000; /* XXX */ hr = pObj->SetInputType(0, &mt, 0); BOOST_REQUIRE(hr == S_OK); MoFreeMediaType(&mt); hr = pObj->GetOutputType(0, 0, &mt); BOOST_REQUIRE(hr == S_OK); pObj->Release(); hr = CoCreateInstance(clsidDec, NULL, CLSCTX_INPROC_SERVER, IID_IMediaObject, (LPVOID*)&pObj); BOOST_REQUIRE(hr == S_OK); BOOST_REQUIRE(pObj != NULL); hr = pObj->SetInputType(0, &mt, 0); BOOST_REQUIRE(hr == S_OK); for (DWORD idx = 0; (hr = pObj->GetOutputType(0, idx, &mt)) == S_OK; ++idx) { BOOST_CHECK(mt.majortype == MEDIATYPE_Video); BOOST_CHECK(mt.bFixedSizeSamples == TRUE); BOOST_CHECK(mt.bTemporalCompression == FALSE); BOOST_CHECK(mt.formattype == FORMAT_VideoInfo); DWORD fccOut = DirectShowFormatToVCMFormat(mt.subtype); pvih = (VIDEOINFOHEADER*)mt.pbFormat; BOOST_CHECK(pvih->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)); BOOST_CHECK(pvih->bmiHeader.biWidth == TEST_WIDTH); BOOST_CHECK(pvih->bmiHeader.biHeight == TEST_HEIGHT); BOOST_CHECK(pvih->bmiHeader.biPlanes == 1); BOOST_CHECK(pvih->bmiHeader.biBitCount == FCC2BitCount(fccOut)); BOOST_CHECK(pvih->bmiHeader.biCompression == FCC2Compression(fccOut)); outTypes.push_back(mt.subtype); MoFreeMediaType(&mt); } BOOST_CHECK(hr == DMO_E_NO_MORE_ITEMS); BOOST_CHECK_EQUAL(outTypes, expected); pObj->Release(); }