| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/media/webrtc/webrtc_video_track_adapter.h" | 5 #include "content/renderer/media/webrtc/webrtc_video_track_adapter.h" |
| 6 | 6 |
| 7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
| 8 #include "content/common/media/media_stream_options.h" | 8 #include "content/common/media/media_stream_options.h" |
| 9 #include "content/renderer/media/media_stream_video_source.h" | 9 #include "content/renderer/media/media_stream_video_source.h" |
| 10 #include "content/renderer/media/media_stream_video_track.h" | 10 #include "content/renderer/media/media_stream_video_track.h" |
| 11 | 11 |
| 12 namespace { | 12 namespace { |
| 13 | 13 |
| 14 bool ConstraintKeyExists(const blink::WebMediaConstraints& constraints, | 14 bool ConstraintKeyExists(const blink::WebMediaConstraints& constraints, |
| 15 const blink::WebString& name) { | 15 const blink::WebString& name) { |
| 16 blink::WebString value_str; | 16 blink::WebString value_str; |
| 17 return constraints.getMandatoryConstraintValue(name, value_str) || | 17 return constraints.getMandatoryConstraintValue(name, value_str) || |
| 18 constraints.getOptionalConstraintValue(name, value_str); | 18 constraints.getOptionalConstraintValue(name, value_str); |
| 19 } | 19 } |
| 20 | 20 |
| 21 // Used to make sure |source| is released on the main render thread. |
| 22 void ReleaseWebRtcSourceOnMainRenderThread( |
| 23 webrtc::VideoSourceInterface* source) { |
| 24 source->Release(); |
| 25 } |
| 26 |
| 21 } // anonymouse namespace | 27 } // anonymouse namespace |
| 22 | 28 |
| 23 namespace content { | 29 namespace content { |
| 24 | 30 |
| 25 // Simple help class used for receiving video frames on the IO-thread from | 31 // Simple help class used for receiving video frames on the IO-thread from |
| 26 // a MediaStreamVideoTrack and forward the frames to a | 32 // a MediaStreamVideoTrack and forward the frames to a |
| 27 // WebRtcVideoCapturerAdapter that implements a video capturer for libjingle. | 33 // WebRtcVideoCapturerAdapter on libjingle's worker thread. |
| 34 // WebRtcVideoCapturerAdapter implements a video capturer for libjingle. |
| 28 class WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter | 35 class WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter |
| 29 : public base::RefCountedThreadSafe<WebRtcVideoSourceAdapter> { | 36 : public base::RefCountedThreadSafe<WebRtcVideoSourceAdapter> { |
| 30 public: | 37 public: |
| 31 WebRtcVideoSourceAdapter( | 38 WebRtcVideoSourceAdapter( |
| 39 const scoped_refptr<base::MessageLoopProxy>& libjingle_worker_thread, |
| 32 const scoped_refptr<webrtc::VideoSourceInterface>& source, | 40 const scoped_refptr<webrtc::VideoSourceInterface>& source, |
| 33 WebRtcVideoCapturerAdapter* capture_adapter); | 41 WebRtcVideoCapturerAdapter* capture_adapter); |
| 34 | 42 |
| 35 void OnVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame, | 43 void OnVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame, |
| 36 const media::VideoCaptureFormat& format); | 44 const media::VideoCaptureFormat& format); |
| 37 | 45 |
| 38 private: | 46 private: |
| 47 void OnVideoFrameOnWorkerThread(const scoped_refptr<media::VideoFrame>& frame, |
| 48 const media::VideoCaptureFormat& format); |
| 39 friend class base::RefCountedThreadSafe<WebRtcVideoSourceAdapter>; | 49 friend class base::RefCountedThreadSafe<WebRtcVideoSourceAdapter>; |
| 40 virtual ~WebRtcVideoSourceAdapter(); | 50 virtual ~WebRtcVideoSourceAdapter(); |
| 41 | 51 |
| 52 scoped_refptr<base::MessageLoopProxy> render_thread_message_loop_; |
| 53 |
| 42 // Used to DCHECK that frames are called on the IO-thread. | 54 // Used to DCHECK that frames are called on the IO-thread. |
| 43 base::ThreadChecker io_thread_checker_; | 55 base::ThreadChecker io_thread_checker_; |
| 56 |
| 57 // Used for posting frames to libjingle's worker thread. Accessed on the |
| 58 // IO-thread. |
| 59 scoped_refptr<base::MessageLoopProxy> libjingle_worker_thread_; |
| 60 |
| 44 scoped_refptr<webrtc::VideoSourceInterface> video_source_; | 61 scoped_refptr<webrtc::VideoSourceInterface> video_source_; |
| 45 // |capture_adapter_| is owned by |video_source_| | 62 // |capture_adapter_| is owned by |video_source_| |
| 46 WebRtcVideoCapturerAdapter* capture_adapter_; | 63 WebRtcVideoCapturerAdapter* capture_adapter_; |
| 47 }; | 64 }; |
| 48 | 65 |
| 49 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter( | 66 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter( |
| 67 const scoped_refptr<base::MessageLoopProxy>& libjingle_worker_thread, |
| 50 const scoped_refptr<webrtc::VideoSourceInterface>& source, | 68 const scoped_refptr<webrtc::VideoSourceInterface>& source, |
| 51 WebRtcVideoCapturerAdapter* capture_adapter) | 69 WebRtcVideoCapturerAdapter* capture_adapter) |
| 52 : video_source_(source), | 70 : render_thread_message_loop_(base::MessageLoopProxy::current()), |
| 71 libjingle_worker_thread_(libjingle_worker_thread), |
| 72 video_source_(source), |
| 53 capture_adapter_(capture_adapter) { | 73 capture_adapter_(capture_adapter) { |
| 54 io_thread_checker_.DetachFromThread(); | 74 io_thread_checker_.DetachFromThread(); |
| 55 } | 75 } |
| 56 | 76 |
| 57 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::~WebRtcVideoSourceAdapter() { | 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(); |
| 83 source->AddRef(); |
| 84 video_source_ = NULL; |
| 85 render_thread_message_loop_->PostTask( |
| 86 FROM_HERE, |
| 87 base::Bind(&ReleaseWebRtcSourceOnMainRenderThread, |
| 88 base::Unretained(source))); |
| 89 } |
| 58 } | 90 } |
| 59 | 91 |
| 60 void WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnIO( | 92 void WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnIO( |
| 61 const scoped_refptr<media::VideoFrame>& frame, | 93 const scoped_refptr<media::VideoFrame>& frame, |
| 62 const media::VideoCaptureFormat& format) { | 94 const media::VideoCaptureFormat& format) { |
| 63 DCHECK(io_thread_checker_.CalledOnValidThread()); | 95 DCHECK(io_thread_checker_.CalledOnValidThread()); |
| 96 libjingle_worker_thread_->PostTask( |
| 97 FROM_HERE, |
| 98 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread, |
| 99 this, frame, format)); |
| 100 } |
| 101 |
| 102 void |
| 103 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread( |
| 104 const scoped_refptr<media::VideoFrame>& frame, |
| 105 const media::VideoCaptureFormat& format) { |
| 106 DCHECK(libjingle_worker_thread_->BelongsToCurrentThread()); |
| 64 capture_adapter_->OnFrameCaptured(frame); | 107 capture_adapter_->OnFrameCaptured(frame); |
| 65 } | 108 } |
| 66 | 109 |
| 67 WebRtcVideoTrackAdapter::WebRtcVideoTrackAdapter( | 110 WebRtcVideoTrackAdapter::WebRtcVideoTrackAdapter( |
| 68 const blink::WebMediaStreamTrack& track, | 111 const blink::WebMediaStreamTrack& track, |
| 69 MediaStreamDependencyFactory* factory) | 112 MediaStreamDependencyFactory* factory) |
| 70 : web_track_(track) { | 113 : web_track_(track) { |
| 71 const blink::WebMediaConstraints& constraints = | 114 const blink::WebMediaConstraints& constraints = |
| 72 MediaStreamVideoTrack::GetVideoTrack(track)->constraints(); | 115 MediaStreamVideoTrack::GetVideoTrack(track)->constraints(); |
| 73 | 116 |
| 74 bool is_screencast = ConstraintKeyExists( | 117 bool is_screencast = ConstraintKeyExists( |
| 75 constraints, base::UTF8ToUTF16(kMediaStreamSource)); | 118 constraints, base::UTF8ToUTF16(kMediaStreamSource)); |
| 76 WebRtcVideoCapturerAdapter* capture_adapter = | 119 WebRtcVideoCapturerAdapter* capture_adapter = |
| 77 factory->CreateVideoCapturer(is_screencast); | 120 factory->CreateVideoCapturer(is_screencast); |
| 78 | 121 |
| 79 // |video_source| owns |capture_adapter| | 122 // |video_source| owns |capture_adapter| |
| 80 scoped_refptr<webrtc::VideoSourceInterface> video_source( | 123 scoped_refptr<webrtc::VideoSourceInterface> video_source( |
| 81 factory->CreateVideoSource(capture_adapter, | 124 factory->CreateVideoSource(capture_adapter, |
| 82 track.source().constraints())); | 125 track.source().constraints())); |
| 83 | 126 |
| 84 video_track_ = factory->CreateLocalVideoTrack(web_track_.id().utf8(), | 127 video_track_ = factory->CreateLocalVideoTrack(web_track_.id().utf8(), |
| 85 video_source.get()); | 128 video_source.get()); |
| 86 | 129 |
| 87 video_track_->set_enabled(web_track_.isEnabled()); | 130 video_track_->set_enabled(web_track_.isEnabled()); |
| 88 | 131 |
| 89 source_adapter_ = new WebRtcVideoSourceAdapter(video_source, | 132 source_adapter_ = new WebRtcVideoSourceAdapter( |
| 90 capture_adapter); | 133 factory->GetWebRtcWorkerThread(), |
| 134 video_source, |
| 135 capture_adapter); |
| 91 | 136 |
| 92 AddToVideoTrack( | 137 AddToVideoTrack( |
| 93 this, | 138 this, |
| 94 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO, | 139 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO, |
| 95 source_adapter_), | 140 source_adapter_), |
| 96 web_track_); | 141 web_track_); |
| 97 | 142 |
| 98 DVLOG(3) << "WebRtcVideoTrackAdapter ctor() : is_screencast " | 143 DVLOG(3) << "WebRtcVideoTrackAdapter ctor() : is_screencast " |
| 99 << is_screencast; | 144 << is_screencast; |
| 100 } | 145 } |
| 101 | 146 |
| 102 WebRtcVideoTrackAdapter::~WebRtcVideoTrackAdapter() { | 147 WebRtcVideoTrackAdapter::~WebRtcVideoTrackAdapter() { |
| 103 DCHECK(thread_checker_.CalledOnValidThread()); | 148 DCHECK(thread_checker_.CalledOnValidThread()); |
| 104 DVLOG(3) << "WebRtcVideoTrackAdapter dtor()."; | 149 DVLOG(3) << "WebRtcVideoTrackAdapter dtor()."; |
| 105 RemoveFromVideoTrack(this, web_track_); | 150 RemoveFromVideoTrack(this, web_track_); |
| 106 } | 151 } |
| 107 | 152 |
| 108 void WebRtcVideoTrackAdapter::OnEnabledChanged(bool enabled) { | 153 void WebRtcVideoTrackAdapter::OnEnabledChanged(bool enabled) { |
| 109 DCHECK(thread_checker_.CalledOnValidThread()); | 154 DCHECK(thread_checker_.CalledOnValidThread()); |
| 110 video_track_->set_enabled(enabled); | 155 video_track_->set_enabled(enabled); |
| 111 } | 156 } |
| 112 | 157 |
| 113 } // namespace content | 158 } // namespace content |
| OLD | NEW |