locked
Colour Conversion IMFTransform throws exception in COLORCNV.DLL RRS feed

  • Question

  • Hi folks,

    I'm trying to use the IMFTransform interface to convert a YUY2 video frame buffer (single frame) to RGB24. I have checked the IMFSample* I am getting, and it has the correct type and the correct 1280*960*2 bytes of data. Here is my code I am using to convert to RGB24:

    	// ----------------------------------------------------------------------------
    	// Convert data to RGB colorspace
    	// ----------------------------------------------------------------------------
    	if (bNeedsConvert)
    	{
    		// Create instance of IMFTransform interface pointer as CColorConvertDMO
    		hr = CoCreateInstance(CLSID_CColorConvertDMO, NULL, CLSCTX_INPROC_SERVER, IID_IMFTransform, (LPVOID*)&pTransform);
    		if (FAILED(hr))
    		{
    			fprintf(stderr, "CoCreateInstance for IMFTransform failed, code 0x%x\n", hr);
    			return hr;
    		}
    
    		// Set input type as media type of our input stream
    		hr = pTransform->SetInputType(0, pType, 0);
    		if (FAILED(hr))
    		{
    			fprintf(stderr, "pTransform->SetInputType failed, code 0x%x\n", hr);
    			return hr;
    		}
    
    		// Create new media type
    		hr = MFCreateMediaType(&pOutputType);
    
    		// Set colorspace in output type to RGB24, uncompressed, not interlaced
    		hr = pOutputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
    		hr = pOutputType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB24);
    		hr = pOutputType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, 1);
    		hr = pOutputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
    		hr = pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
    
    		// Copy data from input type to output type
    		// Frame Size
    		UINT32 uX, uY;
    		hr = GetFrameSize(pType, &uX, &uY);
    		hr = SetFrameSize(pOutputType, uX, uY);
    		// Frame rate
    		hr = GetFrameRate(pType, &uX, &uY);
    		hr = SetFrameRate(pOutputType, uX, uY);
    		// Pixel aspect ratio
    		hr = GetPixelAspectRatio(pType, &uX, &uY);
    		hr = SetPixelAspectRatio(pOutputType, uX, uY);
    
    		// Set transform output type
    		hr = pTransform->SetOutputType(0, pOutputType, 0);
    		if (FAILED(hr))
    		{
    			fprintf(stderr, "pTransform->SetOutputType failed, code 0x%x\n", hr);
    			return hr;
    		}
    
    		// Notify the transform we are about to begin streaming data
    		hr = pTransform->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
    		if (FAILED(hr))
    		{
    			fprintf(stderr, "pTransform->ProcessMessage failed, code 0x%x\n", hr);
    			return hr;
    		}
    
    		// Send our input sample to the transform
    		hr = pTransform->ProcessInput(0, pSample, 0);
    		if (FAILED(hr))
    		{
    			fprintf(stderr, "pTransform->ProcessInput failed, code 0x%x\n", hr);
    			return hr;
    		}
    
    		MFT_OUTPUT_DATA_BUFFER modbBuffer;
    		DWORD dwStatus = 0;
    		hr = pTransform->ProcessOutput(0, 1, &modbBuffer, &dwStatus);
    		if (FAILED(hr))
    		{
    			fprintf(stderr, "pTransform->ProcessOutput failed, code 0x%x\n", hr);
    			return hr;
    		}
    	}

    All HRESULTS are OK. At line pTransform->ProcessOutput, I get:

    Exception thrown at 0x00007FFFCD03A1CC (COLORCNV.DLL) in cam.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.

    I've checked all my pointers I send to the transform and they are good. Bit stumped here. TIA for any input.


    • Edited by Miles Burchell Sunday, February 17, 2019 12:51 AM Mistake copying code
    Sunday, February 17, 2019 12:49 AM

Answers

All replies

  • It's because (MFT_OUTPUT_DATA_BUFFER.pSample == NULL). You are supposed to provide buffer for output here.

    http://alax.info/blog/tag/directshow

    • Marked as answer by Miles Burchell Sunday, February 17, 2019 10:36 AM
    Sunday, February 17, 2019 8:26 AM
  • Wow. Can't believe I missed that. Thanks.

    For any future people who might happen to find this thread via Google, here's what I ended up using:

    // Get output information and set up buffer
    	MFT_OUTPUT_STREAM_INFO mosiBuffer;
    	MFT_OUTPUT_DATA_BUFFER modbBuffer;
    	hr = pTransform->GetOutputStreamInfo(0, &mosiBuffer);
    	if (FAILED(hr))
    	{
    		fprintf(stderr, "pTransform->GetOutputStreamInfo failed, code 0x%x\n", hr);
    		return hr;
    	}
    
    	RtlZeroMemory(&modbBuffer, sizeof(MFT_OUTPUT_DATA_BUFFER));
    
    	if (mosiBuffer.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES ||
    		mosiBuffer.dwFlags & MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES)
    	{
    		fprintf(stderr, "Transform stream provides its own samples.\n");
    	}
    	else
    	{
    		fprintf(stderr, "Creating sample buffer size %u.\n", mosiBuffer.cbSize);
    
    		IMFMediaBuffer* pBuffer = NULL; // our new buffer
    
    		hr = MFCreateMemoryBuffer(mosiBuffer.cbSize, &pBuffer);
    		if (FAILED(hr))
    		{
    			fprintf(stderr, "MFCreateMemoryBuffer failed, code 0x%x\n", hr);
    			return hr;
    		}
    
    		hr = MFCreateSample(&pSampleOut);
    		if (FAILED(hr))
    		{
    			fprintf(stderr, "MFCreateSample failed, code 0x%x\n", hr);
    			return hr;
    		}
    
    		hr = pSampleOut->AddBuffer(pBuffer);
    		if (FAILED(hr))
    		{
    			fprintf(stderr, "pSampleOut->AddBuffer failed, code 0x%x\n", hr);
    			return hr;
    		}
    
    		modbBuffer.pSample = pSampleOut;
    	}
    
    	// Process data
    	hr = pTransform->ProcessOutput(0, 1, &modbBuffer, &dwStatus);
    	if (FAILED(hr))
    	{
    		fprintf(stderr, "pTransform->ProcessOutput failed, code 0x%x\n", hr);
    		return hr;
    	}

    Sunday, February 17, 2019 10:39 AM