如果想启动摄像头,并预览视频,m76中的做法是:
首先定义一个VideoTrackSource ,
class CapturerTrackSource : public webrtc::VideoTrackSource {
。。。
具体后面说明
}
之后创建该VideoTrackSource 的一个实例,这个实例用于后面创建VideoTrack。
不过,创建的使用要注意后续释放这个对象是要保持在同一个线程,所以如下创建:
webrtc::MethodCall0 callCreate(this, &SimplePeerConnection::createVcmVideoSource);
callCreate.Marshal(RTC_FROM_HERE, g_worker_thread.get());
接着创建video track
rtc::scoped_refptr video_track(
g_peer_connection_factory->CreateVideoTrack(kVideoLabel,
localVideoTrackSource_));
监听视频流
video_track->AddOrUpdateSink(&((MediaStream*)local_stream_.get())->videoObserver(), rtc::VideoSinkWants());
+++++++++++++++++++++++++++++++++++++++++++++++
分析一下VideoTrackSource和videoTrack的关系
videoTrack实现VideoTrackInterface,有下面三个重要接口:
void AddOrUpdateSink(rtc::VideoSinkInterface* sink,
const rtc::VideoSinkWants& wants) override {}
void RemoveSink(rtc::VideoSinkInterface* sink) override {}
virtual VideoTrackSourceInterface* GetSource() const = 0;
实际上,是通过 GetSource(),找到source,然后在AddOrUpdateSink,RemoveSink时,调用source的对应方法,将数据的消费者注册到source里面
所以VideoTrackSource实际上组织VideoTrack和TrackSource,为他们搭上关系
因此,VideoTrackSource要一个VideoSource,用于代理track的AddOrUpdateSink,RemoveSink
具体来说:
class CapturerTrackSource : public webrtc::VideoTrackSource
里面有一个Create函数, 创建了一个VcmCapturer,这个一个VideoSource
static rtc::scoped_refptr Create() {
const size_t kWidth = 640;
const size_t kHeight = 480;
const size_t kFps = 30;
const size_t kDeviceIndex = 0;
std::unique_ptr capturer = absl::WrapUnique(
webrtc::VcmCapturer::Create(kWidth, kHeight, kFps, kDeviceIndex));
if (!capturer) {
return nullptr;
}
return new rtc::RefCountedObject(std::move(capturer));
}
有几层继承关系
class VcmCapturer : public CustomVideoCapturer, public rtc::VideoSinkInterface<VideoFrame> {
VcmCapturer本身主要用于启动物理摄像头
class CustomVideoCapturer : public rtc::VideoSourceInterface<VideoFrame> {
。。。
里面有:
rtc::VideoBroadcaster broadcaster_;
cricket::VideoAdapter video_adapter_;
帮忙 VcmCapturer 处理掉AddOrUpdateSink,RemoveSink
video_adapter_可以用来对数据做转换(适配)
https://my.oschina.net/u/4249347/blog/4453525 一篇视频处理的文档
网友评论