webrtc 视频数据流程概览

        视频数据由VideoCapture 采集后交给VideoSource,VideoSource 通过VideoBroadcaster成员,把数据发送给每个VideoSink(VideoEncoder和LoacalPreview)。VideoEncoder把视频数据编码之后交给网络层进行发送,LoacalPreview把视频数据渲染到屏幕上。

        从网络层收到视频数据后,先交给VideoEncoder LoacalPreview进行解码,解码之后交给VideoBroadcaster,最后由VideoBroadcaster分发给每个VideoSink(RemoteRenderer)。RemoteRenderer把视频数据渲染到屏幕上。

       1、视频采集

        VideoCaptureModule ,定义了启停采集(启动时设置参数)和视频数据回调的接口 RegisterCaptureDataCallback,内部还有一个DeviceInfo类,定义了获取相机设备信息的接口。

  

        webrtc::videocapturemodule::VideoCaptureImpl 是webrtc::VideoCaptureModule的子类,其中平台无关的视频采集逻辑实现,主要是调用数据回调,以及进行必要的数据格式转换。

         此外,webrtc还定义了一个VideoCaptureFactory类,不过只有其中创建VideoCaptureModule 和 DeviceInfo 两个接口,而这两个接口的实现都在平台相关的代码中。

        windows平台相关的逻辑在VideoCaptureImpl的子类实现,windows的平台是在webrtc::videocapturemodule::VideoCaptureDS ,利用Directshow实现视频采集。   

          videoCaptureModule   ​​​​​​的基本使用可以参考test/vcm_capturer.cc的代码:

       *) VideoCaptureFactory::CreateDeviceInfo 创建DeviceInfo 对象。

        *)device_info->GetDeviceName 获取设备唯一标识(其中deviceUniqueIdUTF8 参数)

        *)  vcm_->RegisterCaptureDataCallback(this);设置视频的数据回调

        *)把采集参数(宽高,帧率,数据格式)设置到VideoCaptureCapability 对象中。

        停止采集很简单,只需要调用vcm_stopcapture,并解除对vcm_的引用(置nullptr)即可。

         1.1)windows 上的视频采集可以使用DirectShow 实现。

        DirectShow 的核心思想是模块化架构,每一个组件叫做filter,应用开发人员只需要把不同的filter组合起来,形成一个filter graph 即可。真正和硬件打交道的都由filter实现。

        *)枚举设备:modules/video_capture/windows/device_info_ds.cc

        *)启停设备、设置采集格式:modules/video_capture/windows/video_capture_ds.cc

        *)接收视频数据:modules/video_capture/windows/sink_filter_ds.cc

        2、视频渲染        

        本地视频数据采集以后,被封装为VideoFrame对象,并在本地进行预览,以及送入视频编码模块,用于编码发送。此外,从其他客户端收到的视频数据(远端视频)经过解码后,也将得到VideoFrame对象,并在本地进行渲染。

        windows 视频渲染:

        webrtc windows 视频渲染没有在SDK层的代码实现。而是在demo 中实现的。其中windows demo 调用的是MFC的绘图接口BitBlt,webrtc调用的是GTK提供的绘图接口。

        windows linux 视频渲染的流程是一样的,在demo 层实现了一个rtc::video-sinkInterface<VideoFrame>的子类(VideoRenderer),调用webrtc::VideoTrackInterface::AddOrUpdateSink把Renderer添加到Track 中,Renderer的OnFrame函数会在需要渲染新的帧时被调用。在onFrame回调中,Demo会把YUV格式的视频数据转换为RGB格式,之后就在MFC/GTK中的绘图回调里面把RGB格式的视频数据绘制到界面上。

        4、视频编解码

           VP9支持SVC,当VP8 和H.264不支持,SVC能把视频数据编码出多个层,解码时有了基本层就可以解码出基本的视频内容。如果再有更多的增强层,则能解码出质量更多的视频内容,如果需要使用SVC,就不能选择VP8和H.264了。

        也可以考虑simulcast。simulcast 是用多个编码器把一份视频数据编码分为多种分辨率和帧率,发送端把多路编码后的数据发送到服务器,这样不同的接收端就可以根据自己的网络条件和设备性能选择不同的数据。

        1)视频编码分析:

       windows 的 Linux 的视频编码使用的是OpenH264库的软件实现,我们在创建PC Factory时传入的fatory 是BuiltinVideoEncoderFactory,最终创建的是H264EncoderImpl。

       src\modules\video_coding\codecs\h264\H264_encoder_impl.cc
       InitEncode:初始化编码器   

       openh264的接口虽然包含SVC字样,但是openh264库并不支持H.264的SVC编码器。

InitEncode:

 Encode:

         SetRates:设置/更新码率、帧率等参数。

        销毁编码器:

 

         H264DecoderImpl 实现了c++的VideoDecoder 接口,在src\modules\video_coding\codecs\h264\H264_decoder_impl.cc

         H264DecoderImpl::Configure 初始化解码器,创建和配置ffmpeg 解码器。

        webrtc 没有使用ffmpeg 的内存管理,而是实现了自己的内存管理,具体在H264DecoderImpl::AVGetBuffer2 和H264DecoderImpl::AVFreeBuffer2 中。

         

        2)视频解码

        H264DecoderImpl 实现了c++的VideoDecoder接口。

        视频数据流程调用栈:

       图一: windows 视频数据调用流程

猜你喜欢

转载自blog.csdn.net/abc1231987/article/details/121074639