Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(295)

Side by Side Diff: content/renderer/media/media_stream_video_capturer_source.cc

Issue 242013002: Refactor video capturing code in the render process (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merged again :( Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/media_stream_video_capturer_source.h" 5 #include "content/renderer/media/media_stream_video_capturer_source.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
8 #include "base/location.h" 9 #include "base/location.h"
9 #include "content/renderer/media/video_capture_impl_manager.h" 10 #include "content/renderer/media/video_capture_impl_manager.h"
10 #include "content/renderer/render_thread_impl.h" 11 #include "content/renderer/render_thread_impl.h"
12 #include "media/base/bind_to_current_loop.h"
11 #include "media/base/video_frame.h" 13 #include "media/base/video_frame.h"
12 14
13 namespace { 15 namespace {
14 16
15 struct SourceVideoFormat { 17 struct SourceVideoFormat {
16 int width; 18 int width;
17 int height; 19 int height;
18 int frame_rate; 20 int frame_rate;
19 }; 21 };
20 22
(...skipping 10 matching lines...) Expand all
31 33
32 namespace content { 34 namespace content {
33 35
34 VideoCapturerDelegate::VideoCapturerDelegate( 36 VideoCapturerDelegate::VideoCapturerDelegate(
35 const StreamDeviceInfo& device_info) 37 const StreamDeviceInfo& device_info)
36 : session_id_(device_info.session_id), 38 : session_id_(device_info.session_id),
37 is_screen_cast_(device_info.device.type == MEDIA_TAB_VIDEO_CAPTURE || 39 is_screen_cast_(device_info.device.type == MEDIA_TAB_VIDEO_CAPTURE ||
38 device_info.device.type == MEDIA_DESKTOP_VIDEO_CAPTURE), 40 device_info.device.type == MEDIA_DESKTOP_VIDEO_CAPTURE),
39 got_first_frame_(false) { 41 got_first_frame_(false) {
40 DVLOG(3) << "VideoCapturerDelegate::ctor"; 42 DVLOG(3) << "VideoCapturerDelegate::ctor";
41 // RenderThreadImpl::current() may be NULL in testing. 43
44 // NULL in unit test.
42 if (RenderThreadImpl::current()) { 45 if (RenderThreadImpl::current()) {
43 capture_engine_ = RenderThreadImpl::current()->video_capture_impl_manager() 46 VideoCaptureImplManager* manager =
44 ->UseDevice(device_info.session_id); 47 RenderThreadImpl::current()->video_capture_impl_manager();
45 DCHECK(capture_engine_); 48 if (manager)
Ami GONE FROM CHROMIUM 2014/04/24 21:04:31 how can this fail? (here and elsewhere below)
Alpha Left Google 2014/04/24 22:50:34 Ownership: RenderThreadImpl owns Blink owns WebMe
49 release_device_cb_ = manager->UseDevice(session_id_);
46 } 50 }
47 message_loop_proxy_ = base::MessageLoopProxy::current();
48 } 51 }
49 52
50 VideoCapturerDelegate::~VideoCapturerDelegate() { 53 VideoCapturerDelegate::~VideoCapturerDelegate() {
51 DVLOG(3) << "VideoCapturerDelegate::dtor"; 54 DVLOG(3) << "VideoCapturerDelegate::dtor";
52 DCHECK(new_frame_callback_.is_null()); 55 DCHECK(new_frame_callback_.is_null());
56 if (!release_device_cb_.is_null())
57 release_device_cb_.Run();
53 } 58 }
54 59
55 void VideoCapturerDelegate::GetCurrentSupportedFormats( 60 void VideoCapturerDelegate::GetCurrentSupportedFormats(
56 int max_requested_width, 61 int max_requested_width,
57 int max_requested_height, 62 int max_requested_height,
58 const SupportedFormatsCallback& callback) { 63 const VideoCaptureDeviceFormatsCB& callback) {
59 DVLOG(3) << "GetCurrentSupportedFormats(" 64 DVLOG(3) << "GetCurrentSupportedFormats("
60 << " { max_requested_height = " << max_requested_height << "})" 65 << " { max_requested_height = " << max_requested_height << "})"
61 << " { max_requested_width = " << max_requested_width << "})"; 66 << " { max_requested_width = " << max_requested_width << "})";
62 67
63 if (is_screen_cast_) { 68 if (is_screen_cast_) {
64 media::VideoCaptureFormats formats; 69 media::VideoCaptureFormats formats;
65 const int width = max_requested_width ? 70 const int width = max_requested_width ?
66 max_requested_width : MediaStreamVideoSource::kDefaultWidth; 71 max_requested_width : MediaStreamVideoSource::kDefaultWidth;
67 const int height = max_requested_height ? 72 const int height = max_requested_height ?
68 max_requested_height : MediaStreamVideoSource::kDefaultHeight; 73 max_requested_height : MediaStreamVideoSource::kDefaultHeight;
69 formats.push_back( 74 formats.push_back(
70 media::VideoCaptureFormat( 75 media::VideoCaptureFormat(
71 gfx::Size(width, height), 76 gfx::Size(width, height),
72 MediaStreamVideoSource::kDefaultFrameRate, 77 MediaStreamVideoSource::kDefaultFrameRate,
73 media::PIXEL_FORMAT_I420)); 78 media::PIXEL_FORMAT_I420));
74 callback.Run(formats); 79 callback.Run(formats);
75 return; 80 return;
76 } 81 }
77 82
83 if (!RenderThreadImpl::current())
Ami GONE FROM CHROMIUM 2014/04/24 21:04:31 comment this is for tests (here and elsewhere belo
Alpha Left Google 2014/04/24 22:50:34 Done.
84 return;
85 VideoCaptureImplManager* manager =
86 RenderThreadImpl::current()->video_capture_impl_manager();
87 if (!manager)
88 return;
78 DCHECK(source_formats_callback_.is_null()); 89 DCHECK(source_formats_callback_.is_null());
79 source_formats_callback_ = callback; 90 source_formats_callback_ = callback;
80 capture_engine_->GetDeviceFormatsInUse(base::Bind( 91 manager->GetDeviceFormatsInUse(
81 &VideoCapturerDelegate::OnDeviceFormatsInUseReceived, this)); 92 session_id_,
93 media::BindToCurrentLoop(
94 base::Bind(
95 &VideoCapturerDelegate::OnDeviceFormatsInUseReceived, this)));
82 } 96 }
83 97
84 void VideoCapturerDelegate::StartDeliver( 98 void VideoCapturerDelegate::StartToDeliver(
85 const media::VideoCaptureParams& params, 99 const media::VideoCaptureParams& params,
86 const NewFrameCallback& new_frame_callback, 100 const VideoCaptureDeliverFrameCB& new_frame_callback,
87 const StartedCallback& started_callback) { 101 const StartedCallback& started_callback) {
88 DCHECK(params.requested_format.IsValid()); 102 DCHECK(params.requested_format.IsValid());
89 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); 103 DCHECK(thread_checker_.CalledOnValidThread());
90 new_frame_callback_ = new_frame_callback; 104 new_frame_callback_ = new_frame_callback;
91 started_callback_ = started_callback; 105 started_callback_ = started_callback;
92 got_first_frame_ = false; 106 got_first_frame_ = false;
93 107
94 // Increase the reference count to ensure the object is not deleted until 108 if (!RenderThreadImpl::current())
95 // it is unregistered in VideoCapturerDelegate::OnRemoved. 109 return;
96 AddRef(); 110 VideoCaptureImplManager* manager =
97 capture_engine_->StartCapture(this, params); 111 RenderThreadImpl::current()->video_capture_impl_manager();
112 if (!manager)
113 return;
114 stop_capture_cb_ =
115 manager->StartCapture(
116 session_id_,
117 params,
118 media::BindToCurrentLoop(base::Bind(
119 &VideoCapturerDelegate::OnStateUpdateOnRenderThread, this)),
120 media::BindToCurrentLoop(base::Bind(
121 &VideoCapturerDelegate::OnFrameReadyOnRenderThread, this)));
98 } 122 }
99 123
100 void VideoCapturerDelegate::StopDeliver() { 124 void VideoCapturerDelegate::StopDeliver() {
101 // Immediately make sure we don't provide more frames. 125 // Immediately make sure we don't provide more frames.
102 DVLOG(3) << "VideoCapturerDelegate::StopDeliver()"; 126 DVLOG(3) << "VideoCapturerDelegate::StopDeliver()";
103 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); 127 DCHECK(thread_checker_.CalledOnValidThread());
104 capture_engine_->StopCapture(this); 128 if (!stop_capture_cb_.is_null()) {
129 base::ResetAndReturn(&stop_capture_cb_).Run();
130 }
105 new_frame_callback_.Reset(); 131 new_frame_callback_.Reset();
106 started_callback_.Reset(); 132 started_callback_.Reset();
107 source_formats_callback_.Reset(); 133 source_formats_callback_.Reset();
108 } 134 }
109 135
110 void VideoCapturerDelegate::OnStarted(media::VideoCapture* capture) {
111 DVLOG(3) << "VideoCapturerDelegate::OnStarted";
112 DCHECK(!message_loop_proxy_->BelongsToCurrentThread());
113 }
114
115 void VideoCapturerDelegate::OnStopped(media::VideoCapture* capture) {
116 DCHECK(!message_loop_proxy_->BelongsToCurrentThread());
117 }
118
119 void VideoCapturerDelegate::OnPaused(media::VideoCapture* capture) {
120 DCHECK(!message_loop_proxy_->BelongsToCurrentThread());
121 }
122
123 void VideoCapturerDelegate::OnError(media::VideoCapture* capture,
124 int error_code) {
125 DVLOG(3) << "VideoCapturerDelegate::OnError";
126 DCHECK(!message_loop_proxy_->BelongsToCurrentThread());
127 message_loop_proxy_->PostTask(
128 FROM_HERE,
129 base::Bind(&VideoCapturerDelegate::OnErrorOnRenderThread, this, capture));
130 }
131
132 void VideoCapturerDelegate::OnRemoved(media::VideoCapture* capture) {
133 DVLOG(3) << " MediaStreamVideoCapturerSource::OnRemoved";
134 DCHECK(!message_loop_proxy_->BelongsToCurrentThread());
135
136 // Balance the AddRef in StartDeliver.
137 // This means we are no longer registered as an event handler and can safely
138 // be deleted.
139 Release();
140 }
141
142 void VideoCapturerDelegate::OnFrameReady(
143 media::VideoCapture* capture,
144 const scoped_refptr<media::VideoFrame>& frame) {
145 DCHECK(!message_loop_proxy_->BelongsToCurrentThread());
146 message_loop_proxy_->PostTask(
147 FROM_HERE,
148 base::Bind(&VideoCapturerDelegate::OnFrameReadyOnRenderThread,
149 this,
150 capture,
151 frame));
152 }
153
154 void VideoCapturerDelegate::OnFrameReadyOnRenderThread( 136 void VideoCapturerDelegate::OnFrameReadyOnRenderThread(
155 media::VideoCapture* capture, 137 const scoped_refptr<media::VideoFrame>& frame,
156 const scoped_refptr<media::VideoFrame>& frame) { 138 const media::VideoCaptureFormat& format,
139 const base::TimeTicks& timestamp) {
157 if (!got_first_frame_) { 140 if (!got_first_frame_) {
158 got_first_frame_ = true; 141 got_first_frame_ = true;
159 if (!started_callback_.is_null()) 142 if (!started_callback_.is_null())
160 started_callback_.Run(true); 143 started_callback_.Run(true);
161 } 144 }
162 145
163 if (!new_frame_callback_.is_null()) { 146 if (!new_frame_callback_.is_null()) {
164 new_frame_callback_.Run(frame); 147 new_frame_callback_.Run(frame, format, timestamp);
165 } 148 }
166 } 149 }
167 150
168 void VideoCapturerDelegate::OnErrorOnRenderThread( 151 void VideoCapturerDelegate::OnStateUpdateOnRenderThread(
169 media::VideoCapture* capture) { 152 VideoCaptureState state) {
170 if (!started_callback_.is_null()) 153 if (state == VIDEO_CAPTURE_STATE_ERROR && !started_callback_.is_null()) {
171 started_callback_.Run(false); 154 started_callback_.Run(false);
155 }
172 } 156 }
173 157
174 void VideoCapturerDelegate::OnDeviceFormatsInUseReceived( 158 void VideoCapturerDelegate::OnDeviceFormatsInUseReceived(
175 const media::VideoCaptureFormats& formats_in_use) { 159 const media::VideoCaptureFormats& formats_in_use) {
176 DVLOG(3) << "OnDeviceFormatsInUseReceived: " << formats_in_use.size(); 160 DVLOG(3) << "OnDeviceFormatsInUseReceived: " << formats_in_use.size();
177 DCHECK(message_loop_proxy_ == base::MessageLoopProxy::current()); 161 DCHECK(thread_checker_.CalledOnValidThread());
178 // StopDeliver() might have destroyed |source_formats_callback_| before 162 // StopDeliver() might have destroyed |source_formats_callback_| before
179 // arriving here. 163 // arriving here.
180 if (source_formats_callback_.is_null()) 164 if (source_formats_callback_.is_null())
181 return; 165 return;
182 if (!formats_in_use.empty()) { 166 if (!formats_in_use.empty()) {
183 source_formats_callback_.Run(formats_in_use); 167 source_formats_callback_.Run(formats_in_use);
184 source_formats_callback_.Reset(); 168 source_formats_callback_.Reset();
185 } else { 169 return;
186 // If there are no formats in use, try to retrieve the whole list of
187 // supported formats.
188 capture_engine_->GetDeviceSupportedFormats(base::Bind(
189 &VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated, this));
190 } 170 }
171
172 // If there are no formats in use, try to retrieve the whole list of
173 // supported formats.
174 if (!RenderThreadImpl::current())
175 return;
176 VideoCaptureImplManager* manager =
177 RenderThreadImpl::current()->video_capture_impl_manager();
178 if (!manager)
179 return;
180 manager->GetDeviceSupportedFormats(
181 session_id_,
182 media::BindToCurrentLoop(
183 base::Bind(
184 &VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated,
185 this)));
191 } 186 }
192 187
193 void VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated( 188 void VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated(
194 const media::VideoCaptureFormats& formats) { 189 const media::VideoCaptureFormats& formats) {
195 DVLOG(3) << "OnDeviceSupportedFormatsEnumerated: " << formats.size() 190 DVLOG(3) << "OnDeviceSupportedFormatsEnumerated: " << formats.size()
196 << " received"; 191 << " received";
197 DCHECK(message_loop_proxy_ == base::MessageLoopProxy::current()); 192 DCHECK(thread_checker_.CalledOnValidThread());
198 // StopDeliver() might have destroyed |source_formats_callback_| before 193 // StopDeliver() might have destroyed |source_formats_callback_| before
199 // arriving here. 194 // arriving here.
200 if (source_formats_callback_.is_null()) 195 if (source_formats_callback_.is_null())
201 return; 196 return;
202 if (formats.size()) { 197 if (formats.size()) {
203 source_formats_callback_.Run(formats); 198 source_formats_callback_.Run(formats);
204 } else { 199 } else {
205 // The capture device doesn't seem to support capability enumeration, 200 // The capture device doesn't seem to support capability enumeration,
206 // compose a fallback list of capabilities. 201 // compose a fallback list of capabilities.
207 media::VideoCaptureFormats default_formats; 202 media::VideoCaptureFormats default_formats;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 base::Unretained(this))); 234 base::Unretained(this)));
240 } 235 }
241 236
242 void MediaStreamVideoCapturerSource::StartSourceImpl( 237 void MediaStreamVideoCapturerSource::StartSourceImpl(
243 const media::VideoCaptureParams& params) { 238 const media::VideoCaptureParams& params) {
244 media::VideoCaptureParams new_params(params); 239 media::VideoCaptureParams new_params(params);
245 if (device_info().device.type == MEDIA_TAB_VIDEO_CAPTURE || 240 if (device_info().device.type == MEDIA_TAB_VIDEO_CAPTURE ||
246 device_info().device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) { 241 device_info().device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) {
247 new_params.allow_resolution_change = true; 242 new_params.allow_resolution_change = true;
248 } 243 }
249 delegate_->StartDeliver( 244 delegate_->StartToDeliver(
250 new_params, 245 new_params,
251 base::Bind(&MediaStreamVideoCapturerSource::DeliverVideoFrame, 246 base::Bind(&MediaStreamVideoCapturerSource::DeliverVideoFrame,
252 base::Unretained(this)), 247 base::Unretained(this)),
253 base::Bind(&MediaStreamVideoCapturerSource::OnStartDone, 248 base::Bind(&MediaStreamVideoCapturerSource::OnStartDone,
254 base::Unretained(this))); 249 base::Unretained(this)));
255 } 250 }
256 251
257 void MediaStreamVideoCapturerSource::StopSourceImpl() { 252 void MediaStreamVideoCapturerSource::StopSourceImpl() {
258 delegate_->StopDeliver(); 253 delegate_->StopDeliver();
259 } 254 }
260 255
261 } // namespace content 256 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698