加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

视频 – Windows Media Foundation使用IMFTransform将mp4电影帧

发布时间:2020-12-14 04:00:27 所属栏目:Windows 来源:网络整理
导读:我正在尝试使用 Windows Media Foundation类解码mp4视频,并将帧转换为可由DirectX着色器用于渲染的2D纹理.我已经能够使用MFCreateSourceReaderfromURL读取源流,并且能够按预期读取其主要类型MFMEdiaType_Video和次要类型为MFVideoFormat_H264的流的媒体类型.
我正在尝试使用 Windows Media Foundation类解码mp4视频,并将帧转换为可由DirectX着色器用于渲染的2D纹理.我已经能够使用MFCreateSourceReaderfromURL读取源流,并且能够按预期读取其主要类型MFMEdiaType_Video和次要类型为MFVideoFormat_H264的流的媒体类型.

我现在需要将此格式转换为RGB格式,该格式可用于初始化D3D11_TEXTURE2D资源和资源视图,然后可以将其传递给HLSL像素着色器进行采样.我已经厌倦了使用IMFTransform类为我做转换但是当我尝试将转换的输出类型设置为任何MFVideoFormat_RGB变体时,我得到一个错误.我也尝试在源阅读器上设置一个新的输出类型,并且只是希望以正确的格式获取样本的采样,但我再次没有运气.

所以我的问题是:

>这种转换是否可行?
>这可以通过IMFTransform / SourceReader类完成,就像我上面已经累了一样,我只需要调整代码,还是需要手动进行这种类型的转换?
>这是将视频纹理数据输入到着色器中进行采样的最佳方式,还是有一个我没想过的更简单的替代方法.

正在使用的操作系统是Windows 7,所以我不能使用SourceReaderEx或ID3D11VideoDevice接口,因为据我所知,这些解决方案似乎只在Windows 8上可用.

我们非常感谢任何正确方向的帮助/指针,如有必要,我还可以提供一些源代码.

解决方法

我发现你在理解Media Foundation时有些错误.您希望从MFVideoFormat_H264获取RGB格式的图像,但不使用解码器H264.您写道“我已经厌倦了使用IMFTransform类” – IMFTransform不是类.它是Transform COM对象的接口.您必须创建COM对象Media Foundation H264解码器. Microsoft软件H264解码器的CLSID是CLSID_CMSH264DecoderMFT.但是,从该解码器,您可以获得以下格式的输出图像:
输出类型

MFVideoFormat_I420

MFVideoFormat_IYUV

MFVideoFormat_NV12

MFVideoFormat_YUY2

MFVideoFormat_YV12

您可以从其中一个创建D3D11_TEXTURE2D.或者您可以从我的项目CaptureManager SDK中执行以下操作:

CComPtrCustom<IMFTransform> lColorConvert;

                if (!Result(lColorConvert.CoCreateInstance(__uuidof(CColorConvertDMO))))
                {
                    lresult = MediaFoundationManager::setInputType(
                        lColorConvert,lVideoMediaType,0);

                    if (lresult)
                    {
                        break;
                    }

                    DWORD lTypeIndex = 0;

                    while (!lresult)
                    {

                        CComPtrCustom<IMFMediaType> lOutputType;

                        lresult = lColorConvert->GetOutputAvailableType(0,lTypeIndex++,&lOutputType);

                        if (!lresult)
                        {


                            lresult = MediaFoundationManager::getGUID(
                                lOutputType,MF_MT_SUBTYPE,lSubType);

                            if (lresult)
                            {
                                break;
                            }

                            if (lSubType == MFVideoFormat_RGB32)
                            {
                                LONG lstride = 0;

                                MediaFoundationManager::getStrideForBitmapInfoHeader(
                                    lSubType,lWidth,lstride);

                                if (lstride < 0)
                                    lstride = -lstride;

                                lBitRate = (lHight * (UINT32)lstride * 8 * lNumerator) / lDenominator;

                                lresult = MediaFoundationManager::setUINT32(
                                    lOutputType,MF_MT_AVG_BITRATE,lBitRate);

                                if (lresult)
                                {
                                    break;
                                }


                                PROPVARIANT lVarItem;

                                lresult = MediaFoundationManager::getItem(
                                    *aPtrPtrInputMediaType,MF_MT_FRAME_RATE,lVarItem);

                                if (lresult)
                                {
                                    break;
                                }

                                lresult = MediaFoundationManager::setItem(
                                    lOutputType,lVarItem);

                                if (lresult)
                                {
                                    break;
                                }

                                (*aPtrPtrInputMediaType)->Release();

                                *aPtrPtrInputMediaType = lOutputType.detach();

                                break;
                            }
                        }
                    }
                }

您可以设置ColorConvertDMO,以便将H264解码器的输出格式转换为您所需的格式.

此外,您可以通过链接查看代码:videoInput.此代码从网络摄像头获取实时视频并将其解码为RGB.如果您更换mp4视频文件源上的网络摄像头源,您将获得接近您需要的解决方案.

问候

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读