예제 #1
0
HRESULT CDelay::InternalGetInputType(DWORD dwInputStreamIndex, DWORD dwTypeIndex, 
                                          DMO_MEDIA_TYPE *pmt)
{
    if (dwTypeIndex != 0)
    {
        return DMO_E_NO_MORE_ITEMS;
    }

    // if pmt is NULL, we just return S_OK if the type index is in range
    if (pmt == NULL)
    {
        return S_OK;
    }

    if (OutputTypeSet(0))   // If the input type is set, we prefer that one
    {
        
        return MoCopyMediaType(pmt, OutputType(0));
    }

    else {
    // if output type is not set, propose something we like
        return GetPcmType(pmt);
    }
}
예제 #2
0
/////////////////////////////////
//
//  IMediaObjectImpl::InternalGetInputType
//
//  *** Called by GetInputType, description below ***
//
//  The GetInputType method retrieves a preferred media type for a specified
//  input stream.
//
//  Parameters
//
//      dwInputStreamIndex
//          Zero-based index of an input stream on the DMO.
//
//      dwTypeIndex
//          Zero-based index on the set of acceptable media types.
//
//      pmt
//          [out] Pointer to a DMO_MEDIA_TYPE structure allocated by the caller.
//          The method fills the structure with the media type. The format block
//          might be NULL, in which case the format type GUID is GUID_NULL.
//
//  Return Value
//      S_OK Success
//      DMO_E_INVALIDSTREAMINDEX Invalid stream index
//      DMO_E_NO_MORE_ITEMS Type index is out of range
//      E_OUTOFMEMORY Insufficient memory
//      E_POINTER NULL pointer argument
//
//  Call this method to enumerate an input stream's preferred media types. The
//  DMO assigns each media type an index value in order of preference. The most
//  preferred type has an index of zero. To enumerate all the types, make
//  successive calls while incrementing the type index until the method returns
//  DMO_E_NO_MORE_ITEMS.
//
//  If the method succeeds, call MoFreeMediaType to free the format block.
//
//  To set the media type, call the SetInputType method. Setting the media type
//  on one stream can change another stream's preferred types. In fact, a
//  stream might not have a preferred type until the type is set on another
//  stream. For example, a decoder might not have a preferred output type until
//  the input type is set. However, the DMO is not required to update its
//  preferred types dynamically in this fashion. Thus, the types returned by
//  this method are not guaranteed to be valid; they might fail when used in the
//  SetInputType method. Conversely, the DMO is not guaranteed to enumerate every
//  media type that it supports. To test whether a particular media type is
//  acceptable, call SetInputType with the DMO_SET_TYPEF_TEST_ONLY flag.
//
HRESULT CHXAudioDeviceHookBase::InternalGetInputType(DWORD dwInputStreamIndex, DWORD dwTypeIndex, DMO_MEDIA_TYPE *pmt)
{
    // This function resembles InternalGetOutputType() since the input and output types must
    // be consistent for DirectSound

    HRESULT hr = S_OK;

    if (dwTypeIndex > 0)
    {
        return DMO_E_NO_MORE_ITEMS;
    }

    // If pmt is NULL, and the type index is in range, we return S_OK
    if (pmt == NULL)
    {
        return S_OK;
    }

    // If the output type is set, we prefer to use that one
    if (OutputTypeSet(0))
    {
        return MoCopyMediaType(pmt, OutputType(0));
    }

    hr = MoInitMediaType(pmt, sizeof(WAVEFORMATEX));

    if (SUCCEEDED(hr))
    {
        pmt->majortype  = MEDIATYPE_Audio;
        pmt->subtype    = MEDIASUBTYPE_PCM;         // We take PCM format!
        pmt->formattype = FORMAT_None;
    }

    return hr;
}
예제 #3
0
STDMETHODIMP CDelay::Process(ULONG ulSize, BYTE *pData, REFERENCE_TIME refTimeStart, DWORD dwFlags)
{
    if (dwFlags &= ~DMO_INPLACE_ZERO)
        return E_INVALIDARG;

    if (!pData) 
    {
        return E_POINTER;
    }


	ATLTRACE2(atlTraceGeneral, 3, "Process: %d bytes. Time stamp: %f\n", 
		ulSize, RefTime2Double(refTimeStart));



    LockIt lock(this);
    
    if (!InputTypeSet(0) || !OutputTypeSet(0)) 
    {
        return DMO_E_TYPE_NOT_SET;
    }
    
    //  Make sure all streams have media types set and resources are allocated
    HRESULT hr = AllocateStreamingResources();
    
	if (SUCCEEDED(hr))
		hr = DoProcessOutput(pData, pData, ulSize / m_pWave->nBlockAlign);

	return hr;

    // If this DMO supported an effect tail, it would return S_FALSE until 
    // the tail was processed. See IMediaObjectInPlace::Process documentation.
}
예제 #4
0
HRESULT CDelay::InternalGetOutputSizeInfo(DWORD dwOutputStreamIndex, DWORD *pcbSize,
                                               DWORD *pcbAlignment)
{
     // IMediaObjectImpl validates this for us... 
    _ASSERTE(OutputTypeSet(dwOutputStreamIndex));

    // And we expect only PCM audio types.
   _ASSERTE(OutputType(dwOutputStreamIndex)->formattype == FORMAT_WaveFormatEx);
    
    WAVEFORMATEX *pWave = (WAVEFORMATEX*)OutputType(dwOutputStreamIndex)->pbFormat;
    
    *pcbSize = pWave->nBlockAlign;
    *pcbAlignment = 1;
    
    return S_OK;  
}
예제 #5
0
STDMETHODIMP CDelay::Clone(IMediaObjectInPlace **ppMediaObject)
{
    HRESULT hr;


    if (!ppMediaObject)
    {
        return E_POINTER;
    }

    *ppMediaObject = NULL;

    // Make a new one
    CDelay *pTemp = new CComObject<CDelay>;

    if (!pTemp)
    {
        return E_OUTOFMEMORY;
    }
    
    // Set the media types
    CComQIPtr<IMediaObject, &IID_IMediaObject> pMediaObj(pTemp);
    _ASSERTE(pMediaObj != NULL);

    if (InputTypeSet(0))
    {
        hr = pMediaObj->SetInputType(0, InputType(0), 0);
        if (FAILED(hr))
        {
            return hr;
        }
    }

    if (OutputTypeSet(0))
    {
        hr = pMediaObj->SetOutputType(0, OutputType(0), 0);
        if (FAILED(hr))
        {
            return hr;
        }
    }

    // Everything is OK, return the AddRef'd pointer.
    return pTemp->QueryInterface(IID_IMediaObjectInPlace, (void**)ppMediaObject);
}
예제 #6
0
HRESULT CDelay::InternalCheckOutputType(DWORD dwOutputStreamIndex, const DMO_MEDIA_TYPE *pmt)
{
    // If our output type is already set, reject format changes
    if (OutputTypeSet(dwOutputStreamIndex) && !TypesMatch(pmt, OutputType(dwOutputStreamIndex)))
    {
        return DMO_E_INVALIDTYPE;
    }
    
    // If our input type is already set, the output type must match
    else if (InputTypeSet(dwOutputStreamIndex) && !TypesMatch(pmt, InputType(dwOutputStreamIndex)))
    {
        return DMO_E_INVALIDTYPE;
    }
    
    // If no types are set yet, validate the format 
    else 
    {
        return CheckPcmFormat(pmt);
    }
    
}
예제 #7
0
////////////////////////////////////
//
// IMediaObjectImpl::InternalCheckInputType
//
// Queries whether an input stream can accept a given media type.
// The derived class must declare and implement this method.
//
//  Parameters
//
//      dwInputStreamIndex
//          Index of an input stream.
//
//      pmt
//          Pointer to a DMO_MEDIA_TYPE structure that describes the media type.
//
//  Return Value
//
//       Returns S_OK if the media type is valid, or DMO_E_INVALIDTYPE otherwise.
//
//  Note:
//
//  Called by IMediaObject::SetInputType
//
HRESULT CHXAudioDeviceHookBase::InternalCheckInputType(DWORD dwInputStreamIndex, const DMO_MEDIA_TYPE *pmt)
{
    WAVEFORMATEX* pWave = (WAVEFORMATEX*)pmt->pbFormat;

    HRESULT hr = S_OK;

    // Check that we're PCM or float
    if ((NULL                       == pmt) ||
        (MEDIATYPE_Audio            != pmt->majortype) ||
        (MEDIASUBTYPE_PCM           != pmt->subtype) ||
        (FORMAT_WaveFormatEx        != pmt->formattype &&
         FORMAT_None                != pmt->formattype) ||
        (pmt->cbFormat              <  sizeof(WAVEFORMATEX)) ||
        (NULL                       == pmt->pbFormat))
    {
        hr = DMO_E_INVALIDTYPE;
    }

    // If other type set, accept only if identical to that.  Otherwise accept
    // any standard PCM/float audio.
    if (SUCCEEDED(hr))
    {
        if (OutputTypeSet(0))
        {
            const DMO_MEDIA_TYPE* pmtOutput;
            pmtOutput = OutputType(0);
            if (memcmp(pmt->pbFormat, pmtOutput->pbFormat, sizeof(WAVEFORMATEX)))
            {
                hr = DMO_E_INVALIDTYPE;
            }
        }
        else
        {
            WAVEFORMATEX* pWave = (WAVEFORMATEX*)pmt->pbFormat;
            if ((WAVE_FORMAT_PCM != pWave->wFormatTag) ||
                ((8 != pWave->wBitsPerSample) && (16 != pWave->wBitsPerSample)) ||
                ((1 != pWave->nChannels) && (2 != pWave->nChannels)) ||
                ( // Supported sample rates:
                 (96000 != pWave->nSamplesPerSec) &&
                 (48000 != pWave->nSamplesPerSec) &&
                 (44100 != pWave->nSamplesPerSec) &&
                 (32000 != pWave->nSamplesPerSec) &&
                 (22050 != pWave->nSamplesPerSec) &&
                 (16000 != pWave->nSamplesPerSec) &&
                 (11025 != pWave->nSamplesPerSec) &&
                 (8000 != pWave->nSamplesPerSec) &&
                 TRUE   // You may delete && TRUE
                ) ||
                (pWave->nBlockAlign != pWave->nChannels * pWave->wBitsPerSample / 8) ||
                (pWave->nAvgBytesPerSec != pWave->nSamplesPerSec * pWave->nBlockAlign))
            {
                hr = DMO_E_INVALIDTYPE;
            }
        }
    }

    if (SUCCEEDED(hr))
    {
        // We will remember the number of channels, bps, and sample rate of the input type
        m_nChannels = pWave->nChannels;
        m_wBitsPerSample = pWave->wBitsPerSample;
        m_nSamplesPerSec = pWave->nSamplesPerSec;
    }

    return hr;
}