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

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

Issue 2447233002: FakeVideoCaptureDevice: Y16 testing support. (Closed)
Patch Set: Nits. Created 4 years, 1 month 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 "media/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
(...skipping 10 matching lines...) Expand all
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 media {
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 // Gradient travels from bottom to top in 5 seconds.
32 static const float kGradientFrequency = 1.f / 5;
31 33
32 static const uint32_t kMinZoom = 100; 34 static const uint32_t kMinZoom = 100;
33 static const uint32_t kMaxZoom = 400; 35 static const uint32_t kMaxZoom = 400;
34 static const uint32_t kZoomStep = 1; 36 static const uint32_t kZoomStep = 1;
35 37
36 void DrawPacman(bool use_argb, 38 // Starting from top left, -45 deg gradient. Value at point (row, column) is
39 // calculated as (top_left_value + (row + column) * step) % MAX_VALUE, where
40 // step is MAX_VALUE / (width + height). MAX_VALUE is 255 (for 8 bit per
41 // component) or 65535 for Y16.
42 // This is handy for pixel tests where we use the squares to verify rendering.
43 void DrawGradientSquares(VideoPixelFormat frame_format,
44 uint8_t* const pixels,
45 base::TimeDelta elapsed_time,
46 const gfx::Size& frame_size) {
47 const int width = frame_size.width();
48 const int height = frame_size.height();
49 const int side = width / 16; // square side length.
50 DCHECK(side);
51 const gfx::Point squares[] = {{0, 0},
52 {width - side, 0},
53 {0, height - side},
54 {width - side, height - side}};
55 const float start =
56 fmod(65536 * elapsed_time.InSecondsF() * kGradientFrequency, 65536);
57 const float color_step = 65535 / static_cast<float>(width + height);
58 for (const auto& corner : squares) {
59 for (int y = corner.y(); y < corner.y() + side; ++y) {
60 for (int x = corner.x(); x < corner.x() + side; ++x) {
61 const unsigned int value =
62 static_cast<unsigned int>(start + (x + y) * color_step) & 0xFFFF;
63 size_t offset = (y * width) + x;
64 switch (frame_format) {
65 case PIXEL_FORMAT_Y16:
66 pixels[offset * sizeof(uint16_t)] = value & 0xFF;
67 pixels[offset * sizeof(uint16_t) + 1] = value >> 8;
68 break;
69 case PIXEL_FORMAT_ARGB:
70 pixels[offset * sizeof(uint32_t) + 1] = value >> 8;
71 pixels[offset * sizeof(uint32_t) + 2] = value >> 8;
72 pixels[offset * sizeof(uint32_t) + 3] = value >> 8;
73 break;
74 default:
75 pixels[offset] = value >> 8;
76 break;
77 }
78 }
79 }
80 }
81 }
82
83 void DrawPacman(VideoPixelFormat frame_format,
37 uint8_t* const data, 84 uint8_t* const data,
38 base::TimeDelta elapsed_time, 85 base::TimeDelta elapsed_time,
39 float frame_rate, 86 float frame_rate,
40 const gfx::Size& frame_size, 87 const gfx::Size& frame_size,
41 uint32_t zoom) { 88 uint32_t zoom) {
42 // |kN32_SkColorType| stands for the appropriate RGBA/BGRA format. 89 // |kN32_SkColorType| stands for the appropriate RGBA/BGRA format.
43 const SkColorType colorspace = 90 const SkColorType colorspace = (frame_format == PIXEL_FORMAT_ARGB)
44 use_argb ? kN32_SkColorType : kAlpha_8_SkColorType; 91 ? kN32_SkColorType
92 : kAlpha_8_SkColorType;
93 // Skia doesn't support 16 bit alpha rendering, so we 8 bit alpha and then use
94 // this as high byte values in 16 bit pixels.
45 const SkImageInfo info = SkImageInfo::Make( 95 const SkImageInfo info = SkImageInfo::Make(
46 frame_size.width(), frame_size.height(), colorspace, kOpaque_SkAlphaType); 96 frame_size.width(), frame_size.height(), colorspace, kOpaque_SkAlphaType);
47 SkBitmap bitmap; 97 SkBitmap bitmap;
48 bitmap.setInfo(info); 98 bitmap.setInfo(info);
49 bitmap.setPixels(data); 99 bitmap.setPixels(data);
50 SkPaint paint; 100 SkPaint paint;
51 paint.setStyle(SkPaint::kFill_Style); 101 paint.setStyle(SkPaint::kFill_Style);
52 SkCanvas canvas(bitmap); 102 SkCanvas canvas(bitmap);
53 103
54 const SkScalar unscaled_zoom = zoom / 100.f; 104 const SkScalar unscaled_zoom = zoom / 100.f;
55 SkMatrix matrix; 105 SkMatrix matrix;
56 matrix.setScale(unscaled_zoom, unscaled_zoom, frame_size.width() / 2, 106 matrix.setScale(unscaled_zoom, unscaled_zoom, frame_size.width() / 2,
57 frame_size.height() / 2); 107 frame_size.height() / 2);
58 canvas.setMatrix(matrix); 108 canvas.setMatrix(matrix);
59 109
60 // Equalize Alpha_8 that has light green background while RGBA has white. 110 // Equalize Alpha_8 that has light green background while RGBA has white.
61 if (use_argb) { 111 if (frame_format == PIXEL_FORMAT_ARGB) {
62 const SkRect full_frame = 112 const SkRect full_frame =
63 SkRect::MakeWH(frame_size.width(), frame_size.height()); 113 SkRect::MakeWH(frame_size.width(), frame_size.height());
64 paint.setARGB(255, 0, 127, 0); 114 paint.setARGB(255, 0, 127, 0);
65 canvas.drawRect(full_frame, paint); 115 canvas.drawRect(full_frame, paint);
66 } 116 }
67 paint.setColor(SK_ColorGREEN); 117 paint.setColor(SK_ColorGREEN);
68 118
69 // Draw a sweeping circle to show an animation. 119 // Draw a sweeping circle to show an animation.
70 const float end_angle = 120 const float end_angle =
71 fmod(kPacmanAngularVelocity * elapsed_time.InSecondsF(), 361); 121 fmod(kPacmanAngularVelocity * elapsed_time.InSecondsF(), 361);
72 const int radius = std::min(frame_size.width(), frame_size.height()) / 4; 122 const int radius = std::min(frame_size.width(), frame_size.height()) / 4;
73 const SkRect rect = SkRect::MakeXYWH(frame_size.width() / 2 - radius, 123 const SkRect rect = SkRect::MakeXYWH(frame_size.width() / 2 - radius,
74 frame_size.height() / 2 - radius, 124 frame_size.height() / 2 - radius,
75 2 * radius, 2 * radius); 125 2 * radius, 2 * radius);
76 canvas.drawArc(rect, 0, end_angle, true, paint); 126 canvas.drawArc(rect, 0, end_angle, true, paint);
77 127
78 // Draw current time. 128 // Draw current time.
79 const int milliseconds = elapsed_time.InMilliseconds() % 1000; 129 const int milliseconds = elapsed_time.InMilliseconds() % 1000;
80 const int seconds = elapsed_time.InSeconds() % 60; 130 const int seconds = elapsed_time.InSeconds() % 60;
81 const int minutes = elapsed_time.InMinutes() % 60; 131 const int minutes = elapsed_time.InMinutes() % 60;
82 const int hours = elapsed_time.InHours(); 132 const int hours = elapsed_time.InHours();
83 const int frame_count = elapsed_time.InMilliseconds() * frame_rate / 1000; 133 const int frame_count = elapsed_time.InMilliseconds() * frame_rate / 1000;
84 134
85 const std::string time_string = 135 const std::string time_string =
86 base::StringPrintf("%d:%02d:%02d:%03d %d", hours, minutes, seconds, 136 base::StringPrintf("%d:%02d:%02d:%03d %d", hours, minutes, seconds,
87 milliseconds, frame_count); 137 milliseconds, frame_count);
88 canvas.scale(3, 3); 138 canvas.scale(3, 3);
89 canvas.drawText(time_string.data(), time_string.length(), 30, 20, paint); 139 canvas.drawText(time_string.data(), time_string.length(), 30, 20, paint);
140
141 if (frame_format == PIXEL_FORMAT_Y16) {
142 // Use 8 bit bitmap rendered to first half of the buffer as high byte values
143 // for the whole buffer. Low byte values are not important.
144 for (int i = frame_size.GetArea() - 1; i >= 0; --i)
145 data[i * 2 + 1] = data[i];
146 }
147 DrawGradientSquares(frame_format, data, elapsed_time, frame_size);
90 } 148 }
91 149
92 // Creates a PNG-encoded frame and sends it back to |callback|. The other 150 // Creates a PNG-encoded frame and sends it back to |callback|. The other
93 // parameters are used to replicate the PacMan rendering. 151 // parameters are used to replicate the PacMan rendering.
94 void DoTakeFakePhoto(VideoCaptureDevice::TakePhotoCallback callback, 152 void DoTakeFakePhoto(VideoCaptureDevice::TakePhotoCallback callback,
95 const VideoCaptureFormat& capture_format, 153 const VideoCaptureFormat& capture_format,
96 base::TimeDelta elapsed_time, 154 base::TimeDelta elapsed_time,
97 float fake_capture_rate, 155 float fake_capture_rate,
98 uint32_t zoom) { 156 uint32_t zoom) {
99 std::unique_ptr<uint8_t[]> buffer(new uint8_t[VideoFrame::AllocationSize( 157 std::unique_ptr<uint8_t[]> buffer(new uint8_t[VideoFrame::AllocationSize(
100 PIXEL_FORMAT_ARGB, capture_format.frame_size)]); 158 PIXEL_FORMAT_ARGB, capture_format.frame_size)]);
101 159
102 DrawPacman(true /* use_argb */, buffer.get(), elapsed_time, fake_capture_rate, 160 DrawPacman(PIXEL_FORMAT_ARGB, buffer.get(), elapsed_time, fake_capture_rate,
103 capture_format.frame_size, zoom); 161 capture_format.frame_size, zoom);
104 162
105 mojom::BlobPtr blob = mojom::Blob::New(); 163 mojom::BlobPtr blob = mojom::Blob::New();
106 const bool result = gfx::PNGCodec::Encode( 164 const bool result = gfx::PNGCodec::Encode(
107 buffer.get(), gfx::PNGCodec::FORMAT_RGBA, capture_format.frame_size, 165 buffer.get(), gfx::PNGCodec::FORMAT_RGBA, capture_format.frame_size,
108 capture_format.frame_size.width() * 4, true /* discard_transparency */, 166 capture_format.frame_size.width() * 4, true /* discard_transparency */,
109 std::vector<gfx::PNGCodec::Comment>(), &blob->data); 167 std::vector<gfx::PNGCodec::Comment>(), &blob->data);
110 DCHECK(result); 168 DCHECK(result);
111 169
112 blob->mime_type = "image/png"; 170 blob->mime_type = "image/png";
113 callback.Run(std::move(blob)); 171 callback.Run(std::move(blob));
114 } 172 }
115 173
116 FakeVideoCaptureDevice::FakeVideoCaptureDevice(BufferOwnership buffer_ownership, 174 FakeVideoCaptureDevice::FakeVideoCaptureDevice(BufferOwnership buffer_ownership,
117 float fake_capture_rate) 175 float fake_capture_rate,
176 VideoPixelFormat pixel_format)
118 : buffer_ownership_(buffer_ownership), 177 : buffer_ownership_(buffer_ownership),
119 fake_capture_rate_(fake_capture_rate), 178 fake_capture_rate_(fake_capture_rate),
179 pixel_format_(pixel_format),
120 current_zoom_(kMinZoom), 180 current_zoom_(kMinZoom),
121 weak_factory_(this) {} 181 weak_factory_(this) {}
122 182
123 FakeVideoCaptureDevice::~FakeVideoCaptureDevice() { 183 FakeVideoCaptureDevice::~FakeVideoCaptureDevice() {
124 DCHECK(thread_checker_.CalledOnValidThread()); 184 DCHECK(thread_checker_.CalledOnValidThread());
125 } 185 }
126 186
127 void FakeVideoCaptureDevice::AllocateAndStart( 187 void FakeVideoCaptureDevice::AllocateAndStart(
128 const VideoCaptureParams& params, 188 const VideoCaptureParams& params,
129 std::unique_ptr<VideoCaptureDevice::Client> client) { 189 std::unique_ptr<VideoCaptureDevice::Client> client) {
130 DCHECK(thread_checker_.CalledOnValidThread()); 190 DCHECK(thread_checker_.CalledOnValidThread());
131 191
132 client_ = std::move(client); 192 client_ = std::move(client);
133 193
134 // Incoming |params| can be none of the supported formats, so we get the 194 // Incoming |params| can be none of the supported formats, so we get the
135 // closest thing rounded up. TODO(mcasas): Use the |params|, if they belong to 195 // closest thing rounded up. TODO(mcasas): Use the |params|, if they belong to
136 // the supported ones, when http://crbug.com/309554 is verified. 196 // the supported ones, when http://crbug.com/309554 is verified.
137 capture_format_.frame_rate = fake_capture_rate_; 197 capture_format_.frame_rate = fake_capture_rate_;
138 if (params.requested_format.frame_size.width() > 1280) 198 if (params.requested_format.frame_size.width() > 1280)
139 capture_format_.frame_size.SetSize(1920, 1080); 199 capture_format_.frame_size.SetSize(1920, 1080);
140 else if (params.requested_format.frame_size.width() > 640) 200 else if (params.requested_format.frame_size.width() > 640)
141 capture_format_.frame_size.SetSize(1280, 720); 201 capture_format_.frame_size.SetSize(1280, 720);
142 else if (params.requested_format.frame_size.width() > 320) 202 else if (params.requested_format.frame_size.width() > 320)
143 capture_format_.frame_size.SetSize(640, 480); 203 capture_format_.frame_size.SetSize(640, 480);
204 else if (params.requested_format.frame_size.width() > 96)
205 capture_format_.frame_size.SetSize(320, 240);
144 else 206 else
145 capture_format_.frame_size.SetSize(320, 240); 207 capture_format_.frame_size.SetSize(96, 96);
146 208
209 capture_format_.pixel_format = pixel_format_;
147 if (buffer_ownership_ == BufferOwnership::CLIENT_BUFFERS) { 210 if (buffer_ownership_ == BufferOwnership::CLIENT_BUFFERS) {
148 capture_format_.pixel_storage = PIXEL_STORAGE_CPU; 211 capture_format_.pixel_storage = PIXEL_STORAGE_CPU;
149 capture_format_.pixel_format = PIXEL_FORMAT_ARGB; 212 capture_format_.pixel_format = PIXEL_FORMAT_ARGB;
150 DVLOG(1) << "starting with client argb buffers"; 213 DVLOG(1) << "starting with client argb buffers";
151 } else if (buffer_ownership_ == BufferOwnership::OWN_BUFFERS) { 214 } else if (buffer_ownership_ == BufferOwnership::OWN_BUFFERS) {
152 capture_format_.pixel_storage = PIXEL_STORAGE_CPU; 215 capture_format_.pixel_storage = PIXEL_STORAGE_CPU;
153 capture_format_.pixel_format = PIXEL_FORMAT_I420; 216 DVLOG(1) << "starting with own " << VideoPixelFormatToString(pixel_format_)
154 DVLOG(1) << "starting with own I420 buffers"; 217 << " buffers";
155 } 218 }
156 219
157 if (capture_format_.pixel_format == PIXEL_FORMAT_I420) { 220 if (buffer_ownership_ == BufferOwnership::OWN_BUFFERS) {
158 fake_frame_.reset(new uint8_t[VideoFrame::AllocationSize( 221 fake_frame_.reset(new uint8_t[VideoFrame::AllocationSize(
159 PIXEL_FORMAT_I420, capture_format_.frame_size)]); 222 pixel_format_, capture_format_.frame_size)]);
160 } 223 }
161 224
162 beep_time_ = base::TimeDelta(); 225 beep_time_ = base::TimeDelta();
163 elapsed_time_ = base::TimeDelta(); 226 elapsed_time_ = base::TimeDelta();
164 227
165 if (buffer_ownership_ == BufferOwnership::CLIENT_BUFFERS) 228 if (buffer_ownership_ == BufferOwnership::CLIENT_BUFFERS)
166 BeepAndScheduleNextCapture( 229 BeepAndScheduleNextCapture(
167 base::TimeTicks::Now(), 230 base::TimeTicks::Now(),
168 base::Bind(&FakeVideoCaptureDevice::CaptureUsingClientBuffers, 231 base::Bind(&FakeVideoCaptureDevice::CaptureUsingClientBuffers,
169 weak_factory_.GetWeakPtr())); 232 weak_factory_.GetWeakPtr()));
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 base::ThreadTaskRunnerHandle::Get()->PostTask( 291 base::ThreadTaskRunnerHandle::Get()->PostTask(
229 FROM_HERE, 292 FROM_HERE,
230 base::Bind(&DoTakeFakePhoto, base::Passed(&callback), capture_format_, 293 base::Bind(&DoTakeFakePhoto, base::Passed(&callback), capture_format_,
231 elapsed_time_, fake_capture_rate_, current_zoom_)); 294 elapsed_time_, fake_capture_rate_, current_zoom_));
232 } 295 }
233 296
234 void FakeVideoCaptureDevice::CaptureUsingOwnBuffers( 297 void FakeVideoCaptureDevice::CaptureUsingOwnBuffers(
235 base::TimeTicks expected_execution_time) { 298 base::TimeTicks expected_execution_time) {
236 DCHECK(thread_checker_.CalledOnValidThread()); 299 DCHECK(thread_checker_.CalledOnValidThread());
237 const size_t frame_size = capture_format_.ImageAllocationSize(); 300 const size_t frame_size = capture_format_.ImageAllocationSize();
301
238 memset(fake_frame_.get(), 0, frame_size); 302 memset(fake_frame_.get(), 0, frame_size);
239 303 DrawPacman(capture_format_.pixel_format, fake_frame_.get(), elapsed_time_,
240 DrawPacman(false /* use_argb */, fake_frame_.get(), elapsed_time_,
241 fake_capture_rate_, capture_format_.frame_size, current_zoom_); 304 fake_capture_rate_, capture_format_.frame_size, current_zoom_);
242
243 // Give the captured frame to the client. 305 // Give the captured frame to the client.
244 base::TimeTicks now = base::TimeTicks::Now(); 306 base::TimeTicks now = base::TimeTicks::Now();
245 if (first_ref_time_.is_null()) 307 if (first_ref_time_.is_null())
246 first_ref_time_ = now; 308 first_ref_time_ = now;
247 client_->OnIncomingCapturedData(fake_frame_.get(), frame_size, 309 client_->OnIncomingCapturedData(fake_frame_.get(), frame_size,
248 capture_format_, 0 /* rotation */, now, 310 capture_format_, 0 /* rotation */, now,
249 now - first_ref_time_); 311 now - first_ref_time_);
250 BeepAndScheduleNextCapture( 312 BeepAndScheduleNextCapture(
251 expected_execution_time, 313 expected_execution_time,
252 base::Bind(&FakeVideoCaptureDevice::CaptureUsingOwnBuffers, 314 base::Bind(&FakeVideoCaptureDevice::CaptureUsingOwnBuffers,
253 weak_factory_.GetWeakPtr())); 315 weak_factory_.GetWeakPtr()));
254 } 316 }
255 317
256 void FakeVideoCaptureDevice::CaptureUsingClientBuffers( 318 void FakeVideoCaptureDevice::CaptureUsingClientBuffers(
257 base::TimeTicks expected_execution_time) { 319 base::TimeTicks expected_execution_time) {
258 DCHECK(thread_checker_.CalledOnValidThread()); 320 DCHECK(thread_checker_.CalledOnValidThread());
259 321
260 std::unique_ptr<VideoCaptureDevice::Client::Buffer> capture_buffer( 322 std::unique_ptr<VideoCaptureDevice::Client::Buffer> capture_buffer(
261 client_->ReserveOutputBuffer(capture_format_.frame_size, 323 client_->ReserveOutputBuffer(capture_format_.frame_size,
262 capture_format_.pixel_format, 324 capture_format_.pixel_format,
263 capture_format_.pixel_storage)); 325 capture_format_.pixel_storage));
264 DLOG_IF(ERROR, !capture_buffer) << "Couldn't allocate Capture Buffer"; 326 DLOG_IF(ERROR, !capture_buffer) << "Couldn't allocate Capture Buffer";
265 DCHECK(capture_buffer->data()) << "Buffer has NO backing memory"; 327 DCHECK(capture_buffer->data()) << "Buffer has NO backing memory";
266 328
267 DCHECK_EQ(PIXEL_STORAGE_CPU, capture_format_.pixel_storage); 329 DCHECK_EQ(PIXEL_STORAGE_CPU, capture_format_.pixel_storage);
268 DCHECK_EQ(PIXEL_FORMAT_ARGB, capture_format_.pixel_format);
269 uint8_t* data_ptr = static_cast<uint8_t*>(capture_buffer->data()); 330 uint8_t* data_ptr = static_cast<uint8_t*>(capture_buffer->data());
270 memset(data_ptr, 0, capture_buffer->mapped_size()); 331 memset(data_ptr, 0, capture_buffer->mapped_size());
271 DrawPacman(true /* use_argb */, data_ptr, elapsed_time_, fake_capture_rate_, 332 DrawPacman(capture_format_.pixel_format, data_ptr, elapsed_time_,
272 capture_format_.frame_size, current_zoom_); 333 fake_capture_rate_, capture_format_.frame_size, current_zoom_);
273 334
274 // Give the captured frame to the client. 335 // Give the captured frame to the client.
275 base::TimeTicks now = base::TimeTicks::Now(); 336 base::TimeTicks now = base::TimeTicks::Now();
276 if (first_ref_time_.is_null()) 337 if (first_ref_time_.is_null())
277 first_ref_time_ = now; 338 first_ref_time_ = now;
278 client_->OnIncomingCapturedBuffer(std::move(capture_buffer), capture_format_, 339 client_->OnIncomingCapturedBuffer(std::move(capture_buffer), capture_format_,
279 now, now - first_ref_time_); 340 now, now - first_ref_time_);
280 341
281 BeepAndScheduleNextCapture( 342 BeepAndScheduleNextCapture(
282 expected_execution_time, 343 expected_execution_time,
(...skipping 22 matching lines...) Expand all
305 // Don't accumulate any debt if we are lagging behind - just post the next 366 // Don't accumulate any debt if we are lagging behind - just post the next
306 // frame immediately and continue as normal. 367 // frame immediately and continue as normal.
307 const base::TimeTicks next_execution_time = 368 const base::TimeTicks next_execution_time =
308 std::max(current_time, expected_execution_time + frame_interval); 369 std::max(current_time, expected_execution_time + frame_interval);
309 const base::TimeDelta delay = next_execution_time - current_time; 370 const base::TimeDelta delay = next_execution_time - current_time;
310 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 371 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
311 FROM_HERE, base::Bind(next_capture, next_execution_time), delay); 372 FROM_HERE, base::Bind(next_capture, next_execution_time), delay);
312 } 373 }
313 374
314 } // namespace media 375 } // namespace media
OLDNEW
« no previous file with comments | « media/capture/video/fake_video_capture_device.h ('k') | media/capture/video/fake_video_capture_device_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698