Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 利用媒体基础编码直接X面_C++_Directx 11_Ms Media Foundation_Dxgi - Fatal编程技术网

C++ 利用媒体基础编码直接X面

C++ 利用媒体基础编码直接X面,c++,directx-11,ms-media-foundation,dxgi,C++,Directx 11,Ms Media Foundation,Dxgi,我正在尝试使用MediaFoundation API对视频进行编码,但将示例推送到编写器时遇到问题 我正在通过桌面复制API对帧进行编码。我最终得到的是一个带有桌面图像的ID3D11Texture2D 我正在尝试创建一个包含此曲面的IMFVideoSample,然后将该视频样本推送到一个SinkWriter 我试着用不同的方式来处理这个问题: 我调用了MFCreateVideoSampleFromSurface(texture,&pSample)其中texture是ID3D11Texture2

我正在尝试使用MediaFoundation API对视频进行编码,但将示例推送到编写器时遇到问题

我正在通过桌面复制API对帧进行编码。我最终得到的是一个带有桌面图像的ID3D11Texture2D

我正在尝试创建一个包含此曲面的IMFVideoSample,然后将该视频样本推送到一个SinkWriter

我试着用不同的方式来处理这个问题:

  • 我调用了
    MFCreateVideoSampleFromSurface(texture,&pSample)
    其中texture是ID3D11Texture2D,填入SampleTime和SampleDuration,然后将创建的样本传递给SinkWriter。
    新喀里多尼亚返回E_INVALIDARG

  • 我尝试通过传递nullptr作为第一个参数来创建示例,并使用MFCreateDXGISurfaceBuffer自己创建缓冲区,然后将生成的缓冲区传递到示例中。
    那也没用

  • 我通读了MediaFoundation文档,找不到有关如何使用DirectX纹理创建示例的详细信息

我没有东西可以试了。

有没有人曾经使用过这个API,并且能想到我应该检查的东西,或者我可以如何调试这个API?

首先,你应该学会使用它。 很可能,它会立即告诉您问题所在

但我的猜测是,可能会出现以下问题

  • 除SampleTime/SampleDuration外,可能还需要其他一些属性

  • 可能,SinkWriter需要一个可以在CPU上读取的纹理。要解决这个问题,当一个帧可用时,创建一个相同格式+大小的暂存纹理,调用CopyResource将桌面复制到暂存纹理,然后将该暂存纹理传递给MF

  • 即使您使用硬件编码器,因此CPU从不尝试读取纹理数据,我也不认为直接将桌面纹理传递给MF是个好主意

  • 为采样设置D3D纹理时,不会在任何位置复制数据,采样仅保留纹理

    MF异步工作,如果需要,它可以在其拓扑节点中缓冲多个样本


    DD同步提供数据,您只能在AcquireNextFrame和ReleaseFrame调用之间访问纹理。

    我认为您在使用
    MFCreateVideoSampleFromSurface
    MFCreateDXGISurfaceBuffer
    时犯了错误。这些函数创建用于写入DirectX和visualization表面的缓冲区,并使用接口
    IMF2DBuffer
    创建对象,但编码器和写入器需要使用
    IMFMediaBuffer
    的对象。他们无法理解
    IMF2DBuffer
    。尝试使用函数“MFCreateSampleCopierMFT”-它创建了MFT对象,用于从
    IMFMediaBuffer
    复制到
    IMF2DBuffer
    上。也许它可以做反向工作!?!你确定吗?查看
    MFCreateDXGISurfaceBuffer
    的文档,它声明它返回指向IMFMediaBuffer的指针。从由DXGI曲面支持的示例/缓冲区中获取数据的最佳方法似乎是MFGetService。此上的另一个线程表示这两个API应该能够处理此任务:。关于这两种方法的最佳使用,我找不到任何合适的例子。我们将尝试向另一个方向发展,这是一个遗憾,因为DesktopDuplication+MediaFoundation似乎是解决我们问题的最佳解决方案。您使用DesktopDuplication+MediaFoundation的想法很有趣。在“CaptureProject”网站上的项目CaptureManager SDK中,我使用DirectX9+MediaFoundation捕获实时屏幕视频,但它从桌面管理器复制图像(在任务管理器程序中,桌面管理器占15%)。我认为使用DesktopReplication可以更有效。@Tiago Magalhães您找到解决问题的方法了吗?我也被它困住了,因为我找不到相关的资源。我尽量不让问题陷入太多细节,但我正在复制桌面纹理,然后将其传递给MF,方法是获取桌面纹理描述符,并在使用CopyResource之前使用该描述符创建一个新纹理。但是,感谢为mftrace指针提供了lor,我将对此进行查看。我使用了mfctrace,发现发送到接收器的样本被报告为大小为0B,因此它们的创建出现问题。@Soons,我甚至尝试创建了一个暂存纹理,并调用了CopyResource,对输出没有影响。只需要一个绿色屏幕。