예제 #1
0
/////////////////////
//
//  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;
}
예제 #2
0
//////////////////////////////////////////////////////////////////////////////
//
// 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(&params);

    if (SUCCEEDED(hr))
        hr = pNewGargle->SetAllParameters(&params);

    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;
}