Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 gfx::Point squares[] = {{0, 0}, | |
|
mcasas
2016/10/25 22:13:12
const ?
Also |start| in the next line.
aleksandar.stojiljkovic
2016/10/25 23:20:40
Done.
| |
| 52 {width - side, 0}, | |
| 53 {0, height - side}, | |
| 54 {width - side, height - side}}; | |
| 55 float start = | |
| 56 fmod(65536 * elapsed_time.InSecondsF() * kGradientFrequency, 65536); | |
| 57 const float color_step = 65535 / static_cast<float>(width + height); | |
| 58 for (unsigned i = 0; i < sizeof(squares) / sizeof(gfx::Point); ++i) { | |
|
mcasas
2016/10/25 22:13:12
Suggestion:
for (const auto& corner : squares)
aleksandar.stojiljkovic
2016/10/25 23:20:39
Done.
| |
| 59 for (int y = squares[i].y(); y < squares[i].y() + side; ++y) { | |
| 60 for (int x = squares[i].x(); x < squares[i].x() + side; ++x) { | |
| 61 unsigned value = | |
|
mcasas
2016/10/25 22:13:12
const unsigned int?
aleksandar.stojiljkovic
2016/10/25 23:20:39
Done.
| |
| 62 static_cast<unsigned>(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 } | |
|
mcasas
2016/10/25 22:13:12
No need for {} in one-line bodies.
aleksandar.stojiljkovic
2016/10/25 23:20:39
Done.
| |
| 147 } | |
| 148 DrawGradientSquares(frame_format, data, elapsed_time, frame_size); | |
|
mcasas
2016/10/25 22:13:12
So, just to make sure, I think you mentioned
elsew
aleksandar.stojiljkovic
2016/10/25 23:20:40
I run CQ in Patch Set 1: all passed - layout test
| |
| 90 } | 149 } |
| 91 | 150 |
| 92 // Creates a PNG-encoded frame and sends it back to |callback|. The other | 151 // Creates a PNG-encoded frame and sends it back to |callback|. The other |
| 93 // parameters are used to replicate the PacMan rendering. | 152 // parameters are used to replicate the PacMan rendering. |
| 94 void DoTakeFakePhoto(VideoCaptureDevice::TakePhotoCallback callback, | 153 void DoTakeFakePhoto(VideoCaptureDevice::TakePhotoCallback callback, |
| 95 const VideoCaptureFormat& capture_format, | 154 const VideoCaptureFormat& capture_format, |
| 96 base::TimeDelta elapsed_time, | 155 base::TimeDelta elapsed_time, |
| 97 float fake_capture_rate, | 156 float fake_capture_rate, |
| 98 uint32_t zoom) { | 157 uint32_t zoom) { |
| 99 std::unique_ptr<uint8_t[]> buffer(new uint8_t[VideoFrame::AllocationSize( | 158 std::unique_ptr<uint8_t[]> buffer(new uint8_t[VideoFrame::AllocationSize( |
| 100 PIXEL_FORMAT_ARGB, capture_format.frame_size)]); | 159 PIXEL_FORMAT_ARGB, capture_format.frame_size)]); |
| 101 | 160 |
| 102 DrawPacman(true /* use_argb */, buffer.get(), elapsed_time, fake_capture_rate, | 161 DrawPacman(PIXEL_FORMAT_ARGB, buffer.get(), elapsed_time, fake_capture_rate, |
| 103 capture_format.frame_size, zoom); | 162 capture_format.frame_size, zoom); |
| 104 | 163 |
| 105 mojom::BlobPtr blob = mojom::Blob::New(); | 164 mojom::BlobPtr blob = mojom::Blob::New(); |
| 106 const bool result = gfx::PNGCodec::Encode( | 165 const bool result = gfx::PNGCodec::Encode( |
| 107 buffer.get(), gfx::PNGCodec::FORMAT_RGBA, capture_format.frame_size, | 166 buffer.get(), gfx::PNGCodec::FORMAT_RGBA, capture_format.frame_size, |
| 108 capture_format.frame_size.width() * 4, true /* discard_transparency */, | 167 capture_format.frame_size.width() * 4, true /* discard_transparency */, |
| 109 std::vector<gfx::PNGCodec::Comment>(), &blob->data); | 168 std::vector<gfx::PNGCodec::Comment>(), &blob->data); |
| 110 DCHECK(result); | 169 DCHECK(result); |
| 111 | 170 |
| 112 blob->mime_type = "image/png"; | 171 blob->mime_type = "image/png"; |
| 113 callback.Run(std::move(blob)); | 172 callback.Run(std::move(blob)); |
| 114 } | 173 } |
| 115 | 174 |
| 116 FakeVideoCaptureDevice::FakeVideoCaptureDevice(BufferOwnership buffer_ownership, | 175 FakeVideoCaptureDevice::FakeVideoCaptureDevice(BufferOwnership buffer_ownership, |
| 117 float fake_capture_rate) | 176 float fake_capture_rate, |
| 177 VideoPixelFormat pixel_format) | |
| 118 : buffer_ownership_(buffer_ownership), | 178 : buffer_ownership_(buffer_ownership), |
| 119 fake_capture_rate_(fake_capture_rate), | 179 fake_capture_rate_(fake_capture_rate), |
| 180 pixel_format_(pixel_format), | |
| 120 current_zoom_(kMinZoom), | 181 current_zoom_(kMinZoom), |
| 121 weak_factory_(this) {} | 182 weak_factory_(this) {} |
| 122 | 183 |
| 123 FakeVideoCaptureDevice::~FakeVideoCaptureDevice() { | 184 FakeVideoCaptureDevice::~FakeVideoCaptureDevice() { |
| 124 DCHECK(thread_checker_.CalledOnValidThread()); | 185 DCHECK(thread_checker_.CalledOnValidThread()); |
| 125 } | 186 } |
| 126 | 187 |
| 127 void FakeVideoCaptureDevice::AllocateAndStart( | 188 void FakeVideoCaptureDevice::AllocateAndStart( |
| 128 const VideoCaptureParams& params, | 189 const VideoCaptureParams& params, |
| 129 std::unique_ptr<VideoCaptureDevice::Client> client) { | 190 std::unique_ptr<VideoCaptureDevice::Client> client) { |
| 130 DCHECK(thread_checker_.CalledOnValidThread()); | 191 DCHECK(thread_checker_.CalledOnValidThread()); |
| 131 | 192 |
| 132 client_ = std::move(client); | 193 client_ = std::move(client); |
| 133 | 194 |
| 134 // Incoming |params| can be none of the supported formats, so we get the | 195 // 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 | 196 // closest thing rounded up. TODO(mcasas): Use the |params|, if they belong to |
| 136 // the supported ones, when http://crbug.com/309554 is verified. | 197 // the supported ones, when http://crbug.com/309554 is verified. |
| 137 capture_format_.frame_rate = fake_capture_rate_; | 198 capture_format_.frame_rate = fake_capture_rate_; |
| 138 if (params.requested_format.frame_size.width() > 1280) | 199 if (params.requested_format.frame_size.width() > 1280) |
| 139 capture_format_.frame_size.SetSize(1920, 1080); | 200 capture_format_.frame_size.SetSize(1920, 1080); |
| 140 else if (params.requested_format.frame_size.width() > 640) | 201 else if (params.requested_format.frame_size.width() > 640) |
| 141 capture_format_.frame_size.SetSize(1280, 720); | 202 capture_format_.frame_size.SetSize(1280, 720); |
| 142 else if (params.requested_format.frame_size.width() > 320) | 203 else if (params.requested_format.frame_size.width() > 320) |
| 143 capture_format_.frame_size.SetSize(640, 480); | 204 capture_format_.frame_size.SetSize(640, 480); |
| 205 else if (params.requested_format.frame_size.width() > 96) | |
| 206 capture_format_.frame_size.SetSize(320, 240); | |
| 144 else | 207 else |
| 145 capture_format_.frame_size.SetSize(320, 240); | 208 capture_format_.frame_size.SetSize(96, 96); |
| 146 | 209 |
| 210 capture_format_.pixel_format = pixel_format_; | |
| 147 if (buffer_ownership_ == BufferOwnership::CLIENT_BUFFERS) { | 211 if (buffer_ownership_ == BufferOwnership::CLIENT_BUFFERS) { |
| 148 capture_format_.pixel_storage = PIXEL_STORAGE_CPU; | 212 capture_format_.pixel_storage = PIXEL_STORAGE_CPU; |
| 149 capture_format_.pixel_format = PIXEL_FORMAT_ARGB; | 213 capture_format_.pixel_format = PIXEL_FORMAT_ARGB; |
| 150 DVLOG(1) << "starting with client argb buffers"; | 214 DVLOG(1) << "starting with client argb buffers"; |
| 151 } else if (buffer_ownership_ == BufferOwnership::OWN_BUFFERS) { | 215 } else if (buffer_ownership_ == BufferOwnership::OWN_BUFFERS) { |
| 152 capture_format_.pixel_storage = PIXEL_STORAGE_CPU; | 216 capture_format_.pixel_storage = PIXEL_STORAGE_CPU; |
| 153 capture_format_.pixel_format = PIXEL_FORMAT_I420; | 217 DVLOG(1) << "starting with own" << VideoPixelFormatToString(pixel_format_) |
| 154 DVLOG(1) << "starting with own I420 buffers"; | 218 << "buffers"; |
|
mcasas
2016/10/25 22:13:12
nit: whitespace here before "buffers" and after "o
aleksandar.stojiljkovic
2016/10/25 23:20:39
Done.
| |
| 155 } | 219 } |
| 156 | 220 |
| 157 if (capture_format_.pixel_format == PIXEL_FORMAT_I420) { | 221 if (buffer_ownership_ == BufferOwnership::OWN_BUFFERS) { |
| 158 fake_frame_.reset(new uint8_t[VideoFrame::AllocationSize( | 222 fake_frame_.reset(new uint8_t[VideoFrame::AllocationSize( |
| 159 PIXEL_FORMAT_I420, capture_format_.frame_size)]); | 223 pixel_format_, capture_format_.frame_size)]); |
| 160 } | 224 } |
| 161 | 225 |
| 162 beep_time_ = base::TimeDelta(); | 226 beep_time_ = base::TimeDelta(); |
| 163 elapsed_time_ = base::TimeDelta(); | 227 elapsed_time_ = base::TimeDelta(); |
| 164 | 228 |
| 165 if (buffer_ownership_ == BufferOwnership::CLIENT_BUFFERS) | 229 if (buffer_ownership_ == BufferOwnership::CLIENT_BUFFERS) |
| 166 BeepAndScheduleNextCapture( | 230 BeepAndScheduleNextCapture( |
| 167 base::TimeTicks::Now(), | 231 base::TimeTicks::Now(), |
| 168 base::Bind(&FakeVideoCaptureDevice::CaptureUsingClientBuffers, | 232 base::Bind(&FakeVideoCaptureDevice::CaptureUsingClientBuffers, |
| 169 weak_factory_.GetWeakPtr())); | 233 weak_factory_.GetWeakPtr())); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 228 base::ThreadTaskRunnerHandle::Get()->PostTask( | 292 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 229 FROM_HERE, | 293 FROM_HERE, |
| 230 base::Bind(&DoTakeFakePhoto, base::Passed(&callback), capture_format_, | 294 base::Bind(&DoTakeFakePhoto, base::Passed(&callback), capture_format_, |
| 231 elapsed_time_, fake_capture_rate_, current_zoom_)); | 295 elapsed_time_, fake_capture_rate_, current_zoom_)); |
| 232 } | 296 } |
| 233 | 297 |
| 234 void FakeVideoCaptureDevice::CaptureUsingOwnBuffers( | 298 void FakeVideoCaptureDevice::CaptureUsingOwnBuffers( |
| 235 base::TimeTicks expected_execution_time) { | 299 base::TimeTicks expected_execution_time) { |
| 236 DCHECK(thread_checker_.CalledOnValidThread()); | 300 DCHECK(thread_checker_.CalledOnValidThread()); |
| 237 const size_t frame_size = capture_format_.ImageAllocationSize(); | 301 const size_t frame_size = capture_format_.ImageAllocationSize(); |
| 302 | |
| 238 memset(fake_frame_.get(), 0, frame_size); | 303 memset(fake_frame_.get(), 0, frame_size); |
| 239 | 304 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_); | 305 fake_capture_rate_, capture_format_.frame_size, current_zoom_); |
| 242 | |
| 243 // Give the captured frame to the client. | 306 // Give the captured frame to the client. |
| 244 base::TimeTicks now = base::TimeTicks::Now(); | 307 base::TimeTicks now = base::TimeTicks::Now(); |
| 245 if (first_ref_time_.is_null()) | 308 if (first_ref_time_.is_null()) |
| 246 first_ref_time_ = now; | 309 first_ref_time_ = now; |
| 247 client_->OnIncomingCapturedData(fake_frame_.get(), frame_size, | 310 client_->OnIncomingCapturedData(fake_frame_.get(), frame_size, |
| 248 capture_format_, 0 /* rotation */, now, | 311 capture_format_, 0 /* rotation */, now, |
| 249 now - first_ref_time_); | 312 now - first_ref_time_); |
| 250 BeepAndScheduleNextCapture( | 313 BeepAndScheduleNextCapture( |
| 251 expected_execution_time, | 314 expected_execution_time, |
| 252 base::Bind(&FakeVideoCaptureDevice::CaptureUsingOwnBuffers, | 315 base::Bind(&FakeVideoCaptureDevice::CaptureUsingOwnBuffers, |
| 253 weak_factory_.GetWeakPtr())); | 316 weak_factory_.GetWeakPtr())); |
| 254 } | 317 } |
| 255 | 318 |
| 256 void FakeVideoCaptureDevice::CaptureUsingClientBuffers( | 319 void FakeVideoCaptureDevice::CaptureUsingClientBuffers( |
| 257 base::TimeTicks expected_execution_time) { | 320 base::TimeTicks expected_execution_time) { |
| 258 DCHECK(thread_checker_.CalledOnValidThread()); | 321 DCHECK(thread_checker_.CalledOnValidThread()); |
| 259 | 322 |
| 260 std::unique_ptr<VideoCaptureDevice::Client::Buffer> capture_buffer( | 323 std::unique_ptr<VideoCaptureDevice::Client::Buffer> capture_buffer( |
| 261 client_->ReserveOutputBuffer(capture_format_.frame_size, | 324 client_->ReserveOutputBuffer(capture_format_.frame_size, |
| 262 capture_format_.pixel_format, | 325 capture_format_.pixel_format, |
| 263 capture_format_.pixel_storage)); | 326 capture_format_.pixel_storage)); |
| 264 DLOG_IF(ERROR, !capture_buffer) << "Couldn't allocate Capture Buffer"; | 327 DLOG_IF(ERROR, !capture_buffer) << "Couldn't allocate Capture Buffer"; |
| 265 DCHECK(capture_buffer->data()) << "Buffer has NO backing memory"; | 328 DCHECK(capture_buffer->data()) << "Buffer has NO backing memory"; |
| 266 | 329 |
| 267 DCHECK_EQ(PIXEL_STORAGE_CPU, capture_format_.pixel_storage); | 330 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()); | 331 uint8_t* data_ptr = static_cast<uint8_t*>(capture_buffer->data()); |
| 270 memset(data_ptr, 0, capture_buffer->mapped_size()); | 332 memset(data_ptr, 0, capture_buffer->mapped_size()); |
| 271 DrawPacman(true /* use_argb */, data_ptr, elapsed_time_, fake_capture_rate_, | 333 DrawPacman(capture_format_.pixel_format, data_ptr, elapsed_time_, |
| 272 capture_format_.frame_size, current_zoom_); | 334 fake_capture_rate_, capture_format_.frame_size, current_zoom_); |
| 273 | 335 |
| 274 // Give the captured frame to the client. | 336 // Give the captured frame to the client. |
| 275 base::TimeTicks now = base::TimeTicks::Now(); | 337 base::TimeTicks now = base::TimeTicks::Now(); |
| 276 if (first_ref_time_.is_null()) | 338 if (first_ref_time_.is_null()) |
| 277 first_ref_time_ = now; | 339 first_ref_time_ = now; |
| 278 client_->OnIncomingCapturedBuffer(std::move(capture_buffer), capture_format_, | 340 client_->OnIncomingCapturedBuffer(std::move(capture_buffer), capture_format_, |
| 279 now, now - first_ref_time_); | 341 now, now - first_ref_time_); |
| 280 | 342 |
| 281 BeepAndScheduleNextCapture( | 343 BeepAndScheduleNextCapture( |
| 282 expected_execution_time, | 344 expected_execution_time, |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 305 // Don't accumulate any debt if we are lagging behind - just post the next | 367 // Don't accumulate any debt if we are lagging behind - just post the next |
| 306 // frame immediately and continue as normal. | 368 // frame immediately and continue as normal. |
| 307 const base::TimeTicks next_execution_time = | 369 const base::TimeTicks next_execution_time = |
| 308 std::max(current_time, expected_execution_time + frame_interval); | 370 std::max(current_time, expected_execution_time + frame_interval); |
| 309 const base::TimeDelta delay = next_execution_time - current_time; | 371 const base::TimeDelta delay = next_execution_time - current_time; |
| 310 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 372 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 311 FROM_HERE, base::Bind(next_capture, next_execution_time), delay); | 373 FROM_HERE, base::Bind(next_capture, next_execution_time), delay); |
| 312 } | 374 } |
| 313 | 375 |
| 314 } // namespace media | 376 } // namespace media |
| OLD | NEW |