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

Side by Side Diff: device/capture/video/fake_video_capture_device.cc

Issue 2214533002: move //media/capture to //device/capture (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "media/capture/video/fake_video_capture_device.h" 5 #include "device/capture/video/fake_video_capture_device.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <algorithm> 8 #include <algorithm>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/single_thread_task_runner.h" 13 #include "base/single_thread_task_runner.h"
14 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
15 #include "base/threading/thread_task_runner_handle.h" 15 #include "base/threading/thread_task_runner_handle.h"
16 #include "media/audio/fake_audio_input_stream.h" 16 #include "media/audio/fake_audio_input_stream.h"
17 #include "media/base/video_frame.h" 17 #include "media/base/video_frame.h"
18 #include "mojo/public/cpp/bindings/string.h" 18 #include "mojo/public/cpp/bindings/string.h"
19 #include "third_party/skia/include/core/SkBitmap.h" 19 #include "third_party/skia/include/core/SkBitmap.h"
20 #include "third_party/skia/include/core/SkCanvas.h" 20 #include "third_party/skia/include/core/SkCanvas.h"
21 #include "third_party/skia/include/core/SkMatrix.h" 21 #include "third_party/skia/include/core/SkMatrix.h"
22 #include "third_party/skia/include/core/SkPaint.h" 22 #include "third_party/skia/include/core/SkPaint.h"
23 #include "ui/gfx/codec/png_codec.h" 23 #include "ui/gfx/codec/png_codec.h"
24 24
25 namespace media { 25 namespace device {
26 26
27 // Sweep at 600 deg/sec. 27 // Sweep at 600 deg/sec.
28 static const float kPacmanAngularVelocity = 600; 28 static const float kPacmanAngularVelocity = 600;
29 // Beep every 500 ms. 29 // Beep every 500 ms.
30 static const int kBeepInterval = 500; 30 static const int kBeepInterval = 500;
31 31
32 static const uint32_t kMinZoom = 100; 32 static const uint32_t kMinZoom = 100;
33 static const uint32_t kMaxZoom = 400; 33 static const uint32_t kMaxZoom = 400;
34 34
35 void DrawPacman(bool use_argb, 35 void DrawPacman(bool use_argb,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 } 89 }
90 90
91 // Creates a PNG-encoded frame and sends it back to |callback|. The other 91 // Creates a PNG-encoded frame and sends it back to |callback|. The other
92 // parameters are used to replicate the PacMan rendering. 92 // parameters are used to replicate the PacMan rendering.
93 void DoTakeFakePhoto(VideoCaptureDevice::TakePhotoCallback callback, 93 void DoTakeFakePhoto(VideoCaptureDevice::TakePhotoCallback callback,
94 const VideoCaptureFormat& capture_format, 94 const VideoCaptureFormat& capture_format,
95 base::TimeDelta elapsed_time, 95 base::TimeDelta elapsed_time,
96 float fake_capture_rate, 96 float fake_capture_rate,
97 uint32_t zoom) { 97 uint32_t zoom) {
98 std::unique_ptr<uint8_t[]> buffer(new uint8_t[VideoFrame::AllocationSize( 98 std::unique_ptr<uint8_t[]> buffer(new uint8_t[VideoFrame::AllocationSize(
99 PIXEL_FORMAT_ARGB, capture_format.frame_size)]); 99 media::PIXEL_FORMAT_ARGB, capture_format.frame_size)]);
100 100
101 DrawPacman(true /* use_argb */, buffer.get(), elapsed_time, fake_capture_rate, 101 DrawPacman(true /* use_argb */, buffer.get(), elapsed_time, fake_capture_rate,
102 capture_format.frame_size, zoom); 102 capture_format.frame_size, zoom);
103 103
104 mojom::BlobPtr blob = mojom::Blob::New(); 104 media::mojom::BlobPtr blob = media::mojom::Blob::New();
105 const bool result = gfx::PNGCodec::Encode( 105 const bool result = gfx::PNGCodec::Encode(
106 buffer.get(), gfx::PNGCodec::FORMAT_RGBA, capture_format.frame_size, 106 buffer.get(), gfx::PNGCodec::FORMAT_RGBA, capture_format.frame_size,
107 capture_format.frame_size.width() * 4, true /* discard_transparency */, 107 capture_format.frame_size.width() * 4, true /* discard_transparency */,
108 std::vector<gfx::PNGCodec::Comment>(), &blob->data); 108 std::vector<gfx::PNGCodec::Comment>(), &blob->data);
109 DCHECK(result); 109 DCHECK(result);
110 110
111 blob->mime_type = "image/png"; 111 blob->mime_type = "image/png";
112 callback.Run(std::move(blob)); 112 callback.Run(std::move(blob));
113 } 113 }
114 114
(...skipping 22 matching lines...) Expand all
137 if (params.requested_format.frame_size.width() > 1280) 137 if (params.requested_format.frame_size.width() > 1280)
138 capture_format_.frame_size.SetSize(1920, 1080); 138 capture_format_.frame_size.SetSize(1920, 1080);
139 else if (params.requested_format.frame_size.width() > 640) 139 else if (params.requested_format.frame_size.width() > 640)
140 capture_format_.frame_size.SetSize(1280, 720); 140 capture_format_.frame_size.SetSize(1280, 720);
141 else if (params.requested_format.frame_size.width() > 320) 141 else if (params.requested_format.frame_size.width() > 320)
142 capture_format_.frame_size.SetSize(640, 480); 142 capture_format_.frame_size.SetSize(640, 480);
143 else 143 else
144 capture_format_.frame_size.SetSize(320, 240); 144 capture_format_.frame_size.SetSize(320, 240);
145 145
146 if (buffer_ownership_ == BufferOwnership::CLIENT_BUFFERS) { 146 if (buffer_ownership_ == BufferOwnership::CLIENT_BUFFERS) {
147 capture_format_.pixel_storage = PIXEL_STORAGE_CPU; 147 capture_format_.pixel_storage = media::PIXEL_STORAGE_CPU;
148 capture_format_.pixel_format = PIXEL_FORMAT_ARGB; 148 capture_format_.pixel_format = media::PIXEL_FORMAT_ARGB;
149 DVLOG(1) << "starting with client argb buffers"; 149 DVLOG(1) << "starting with client argb buffers";
150 } else if (buffer_ownership_ == BufferOwnership::OWN_BUFFERS) { 150 } else if (buffer_ownership_ == BufferOwnership::OWN_BUFFERS) {
151 capture_format_.pixel_storage = PIXEL_STORAGE_CPU; 151 capture_format_.pixel_storage = media::PIXEL_STORAGE_CPU;
152 capture_format_.pixel_format = PIXEL_FORMAT_I420; 152 capture_format_.pixel_format = media::PIXEL_FORMAT_I420;
153 DVLOG(1) << "starting with own I420 buffers"; 153 DVLOG(1) << "starting with own I420 buffers";
154 } 154 }
155 155
156 if (capture_format_.pixel_format == PIXEL_FORMAT_I420) { 156 if (capture_format_.pixel_format == media::PIXEL_FORMAT_I420) {
157 fake_frame_.reset(new uint8_t[VideoFrame::AllocationSize( 157 fake_frame_.reset(new uint8_t[VideoFrame::AllocationSize(
158 PIXEL_FORMAT_I420, capture_format_.frame_size)]); 158 media::PIXEL_FORMAT_I420, capture_format_.frame_size)]);
159 } 159 }
160 160
161 beep_time_ = base::TimeDelta(); 161 beep_time_ = base::TimeDelta();
162 elapsed_time_ = base::TimeDelta(); 162 elapsed_time_ = base::TimeDelta();
163 163
164 if (buffer_ownership_ == BufferOwnership::CLIENT_BUFFERS) 164 if (buffer_ownership_ == BufferOwnership::CLIENT_BUFFERS)
165 BeepAndScheduleNextCapture( 165 BeepAndScheduleNextCapture(
166 base::TimeTicks::Now(), 166 base::TimeTicks::Now(),
167 base::Bind(&FakeVideoCaptureDevice::CaptureUsingClientBuffers, 167 base::Bind(&FakeVideoCaptureDevice::CaptureUsingClientBuffers,
168 weak_factory_.GetWeakPtr())); 168 weak_factory_.GetWeakPtr()));
169 else if (buffer_ownership_ == BufferOwnership::OWN_BUFFERS) 169 else if (buffer_ownership_ == BufferOwnership::OWN_BUFFERS)
170 BeepAndScheduleNextCapture( 170 BeepAndScheduleNextCapture(
171 base::TimeTicks::Now(), 171 base::TimeTicks::Now(),
172 base::Bind(&FakeVideoCaptureDevice::CaptureUsingOwnBuffers, 172 base::Bind(&FakeVideoCaptureDevice::CaptureUsingOwnBuffers,
173 weak_factory_.GetWeakPtr())); 173 weak_factory_.GetWeakPtr()));
174 } 174 }
175 175
176 void FakeVideoCaptureDevice::StopAndDeAllocate() { 176 void FakeVideoCaptureDevice::StopAndDeAllocate() {
177 DCHECK(thread_checker_.CalledOnValidThread()); 177 DCHECK(thread_checker_.CalledOnValidThread());
178 client_.reset(); 178 client_.reset();
179 } 179 }
180 180
181 void FakeVideoCaptureDevice::GetPhotoCapabilities( 181 void FakeVideoCaptureDevice::GetPhotoCapabilities(
182 GetPhotoCapabilitiesCallback callback) { 182 GetPhotoCapabilitiesCallback callback) {
183 mojom::PhotoCapabilitiesPtr photo_capabilities = 183 media::mojom::PhotoCapabilitiesPtr photo_capabilities =
184 mojom::PhotoCapabilities::New(); 184 media::mojom::PhotoCapabilities::New();
185 photo_capabilities->iso = mojom::Range::New(); 185 photo_capabilities->iso = media::mojom::Range::New();
186 photo_capabilities->iso->current = 100; 186 photo_capabilities->iso->current = 100;
187 photo_capabilities->iso->max = 100; 187 photo_capabilities->iso->max = 100;
188 photo_capabilities->iso->min = 100; 188 photo_capabilities->iso->min = 100;
189 photo_capabilities->height = mojom::Range::New(); 189 photo_capabilities->height = media::mojom::Range::New();
190 photo_capabilities->height->current = capture_format_.frame_size.height(); 190 photo_capabilities->height->current = capture_format_.frame_size.height();
191 photo_capabilities->height->max = 1080; 191 photo_capabilities->height->max = 1080;
192 photo_capabilities->height->min = 240; 192 photo_capabilities->height->min = 240;
193 photo_capabilities->width = mojom::Range::New(); 193 photo_capabilities->width = media::mojom::Range::New();
194 photo_capabilities->width->current = capture_format_.frame_size.width(); 194 photo_capabilities->width->current = capture_format_.frame_size.width();
195 photo_capabilities->width->max = 1920; 195 photo_capabilities->width->max = 1920;
196 photo_capabilities->width->min = 320; 196 photo_capabilities->width->min = 320;
197 photo_capabilities->focus_mode = mojom::FocusMode::UNAVAILABLE; 197 photo_capabilities->focus_mode = media::mojom::FocusMode::UNAVAILABLE;
198 photo_capabilities->zoom = mojom::Range::New(); 198 photo_capabilities->zoom = media::mojom::Range::New();
199 photo_capabilities->zoom->current = current_zoom_; 199 photo_capabilities->zoom->current = current_zoom_;
200 photo_capabilities->zoom->max = kMaxZoom; 200 photo_capabilities->zoom->max = kMaxZoom;
201 photo_capabilities->zoom->min = kMinZoom; 201 photo_capabilities->zoom->min = kMinZoom;
202 photo_capabilities->focus_mode = mojom::FocusMode::UNAVAILABLE; 202 photo_capabilities->focus_mode = media::mojom::FocusMode::UNAVAILABLE;
203 callback.Run(std::move(photo_capabilities)); 203 callback.Run(std::move(photo_capabilities));
204 } 204 }
205 205
206 void FakeVideoCaptureDevice::SetPhotoOptions(mojom::PhotoSettingsPtr settings, 206 void FakeVideoCaptureDevice::SetPhotoOptions(
207 SetPhotoOptionsCallback callback) { 207 media::mojom::PhotoSettingsPtr settings,
208 SetPhotoOptionsCallback callback) {
208 if (settings->has_zoom) 209 if (settings->has_zoom)
209 current_zoom_ = std::max(kMinZoom, std::min(settings->zoom, kMaxZoom)); 210 current_zoom_ = std::max(kMinZoom, std::min(settings->zoom, kMaxZoom));
210 callback.Run(true); 211 callback.Run(true);
211 } 212 }
212 213
213 void FakeVideoCaptureDevice::TakePhoto(TakePhotoCallback callback) { 214 void FakeVideoCaptureDevice::TakePhoto(TakePhotoCallback callback) {
214 base::ThreadTaskRunnerHandle::Get()->PostTask( 215 base::ThreadTaskRunnerHandle::Get()->PostTask(
215 FROM_HERE, 216 FROM_HERE,
216 base::Bind(&DoTakeFakePhoto, base::Passed(&callback), capture_format_, 217 base::Bind(&DoTakeFakePhoto, base::Passed(&callback), capture_format_,
217 elapsed_time_, fake_capture_rate_, current_zoom_)); 218 elapsed_time_, fake_capture_rate_, current_zoom_));
(...skipping 25 matching lines...) Expand all
243 base::TimeTicks expected_execution_time) { 244 base::TimeTicks expected_execution_time) {
244 DCHECK(thread_checker_.CalledOnValidThread()); 245 DCHECK(thread_checker_.CalledOnValidThread());
245 246
246 std::unique_ptr<VideoCaptureDevice::Client::Buffer> capture_buffer( 247 std::unique_ptr<VideoCaptureDevice::Client::Buffer> capture_buffer(
247 client_->ReserveOutputBuffer(capture_format_.frame_size, 248 client_->ReserveOutputBuffer(capture_format_.frame_size,
248 capture_format_.pixel_format, 249 capture_format_.pixel_format,
249 capture_format_.pixel_storage)); 250 capture_format_.pixel_storage));
250 DLOG_IF(ERROR, !capture_buffer) << "Couldn't allocate Capture Buffer"; 251 DLOG_IF(ERROR, !capture_buffer) << "Couldn't allocate Capture Buffer";
251 DCHECK(capture_buffer->data()) << "Buffer has NO backing memory"; 252 DCHECK(capture_buffer->data()) << "Buffer has NO backing memory";
252 253
253 if (capture_format_.pixel_storage == PIXEL_STORAGE_GPUMEMORYBUFFER && 254 if (capture_format_.pixel_storage == media::PIXEL_STORAGE_GPUMEMORYBUFFER &&
254 capture_format_.pixel_format == media::PIXEL_FORMAT_I420) { 255 capture_format_.pixel_format == media::PIXEL_FORMAT_I420) {
255 // Since SkBitmap expects a packed&continuous memory region for I420, we 256 // Since SkBitmap expects a packed&continuous memory region for I420, we
256 // need to use |fake_frame_| to draw onto. 257 // need to use |fake_frame_| to draw onto.
257 memset(fake_frame_.get(), 0, capture_format_.ImageAllocationSize()); 258 memset(fake_frame_.get(), 0, capture_format_.ImageAllocationSize());
258 DrawPacman(false /* use_argb */, fake_frame_.get(), elapsed_time_, 259 DrawPacman(false /* use_argb */, fake_frame_.get(), elapsed_time_,
259 fake_capture_rate_, capture_format_.frame_size, current_zoom_); 260 fake_capture_rate_, capture_format_.frame_size, current_zoom_);
260 261
261 // Copy data from |fake_frame_| into the reserved planes of GpuMemoryBuffer. 262 // Copy data from |fake_frame_| into the reserved planes of GpuMemoryBuffer.
262 size_t offset = 0; 263 size_t offset = 0;
263 for (size_t i = 0; i < VideoFrame::NumPlanes(PIXEL_FORMAT_I420); ++i) { 264 for (size_t i = 0; i < VideoFrame::NumPlanes(media::PIXEL_FORMAT_I420);
265 ++i) {
264 const size_t plane_size = 266 const size_t plane_size =
265 VideoFrame::PlaneSize(PIXEL_FORMAT_I420, i, 267 VideoFrame::PlaneSize(media::PIXEL_FORMAT_I420, i,
266 capture_format_.frame_size) 268 capture_format_.frame_size)
267 .GetArea(); 269 .GetArea();
268 memcpy(capture_buffer->data(i), fake_frame_.get() + offset, plane_size); 270 memcpy(capture_buffer->data(i), fake_frame_.get() + offset, plane_size);
269 offset += plane_size; 271 offset += plane_size;
270 } 272 }
271 } else { 273 } else {
272 DCHECK_EQ(capture_format_.pixel_storage, PIXEL_STORAGE_CPU); 274 DCHECK_EQ(capture_format_.pixel_storage, media::PIXEL_STORAGE_CPU);
273 DCHECK_EQ(capture_format_.pixel_format, PIXEL_FORMAT_ARGB); 275 DCHECK_EQ(capture_format_.pixel_format, media::PIXEL_FORMAT_ARGB);
274 uint8_t* data_ptr = static_cast<uint8_t*>(capture_buffer->data()); 276 uint8_t* data_ptr = static_cast<uint8_t*>(capture_buffer->data());
275 memset(data_ptr, 0, capture_buffer->mapped_size()); 277 memset(data_ptr, 0, capture_buffer->mapped_size());
276 DrawPacman(true /* use_argb */, data_ptr, elapsed_time_, fake_capture_rate_, 278 DrawPacman(true /* use_argb */, data_ptr, elapsed_time_, fake_capture_rate_,
277 capture_format_.frame_size, current_zoom_); 279 capture_format_.frame_size, current_zoom_);
278 } 280 }
279 281
280 // Give the captured frame to the client. 282 // Give the captured frame to the client.
281 base::TimeTicks now = base::TimeTicks::Now(); 283 base::TimeTicks now = base::TimeTicks::Now();
282 if (first_ref_time_.is_null()) 284 if (first_ref_time_.is_null())
283 first_ref_time_ = now; 285 first_ref_time_ = now;
(...skipping 11 matching lines...) Expand all
295 const base::Callback<void(base::TimeTicks)>& next_capture) { 297 const base::Callback<void(base::TimeTicks)>& next_capture) {
296 const base::TimeDelta beep_interval = 298 const base::TimeDelta beep_interval =
297 base::TimeDelta::FromMilliseconds(kBeepInterval); 299 base::TimeDelta::FromMilliseconds(kBeepInterval);
298 const base::TimeDelta frame_interval = 300 const base::TimeDelta frame_interval =
299 base::TimeDelta::FromMicroseconds(1e6 / fake_capture_rate_); 301 base::TimeDelta::FromMicroseconds(1e6 / fake_capture_rate_);
300 beep_time_ += frame_interval; 302 beep_time_ += frame_interval;
301 elapsed_time_ += frame_interval; 303 elapsed_time_ += frame_interval;
302 304
303 // Generate a synchronized beep twice per second. 305 // Generate a synchronized beep twice per second.
304 if (beep_time_ >= beep_interval) { 306 if (beep_time_ >= beep_interval) {
305 FakeAudioInputStream::BeepOnce(); 307 media::FakeAudioInputStream::BeepOnce();
306 beep_time_ -= beep_interval; 308 beep_time_ -= beep_interval;
307 } 309 }
308 310
309 // Reschedule next CaptureTask. 311 // Reschedule next CaptureTask.
310 const base::TimeTicks current_time = base::TimeTicks::Now(); 312 const base::TimeTicks current_time = base::TimeTicks::Now();
311 // Don't accumulate any debt if we are lagging behind - just post the next 313 // Don't accumulate any debt if we are lagging behind - just post the next
312 // frame immediately and continue as normal. 314 // frame immediately and continue as normal.
313 const base::TimeTicks next_execution_time = 315 const base::TimeTicks next_execution_time =
314 std::max(current_time, expected_execution_time + frame_interval); 316 std::max(current_time, expected_execution_time + frame_interval);
315 const base::TimeDelta delay = next_execution_time - current_time; 317 const base::TimeDelta delay = next_execution_time - current_time;
316 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 318 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
317 FROM_HERE, base::Bind(next_capture, next_execution_time), delay); 319 FROM_HERE, base::Bind(next_capture, next_execution_time), delay);
318 } 320 }
319 321
320 } // namespace media 322 } // namespace device
OLDNEW
« no previous file with comments | « device/capture/video/fake_video_capture_device.h ('k') | device/capture/video/fake_video_capture_device_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698