I'm trying to use Color Converter DMO (http://msdn.microsoft.com/en-us/library/windows/desktop/ff819079(v=vs.85).aspx) to convert RBG24 to YV12/NV12 via Media Foundation. I've created an instance of Color Converter DSP via CLSID_CColorConvertDMO and then tried to set the needed input/output types, but the calls always return E_INVALIDARG even when using media types that are returned by GetOutputAvailableType
and GetInputAvailableType
. If I set the media type to NULL
then i get the error that the media type is invalid, that makes sense. I've seen examples from MSDN, where people do the same - enumerate available types and then set them as input types - and they claim it works, but i'm kinda stuck on the E_INVALIDARG. I understand that this is hard to answer without a code example, if no one has had similar experience, I'll try to post a snipplet, but maybe someone has experienced the same issue?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
This DMO/DSP is dual interfaced and is both a DMO with IMediaObject
and an MFT with IMFTransform
. The two interfaces share a lot common, and here is a code snippet to test initialization of RGB24 into YV12 conversion:
#include "stdafx.h" #include <dshow.h> #include <dmo.h> #include <wmcodecdsp.h> #pragma comment(lib, "strmiids.lib") #pragma comment(lib, "wmcodecdspuuid.lib") int _tmain(int argc, _TCHAR* argv[]) { ATLVERIFY(SUCCEEDED(CoInitialize(NULL))); CComPtr<IMediaObject> pMediaObject; ATLVERIFY(SUCCEEDED(pMediaObject.CoCreateInstance(CLSID_CColorConvertDMO))); VIDEOINFOHEADER InputVideoInfoHeader; ZeroMemory(&InputVideoInfoHeader, sizeof InputVideoInfoHeader); InputVideoInfoHeader.bmiHeader.biSize = sizeof InputVideoInfoHeader.bmiHeader; InputVideoInfoHeader.bmiHeader.biWidth = 1920; InputVideoInfoHeader.bmiHeader.biHeight = 1080; InputVideoInfoHeader.bmiHeader.biPlanes = 1; InputVideoInfoHeader.bmiHeader.biBitCount = 24; InputVideoInfoHeader.bmiHeader.biCompression = BI_RGB; InputVideoInfoHeader.bmiHeader.biSizeImage = 1080 * (1920 * 3); DMO_MEDIA_TYPE InputMediaType; ZeroMemory(&InputMediaType, sizeof InputMediaType); InputMediaType.majortype = MEDIATYPE_Video; InputMediaType.subtype = MEDIASUBTYPE_RGB24; InputMediaType.bFixedSizeSamples = TRUE; InputMediaType.bTemporalCompression = FALSE; InputMediaType.lSampleSize = InputVideoInfoHeader.bmiHeader.biSizeImage; InputMediaType.formattype = FORMAT_VideoInfo; InputMediaType.cbFormat = sizeof InputVideoInfoHeader; InputMediaType.pbFormat = (BYTE*) &InputVideoInfoHeader; const HRESULT nSetInputTypeResult = pMediaObject->SetInputType(0, &InputMediaType, 0); _tprintf(_T("nSetInputTypeResult 0x%08x\n"), nSetInputTypeResult); VIDEOINFOHEADER OutputVideoInfoHeader = InputVideoInfoHeader; OutputVideoInfoHeader.bmiHeader.biBitCount = 12; OutputVideoInfoHeader.bmiHeader.biCompression = MAKEFOURCC('Y', 'V', '1', '2'); OutputVideoInfoHeader.bmiHeader.biSizeImage = 1080 * 1920 * 12 / 8; DMO_MEDIA_TYPE OutputMediaType = InputMediaType; OutputMediaType.subtype = MEDIASUBTYPE_YV12; OutputMediaType.lSampleSize = OutputVideoInfoHeader.bmiHeader.biSizeImage; OutputMediaType.cbFormat = sizeof OutputVideoInfoHeader; OutputMediaType.pbFormat = (BYTE*) &OutputVideoInfoHeader; const HRESULT nSetOutputTypeResult = pMediaObject->SetOutputType(0, &OutputMediaType, 0); _tprintf(_T("nSetOutputTypeResult 0x%08x\n"), nSetOutputTypeResult); // TODO: ProcessInput, ProcessOutput pMediaObject.Release(); CoUninitialize(); return 0; }
This should work fine and print two S_OK
s out...