Make sure webrtc::VideoSourceInterface is released on the main render thread.
[chromium-blink-merge.git] / content / renderer / media / webrtc / webrtc_video_track_adapter.cc
blob55ee5d45d3d4d116f5176cac10f6048ca8225025
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"
12 namespace {
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 } // anonymouse namespace
23 namespace content {
25 // Used to make sure |source| is released on the main render thread.
26 void ReleaseWebRtcSourceOnMainRenderThread(
27 webrtc::VideoSourceInterface* source) {
28 source->Release();
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 that implements a video capturer for libjingle.
34 class WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter
35 : public base::RefCountedThreadSafe<WebRtcVideoSourceAdapter> {
36 public:
37 WebRtcVideoSourceAdapter(
38 const scoped_refptr<webrtc::VideoSourceInterface>& source,
39 WebRtcVideoCapturerAdapter* capture_adapter);
41 void OnVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame,
42 const media::VideoCaptureFormat& format);
44 private:
45 friend class base::RefCountedThreadSafe<WebRtcVideoSourceAdapter>;
46 virtual ~WebRtcVideoSourceAdapter();
48 scoped_refptr<base::MessageLoopProxy> render_thread_message_loop_;
49 // Used to DCHECK that frames are called on the IO-thread.
50 base::ThreadChecker io_thread_checker_;
52 // |video_source_| is a libjingle object that must be released on the main
53 // render thread.
54 scoped_refptr<webrtc::VideoSourceInterface> video_source_;
55 // |capture_adapter_| is owned by |video_source_|
56 WebRtcVideoCapturerAdapter* capture_adapter_;
59 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter(
60 const scoped_refptr<webrtc::VideoSourceInterface>& source,
61 WebRtcVideoCapturerAdapter* capture_adapter)
62 : render_thread_message_loop_(base::MessageLoopProxy::current()),
63 video_source_(source),
64 capture_adapter_(capture_adapter) {
65 io_thread_checker_.DetachFromThread();
68 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::~WebRtcVideoSourceAdapter() {
69 if (!render_thread_message_loop_->BelongsToCurrentThread()) {
70 webrtc::VideoSourceInterface* source = video_source_.get();
71 source->AddRef();
72 video_source_ = NULL;
73 render_thread_message_loop_->PostTask(
74 FROM_HERE,
75 base::Bind(&ReleaseWebRtcSourceOnMainRenderThread,
76 base::Unretained(source)));
80 void WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnIO(
81 const scoped_refptr<media::VideoFrame>& frame,
82 const media::VideoCaptureFormat& format) {
83 DCHECK(io_thread_checker_.CalledOnValidThread());
84 capture_adapter_->OnFrameCaptured(frame);
87 WebRtcVideoTrackAdapter::WebRtcVideoTrackAdapter(
88 const blink::WebMediaStreamTrack& track,
89 MediaStreamDependencyFactory* factory)
90 : web_track_(track) {
91 const blink::WebMediaConstraints& constraints =
92 MediaStreamVideoTrack::GetVideoTrack(track)->constraints();
94 bool is_screencast = ConstraintKeyExists(
95 constraints, base::UTF8ToUTF16(kMediaStreamSource));
96 WebRtcVideoCapturerAdapter* capture_adapter =
97 factory->CreateVideoCapturer(is_screencast);
99 // |video_source| owns |capture_adapter|
100 scoped_refptr<webrtc::VideoSourceInterface> video_source(
101 factory->CreateVideoSource(capture_adapter,
102 track.source().constraints()));
104 video_track_ = factory->CreateLocalVideoTrack(web_track_.id().utf8(),
105 video_source.get());
107 video_track_->set_enabled(web_track_.isEnabled());
109 source_adapter_ = new WebRtcVideoSourceAdapter(video_source,
110 capture_adapter);
112 MediaStreamVideoTrack::GetVideoTrack(track)->AddSink(
113 this, base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO,
114 source_adapter_));
116 DVLOG(3) << "WebRtcVideoTrackAdapter ctor() : is_screencast "
117 << is_screencast;
120 WebRtcVideoTrackAdapter::~WebRtcVideoTrackAdapter() {
121 DCHECK(thread_checker_.CalledOnValidThread());
122 DVLOG(3) << "WebRtcVideoTrackAdapter dtor().";
123 MediaStreamVideoTrack::GetVideoTrack(web_track_)->RemoveSink(this);
126 void WebRtcVideoTrackAdapter::OnEnabledChanged(bool enabled) {
127 DCHECK(thread_checker_.CalledOnValidThread());
128 video_track_->set_enabled(enabled);
131 } // namespace content