| 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/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/callback_helpers.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "content/renderer/media/video_capture_impl_manager.h" | 10 #include "content/renderer/media/video_capture_impl_manager.h" |
| 11 #include "content/renderer/render_thread_impl.h" | 11 #include "content/renderer/render_thread_impl.h" |
| 12 #include "media/base/bind_to_current_loop.h" | 12 #include "media/base/bind_to_current_loop.h" |
| 13 #include "media/base/video_frame.h" | 13 #include "media/base/video_frame.h" |
| 14 | 14 |
| 15 namespace { | 15 namespace { |
| 16 | 16 |
| 17 struct SourceVideoResolution { | 17 // Resolutions used if the source doesn't support capability enumeration. |
| 18 struct { |
| 18 int width; | 19 int width; |
| 19 int height; | 20 int height; |
| 20 }; | 21 } const kVideoResolutions[] = {{1920, 1080}, |
| 22 {1280, 720}, |
| 23 {960, 720}, |
| 24 {640, 480}, |
| 25 {640, 360}, |
| 26 {320, 240}, |
| 27 {320, 180}}; |
| 21 | 28 |
| 22 // Resolutions used if the source doesn't support capability enumeration. | |
| 23 const SourceVideoResolution kVideoResolutions[] = {{1920, 1080}, | |
| 24 {1280, 720}, | |
| 25 {960, 720}, | |
| 26 {640, 480}, | |
| 27 {640, 360}, | |
| 28 {320, 240}, | |
| 29 {320, 180}}; | |
| 30 // Frame rates for sources with no support for capability enumeration. | 29 // Frame rates for sources with no support for capability enumeration. |
| 31 const int kVideoFrameRates[] = {30, 60}; | 30 const int kVideoFrameRates[] = {30, 60}; |
| 32 | 31 |
| 33 // Hard upper-bound frame rate for tab/desktop capture. | 32 // Hard upper-bound frame rate for tab/desktop capture. |
| 34 const double kMaxScreenCastFrameRate = 120.0; | 33 const double kMaxScreenCastFrameRate = 120.0; |
| 35 | 34 |
| 36 } // namespace | 35 } // namespace |
| 37 | 36 |
| 38 namespace content { | 37 namespace content { |
| 39 | 38 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 gfx::Size(width, height), | 80 gfx::Size(width, height), |
| 82 static_cast<float>(std::min(kMaxScreenCastFrameRate, | 81 static_cast<float>(std::min(kMaxScreenCastFrameRate, |
| 83 max_requested_frame_rate)), | 82 max_requested_frame_rate)), |
| 84 media::PIXEL_FORMAT_I420))); | 83 media::PIXEL_FORMAT_I420))); |
| 85 return; | 84 return; |
| 86 } | 85 } |
| 87 | 86 |
| 88 // NULL in unit test. | 87 // NULL in unit test. |
| 89 if (!RenderThreadImpl::current()) | 88 if (!RenderThreadImpl::current()) |
| 90 return; | 89 return; |
| 91 VideoCaptureImplManager* manager = | 90 VideoCaptureImplManager* const manager = |
| 92 RenderThreadImpl::current()->video_capture_impl_manager(); | 91 RenderThreadImpl::current()->video_capture_impl_manager(); |
| 93 if (!manager) | 92 if (!manager) |
| 94 return; | 93 return; |
| 95 DCHECK(source_formats_callback_.is_null()); | 94 DCHECK(source_formats_callback_.is_null()); |
| 96 source_formats_callback_ = callback; | 95 source_formats_callback_ = callback; |
| 97 manager->GetDeviceFormatsInUse( | 96 manager->GetDeviceFormatsInUse( |
| 98 session_id_, | 97 session_id_, |
| 99 media::BindToCurrentLoop( | 98 media::BindToCurrentLoop( |
| 100 base::Bind( | 99 base::Bind( |
| 101 &VideoCapturerDelegate::OnDeviceFormatsInUseReceived, | 100 &VideoCapturerDelegate::OnDeviceFormatsInUseReceived, |
| 102 weak_factory_.GetWeakPtr()))); | 101 weak_factory_.GetWeakPtr()))); |
| 103 } | 102 } |
| 104 | 103 |
| 105 void VideoCapturerDelegate::StartCapture( | 104 void VideoCapturerDelegate::StartCapture( |
| 106 const media::VideoCaptureParams& params, | 105 const media::VideoCaptureParams& params, |
| 107 const VideoCaptureDeliverFrameCB& new_frame_callback, | 106 const VideoCaptureDeliverFrameCB& new_frame_callback, |
| 108 scoped_refptr<base::SingleThreadTaskRunner> frame_callback_task_runner, | 107 scoped_refptr<base::SingleThreadTaskRunner> frame_callback_task_runner, |
| 109 const RunningCallback& running_callback) { | 108 const RunningCallback& running_callback) { |
| 110 DCHECK(params.requested_format.IsValid()); | 109 DCHECK(params.requested_format.IsValid()); |
| 111 DCHECK(thread_checker_.CalledOnValidThread()); | 110 DCHECK(thread_checker_.CalledOnValidThread()); |
| 112 running_callback_ = running_callback; | 111 running_callback_ = running_callback; |
| 113 | 112 |
| 114 // NULL in unit test. | 113 // NULL in unit test. |
| 115 if (!RenderThreadImpl::current()) | 114 if (!RenderThreadImpl::current()) |
| 116 return; | 115 return; |
| 117 VideoCaptureImplManager* manager = | 116 VideoCaptureImplManager* const manager = |
| 118 RenderThreadImpl::current()->video_capture_impl_manager(); | 117 RenderThreadImpl::current()->video_capture_impl_manager(); |
| 119 if (!manager) | 118 if (!manager) |
| 120 return; | 119 return; |
| 121 if (frame_callback_task_runner != | 120 if (frame_callback_task_runner != |
| 122 RenderThreadImpl::current()->GetIOMessageLoopProxy()) { | 121 RenderThreadImpl::current()->GetIOMessageLoopProxy()) { |
| 123 DCHECK(false) << "Only IO thread supported right now."; | 122 DCHECK(false) << "Only IO thread supported right now."; |
| 124 running_callback.Run(false); | 123 running_callback.Run(false); |
| 125 return; | 124 return; |
| 126 } | 125 } |
| 127 | 126 |
| 128 stop_capture_cb_ = | 127 stop_capture_cb_ = |
| 129 manager->StartCapture( | 128 manager->StartCapture( |
| 130 session_id_, | 129 session_id_, |
| 131 params, | 130 params, |
| 132 media::BindToCurrentLoop(base::Bind( | 131 media::BindToCurrentLoop(base::Bind( |
| 133 &VideoCapturerDelegate::OnStateUpdateOnRenderThread, | 132 &VideoCapturerDelegate::OnStateUpdate, |
| 134 weak_factory_.GetWeakPtr())), | 133 weak_factory_.GetWeakPtr())), |
| 135 new_frame_callback); | 134 new_frame_callback); |
| 136 } | 135 } |
| 137 | 136 |
| 138 void VideoCapturerDelegate::StopCapture() { | 137 void VideoCapturerDelegate::StopCapture() { |
| 139 // Immediately make sure we don't provide more frames. | 138 // Immediately make sure we don't provide more frames. |
| 140 DVLOG(3) << "VideoCapturerDelegate::StopCapture()"; | 139 DVLOG(3) << "VideoCapturerDelegate::StopCapture()"; |
| 141 DCHECK(thread_checker_.CalledOnValidThread()); | 140 DCHECK(thread_checker_.CalledOnValidThread()); |
| 142 if (!stop_capture_cb_.is_null()) { | 141 if (!stop_capture_cb_.is_null()) { |
| 143 base::ResetAndReturn(&stop_capture_cb_).Run(); | 142 base::ResetAndReturn(&stop_capture_cb_).Run(); |
| 144 } | 143 } |
| 145 running_callback_.Reset(); | 144 running_callback_.Reset(); |
| 146 source_formats_callback_.Reset(); | 145 source_formats_callback_.Reset(); |
| 147 } | 146 } |
| 148 | 147 |
| 149 void VideoCapturerDelegate::OnStateUpdateOnRenderThread( | 148 void VideoCapturerDelegate::OnStateUpdate( |
| 150 VideoCaptureState state) { | 149 VideoCaptureState state) { |
| 151 DCHECK(thread_checker_.CalledOnValidThread()); | 150 DCHECK(thread_checker_.CalledOnValidThread()); |
| 152 DVLOG(3) << "OnStateUpdateOnRenderThread state = " << state; | 151 DVLOG(3) << "OnStateUpdate state = " << state; |
| 153 if (state == VIDEO_CAPTURE_STATE_STARTED && !running_callback_.is_null()) { | 152 if (state == VIDEO_CAPTURE_STATE_STARTED && !running_callback_.is_null()) { |
| 154 running_callback_.Run(true); | 153 running_callback_.Run(true); |
| 155 return; | 154 return; |
| 156 } | 155 } |
| 157 if (state > VIDEO_CAPTURE_STATE_STARTED && !running_callback_.is_null()) { | 156 if (state > VIDEO_CAPTURE_STATE_STARTED && !running_callback_.is_null()) { |
| 158 base::ResetAndReturn(&running_callback_).Run(false); | 157 base::ResetAndReturn(&running_callback_).Run(false); |
| 159 } | 158 } |
| 160 } | 159 } |
| 161 | 160 |
| 162 void VideoCapturerDelegate::OnDeviceFormatsInUseReceived( | 161 void VideoCapturerDelegate::OnDeviceFormatsInUseReceived( |
| 163 const media::VideoCaptureFormats& formats_in_use) { | 162 const media::VideoCaptureFormats& formats_in_use) { |
| 164 DVLOG(3) << "OnDeviceFormatsInUseReceived: " << formats_in_use.size(); | 163 DVLOG(3) << "OnDeviceFormatsInUseReceived: " << formats_in_use.size(); |
| 165 DCHECK(thread_checker_.CalledOnValidThread()); | 164 DCHECK(thread_checker_.CalledOnValidThread()); |
| 166 // StopCapture() might have destroyed |source_formats_callback_| before | 165 // StopCapture() might have destroyed |source_formats_callback_| before |
| 167 // arriving here. | 166 // arriving here. |
| 168 if (source_formats_callback_.is_null()) | 167 if (source_formats_callback_.is_null()) |
| 169 return; | 168 return; |
| 170 // If there are no formats in use, try to retrieve the whole list of | 169 // If there are no formats in use, try to retrieve the whole list of |
| 171 // supported form. | 170 // supported form. |
| 172 if (!formats_in_use.empty()) { | 171 if (!formats_in_use.empty()) { |
| 173 source_formats_callback_.Run(formats_in_use); | 172 source_formats_callback_.Run(formats_in_use); |
| 174 source_formats_callback_.Reset(); | 173 source_formats_callback_.Reset(); |
| 175 return; | 174 return; |
| 176 } | 175 } |
| 177 | 176 |
| 178 // NULL in unit test. | 177 // NULL in unit test. |
| 179 if (!RenderThreadImpl::current()) | 178 if (!RenderThreadImpl::current()) |
| 180 return; | 179 return; |
| 181 VideoCaptureImplManager* manager = | 180 VideoCaptureImplManager* const manager = |
| 182 RenderThreadImpl::current()->video_capture_impl_manager(); | 181 RenderThreadImpl::current()->video_capture_impl_manager(); |
| 183 if (!manager) | 182 if (!manager) |
| 184 return; | 183 return; |
| 185 | 184 |
| 186 manager->GetDeviceSupportedFormats( | 185 manager->GetDeviceSupportedFormats( |
| 187 session_id_, | 186 session_id_, |
| 188 media::BindToCurrentLoop( | 187 media::BindToCurrentLoop( |
| 189 base::Bind( | 188 base::Bind( |
| 190 &VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated, | 189 &VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated, |
| 191 weak_factory_.GetWeakPtr()))); | 190 weak_factory_.GetWeakPtr()))); |
| 192 } | 191 } |
| 193 | 192 |
| 194 void VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated( | 193 void VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated( |
| 195 const media::VideoCaptureFormats& formats) { | 194 const media::VideoCaptureFormats& formats) { |
| 196 DVLOG(3) << "OnDeviceSupportedFormatsEnumerated: " << formats.size() | 195 DVLOG(3) << "OnDeviceSupportedFormatsEnumerated: " << formats.size() |
| 197 << " received"; | 196 << " received"; |
| 198 DCHECK(thread_checker_.CalledOnValidThread()); | 197 DCHECK(thread_checker_.CalledOnValidThread()); |
| 199 // StopCapture() might have destroyed |source_formats_callback_| before | 198 // StopCapture() might have destroyed |source_formats_callback_| before |
| 200 // arriving here. | 199 // arriving here. |
| 201 if (source_formats_callback_.is_null()) | 200 if (source_formats_callback_.is_null()) |
| 202 return; | 201 return; |
| 203 if (formats.size()) { | 202 if (formats.size()) { |
| 204 base::ResetAndReturn(&source_formats_callback_).Run(formats); | 203 base::ResetAndReturn(&source_formats_callback_).Run(formats); |
| 205 } else { | 204 } else { |
| 206 // The capture device doesn't seem to support capability enumeration, | 205 // The capture device doesn't seem to support capability enumeration, |
| 207 // compose a fallback list of capabilities. | 206 // compose a fallback list of capabilities. |
| 208 media::VideoCaptureFormats default_formats; | 207 media::VideoCaptureFormats default_formats; |
| 209 for (size_t i = 0; i < arraysize(kVideoResolutions); ++i) { | 208 for (const auto& resolution : kVideoResolutions) { |
| 210 for (size_t j = 0; j < arraysize(kVideoFrameRates); ++j) { | 209 for (const auto frame_rate : kVideoFrameRates) { |
| 211 default_formats.push_back(media::VideoCaptureFormat( | 210 default_formats.push_back(media::VideoCaptureFormat( |
| 212 gfx::Size(kVideoResolutions[i].width, kVideoResolutions[i].height), | 211 gfx::Size(resolution.width, resolution.height), |
| 213 kVideoFrameRates[j], media::PIXEL_FORMAT_I420)); | 212 frame_rate, |
| 213 media::PIXEL_FORMAT_I420)); |
| 214 } | 214 } |
| 215 } | 215 } |
| 216 base::ResetAndReturn(&source_formats_callback_).Run(default_formats); | 216 base::ResetAndReturn(&source_formats_callback_).Run(default_formats); |
| 217 } | 217 } |
| 218 } | 218 } |
| 219 | 219 |
| 220 MediaStreamVideoCapturerSource::MediaStreamVideoCapturerSource( | 220 MediaStreamVideoCapturerSource::MediaStreamVideoCapturerSource( |
| 221 const SourceStoppedCallback& stop_callback, | 221 const SourceStoppedCallback& stop_callback, |
| 222 scoped_ptr<media::VideoCapturerSource> delegate) | 222 scoped_ptr<media::VideoCapturerSource> delegate) |
| 223 : delegate_(delegate.Pass()) { | 223 : delegate_(delegate.Pass()) { |
| 224 SetStopCallback(stop_callback); | 224 SetStopCallback(stop_callback); |
| 225 } | 225 } |
| 226 | 226 |
| 227 MediaStreamVideoCapturerSource::~MediaStreamVideoCapturerSource() { |
| 228 } |
| 229 |
| 227 void MediaStreamVideoCapturerSource::SetDeviceInfo( | 230 void MediaStreamVideoCapturerSource::SetDeviceInfo( |
| 228 const StreamDeviceInfo& device_info) { | 231 const StreamDeviceInfo& device_info) { |
| 229 MediaStreamVideoSource::SetDeviceInfo(device_info); | 232 MediaStreamVideoSource::SetDeviceInfo(device_info); |
| 230 } | 233 } |
| 231 | 234 |
| 232 MediaStreamVideoCapturerSource::~MediaStreamVideoCapturerSource() { | |
| 233 } | |
| 234 | |
| 235 void MediaStreamVideoCapturerSource::GetCurrentSupportedFormats( | 235 void MediaStreamVideoCapturerSource::GetCurrentSupportedFormats( |
| 236 int max_requested_width, | 236 int max_requested_width, |
| 237 int max_requested_height, | 237 int max_requested_height, |
| 238 double max_requested_frame_rate, | 238 double max_requested_frame_rate, |
| 239 const VideoCaptureDeviceFormatsCB& callback) { | 239 const VideoCaptureDeviceFormatsCB& callback) { |
| 240 delegate_->GetCurrentSupportedFormats( | 240 delegate_->GetCurrentSupportedFormats( |
| 241 max_requested_width, | 241 max_requested_width, |
| 242 max_requested_height, | 242 max_requested_height, |
| 243 max_requested_frame_rate, | 243 max_requested_frame_rate, |
| 244 callback); | 244 callback); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 257 delegate_->StartCapture( | 257 delegate_->StartCapture( |
| 258 new_params, | 258 new_params, |
| 259 frame_callback, | 259 frame_callback, |
| 260 RenderThreadImpl::current() ? | 260 RenderThreadImpl::current() ? |
| 261 RenderThreadImpl::current()->GetIOMessageLoopProxy() : | 261 RenderThreadImpl::current()->GetIOMessageLoopProxy() : |
| 262 nullptr, | 262 nullptr, |
| 263 base::Bind(&MediaStreamVideoCapturerSource::OnStarted, | 263 base::Bind(&MediaStreamVideoCapturerSource::OnStarted, |
| 264 base::Unretained(this))); | 264 base::Unretained(this))); |
| 265 } | 265 } |
| 266 | 266 |
| 267 void MediaStreamVideoCapturerSource::StopSourceImpl() { |
| 268 delegate_->StopCapture(); |
| 269 } |
| 270 |
| 267 void MediaStreamVideoCapturerSource::OnStarted(bool result) { | 271 void MediaStreamVideoCapturerSource::OnStarted(bool result) { |
| 268 OnStartDone(result ? MEDIA_DEVICE_OK : MEDIA_DEVICE_TRACK_START_FAILURE); | 272 OnStartDone(result ? MEDIA_DEVICE_OK : MEDIA_DEVICE_TRACK_START_FAILURE); |
| 269 } | 273 } |
| 270 | 274 |
| 271 void MediaStreamVideoCapturerSource::StopSourceImpl() { | |
| 272 delegate_->StopCapture(); | |
| 273 } | |
| 274 | |
| 275 } // namespace content | 275 } // namespace content |
| OLD | NEW |