媒体基金会 MFTransform 将 MFSample 从 'MJPG' 转换为'YUY2'或'RGB24'



有人知道我应该使用什么MFTransform将"MJPG"MFSample转换为"YUY2"或"RGB24"吗?

任何小费都将不胜感激。感谢

由于这篇文章的访问次数很明显,我将回答我自己的问题。

诀窍是枚举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纹理,然后显示它。这是用core 2 duo和Radeon HD5650以30fps的速度完成的。当使用OpenCL(几个卷积)对图像进行计算时,它会降至每秒15帧。

创建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;

最新更新