Unable to Render DMO - No combination of intermediate filters can be found to make connection

Dotaz Unable to Render DMO - No combination of intermediate filters can be found to make connection

  • 21. února 2012 5:27
     
      Obsahuje kód

    Hello DirectShow Experts!

    I am attempting to write a simple DMO to be used in a DirectShow application.

    The DMO is required to perform some processing on a .wma audio stream (or any other supported type, wma and mp3 being the main two) and output directly to the default DS device.

    So far I believe i have the majority of this DMO corrent, however I am hoping that someone may be able to help me with the input/output validation.

    I am able to successfully register and unregister the dll with regsvr32, and it shows up in the filters list of the graphedit utility. I render an audio file and play in graphedit, this runs fine. I can then add in a default audio effect filter (say the echo for example), and the file plays with the echo. I then however delete that echo filter from the graph and add in my filter in its place. Connecting the output pin from the decoder to the input of the DMO works, however when I attempt to connect the output of the DMO to the 'Default DirectSound Device', i get the error:

    These filters cannot agree on a connection. Verify the type compatibility of input pin and output pin.
    
    No combination of intermediate filters could be found to make the connection. (Return code: 0x80040217)

    When I use the same method in my application (build a graph with a filter that i know should work, test to ensure i have build the graph correctly, then change the CLSID of the working filter to my filter) I get a similar error.

    I am using the IMediaObjectImpl template to build this DMO. My assumption is that I have errors in the InternalCheckInputType(), InternalCheckOutputType(), InternalGetInputType() and InternalGetOutputType() functions. I would be very greatfull if someone could take a look at my code and tell me where i have gone wrong. Please find below the functions, also I have pastebinned the code showing all the implemented template functions here : (http://pastebin.com/3N3e700d)

    // Streaming variables
    CComPtr<IMediaBuffer>	inpBuffer; // Pointer to the input IMediaBuffer interface
    BYTE *					inBufferData;
    DWORD					inBufferLength;
    DWORD					inFlags; // Input Flags
    WORD bitsPerSample;
    DWORD samplesPerSec;
    // timestamp
    REFERENCE_TIME			refTimeStamp;
    REFERENCE_TIME			refTimeLength;
    
    HRESULT channelSwitch::InternalAllocateStreamingResources()
    {
    	const DMO_MEDIA_TYPE* pmt = InputType(0);
    	WAVEFORMATEX* pbFormat = (WAVEFORMATEX*)pmt->pbFormat;
    	// save the bits per sample and samples per sec
    	bitsPerSample = pbFormat->wBitsPerSample;
    	samplesPerSec = pbFormat->nSamplesPerSec;
    	// Assume no extra resources are needed to be allocated for processing
        return S_OK;
    }
    
    HRESULT channelSwitch::InternalCheckInputType(DWORD dwInputStreamIndex, const DMO_MEDIA_TYPE *pmt)
    {
        //  Check if the type is already set and if so reject any type that's not identical
        if (InputTypeSet(dwInputStreamIndex)) {
            if (!TypesMatch(pmt, InputType(dwInputStreamIndex))) {
                return DMO_E_INVALIDTYPE;
            } else {
                return S_OK;
            }
        }
    
        if (pmt->majortype == MEDIATYPE_Audio &&
            pmt->subtype == MEDIASUBTYPE_PCM &&
            pmt->formattype == FORMAT_WaveFormatEx &&
            pmt->pbFormat != NULL) {
    			WAVEFORMATEX* pbFormat = (WAVEFORMATEX*)pmt->pbFormat;
    			if (pbFormat->nChannels == 2 && (pbFormat->wBitsPerSample == 8 || pbFormat->wBitsPerSample == 16) )
    			{
    				return S_OK;
    			} else {
    				return DMO_E_INVALIDTYPE;
    			}
        } else {
            return DMO_E_INVALIDTYPE;
        }
    }
    
    HRESULT channelSwitch::InternalCheckOutputType(DWORD dwOutputStreamIndex, const DMO_MEDIA_TYPE *pmt)
    {
    	
        //  Check if the type is already set and if so reject any type that's not identical
        if (OutputTypeSet(dwOutputStreamIndex)) {
            if (!TypesMatch(pmt, OutputType(dwOutputStreamIndex))) {
                return DMO_E_INVALIDTYPE;
            } else {
                return S_OK;
            }
        }
    	if (!InputTypeSet(0)) 
    	{
                return DMO_E_INVALIDTYPE;
        }
    
    	if (pmt->majortype == MEDIATYPE_Audio &&
            pmt->subtype == MEDIASUBTYPE_PCM &&
            pmt->formattype == FORMAT_WaveFormatEx &&
            pmt->pbFormat != NULL) 
    	{
            return S_OK;
        } else {
            return DMO_E_INVALIDTYPE;
        }
    }
    
    HRESULT channelSwitch::InternalGetInputType(DWORD dwInputStreamIndex, DWORD dwTypeIndex, DMO_MEDIA_TYPE *pmt)
    {
    	switch(dwTypeIndex)
    	{
    	case 0:
    		/* This is not required, i think.
    		// Create the format structure
    		WAVEFORMATEX* wfx = (WAVEFORMATEX*)pmt->pbFormat;
    		// Initialise the format strucutre
    		wfx->wFormatTag = WAVE_FORMAT_PCM;
    		wfx->nChannels = 2;
    		wfx->nSamplesPerSec = 8000; // NEED TO LIST THE SAMPLE RATES
    		wfx->wBitsPerSample = bitsPerSample; // NEED TO LIST "8 or 16"
    		wfx->nBlockAlign = wfx->wBitsPerSample * wfx->nChannels / 8;
    		wfx->nAvgBytesPerSec = wfx->nBlockAlign * wfx->nSamplesPerSec;
    		wfx->cbSize = 0;
    		*/
    
    		// Initialise media type
    		pmt->majortype = MEDIATYPE_Audio;
    		pmt->subtype = MEDIASUBTYPE_PCM;
    		pmt->bFixedSizeSamples = TRUE;
    		pmt->bTemporalCompression = FALSE;
    		pmt->lSampleSize = bitsPerSample * 4;
    		//pmt->lSampleSize = wfx->nBlockAlign; 
    		pmt->formattype = FORMAT_WaveFormatEx;
    		pmt->pUnk = NULL; /// you should ignore this when checking
    		//pmt->pbFormat = (BYTE*)wfx; // --- probly wrong cast
    		return S_OK;
    		break;
    	default:
    		pmt = NULL;
    		return DMO_E_NO_MORE_ITEMS;
    		break;
    	}
    }
    
    HRESULT channelSwitch::InternalGetOutputType(DWORD dwOutputStreamIndex, DWORD dwTypeIndex, DMO_MEDIA_TYPE *pmt)
    {
    	// If input type is not set, an output cannot be set
    	if (!InputTypeSet(0)) {
            return DMO_E_TYPE_NOT_SET;
        }
    	// If GetOutputType()'s pmt parameter is NULL, return S_OK if the type exists.
        // Return DMO_E_NO_MORE_ITEMS if the type does not exists. 
        if (dwTypeIndex != 0) {
            return DMO_E_NO_MORE_ITEMS;
        }
    
    	if (NULL != pmt)
    	{
    		// Allocate memory for format block
    		MoInitMediaType(pmt, (DWORD)sizeof(WAVEFORMATEX));
    		// Create the format structure
    		WAVEFORMATEX* wfx = (WAVEFORMATEX*)pmt->pbFormat;
    		// Initialise the format strucutre
    		wfx->wFormatTag = WAVE_FORMAT_PCM;
    		wfx->nChannels = 2;
    		wfx->nSamplesPerSec = samplesPerSec;
    		wfx->wBitsPerSample = bitsPerSample;
    		wfx->nBlockAlign = wfx->wBitsPerSample * wfx->nChannels / 8;
    		wfx->nAvgBytesPerSec = wfx->nBlockAlign * wfx->nSamplesPerSec;
    		wfx->cbSize = 0;
    
    		// Initialise media type
    		pmt->majortype = MEDIATYPE_Audio;
    		pmt->subtype = MEDIASUBTYPE_PCM;
    		pmt->bFixedSizeSamples = TRUE;
    		pmt->bTemporalCompression = FALSE;
    		pmt->lSampleSize = wfx->nBlockAlign;
    		pmt->formattype = FORMAT_WaveFormatEx;
    		pmt->pUnk = NULL; 
    
    
    	}
    	return S_OK;
    
    
    }

    Thanks

    Chris

Všechny reakce