1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/media/webrtc/webrtc_video_track_adapter.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "content/common/media/media_stream_options.h"
9 #include "content/renderer/media/media_stream_video_source.h"
10 #include "content/renderer/media/media_stream_video_track.h"
14 bool ConstraintKeyExists(const blink::WebMediaConstraints& constraints,
15 const blink::WebString& name) {
16 blink::WebString value_str;
17 return constraints.getMandatoryConstraintValue(name, value_str) ||
18 constraints.getOptionalConstraintValue(name, value_str);
21 // Used to make sure |source| is released on the main render thread.
22 void ReleaseWebRtcSourceOnMainRenderThread(
23 webrtc::VideoSourceInterface* source) {
27 } // anonymouse namespace
31 // Simple help class used for receiving video frames on the IO-thread from
32 // a MediaStreamVideoTrack and forward the frames to a
33 // WebRtcVideoCapturerAdapter on libjingle's worker thread.
34 // WebRtcVideoCapturerAdapter implements a video capturer for libjingle.
35 class WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter
36 : public base::RefCountedThreadSafe<WebRtcVideoSourceAdapter> {
38 WebRtcVideoSourceAdapter(
39 const scoped_refptr<base::MessageLoopProxy>& libjingle_worker_thread,
40 const scoped_refptr<webrtc::VideoSourceInterface>& source,
41 WebRtcVideoCapturerAdapter* capture_adapter);
43 void OnVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame,
44 const media::VideoCaptureFormat& format);
47 void OnVideoFrameOnWorkerThread(const scoped_refptr<media::VideoFrame>& frame,
48 const media::VideoCaptureFormat& format);
49 friend class base::RefCountedThreadSafe<WebRtcVideoSourceAdapter>;
50 virtual ~WebRtcVideoSourceAdapter();
52 scoped_refptr<base::MessageLoopProxy> render_thread_message_loop_;
54 // Used to DCHECK that frames are called on the IO-thread.
55 base::ThreadChecker io_thread_checker_;
57 // Used for posting frames to libjingle's worker thread. Accessed on the
59 scoped_refptr<base::MessageLoopProxy> libjingle_worker_thread_;
61 scoped_refptr<webrtc::VideoSourceInterface> video_source_;
62 // |capture_adapter_| is owned by |video_source_|
63 WebRtcVideoCapturerAdapter* capture_adapter_;
66 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter(
67 const scoped_refptr<base::MessageLoopProxy>& libjingle_worker_thread,
68 const scoped_refptr<webrtc::VideoSourceInterface>& source,
69 WebRtcVideoCapturerAdapter* capture_adapter)
70 : render_thread_message_loop_(base::MessageLoopProxy::current()),
71 libjingle_worker_thread_(libjingle_worker_thread),
72 video_source_(source),
73 capture_adapter_(capture_adapter) {
74 io_thread_checker_.DetachFromThread();
77 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::~WebRtcVideoSourceAdapter() {
78 // Since frames are posted to the worker thread, this object might be deleted
79 // on that thread. However, since |video_source_| was created on the render
80 // thread, it should be released on the render thread.
81 if (!render_thread_message_loop_->BelongsToCurrentThread()) {
82 webrtc::VideoSourceInterface* source = video_source_.get();
85 render_thread_message_loop_->PostTask(
87 base::Bind(&ReleaseWebRtcSourceOnMainRenderThread,
88 base::Unretained(source)));
92 void WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnIO(
93 const scoped_refptr<media::VideoFrame>& frame,
94 const media::VideoCaptureFormat& format) {
95 DCHECK(io_thread_checker_.CalledOnValidThread());
96 libjingle_worker_thread_->PostTask(
98 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread,
99 this, frame, format));
103 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread(
104 const scoped_refptr<media::VideoFrame>& frame,
105 const media::VideoCaptureFormat& format) {
106 DCHECK(libjingle_worker_thread_->BelongsToCurrentThread());
107 capture_adapter_->OnFrameCaptured(frame);
110 WebRtcVideoTrackAdapter::WebRtcVideoTrackAdapter(
111 const blink::WebMediaStreamTrack& track,
112 MediaStreamDependencyFactory* factory)
113 : web_track_(track) {
114 const blink::WebMediaConstraints& constraints =
115 MediaStreamVideoTrack::GetVideoTrack(track)->constraints();
117 bool is_screencast = ConstraintKeyExists(
118 constraints, base::UTF8ToUTF16(kMediaStreamSource));
119 WebRtcVideoCapturerAdapter* capture_adapter =
120 factory->CreateVideoCapturer(is_screencast);
122 // |video_source| owns |capture_adapter|
123 scoped_refptr<webrtc::VideoSourceInterface> video_source(
124 factory->CreateVideoSource(capture_adapter,
125 track.source().constraints()));
127 video_track_ = factory->CreateLocalVideoTrack(web_track_.id().utf8(),
130 video_track_->set_enabled(web_track_.isEnabled());
132 source_adapter_ = new WebRtcVideoSourceAdapter(
133 factory->GetWebRtcWorkerThread(),
139 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO,
143 DVLOG(3) << "WebRtcVideoTrackAdapter ctor() : is_screencast "
147 WebRtcVideoTrackAdapter::~WebRtcVideoTrackAdapter() {
148 DCHECK(thread_checker_.CalledOnValidThread());
149 DVLOG(3) << "WebRtcVideoTrackAdapter dtor().";
150 RemoveFromVideoTrack(this, web_track_);
153 void WebRtcVideoTrackAdapter::OnEnabledChanged(bool enabled) {
154 DCHECK(thread_checker_.CalledOnValidThread());
155 video_track_->set_enabled(enabled);
158 } // namespace content