标签: ms-media-foundation

Microsoft Media Foundation的状态是什么?

Microsoft Media Foundation(MF)是Windows Vista中DirectShow的继承者.我大多忽略它,但它有一些功能(如WMV AC-1文件的解码)很难在DirectShow中实现.Media Foundation也是一个更现代化的API,因此进行切换似乎合乎逻辑.

但是,在线教学资源和官方文档似乎非常缺乏.只有一本书涉及该主题(由微软出版),它不再适用于正常价格.(人们收取500美元,或者更多的二手版本.)

据我所知,没有其他书籍.虽然微软的其他技术通常由多个出版商在多本书中涵盖.

Media Foundation的官方博客自2011年以来一直没有更新.在活跃的两年中,只写了10篇技术文章,其中5篇涉及错误记录/跟踪而不是实际功能.

StackOverflow标签ms-media-foundation仅用于328个问题,其中142个未得到答复.相比之下,有1641个DirectShow问题,其中只有496个未得到答复.

那么微软媒体基金会发生了什么?这个新的API是否会起飞并取代DirectShow,甚至微软还会抛弃MF,转而回到旧的和生锈的(可靠的?)DirectShow.或者是否有另一个非Microsoft框架已经接管了?

ms-media-foundation

26
推荐指数
2
解决办法
5667
查看次数

DirectShow与Media Foundation进行视频捕捉?

我正在尝试在视频捕获/监控/流媒体应用程序中选择这两个API,我不确定哪个是最好的选择.

一点背景:

  • 我需要它与各种视频采集卡/加密狗一起使用.
  • 该应用程序可能会使用C++开发,因此本机API至关重要
  • 性能很重要,因为我需要处理多个视频流

一些谷歌搜索给我的印象是

  • MF仅支持Win 7上的视频捕获
  • Directshow得到更好的支持,但会变得过时
  • MF可以在某些应用中提供更好的性能

MF认为前进更好,但我担心如果MF没有"赶上"并且Directshow仍然是首选的API,那么最终会陷入技术死胡同.建议和建议,请...

windows directshow ms-media-foundation

10
推荐指数
1
解决办法
4979
查看次数

Windows 10中的硬件加速屏幕捕获库

我的应用程序是捕获桌面屏幕(屏幕共享)并发送到其他设备.目前应用程序使用以下方法捕获屏幕
- 使用GDI(Bitblt)
- 使用DirectX(getFrontBufferData)
-
根据Windows版本和用例使用DXGI(桌面复制API),应用程序使用其中一个.

我正在寻找硬件加速api,它比现有的实现更快地完成这项工作.作为参考,我们在Mac OS中有一些东西点击这里.

在Windows中搜索硬件加速屏幕捕获之后,找到了以下一些选项:
- 基于GDI的捕获
- 它是一个常用的软件捕获库,它支持Windows 7中的硬件加速.
- 基于Directx的捕获
- 一些选项提出了以下参考文献中提到的direct3d9和direct3d11捕获.在directx方法中使用getfrontbufferData比gdi本身慢.
- 基于DXGI的捕获
- 它支持Windows 8和更高版本的Windows,它是我的应用程序中的direct3d11基础实现.
- 基于Windows媒体编码器9的捕获
参考文献:http://www.codeproject.com/Articles/5051/Various-methods-for-capturing-the-screen
最快的屏幕捕获方法
但是这些引用看起来很旧,有没有最新版Windows中的此类功能.

前三种方法已经在我的应用程序中以某种方式使用.DXGI在某种程度上更好,因为它具有硬件加速(使用GPU).
我正在寻找一个类似于上部提到的mac应用程序的Windows应用程序/库.我们的用例很简单,可以在不影响系统性能的情况下以最佳方式捕获屏幕框架(我希望只有使用GPU才能实现,这将节省cpu周期).

c++ windows directx screen-capture ms-media-foundation

9
推荐指数
0
解决办法
1318
查看次数

Windows Media Foundation MFT缓冲和视频质量问题(颜色丢失,而不是平滑的曲线,尤其是文本)

我正在尝试使用Windows Media Foundation将从图像(RGBA)源(桌面/相机)捕获的RGBA缓冲区编码为原始H264,传输它们并实时解码在另一端接收的原始H264帧。我正在尝试至少达到30 fps。编码器工作得很好,但解码器却不能。

我了解Microsoft WMF MFT在发出编码/解码数据之前最多缓冲30帧。

图像源仅在发生变化时才会发出帧,而不是连续的RGBA缓冲区流,因此,我的目的是为每个MFT的每个输入缓冲区获得一个编码/解码数据的缓冲区,以便我可以流式传输实时数据并进行渲染。

当我使图像源发送连续更改(通过刺激更改)时,编码器和解码器均能够发出至少10到15 fps的帧。编码器能够利用硬件加速支持。我能够在编码器端达到30 fps,并且还没有使用DirectX表面实现硬件辅助解码。这里的问题不是帧速率,而是MFT对数据的缓冲。

因此,我尝试通过发送MFT_MESSAGE_COMMAND_DRAIN命令并反复调用ProcessOutput直到解码器返回MF_E_TRANSFORM_NEED_MORE_INPUT来消耗解码器MFT 。现在发生的事情是,解码器现在每30个输入h264缓冲区仅发出一帧,我甚至用连续的数据流对其进行了测试,其行为是相同的。好像解码器将所有中间帧都丢弃在GOP中。

如果只缓冲前几个帧,这对我来说是可以的,但是即使在SPS和PPS解析阶段之后,我的解码器实现也仅在其缓冲区一直充满时才输出。

我遇到了Google的铬源代码(https://github.com/adobe/chromium/blob/master/content/common/gpu/media/dxva_video_decode_accelerator.cc),它们遵循相同的方法。

mpDecoder->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, NULL);
Run Code Online (Sandbox Code Playgroud)

我的实现基于 https://github.com/GameTechDev/ChatHeads/blob/master/VideoStreaming/EncodeTransform.cpp

https://github.com/GameTechDev/ChatHeads/blob/master/VideoStreaming/DecodeTransform.cpp

我的问题是,我想念什么吗?Windows Media Foundation是否适合实时流?排干编码器和解码器是否适用于实时用例?

对于我来说,只有两个选择,使此WMF可以作为实时用例工作,或者与Intel的QuickSync等一起使用。我选择WMF作为我的POC,因为在任何MFT不可用的情况下Windows Media Foundation隐式支持硬件/ GPU /软件后备,并且在内部无需太多编码即可选择最佳的MFT。

我遇到了视频质量问题,尽管bitrate属性设置为3Mbps。但是与缓冲问题相比,它的优先级最低。数周来,我一直在敲打键盘,这很难修复。任何帮助,将不胜感激。

码:

编码器设置:

IMFAttributes* attributes = 0;
    HRESULT  hr = MFCreateAttributes(&attributes, 0);

    if (attributes)
    {
        //attributes->SetUINT32(MF_SINK_WRITER_DISABLE_THROTTLING, TRUE);
        attributes->SetGUID(MF_TRANSCODE_CONTAINERTYPE, MFTranscodeContainerType_MPEG4);
    }//end if (attributes)

    hr = MFCreateMediaType(&pMediaTypeOut);
    // Set the output media type.
    if (SUCCEEDED(hr))
    {
        hr = MFCreateMediaType(&pMediaTypeOut);
    }
    if (SUCCEEDED(hr))
    {
        hr = pMediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, …
Run Code Online (Sandbox Code Playgroud)

c++ directx video-streaming h.264 ms-media-foundation

9
推荐指数
1
解决办法
949
查看次数

ffplay中出现绿屏:使用Live555通过RTP流将桌面(DirectX表面)作为H264视频流

我正在尝试使用Windows10上的Live555和Windows Media Foundation的硬件编码器通过RTP流将桌面(NV12格式的DirectX表面)流化为H264视频,并期望由ffplay(ffmpeg 4.2)渲染。但是只有如下所示的绿屏,

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

使用硬件MFT引用了MFWebCamToRTP mediafoundation-sampleEncoding DirectX表面,以实现live555的FramedSource并将输入源更改为DirectX表面而不是webCam。

这是我的Live555的doGetNextFrame回调实现的摘录,以从directX表面提供输入样本:

virtual void doGetNextFrame()
{
    if (!_isInitialised)
    {
        if (!initialise()) {
            printf("Video device initialisation failed, stopping.");
            return;
        }
        else {
            _isInitialised = true;
        }
    }

    //if (!isCurrentlyAwaitingData()) return;

    DWORD processOutputStatus = 0;
    HRESULT mftProcessOutput = S_OK;
    MFT_OUTPUT_STREAM_INFO StreamInfo;
    IMFMediaBuffer *pBuffer = NULL;
    IMFSample *mftOutSample = NULL;
    DWORD mftOutFlags;
    bool frameSent = false;
    bool bTimeout = false;

    // Create sample
    CComPtr<IMFSample> videoSample = NULL;

    // Create buffer
    CComPtr<IMFMediaBuffer> …
Run Code Online (Sandbox Code Playgroud)

directx ffmpeg video-streaming h.264 ms-media-foundation

9
推荐指数
1
解决办法
311
查看次数

提供少量输入样本后,英特尔图形硬件H264 MFT ProcessInput调用失败,在Nvidia硬件MFT上也可以正常工作

我正在使用DesktopDuplication API捕获桌面,并将示例从RGBA转换为GPU中的NV12,并将其提供给MediaFoundation硬件H264 MFT。这在Nvidia图形以及软件编码器上都可以正常工作,但是在只有Intel图形硬件MFT可用时失败。如果我退回到Software MFT,该代码在同一台Intel图形计算机上也可以正常工作。我还确保了编码实际上是在Nvidia图形计算机上的硬件中完成的。

在Intel图形上,MFT返回MEError(“未指定错误”),仅在馈入第一个样本后才发生,随后对ProcessInput的调用(当事件生成器触发METransformNeedInput时)返回“被调用方当前不接受进一步的输入”。MFT很少会在返回这些错误之前消耗更多的样本。这种行为令人困惑,仅当事件生成器通过IMFAsyncCallback异步触发METransformNeedInput时,我才提供示例,并且还应检查提供示例后是否立即触发METransformHaveOutput。当相同的异步逻辑与Nvidia硬件MFT和Microsoft软件编码器一起正常工作时,这真让我感到困惑。

英特尔论坛本身也有一个类似的未解决问题。我的代码类似于intel线程中提到的代码,除了我还将d3d设备管理器设置为如下所示的编码器这一事实。

并且,还有其他三个堆栈溢出线程报告了类似的问题,但没有给出解决方案(MFTransform编码器-> ProcessInput返回E_FAIL如何从D11纹理为Intel MFT编码器创建IMFSample异步MFT没有发送MFTransformHaveOutput事件(Intel硬件MJPEG解码器MFT))。我尝试了所有可能的选择,对此没有任何改进。

颜色转换器代码取自intel media sdk示例。我也在这里上传了完整的代码。

设置d3d管理器的方法:

void SetD3dManager() {

    HRESULT hr = S_OK;

    if (!deviceManager) {

        // Create device manager
        hr = MFCreateDXGIDeviceManager(&resetToken, &deviceManager);
    }

    if (SUCCEEDED(hr)) 
    {
        if (!pD3dDevice) {

            pD3dDevice = GetDeviceDirect3D(0);
        }
    }

    if (pD3dDevice) {

        // NOTE: Getting ready for multi-threaded operation
        const CComQIPtr<ID3D10Multithread> pMultithread = pD3dDevice;
        pMultithread->SetMultithreadProtected(TRUE);

        hr = deviceManager->ResetDevice(pD3dDevice, resetToken);
        CHECK_HR(_pTransform->ProcessMessage(MFT_MESSAGE_SET_D3D_MANAGER, reinterpret_cast<ULONG_PTR>(deviceManager.p)), …
Run Code Online (Sandbox Code Playgroud)

directx video-streaming h.264 hardware-acceleration ms-media-foundation

9
推荐指数
1
解决办法
249
查看次数

Media Foundation捕获的视频是垂直镜像的

我正在使用Media Foundation IMFSourceReaderCallback实现从相机中抓取视频帧,然后使用OpenCV imshow来循环显示帧.
但是我把框架垂直翻转......
这是一个错误吗?我应该设置一些属性来避免这种情况吗?
这是我的代码:

初始化:

IMFAttributes* pDeviceAttrs, *pReaderAttrs;
        hr = MFCreateAttributes(&pDeviceAttrs, 1);
        if (FAILED(hr)) goto Exit;
        hr = pDeviceAttrs->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
        if (FAILED(hr)) goto Exit;
//...
// Correct source provider is activated through ActivateObject  
//
        hr = MFCreateAttributes(&pReaderAttrs, 2);
        if (FAILED(hr)) goto Exit;

        pReaderAttrs->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK,(IUnknown*)this);
        pReaderAttrs->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, TRUE); 

        hr = MFCreateSourceReaderFromMediaSource(pMediaSource, pReaderAttrs, &m_pReader);
        if (FAILED(hr)) goto Exit;
// Correct profile is set
Run Code Online (Sandbox Code Playgroud)

OnReadSample实现:

HRESULT hr = S_OK;
        LONG defaultStride = 0;
        LONG stride = 0;
        BYTE *pBuffer = …
Run Code Online (Sandbox Code Playgroud)

c++ video-capture ms-media-foundation

8
推荐指数
1
解决办法
860
查看次数

使用DirectX11像素着色器将颜色从DXGI_FORMAT_B8G8R8A8_UNORM转换为GPU中的NV12

我正在编写一个代码,以使用桌面复制捕获桌面,并使用英特尔hardwareMFT将其编码为h264。编码器仅接受NV12格式作为输入。我有一个DXGI_FORMAT_B8G8R8A8_UNORM到NV12转换器(https://github.com/NVIDIA/video-sdk-samples/blob/master/nvEncDXGIOutputDuplicationSample/Preproc.cpp)可以正常工作,并且基于DirectX VideoProcessor。

问题是某些英特尔图形硬件上的VideoProcessor仅支持从DXGI_FORMAT_B8G8R8A8_UNORM到YUY2的转换,但不支持NV12的转换,我已经通过GetVideoProcessorOutputFormats枚举支持的格式来确认了相同的转换。尽管VideoProcessor Blt成功实现,没有任何错误,而且我可以看到输出视频中的帧有些像素化,但是如果仔细观察它,我会注意到它。

我猜想,VideoProcessor只是故障转移到了下一个受支持的输出格式(YUY2),而我在不知不觉中将其馈送到认为输入已按照配置在NV12中的编码器。NV12和YUY2之间几乎没有像字节顺序和子采样之类的差异,因此不会出现帧故障或严重损坏的情况。另外,在支持NV12转换的硬件上我也没有像素化问题。

所以我决定使用基于此代码的像素着色器进行颜色转换(https://github.com/bavulapati/DXGICaptureDXColorSpaceConversionIntelEncode/blob/master/DXGICaptureDXColorSpaceConversionIntelEncode/DuplicationManager.cpp)。我能够使像素着色器正常工作,我也已经在这里上传了我的代码(https://codeshare.io/5PJjxP)供参考(尽可能简化了它)。

现在,我剩下两个通道,分别是色度和亮度(ID3D11Texture2D纹理)。对于将两个独立的通道有效地打包到一个ID3D11Texture2D纹理中,以便将其提供给编码器,我确实感到困惑。有没有一种方法可以将Y和UV通道有效地打包到GPU中的单个ID3D11Texture2D中?我非常厌倦基于CPU的方法,因为它价格昂贵,并且无法提供最佳的帧速率。实际上,我什至不愿意将纹理复制到CPU。我正在考虑一种在GPU中执行此操作的方法,而无需在CPU和GPU之间来回复制。

我已经对此进行了相当长时间的研究,没有任何进展,我们将不胜感激。

/**
* This method is incomplete. It's just a template of what I want to achieve.
*/

HRESULT CreateNV12TextureFromLumaAndChromaSurface(ID3D11Texture2D** pOutputTexture)
{
    HRESULT hr = S_OK;

    try
    {
        //Copying from GPU to CPU. Bad :(
        m_pD3D11DeviceContext->CopyResource(m_CPUAccessibleLuminanceSurf, m_LuminanceSurf);

        D3D11_MAPPED_SUBRESOURCE resource;
        UINT subresource = D3D11CalcSubresource(0, 0, 0);

        HRESULT hr = m_pD3D11DeviceContext->Map(m_CPUAccessibleLuminanceSurf, subresource, D3D11_MAP_READ, 0, &resource);

        BYTE* sptr = reinterpret_cast<BYTE*>(resource.pData);
        BYTE* dptrY = nullptr; // point to the address of …
Run Code Online (Sandbox Code Playgroud)

directx yuv directx-11 pixel-shader ms-media-foundation

8
推荐指数
1
解决办法
95
查看次数

如何使用SilverLight播放H264流?

我有一个H264流(IIS - 流畅的流),我想与SilverLight一起玩.显然SilverLight可以做到,但是怎么做?

注意:
SilverLight可以播放VC-1流,但不能播放H264.

此外,我可以提供流和所需的任何其他信息.H264编码器是Media Foundation(MFT)中的编码器.同样适用于VC-1(虽然不可能为平滑流创建相同的块,因为强制关键帧插入会导致视频不稳定.

编辑:H264的MPEG2VIDEOINFO值:

H264的MPEG2VIDEOINFO值

silverlight video-streaming h.264 smooth-streaming ms-media-foundation

7
推荐指数
1
解决办法
1510
查看次数

DirectShow,Media Foundation,DXVA,什么?

我的任务是修改一个使用DirectShow进行视频渲染的应用程序.旧的应用程序工作正常,但它开始显示年龄.

由于我有游戏背景,我想我应该这样做.在使用不同的技术制作了一堆原型之后,我非常确定我可以提取视频到纹理的渲染并使用DirectX来满足所有客户的请求.

但是,我现在已经到了必须选择一种技术的地步,我不能再迷失了......

  • DirectShow的
  • 媒体基金会
    • 媒体会话(<Windows 8)
    • 媒体引擎(> Windows 8)
  • DXVA1
  • DXVA2
  • DXVA-HD

DirectShow显然是最古老的,但仍然运行良好,也主要是因为可用的大量编解码器.

媒体基金会已经推出了Windows Vista,直到Windows 8还有一个名为"媒体会话"的东西,之后他们推出了"媒体引擎".如果我是正确的编解码器被称为MFT?实际上有哪些网站可以像free-codecs.com一样提供这些网站?

除了这两种技术之外,还有DXVA,它允许您将视频解码卸载到GPU.目前,我遇到了3种不同的类型.DXVA1是自XP以来一直存在的实现,DXVA2是更新的API.但什么是DXVA-HD?它比DXVA2更新还是同等名称?

我真的想转向媒体基金会,开箱即用的编解码器非常适合客户想要使用的格式.我所关心的是为它获取编解码器是多么容易...... Windows 8+默认媒体播放器是否仍然具有DirectShow和MF渲染路径并且可以即时交换它们还是微软完全逐步淘汰DirectShow?

我也无法完全理解DXVA应该如何工作.鉴于我想基本上在游戏中渲染视频,只有让所有渲染实际发生在GPU上并将应用程序逻辑保留在CPU上才有意义,但我真的找不到任何关于如何使用Media的好例子基础.这主要是因为我不知道DXVA2和DXVA-HD之间的区别.Windows 7 SDK附带了所有3个实现的示例......

如果有人能够以粗体回答我的问题,请纠正我的错误信息,并指出我正确的方向(DirectX + Media Foundation + DXVA-无论如何),我将非常感激!它可以像"结合Windows 7 SDK的这3个示例来获得您想要的"一样简单.

整个任务的目标是再次获得顶级形式的应用程序,我想绝对肯定我会选择像DirectShow已经拥有的下一个十年的技术:P

directx video directshow dxva ms-media-foundation

7
推荐指数
1
解决办法
1538
查看次数