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

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 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/location.h" 8 #include "base/location.h"
9 #include "content/renderer/media/video_capture_impl_manager.h" 9 #include "content/renderer/media/video_capture_impl_manager.h"
10 #include "content/renderer/render_thread_impl.h" 10 #include "content/renderer/render_thread_impl.h"
11 #include "media/base/bind_to_current_loop.h"
11 #include "media/base/video_frame.h" 12 #include "media/base/video_frame.h"
12 13
13 namespace { 14 namespace {
14 15
15 struct SourceVideoFormat { 16 struct SourceVideoFormat {
16 int width; 17 int width;
17 int height; 18 int height;
18 int frame_rate; 19 int frame_rate;
19 }; 20 };
20 21
(...skipping 10 matching lines...) Expand all
31 32
32 namespace content { 33 namespace content {
33 34
34 VideoCapturerDelegate::VideoCapturerDelegate( 35 VideoCapturerDelegate::VideoCapturerDelegate(
35 const StreamDeviceInfo& device_info) 36 const StreamDeviceInfo& device_info)
36 : session_id_(device_info.session_id), 37 : session_id_(device_info.session_id),
37 is_screen_cast_(device_info.device.type == MEDIA_TAB_VIDEO_CAPTURE || 38 is_screen_cast_(device_info.device.type == MEDIA_TAB_VIDEO_CAPTURE ||
38 device_info.device.type == MEDIA_DESKTOP_VIDEO_CAPTURE), 39 device_info.device.type == MEDIA_DESKTOP_VIDEO_CAPTURE),
39 got_first_frame_(false) { 40 got_first_frame_(false) {
40 DVLOG(3) << "VideoCapturerDelegate::ctor"; 41 DVLOG(3) << "VideoCapturerDelegate::ctor";
41 // RenderThreadImpl::current() may be NULL in testing. 42 message_loop_proxy_ = base::MessageLoopProxy::current();
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 release_device_cb_ = manager->UseDevice(session_id_);
46 } 49 }
47 message_loop_proxy_ = base::MessageLoopProxy::current();
48 } 50 }
49 51
50 VideoCapturerDelegate::~VideoCapturerDelegate() { 52 VideoCapturerDelegate::~VideoCapturerDelegate() {
51 DVLOG(3) << "VideoCapturerDelegate::dtor"; 53 DVLOG(3) << "VideoCapturerDelegate::dtor";
52 DCHECK(new_frame_callback_.is_null()); 54 DCHECK(new_frame_callback_.is_null());
55 if (!release_device_cb_.is_null())
56 release_device_cb_.Run();
53 } 57 }
54 58
55 void VideoCapturerDelegate::GetCurrentSupportedFormats( 59 void VideoCapturerDelegate::GetCurrentSupportedFormats(
56 int max_requested_width, 60 int max_requested_width,
57 int max_requested_height, 61 int max_requested_height,
58 const SupportedFormatsCallback& callback) { 62 const SupportedFormatsCallback& callback) {
59 DVLOG(3) << "GetCurrentSupportedFormats(" 63 DVLOG(3) << "GetCurrentSupportedFormats("
60 << " { max_requested_height = " << max_requested_height << "})" 64 << " { max_requested_height = " << max_requested_height << "})"
61 << " { max_requested_width = " << max_requested_width << "})"; 65 << " { max_requested_width = " << max_requested_width << "})";
62 66
63 if (is_screen_cast_) { 67 if (is_screen_cast_) {
64 media::VideoCaptureFormats formats; 68 media::VideoCaptureFormats formats;
65 const int width = max_requested_width ? 69 const int width = max_requested_width ?
66 max_requested_width : MediaStreamVideoSource::kDefaultWidth; 70 max_requested_width : MediaStreamVideoSource::kDefaultWidth;
67 const int height = max_requested_height ? 71 const int height = max_requested_height ?
68 max_requested_height : MediaStreamVideoSource::kDefaultHeight; 72 max_requested_height : MediaStreamVideoSource::kDefaultHeight;
69 formats.push_back( 73 formats.push_back(
70 media::VideoCaptureFormat( 74 media::VideoCaptureFormat(
71 gfx::Size(width, height), 75 gfx::Size(width, height),
72 MediaStreamVideoSource::kDefaultFrameRate, 76 MediaStreamVideoSource::kDefaultFrameRate,
73 media::PIXEL_FORMAT_I420)); 77 media::PIXEL_FORMAT_I420));
74 callback.Run(formats); 78 callback.Run(formats);
75 return; 79 return;
76 } 80 }
77 81
78 DCHECK(source_formats_callback_.is_null()); 82 DCHECK(source_formats_callback_.is_null());
79 source_formats_callback_ = callback; 83 source_formats_callback_ = callback;
80 capture_engine_->GetDeviceFormatsInUse(base::Bind( 84 VideoCaptureImplManager* manager =
81 &VideoCapturerDelegate::OnDeviceFormatsInUseReceived, this)); 85 RenderThreadImpl::current()->video_capture_impl_manager();
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 don't need to worry about RTI::current() being NUL
Alpha Left Google 2014/04/23 18:48:33 Done.
86 manager->GetDeviceFormatsInUse(
87 session_id_,
88 media::BindToCurrentLoop(
89 base::Bind(
90 &VideoCapturerDelegate::OnDeviceFormatsInUseReceived, this)));
82 } 91 }
83 92
84 void VideoCapturerDelegate::StartDeliver( 93 void VideoCapturerDelegate::StartDeliver(
85 const media::VideoCaptureParams& params, 94 const media::VideoCaptureParams& params,
86 const NewFrameCallback& new_frame_callback, 95 const NewFrameCallback& new_frame_callback,
87 const StartedCallback& started_callback) { 96 const StartedCallback& started_callback) {
88 DCHECK(params.requested_format.IsValid()); 97 DCHECK(params.requested_format.IsValid());
89 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); 98 DCHECK(message_loop_proxy_->BelongsToCurrentThread());
90 new_frame_callback_ = new_frame_callback; 99 new_frame_callback_ = new_frame_callback;
91 started_callback_ = started_callback; 100 started_callback_ = started_callback;
92 got_first_frame_ = false; 101 got_first_frame_ = false;
93 102
94 // Increase the reference count to ensure the object is not deleted until 103 VideoCaptureImplManager* manager =
95 // it is unregistered in VideoCapturerDelegate::OnRemoved. 104 RenderThreadImpl::current()->video_capture_impl_manager();
96 AddRef(); 105 stop_capture_cb_ =
97 capture_engine_->StartCapture(this, params); 106 manager->StartCapture(
107 session_id_,
108 params,
109 media::BindToCurrentLoop(base::Bind(
110 &VideoCapturerDelegate::OnStateUpdateOnRenderThread, this)),
111 media::BindToCurrentLoop(base::Bind(
112 &VideoCapturerDelegate::OnFrameReadyOnRenderThread, this)));
98 } 113 }
99 114
100 void VideoCapturerDelegate::StopDeliver() { 115 void VideoCapturerDelegate::StopDeliver() {
101 // Immediately make sure we don't provide more frames. 116 // Immediately make sure we don't provide more frames.
102 DVLOG(3) << "VideoCapturerDelegate::StopDeliver()"; 117 DVLOG(3) << "VideoCapturerDelegate::StopDeliver()";
103 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); 118 DCHECK(message_loop_proxy_->BelongsToCurrentThread());
104 capture_engine_->StopCapture(this); 119 if (!stop_capture_cb_.is_null()) {
120 stop_capture_cb_.Run();
121 stop_capture_cb_.Reset();
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 base::ResetAndReturn(&stop_capture_cb_); makes it
Alpha Left Google 2014/04/23 18:48:33 Done.
122 }
105 new_frame_callback_.Reset(); 123 new_frame_callback_.Reset();
106 started_callback_.Reset(); 124 started_callback_.Reset();
107 source_formats_callback_.Reset(); 125 source_formats_callback_.Reset();
108 } 126 }
109 127
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( 128 void VideoCapturerDelegate::OnFrameReadyOnRenderThread(
155 media::VideoCapture* capture, 129 const scoped_refptr<media::VideoFrame>& frame,
156 const scoped_refptr<media::VideoFrame>& frame) { 130 const media::VideoCaptureFormat& format,
131 const base::TimeTicks& timestamp) {
157 if (!got_first_frame_) { 132 if (!got_first_frame_) {
158 got_first_frame_ = true; 133 got_first_frame_ = true;
159 if (!started_callback_.is_null()) 134 if (!started_callback_.is_null())
160 started_callback_.Run(true); 135 started_callback_.Run(true);
161 } 136 }
162 137
163 if (!new_frame_callback_.is_null()) { 138 if (!new_frame_callback_.is_null()) {
164 new_frame_callback_.Run(frame); 139 new_frame_callback_.Run(frame);
165 } 140 }
166 } 141 }
167 142
168 void VideoCapturerDelegate::OnErrorOnRenderThread( 143 void VideoCapturerDelegate::OnStateUpdateOnRenderThread(
169 media::VideoCapture* capture) { 144 VideoCaptureState state) {
170 if (!started_callback_.is_null()) 145 if (state == VIDEO_CAPTURE_STATE_ERROR && !started_callback_.is_null()) {
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 what happens if error is delivered before StartCap
Alpha Left Google 2014/04/23 18:48:33 Because stopping of VCIM is not synchronous and we
171 started_callback_.Run(false); 146 started_callback_.Run(false);
147 }
172 } 148 }
173 149
174 void VideoCapturerDelegate::OnDeviceFormatsInUseReceived( 150 void VideoCapturerDelegate::OnDeviceFormatsInUseReceived(
175 const media::VideoCaptureFormats& formats_in_use) { 151 const media::VideoCaptureFormats& formats_in_use) {
176 DVLOG(3) << "OnDeviceFormatsInUseReceived: " << formats_in_use.size(); 152 DVLOG(3) << "OnDeviceFormatsInUseReceived: " << formats_in_use.size();
177 DCHECK(message_loop_proxy_ == base::MessageLoopProxy::current()); 153 DCHECK(message_loop_proxy_ == base::MessageLoopProxy::current());
178 // StopDeliver() might have destroyed |source_formats_callback_| before 154 // StopDeliver() might have destroyed |source_formats_callback_| before
179 // arriving here. 155 // arriving here.
180 if (source_formats_callback_.is_null()) 156 if (source_formats_callback_.is_null())
181 return; 157 return;
182 if (!formats_in_use.empty()) { 158 if (!formats_in_use.empty()) {
183 source_formats_callback_.Run(formats_in_use); 159 source_formats_callback_.Run(formats_in_use);
184 source_formats_callback_.Reset(); 160 source_formats_callback_.Reset();
185 } else { 161 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 } 162 }
163
164 // If there are no formats in use, try to retrieve the whole list of
165 // supported formats.
166 VideoCaptureImplManager* manager =
167 RenderThreadImpl::current()->video_capture_impl_manager();
168 manager->GetDeviceSupportedFormats(
169 session_id_,
170 media::BindToCurrentLoop(
171 base::Bind(
172 &VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated,
173 this)));
191 } 174 }
192 175
193 void VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated( 176 void VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated(
194 const media::VideoCaptureFormats& formats) { 177 const media::VideoCaptureFormats& formats) {
195 DVLOG(3) << "OnDeviceSupportedFormatsEnumerated: " << formats.size() 178 DVLOG(3) << "OnDeviceSupportedFormatsEnumerated: " << formats.size()
196 << " received"; 179 << " received";
197 DCHECK(message_loop_proxy_ == base::MessageLoopProxy::current()); 180 DCHECK(message_loop_proxy_ == base::MessageLoopProxy::current());
198 // StopDeliver() might have destroyed |source_formats_callback_| before 181 // StopDeliver() might have destroyed |source_formats_callback_| before
199 // arriving here. 182 // arriving here.
200 if (source_formats_callback_.is_null()) 183 if (source_formats_callback_.is_null())
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 base::Unretained(this)), 236 base::Unretained(this)),
254 base::Bind(&MediaStreamVideoCapturerSource::OnStartDone, 237 base::Bind(&MediaStreamVideoCapturerSource::OnStartDone,
255 base::Unretained(this))); 238 base::Unretained(this)));
256 } 239 }
257 240
258 void MediaStreamVideoCapturerSource::StopSourceImpl() { 241 void MediaStreamVideoCapturerSource::StopSourceImpl() {
259 delegate_->StopDeliver(); 242 delegate_->StopDeliver();
260 } 243 }
261 244
262 } // namespace content 245 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698