有谁知道我应该使用什么MFTransform将'MJPG'MFSample转换为'YUY2'或'RGB24'?
任何提示都将非常感激。 感谢
答案 0 :(得分:2)
由于这篇文章的访问次数很明显,我将回答我自己的问题。
诀窍是枚举MJPG和YUY2之间的所有转换,因为看起来MJPG和RGB32之间没有直接转换。要在YUY2和RBG32之间转换图像,请使用颜色转换器DSP: http://msdn.microsoft.com/en-us/library/windows/desktop/ff819079%28v=vs.85%29.aspx
我使用此方法从1080p网络摄像头获取样本,然后将MJPG解码为YUY2,然后将YUY2解码为RGB32,然后加载OpenGL RGB32纹理,然后显示它。它以30fps的速度完成,配备2核心2和Radeon HD5650。当使用OpenCL(几次卷积)计算图像时,它降至15 fps。
创建MJPG到YUY2变换的代码:
MFT_REGISTER_TYPE_INFO inputFilter = { MFMediaType_Video, MFVideoFormat_MJPG };
MFT_REGISTER_TYPE_INFO outputFilter = { MFMediaType_Video, MFVideoFormat_YUY2 };
UINT32 unFlags = MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_LOCALMFT | MFT_ENUM_FLAG_SORTANDFILTER;
HRESULT r = MFTEnumEx(MFT_CATEGORY_VIDEO_DECODER, unFlags, &inputFilter, &outputFilter, &ppActivate, &numDecodersMJPG);
if (FAILED(r)) throw gcnew Exception("");
if (numDecodersMJPG < 1) throw gcnew Exception("");
// Activate transform
IMFTransform *pMPEG4 = NULL;
r = ppActivate[0]->ActivateObject(__uuidof(IMFTransform), (void**)&pMPEG4);
if (FAILED(r)) throw gcnew Exception("No se pudo crear el decodificador MJPG.");
下一部分是使用解码器解码压缩样本(首先从MJPG到YUY2,然后从YUY2到RGB32)。它解释如下: http://msdn.microsoft.com/en-us/library/windows/desktop/aa965264%28v=vs.85%29.aspx
或者:
MFT_OUTPUT_STREAM_INFO osi;
HRESULT r = pDecoder->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
if (FAILED(r)) throw gcnew Exception("");
r = pDecoder->ProcessInput(0, sample, 0);
if (FAILED(r)) throw gcnew Exception("");
r = pDecoder->GetOutputStreamInfo(0, &osi);
if (FAILED(r)) throw gcnew Exception("");
DWORD status = 0;
r = pDecoder->GetOutputStatus(&status);
if (FAILED(r)) throw gcnew Exception("");
if (status = MFT_OUTPUT_STATUS_SAMPLE_READY) {
}
// Use your own CreateSample function
IMFSample *outputSample = CreateSample(osi.cbSize);
DWORD outStatus = 0;
MFT_OUTPUT_DATA_BUFFER odf;
odf.dwStreamID = 0;
odf.pSample = outputSample;
odf.dwStatus = 0;
odf.pEvents = NULL;
r = pDecoder->ProcessOutput(0, 1, &odf, &outStatus);
if (r != MF_E_TRANSFORM_NEED_MORE_INPUT && FAILED(r)) {
outputSample->Release();
throw gcnew Exception("");
}
r = pDecoder->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, 0);
if (FAILED(r)) {
outputSample->Release();
throw gcnew Exception("");
}
r = pDecoder->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, 0);
if (FAILED(r)) {
outputSample->Release();
throw gcnew Exception("");
}
return outputSample;