Linux基于webRTC的二次开发(二) 实现远程桌面共享

webRTC中的desktop_capture模块提供了捕获桌面和捕获窗口的相关功能,而实现远程桌面共享功能需要将desktop_capture捕获的画面作为peerconnection的视频源,下面介绍一下相关的方法

peerconnection添加视频源时调用AddTrack(rtc::scoped_refptr<MediaStreamTrackInterface> track,const std::vector<std::string>& stream_ids);,我们需要传入一个rtc::scoped_refptr<webrtc::VideoTrackInterface>类型作为视频源,使用PeerConnectionFactoryInterface::CreateVideoTrack(const std::string& label,VideoTrackSourceInterface* source)创建。

可以看到,我们需要获得VideoTrackSourceInterface*
webrtc提供了AdaptedVideoTrackSource类,该类继承自VideoTrackSourceInterface。我们需要继承实现AdaptedVideoTrackSource,在其中添加捕获桌面获得的图像,然后将其传入父类的OnFrame函数即可
简单代码如下

class MyDesktopCapture : public rtc::AdaptedVideoTrackSource, public webrtc::DesktopCapturer::Callback
{
public:
  explicit MyDesktopCapture();

  static rtc::scoped_refptr<MyDesktopCapture> Create();

  void OnCaptureResult(webrtc::DesktopCapturer::Result result, std::unique_ptr<webrtc::DesktopFrame> desktopframe) override;

  bool is_screencast() const override;

  absl::optional<bool> needs_denoising() const override;

  webrtc::MediaSourceInterface::SourceState state() const override;

  bool remote() const override;

private:

  std::unique_ptr<CaptureThread> capture_;

};

其中OnCaptureResult作为DesktopCatpure的回调,在桌面捕获获得图像时会调用该方法
由于桌面捕获获得的DesktopFrame都是RGBA数据,我们需要将其转换成存放I420数据的VideoFrame,然后调用OnFrame

现在新版本的webrtc不提供ConvertToI420方法,我们需要自己用libyuv实现,将RGBA转换为I420

void MyDesktopCapture::OnCaptureResult(webrtc::DesktopCapturer::Result result, std::unique_ptr<webrtc::DesktopFrame> desktopframe)
{
    if(result!=webrtc::DesktopCapturer::Result::SUCCESS)
        return;
    int width=desktopframe->size().width();
    int height=desktopframe->size().height();

    rtc::scoped_refptr<webrtc::I420Buffer> buffer=webrtc::I420Buffer::Create(width,height);
    int stride=width;
    uint8_t* yplane=buffer->MutableDataY();
    uint8_t* uplane=buffer->MutableDataU();
    uint8_t* vplane=buffer->MutableDataV();
    libyuv::ConvertToI420(desktopframe->data(),0,
                          yplane,stride,
                          uplane,(stride+1)/2,
                          vplane,(stride+1)/2,
                          0,0,
                          width,height,
                          width,height,
                          libyuv::kRotate0,libyuv::FOURCC_ARGB);
    webrtc::VideoFrame frame=webrtc::VideoFrame(buffer,0,0,webrtc::kVideoRotation_0);
    this->OnFrame(frame);

}

最后我们使用该类创建VideoTrack,添加进peerconnection即可
实现效果如下图

posted @ 2019-11-15 17:39  码、农  阅读(...)  评论(...编辑  收藏