首页 > 解决方案 > 使用 Microsoft Media Foundation 和 Desktop Duplication API 创建视频

问题描述

我正在使用DDA捕获桌面图像帧并将它们发送到服务器,这些帧应该用于使用MMF创建视频。我想了解MMF需要做什么,如果我将使用Source ReaderSink Writer捕获的帧渲染视频

有两个问题:

1)嗯,首先,我不能完全理解,如果我已经从DDA接收到视频帧,实际上是否需要带有Media Source的Source Reader?我可以将它们发送到Sink Writer并渲染视频吗?

2)据我所知,如果仍然需要Source ReaderMedia Source ,首先要做的是编写我自己的Media Source,它将理解使用DDA捕获的DXGI_FORMAT_B8G8R8A8_UNORM帧。然后我应该使用带有合适 Decoders\Encoders 的Souce ReaderSink Writer并将媒体数据发送到Media Sinks。请您更详细地解释一下在这种情况下需要做什么?

标签: video-capturems-media-foundationdesktop-duplication

解决方案


在您的情况下,实施SourceReader不是必需的,但您可以继续实施它,它会起作用。

相反,您也可以直接将通过桌面复制捕获的输入缓冲区提供给 SinkWriter。就像下面一样,

CComPtr<IMFAttributes> attribs;
CComPtr<IMFMediaSink>    m_media_sink;
IMFSinkWriterPtr         m_sink_writer;

MFCreateAttributes(&attribs, 0);
attribs->SetUINT32(MF_LOW_LATENCY, TRUE);
attribs->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, TRUE);

IMFMediaTypePtr mediaTypeOut = MediaTypeutput(fps, bit_rate);
MFCreateFMPEG4MediaSink(stream, mediaTypeOut, nullptr, &m_media_sink));
MFCreateSinkWriterFromMediaSink(m_media_sink, attribs, &m_sink_writer);

//Set input media type
mediaTypeIn->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32);
//Set output media type
mediaTypeOut->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);

IMFSamplePtr sample;
MFCreateSample(&sample);
sample->AddBuffer(m_buffer); // m_buffer is source buffer in R8G8B8A8 format

sample->SetSampleTime(m_time_stamp);
sample->SetSampleDuration(m_frame_duration);
m_sink_writer->WriteSample(m_stream_index, sample);

是一个基于 SinkWriter 的完美工作示例。它同时支持网络和文件接收器。它实际上通过 GDI 方法捕获桌面。DDA 几乎一样,使用 DDA 确实可以获得更好的性能。

我还在这里上传了一个实际上基于桌面复制的示例,并直接使用IMFTransform代替,并使用 Live555 将输出视频流式传输为 RTP 流。通过这种方法,我能够达到 100FPS。

如果您决定采用 SinkWriter 方法,则不必担心颜色转换部分,因为它由 SinkWriter 在后台负责。使用IMFTransform,您将不得不处理颜色转换部分,但您将对编码器进行细粒度控制。

这里有一些更多的参考链接供您参考。

  1. https://github.com/ashumeow/webrtc4all/blob/master/gotham/MFT_WebRTC4All/test/test_encoder.cc
  2. DXGI 桌面复制:编码帧以通过网络发送它们
  3. 在 ffplay 中获得绿屏:使用 Live555 通过 RTP 流将桌面(DirectX 表面)流式传输为 H264 视频
  4. 输入少量输入样本后,英特尔图形硬件 H264 MFT ProcessInput 调用失败,同样适用于 Nvidia 硬件 MFT
  5. 使用 DirectX11 像素着色器在 GPU 中从 DXGI_FORMAT_B8G8R8A8_UNORM 到 NV12 的颜色转换
  6. 英特尔 H264 硬件 MFT 不支持 GOP 设置
  7. 使用 Media Foundation 对通过桌面复制获得的 D3D 表面进行编码

推荐阅读