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

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

Issue 2715513008: Make FakeVideoCaptureDeviceFactory configurable to arbitrary fake device configurations (Closed)
Patch Set: Fix compiler warning. Fix WebRtcDepthCaptureBrowserTest. Created 3 years, 10 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 "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 11 matching lines...) Expand all
22 #include "third_party/skia/include/core/SkBitmap.h" 22 #include "third_party/skia/include/core/SkBitmap.h"
23 #include "third_party/skia/include/core/SkCanvas.h" 23 #include "third_party/skia/include/core/SkCanvas.h"
24 #include "third_party/skia/include/core/SkMatrix.h" 24 #include "third_party/skia/include/core/SkMatrix.h"
25 #include "third_party/skia/include/core/SkPaint.h" 25 #include "third_party/skia/include/core/SkPaint.h"
26 #include "ui/gfx/codec/jpeg_codec.h" 26 #include "ui/gfx/codec/jpeg_codec.h"
27 #include "ui/gfx/codec/png_codec.h" 27 #include "ui/gfx/codec/png_codec.h"
28 28
29 namespace media { 29 namespace media {
30 30
31 namespace { 31 namespace {
32
32 // Sweep at 600 deg/sec. 33 // Sweep at 600 deg/sec.
33 static const float kPacmanAngularVelocity = 600; 34 static const float kPacmanAngularVelocity = 600;
34 // Beep every 500 ms. 35 // Beep every 500 ms.
35 static const int kBeepInterval = 500; 36 static const int kBeepInterval = 500;
36 // Gradient travels from bottom to top in 5 seconds. 37 // Gradient travels from bottom to top in 5 seconds.
37 static const float kGradientFrequency = 1.f / 5; 38 static const float kGradientFrequency = 1.f / 5;
38 39
39 static const double kMinZoom = 100.0; 40 static const double kMinZoom = 100.0;
40 static const double kMaxZoom = 400.0; 41 static const double kMaxZoom = 400.0;
41 static const double kZoomStep = 1.0; 42 static const double kZoomStep = 1.0;
42 static const double kInitialZoom = 100.0;
43 43
44 static const gfx::Size kSupportedSizesOrderedByIncreasingWidth[] = { 44 enum class PixelFormatMatchType {
45 gfx::Size(96, 96), gfx::Size(320, 240), gfx::Size(640, 480), 45 EXACT,
46 gfx::Size(1280, 720), gfx::Size(1920, 1080)}; 46 SUPPORTED_THROUGH_CONVERSION,
47 static const int kSupportedSizesCount = 47 INCOMPATIBLE
48 arraysize(kSupportedSizesOrderedByIncreasingWidth); 48 };
49 49
50 static gfx::Size SnapToSupportedSize(const gfx::Size& requested_size) { 50 PixelFormatMatchType DetermineFormatMatchType(
51 for (const gfx::Size& supported_size : 51 media::VideoPixelFormat supported_format,
52 kSupportedSizesOrderedByIncreasingWidth) { 52 media::VideoPixelFormat requested_format) {
53 if (requested_size.width() <= supported_size.width()) 53 if (requested_format == media::PIXEL_FORMAT_I420) {
emircan 2017/03/01 18:58:58 Merge to a single if statement.
chfremer 2017/03/01 21:55:48 Done.
54 return supported_size; 54 if (supported_format == media::PIXEL_FORMAT_MJPEG)
55 return PixelFormatMatchType::SUPPORTED_THROUGH_CONVERSION;
55 } 56 }
56 return kSupportedSizesOrderedByIncreasingWidth[kSupportedSizesCount - 1]; 57 return (requested_format == supported_format)
58 ? PixelFormatMatchType::EXACT
59 : PixelFormatMatchType::INCOMPATIBLE;
57 } 60 }
58 61
59 // Represents the current state of a FakeVideoCaptureDevice. 62 bool CurrentFormatMatchIsWorseThanBest(PixelFormatMatchType current_match,
60 // This is a separate struct because read-access to it is shared with several 63 PixelFormatMatchType best_match) {
61 // collaborating classes. 64 if (current_match == PixelFormatMatchType::INCOMPATIBLE) {
emircan 2017/03/01 18:58:58 I don't think comparing like this is scalable. Can
chfremer 2017/03/01 21:55:48 Done.
62 struct FakeDeviceState { 65 return best_match == PixelFormatMatchType::EXACT ||
63 FakeDeviceState(float zoom, float frame_rate, VideoPixelFormat pixel_format) 66 best_match == PixelFormatMatchType::SUPPORTED_THROUGH_CONVERSION;
64 : zoom(zoom), 67 }
65 format(gfx::Size(), frame_rate, pixel_format, PIXEL_STORAGE_CPU) {} 68 if (current_match == PixelFormatMatchType::SUPPORTED_THROUGH_CONVERSION)
69 return best_match == PixelFormatMatchType::EXACT;
70 return false;
71 }
66 72
67 uint32_t zoom; 73 int FindIndexOfClosestSupportedFormat(
68 VideoCaptureFormat format; 74 const VideoCaptureFormat& requested_format,
69 }; 75 const VideoCaptureFormats& supported_formats) {
76 int best_index = 0;
77 PixelFormatMatchType best_format_match = PixelFormatMatchType::INCOMPATIBLE;
78 int best_width_mismatch = std::numeric_limits<int>::max();
79 float best_frame_rate_mismatch = std::numeric_limits<float>::max();
80 for (int i = 0; i < static_cast<int>(supported_formats.size()); i++) {
81 const auto& supported_format = supported_formats[i];
82 PixelFormatMatchType current_format_match = DetermineFormatMatchType(
83 supported_format.pixel_format, requested_format.pixel_format);
84 if (CurrentFormatMatchIsWorseThanBest(current_format_match,
85 best_format_match)) {
86 continue;
87 }
88 if (supported_format.frame_size.width() <
89 requested_format.frame_size.width())
90 continue;
91 const int current_width_mismatch = supported_format.frame_size.width() -
92 requested_format.frame_size.width();
93 if (current_width_mismatch > best_width_mismatch)
94 continue;
95 const float current_frame_rate_mismatch =
96 std::abs(supported_format.frame_rate - requested_format.frame_rate);
97 if (current_width_mismatch < best_width_mismatch) {
98 best_width_mismatch = current_width_mismatch;
99 best_frame_rate_mismatch = current_frame_rate_mismatch;
100 best_index = i;
101 continue;
102 }
103 DCHECK_EQ(best_frame_rate_mismatch, current_frame_rate_mismatch);
104 if (current_frame_rate_mismatch < best_frame_rate_mismatch) {
105 best_frame_rate_mismatch = current_frame_rate_mismatch;
106 best_index = i;
107 }
108 }
109 return best_index;
110 }
70 111
71 // Paints a "pacman-like" animated circle including textual information such 112 } // anonymous namespace
72 // as a frame count and timer.
73 class PacmanFramePainter {
74 public:
75 enum class Format { I420, SK_N32, Y16 };
76 PacmanFramePainter(Format pixel_format,
77 const FakeDeviceState* fake_device_state);
78
79 void PaintFrame(base::TimeDelta elapsed_time, uint8_t* target_buffer);
80
81 private:
82 void DrawGradientSquares(base::TimeDelta elapsed_time,
83 uint8_t* target_buffer);
84
85 void DrawPacman(base::TimeDelta elapsed_time, uint8_t* target_buffer);
86
87 const Format pixel_format_;
88 const FakeDeviceState* fake_device_state_ = nullptr;
89 };
90 113
91 // Paints and delivers frames to a client, which is set via Initialize(). 114 // Paints and delivers frames to a client, which is set via Initialize().
92 class FrameDeliverer { 115 class FrameDeliverer {
93 public: 116 public:
94 FrameDeliverer(std::unique_ptr<PacmanFramePainter> frame_painter) 117 FrameDeliverer(std::unique_ptr<PacmanFramePainter> frame_painter)
95 : frame_painter_(std::move(frame_painter)) {} 118 : frame_painter_(std::move(frame_painter)) {}
96 virtual ~FrameDeliverer() {} 119 virtual ~FrameDeliverer() {}
97 virtual void Initialize(VideoPixelFormat pixel_format, 120 virtual void Initialize(VideoPixelFormat pixel_format,
98 std::unique_ptr<VideoCaptureDevice::Client> client, 121 std::unique_ptr<VideoCaptureDevice::Client> client,
99 const FakeDeviceState* device_state) { 122 const FakeDeviceState* device_state) {
100 client_ = std::move(client); 123 client_ = std::move(client);
101 device_state_ = device_state; 124 device_state_ = device_state;
102 } 125 }
103 virtual void Uninitialize() {
104 client_.reset();
105 device_state_ = nullptr;
106 }
107 virtual void PaintAndDeliverNextFrame(base::TimeDelta timestamp_to_paint) = 0; 126 virtual void PaintAndDeliverNextFrame(base::TimeDelta timestamp_to_paint) = 0;
108 127
109 protected: 128 protected:
110 base::TimeDelta CalculateTimeSinceFirstInvocation(base::TimeTicks now) { 129 base::TimeDelta CalculateTimeSinceFirstInvocation(base::TimeTicks now) {
111 if (first_ref_time_.is_null()) 130 if (first_ref_time_.is_null())
112 first_ref_time_ = now; 131 first_ref_time_ = now;
113 return now - first_ref_time_; 132 return now - first_ref_time_;
114 } 133 }
115 134
116 PacmanFramePainter* frame_painter() { return frame_painter_.get(); } 135 PacmanFramePainter* frame_painter() { return frame_painter_.get(); }
(...skipping 10 matching lines...) Expand all
127 // Delivers frames using its own buffers via OnIncomingCapturedData(). 146 // Delivers frames using its own buffers via OnIncomingCapturedData().
128 class OwnBufferFrameDeliverer : public FrameDeliverer { 147 class OwnBufferFrameDeliverer : public FrameDeliverer {
129 public: 148 public:
130 OwnBufferFrameDeliverer(std::unique_ptr<PacmanFramePainter> frame_painter); 149 OwnBufferFrameDeliverer(std::unique_ptr<PacmanFramePainter> frame_painter);
131 ~OwnBufferFrameDeliverer() override; 150 ~OwnBufferFrameDeliverer() override;
132 151
133 // Implementation of FrameDeliverer 152 // Implementation of FrameDeliverer
134 void Initialize(VideoPixelFormat pixel_format, 153 void Initialize(VideoPixelFormat pixel_format,
135 std::unique_ptr<VideoCaptureDevice::Client> client, 154 std::unique_ptr<VideoCaptureDevice::Client> client,
136 const FakeDeviceState* device_state) override; 155 const FakeDeviceState* device_state) override;
137 void Uninitialize() override;
138 void PaintAndDeliverNextFrame(base::TimeDelta timestamp_to_paint) override; 156 void PaintAndDeliverNextFrame(base::TimeDelta timestamp_to_paint) override;
139 157
140 private: 158 private:
141 std::unique_ptr<uint8_t[]> buffer_; 159 std::unique_ptr<uint8_t[]> buffer_;
142 }; 160 };
143 161
144 // Delivers frames using buffers provided by the client via 162 // Delivers frames using buffers provided by the client via
145 // OnIncomingCapturedBuffer(). 163 // OnIncomingCapturedBuffer().
146 class ClientBufferFrameDeliverer : public FrameDeliverer { 164 class ClientBufferFrameDeliverer : public FrameDeliverer {
147 public: 165 public:
148 ClientBufferFrameDeliverer(std::unique_ptr<PacmanFramePainter> frame_painter); 166 ClientBufferFrameDeliverer(std::unique_ptr<PacmanFramePainter> frame_painter);
149 ~ClientBufferFrameDeliverer() override; 167 ~ClientBufferFrameDeliverer() override;
150 168
151 // Implementation of FrameDeliverer 169 // Implementation of FrameDeliverer
152 void PaintAndDeliverNextFrame(base::TimeDelta timestamp_to_paint) override; 170 void PaintAndDeliverNextFrame(base::TimeDelta timestamp_to_paint) override;
153 }; 171 };
154 172
155 class JpegEncodingFrameDeliverer : public FrameDeliverer { 173 class JpegEncodingFrameDeliverer : public FrameDeliverer {
156 public: 174 public:
157 JpegEncodingFrameDeliverer(std::unique_ptr<PacmanFramePainter> frame_painter); 175 JpegEncodingFrameDeliverer(std::unique_ptr<PacmanFramePainter> frame_painter);
158 ~JpegEncodingFrameDeliverer() override; 176 ~JpegEncodingFrameDeliverer() override;
159 177
160 // Implementation of FrameDeliveryStrategy 178 // Implementation of FrameDeliveryStrategy
161 void Uninitialize() override;
162 void PaintAndDeliverNextFrame(base::TimeDelta timestamp_to_paint) override; 179 void PaintAndDeliverNextFrame(base::TimeDelta timestamp_to_paint) override;
163 180
164 private: 181 private:
165 std::vector<uint8_t> sk_n32_buffer_; 182 std::vector<uint8_t> sk_n32_buffer_;
166 std::vector<unsigned char> jpeg_buffer_; 183 std::vector<unsigned char> jpeg_buffer_;
167 }; 184 };
168 185
169 // Implements the photo functionality of a VideoCaptureDevice 186 FrameDelivererFactory::FrameDelivererFactory(
170 class FakePhotoDevice { 187 FakeVideoCaptureDevice::DeliveryMode delivery_mode,
171 public: 188 const FakeDeviceState* device_state)
172 FakePhotoDevice(std::unique_ptr<PacmanFramePainter> painter, 189 : delivery_mode_(delivery_mode), device_state_(device_state) {}
173 const FakeDeviceState* fake_device_state);
174 ~FakePhotoDevice();
175 190
176 void GetPhotoCapabilities( 191 std::unique_ptr<FrameDeliverer> FrameDelivererFactory::CreateFrameDeliverer(
177 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback); 192 const VideoCaptureFormat& format) {
178 void TakePhoto(VideoCaptureDevice::TakePhotoCallback callback,
179 base::TimeDelta elapsed_time);
180
181 private:
182 const std::unique_ptr<PacmanFramePainter> painter_;
183 const FakeDeviceState* const fake_device_state_;
184 };
185
186 // Implementation of VideoCaptureDevice that generates test frames. This is
187 // useful for testing the video capture components without having to use real
188 // devices. The implementation schedules delayed tasks to itself to generate and
189 // deliver frames at the requested rate.
190 class FakeVideoCaptureDevice : public VideoCaptureDevice {
191 public:
192 FakeVideoCaptureDevice(
193 std::unique_ptr<FrameDeliverer> frame_delivery_strategy,
194 std::unique_ptr<FakePhotoDevice> photo_device,
195 std::unique_ptr<FakeDeviceState> device_state);
196 ~FakeVideoCaptureDevice() override;
197
198 // VideoCaptureDevice implementation.
199 void AllocateAndStart(const VideoCaptureParams& params,
200 std::unique_ptr<Client> client) override;
201 void StopAndDeAllocate() override;
202 void GetPhotoCapabilities(GetPhotoCapabilitiesCallback callback) override;
203 void SetPhotoOptions(mojom::PhotoSettingsPtr settings,
204 SetPhotoOptionsCallback callback) override;
205 void TakePhoto(TakePhotoCallback callback) override;
206
207 private:
208 void BeepAndScheduleNextCapture(base::TimeTicks expected_execution_time);
209 void OnNextFrameDue(base::TimeTicks expected_execution_time, int session_id);
210
211 const std::unique_ptr<FrameDeliverer> frame_deliverer_;
212 const std::unique_ptr<FakePhotoDevice> photo_device_;
213 const std::unique_ptr<FakeDeviceState> device_state_;
214 int current_session_id_ = 0;
215
216 // Time when the next beep occurs.
217 base::TimeDelta beep_time_;
218 // Time since the fake video started rendering frames.
219 base::TimeDelta elapsed_time_;
220
221 base::ThreadChecker thread_checker_;
222
223 // FakeVideoCaptureDevice post tasks to itself for frame construction and
224 // needs to deal with asynchronous StopAndDeallocate().
225 base::WeakPtrFactory<FakeVideoCaptureDevice> weak_factory_;
226
227 DISALLOW_COPY_AND_ASSIGN(FakeVideoCaptureDevice);
228 };
229
230 } // anonymous namespace
231
232 // static
233 void FakeVideoCaptureDeviceMaker::GetSupportedSizes(
234 std::vector<gfx::Size>* supported_sizes) {
235 for (int i = 0; i < kSupportedSizesCount; i++)
236 supported_sizes->push_back(kSupportedSizesOrderedByIncreasingWidth[i]);
237 }
238
239 // static
240 std::unique_ptr<VideoCaptureDevice> FakeVideoCaptureDeviceMaker::MakeInstance(
241 PixelFormat pixel_format,
242 DeliveryMode delivery_mode,
243 float frame_rate) {
244 auto device_state = base::MakeUnique<FakeDeviceState>(
245 kInitialZoom, frame_rate,
246 static_cast<media::VideoPixelFormat>(pixel_format));
247 PacmanFramePainter::Format painter_format; 193 PacmanFramePainter::Format painter_format;
248 switch (pixel_format) { 194 switch (format.pixel_format) {
249 case PixelFormat::I420: 195 case PIXEL_FORMAT_I420:
250 painter_format = PacmanFramePainter::Format::I420; 196 painter_format = PacmanFramePainter::Format::I420;
251 break; 197 break;
252 case PixelFormat::Y16: 198 case PIXEL_FORMAT_Y16:
253 painter_format = PacmanFramePainter::Format::Y16; 199 painter_format = PacmanFramePainter::Format::Y16;
254 break; 200 break;
255 case PixelFormat::MJPEG: 201 case PIXEL_FORMAT_MJPEG:
256 painter_format = PacmanFramePainter::Format::SK_N32; 202 painter_format = PacmanFramePainter::Format::SK_N32;
257 break; 203 break;
204 default:
205 NOTREACHED();
206 painter_format = PacmanFramePainter::Format::I420;
258 } 207 }
259 auto video_frame_painter = 208 auto frame_painter =
260 base::MakeUnique<PacmanFramePainter>(painter_format, device_state.get()); 209 base::MakeUnique<PacmanFramePainter>(painter_format, device_state_);
261 210
262 std::unique_ptr<FrameDeliverer> frame_delivery_strategy; 211 FakeVideoCaptureDevice::DeliveryMode delivery_mode = delivery_mode_;
263 switch (delivery_mode) { 212 if (format.pixel_format == PIXEL_FORMAT_MJPEG &&
264 case DeliveryMode::USE_DEVICE_INTERNAL_BUFFERS: 213 delivery_mode_ ==
265 if (pixel_format == PixelFormat::MJPEG) { 214 FakeVideoCaptureDevice::DeliveryMode::USE_CLIENT_PROVIDED_BUFFERS) {
266 frame_delivery_strategy = base::MakeUnique<JpegEncodingFrameDeliverer>( 215 DLOG(WARNING) << "PIXEL_FORMAT_MJPEG cannot be used in combination with "
267 std::move(video_frame_painter)); 216 << "USE_CLIENT_PROVIDED_BUFFERS. Switching to "
268 } else { 217 "USE_DEVICE_INTERNAL_BUFFERS.";
emircan 2017/03/01 18:58:58 We should still return an error here to propagate
chfremer 2017/03/01 21:55:48 I tried out your suggestions but then ended up rev
emircan 2017/03/02 20:28:18 Sounds good.
269 frame_delivery_strategy = base::MakeUnique<OwnBufferFrameDeliverer>( 218 delivery_mode =
270 std::move(video_frame_painter)); 219 FakeVideoCaptureDevice::DeliveryMode::USE_DEVICE_INTERNAL_BUFFERS;
271 }
272 break;
273 case DeliveryMode::USE_CLIENT_PROVIDED_BUFFERS:
274 if (pixel_format == PixelFormat::MJPEG) {
275 DLOG(ERROR) << "PixelFormat::MJPEG cannot be used in combination with "
276 << "USE_CLIENT_PROVIDED_BUFFERS.";
277 return nullptr;
278 }
279 frame_delivery_strategy = base::MakeUnique<ClientBufferFrameDeliverer>(
280 std::move(video_frame_painter));
281 break;
282 } 220 }
283 221
284 auto photo_frame_painter = base::MakeUnique<PacmanFramePainter>( 222 switch (delivery_mode) {
285 PacmanFramePainter::Format::SK_N32, device_state.get()); 223 case FakeVideoCaptureDevice::DeliveryMode::USE_DEVICE_INTERNAL_BUFFERS:
286 auto photo_device = base::MakeUnique<FakePhotoDevice>( 224 if (format.pixel_format == PIXEL_FORMAT_MJPEG) {
287 std::move(photo_frame_painter), device_state.get()); 225 return base::MakeUnique<JpegEncodingFrameDeliverer>(
288 226 std::move(frame_painter));
289 return base::MakeUnique<FakeVideoCaptureDevice>( 227 } else {
290 std::move(frame_delivery_strategy), std::move(photo_device), 228 return base::MakeUnique<OwnBufferFrameDeliverer>(
291 std::move(device_state)); 229 std::move(frame_painter));
230 }
231 case FakeVideoCaptureDevice::DeliveryMode::USE_CLIENT_PROVIDED_BUFFERS:
232 return base::MakeUnique<ClientBufferFrameDeliverer>(
233 std::move(frame_painter));
234 }
235 NOTREACHED();
236 return nullptr;
292 } 237 }
293 238
294 PacmanFramePainter::PacmanFramePainter(Format pixel_format, 239 PacmanFramePainter::PacmanFramePainter(Format pixel_format,
295 const FakeDeviceState* fake_device_state) 240 const FakeDeviceState* fake_device_state)
296 : pixel_format_(pixel_format), fake_device_state_(fake_device_state) {} 241 : pixel_format_(pixel_format), fake_device_state_(fake_device_state) {}
297 242
298 void PacmanFramePainter::PaintFrame(base::TimeDelta elapsed_time, 243 void PacmanFramePainter::PaintFrame(base::TimeDelta elapsed_time,
299 uint8_t* target_buffer) { 244 uint8_t* target_buffer) {
300 DrawPacman(elapsed_time, target_buffer); 245 DrawPacman(elapsed_time, target_buffer);
301 DrawGradientSquares(elapsed_time, target_buffer); 246 DrawGradientSquares(elapsed_time, target_buffer);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 canvas.drawText(time_string.data(), time_string.length(), 30, 20, paint); 365 canvas.drawText(time_string.data(), time_string.length(), 30, 20, paint);
421 366
422 if (pixel_format_ == Format::Y16) { 367 if (pixel_format_ == Format::Y16) {
423 // Use 8 bit bitmap rendered to first half of the buffer as high byte values 368 // Use 8 bit bitmap rendered to first half of the buffer as high byte values
424 // for the whole buffer. Low byte values are not important. 369 // for the whole buffer. Low byte values are not important.
425 for (int i = (width * height) - 1; i >= 0; --i) 370 for (int i = (width * height) - 1; i >= 0; --i)
426 target_buffer[i * 2 + 1] = target_buffer[i]; 371 target_buffer[i * 2 + 1] = target_buffer[i];
427 } 372 }
428 } 373 }
429 374
430 FakePhotoDevice::FakePhotoDevice(std::unique_ptr<PacmanFramePainter> painter, 375 FakePhotoDevice::FakePhotoDevice(
431 const FakeDeviceState* fake_device_state) 376 std::unique_ptr<PacmanFramePainter> sk_n32_painter,
432 : painter_(std::move(painter)), fake_device_state_(fake_device_state) {} 377 const FakeDeviceState* fake_device_state)
378 : sk_n32_painter_(std::move(sk_n32_painter)),
379 fake_device_state_(fake_device_state) {}
433 380
434 FakePhotoDevice::~FakePhotoDevice() = default; 381 FakePhotoDevice::~FakePhotoDevice() = default;
435 382
436 void FakePhotoDevice::TakePhoto(VideoCaptureDevice::TakePhotoCallback callback, 383 void FakePhotoDevice::TakePhoto(VideoCaptureDevice::TakePhotoCallback callback,
437 base::TimeDelta elapsed_time) { 384 base::TimeDelta elapsed_time) {
438 // Create a PNG-encoded frame and send it back to |callback|. 385 // Create a PNG-encoded frame and send it back to |callback|.
439 auto required_sk_n32_buffer_size = VideoFrame::AllocationSize( 386 auto required_sk_n32_buffer_size = VideoFrame::AllocationSize(
440 PIXEL_FORMAT_ARGB, fake_device_state_->format.frame_size); 387 PIXEL_FORMAT_ARGB, fake_device_state_->format.frame_size);
441 std::unique_ptr<uint8_t[]> buffer(new uint8_t[required_sk_n32_buffer_size]); 388 std::unique_ptr<uint8_t[]> buffer(new uint8_t[required_sk_n32_buffer_size]);
442 memset(buffer.get(), 0, required_sk_n32_buffer_size); 389 memset(buffer.get(), 0, required_sk_n32_buffer_size);
443 painter_->PaintFrame(elapsed_time, buffer.get()); 390 sk_n32_painter_->PaintFrame(elapsed_time, buffer.get());
444 mojom::BlobPtr blob = mojom::Blob::New(); 391 mojom::BlobPtr blob = mojom::Blob::New();
445 const gfx::PNGCodec::ColorFormat encoding_source_format = 392 const gfx::PNGCodec::ColorFormat encoding_source_format =
446 (kN32_SkColorType == kRGBA_8888_SkColorType) ? gfx::PNGCodec::FORMAT_RGBA 393 (kN32_SkColorType == kRGBA_8888_SkColorType) ? gfx::PNGCodec::FORMAT_RGBA
447 : gfx::PNGCodec::FORMAT_BGRA; 394 : gfx::PNGCodec::FORMAT_BGRA;
448 const bool result = gfx::PNGCodec::Encode( 395 const bool result = gfx::PNGCodec::Encode(
449 buffer.get(), encoding_source_format, 396 buffer.get(), encoding_source_format,
450 fake_device_state_->format.frame_size, 397 fake_device_state_->format.frame_size,
451 VideoFrame::RowBytes(0 /* plane */, PIXEL_FORMAT_ARGB, 398 VideoFrame::RowBytes(0 /* plane */, PIXEL_FORMAT_ARGB,
452 fake_device_state_->format.frame_size.width()), 399 fake_device_state_->format.frame_size.width()),
453 true /* discard_transparency */, std::vector<gfx::PNGCodec::Comment>(), 400 true /* discard_transparency */, std::vector<gfx::PNGCodec::Comment>(),
454 &blob->data); 401 &blob->data);
455 DCHECK(result); 402 DCHECK(result);
456 403
457 blob->mime_type = "image/png"; 404 blob->mime_type = "image/png";
458 callback.Run(std::move(blob)); 405 callback.Run(std::move(blob));
459 } 406 }
460 407
461 FakeVideoCaptureDevice::FakeVideoCaptureDevice( 408 FakeVideoCaptureDevice::FakeVideoCaptureDevice(
462 std::unique_ptr<FrameDeliverer> frame_delivery_strategy, 409 const VideoCaptureFormats& supported_formats,
410 std::unique_ptr<FrameDelivererFactory> frame_deliverer_factory,
463 std::unique_ptr<FakePhotoDevice> photo_device, 411 std::unique_ptr<FakePhotoDevice> photo_device,
464 std::unique_ptr<FakeDeviceState> device_state) 412 std::unique_ptr<FakeDeviceState> device_state)
465 : frame_deliverer_(std::move(frame_delivery_strategy)), 413 : supported_formats_(supported_formats),
414 frame_deliverer_factory_(std::move(frame_deliverer_factory)),
466 photo_device_(std::move(photo_device)), 415 photo_device_(std::move(photo_device)),
467 device_state_(std::move(device_state)), 416 device_state_(std::move(device_state)),
468 weak_factory_(this) {} 417 weak_factory_(this) {}
469 418
470 FakeVideoCaptureDevice::~FakeVideoCaptureDevice() { 419 FakeVideoCaptureDevice::~FakeVideoCaptureDevice() {
471 DCHECK(thread_checker_.CalledOnValidThread()); 420 DCHECK(thread_checker_.CalledOnValidThread());
472 } 421 }
473 422
474 void FakeVideoCaptureDevice::AllocateAndStart( 423 void FakeVideoCaptureDevice::AllocateAndStart(
475 const VideoCaptureParams& params, 424 const VideoCaptureParams& params,
476 std::unique_ptr<VideoCaptureDevice::Client> client) { 425 std::unique_ptr<VideoCaptureDevice::Client> client) {
477 DCHECK(thread_checker_.CalledOnValidThread()); 426 DCHECK(thread_checker_.CalledOnValidThread());
478 427
428 const int closest_supported_format_index = FindIndexOfClosestSupportedFormat(
429 params.requested_format, supported_formats_);
430 const VideoCaptureFormat& selected_format =
431 supported_formats_[closest_supported_format_index];
emircan 2017/03/01 18:58:58 Why don't we make the function FindClosestSupporte
chfremer 2017/03/01 21:55:48 Done.
432
479 beep_time_ = base::TimeDelta(); 433 beep_time_ = base::TimeDelta();
480 elapsed_time_ = base::TimeDelta(); 434 elapsed_time_ = base::TimeDelta();
481 device_state_->format.frame_size = 435 frame_deliverer_ =
482 SnapToSupportedSize(params.requested_format.frame_size); 436 frame_deliverer_factory_->CreateFrameDeliverer(selected_format);
437 device_state_->format.frame_size = selected_format.frame_size;
483 frame_deliverer_->Initialize(device_state_->format.pixel_format, 438 frame_deliverer_->Initialize(device_state_->format.pixel_format,
484 std::move(client), device_state_.get()); 439 std::move(client), device_state_.get());
485 current_session_id_++; 440 current_session_id_++;
486 BeepAndScheduleNextCapture(base::TimeTicks::Now()); 441 BeepAndScheduleNextCapture(base::TimeTicks::Now());
487 } 442 }
488 443
489 void FakeVideoCaptureDevice::StopAndDeAllocate() { 444 void FakeVideoCaptureDevice::StopAndDeAllocate() {
490 DCHECK(thread_checker_.CalledOnValidThread()); 445 DCHECK(thread_checker_.CalledOnValidThread());
491 446
492 // Invalidate WeakPtr to stop the perpetual scheduling of tasks. 447 // Invalidate WeakPtr to stop the perpetual scheduling of tasks.
493 weak_factory_.InvalidateWeakPtrs(); 448 weak_factory_.InvalidateWeakPtrs();
494 frame_deliverer_->Uninitialize(); 449 frame_deliverer_.reset();
495 } 450 }
496 451
497 void FakeVideoCaptureDevice::GetPhotoCapabilities( 452 void FakeVideoCaptureDevice::GetPhotoCapabilities(
498 GetPhotoCapabilitiesCallback callback) { 453 GetPhotoCapabilitiesCallback callback) {
499 DCHECK(thread_checker_.CalledOnValidThread()); 454 DCHECK(thread_checker_.CalledOnValidThread());
500 photo_device_->GetPhotoCapabilities(std::move(callback)); 455 photo_device_->GetPhotoCapabilities(std::move(callback));
501 } 456 }
502 457
503 void FakePhotoDevice::GetPhotoCapabilities( 458 void FakePhotoDevice::GetPhotoCapabilities(
504 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) { 459 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 522
568 void OwnBufferFrameDeliverer::Initialize( 523 void OwnBufferFrameDeliverer::Initialize(
569 VideoPixelFormat pixel_format, 524 VideoPixelFormat pixel_format,
570 std::unique_ptr<VideoCaptureDevice::Client> client, 525 std::unique_ptr<VideoCaptureDevice::Client> client,
571 const FakeDeviceState* device_state) { 526 const FakeDeviceState* device_state) {
572 FrameDeliverer::Initialize(pixel_format, std::move(client), device_state); 527 FrameDeliverer::Initialize(pixel_format, std::move(client), device_state);
573 buffer_.reset(new uint8_t[VideoFrame::AllocationSize( 528 buffer_.reset(new uint8_t[VideoFrame::AllocationSize(
574 pixel_format, device_state->format.frame_size)]); 529 pixel_format, device_state->format.frame_size)]);
575 } 530 }
576 531
577 void OwnBufferFrameDeliverer::Uninitialize() {
578 FrameDeliverer::Uninitialize();
579 buffer_.reset();
580 }
581
582 void OwnBufferFrameDeliverer::PaintAndDeliverNextFrame( 532 void OwnBufferFrameDeliverer::PaintAndDeliverNextFrame(
583 base::TimeDelta timestamp_to_paint) { 533 base::TimeDelta timestamp_to_paint) {
584 if (!client()) 534 if (!client())
585 return; 535 return;
586 const size_t frame_size = device_state()->format.ImageAllocationSize(); 536 const size_t frame_size = device_state()->format.ImageAllocationSize();
587 memset(buffer_.get(), 0, frame_size); 537 memset(buffer_.get(), 0, frame_size);
588 frame_painter()->PaintFrame(timestamp_to_paint, buffer_.get()); 538 frame_painter()->PaintFrame(timestamp_to_paint, buffer_.get());
589 base::TimeTicks now = base::TimeTicks::Now(); 539 base::TimeTicks now = base::TimeTicks::Now();
590 client()->OnIncomingCapturedData(buffer_.get(), frame_size, 540 client()->OnIncomingCapturedData(buffer_.get(), frame_size,
591 device_state()->format, 0 /* rotation */, 541 device_state()->format, 0 /* rotation */,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 device_state()->format, now, 574 device_state()->format, now,
625 CalculateTimeSinceFirstInvocation(now)); 575 CalculateTimeSinceFirstInvocation(now));
626 } 576 }
627 577
628 JpegEncodingFrameDeliverer::JpegEncodingFrameDeliverer( 578 JpegEncodingFrameDeliverer::JpegEncodingFrameDeliverer(
629 std::unique_ptr<PacmanFramePainter> frame_painter) 579 std::unique_ptr<PacmanFramePainter> frame_painter)
630 : FrameDeliverer(std::move(frame_painter)) {} 580 : FrameDeliverer(std::move(frame_painter)) {}
631 581
632 JpegEncodingFrameDeliverer::~JpegEncodingFrameDeliverer() = default; 582 JpegEncodingFrameDeliverer::~JpegEncodingFrameDeliverer() = default;
633 583
634 void JpegEncodingFrameDeliverer::Uninitialize() {
635 FrameDeliverer::Uninitialize();
636 sk_n32_buffer_.clear();
637 jpeg_buffer_.clear();
638 }
639
640 void JpegEncodingFrameDeliverer::PaintAndDeliverNextFrame( 584 void JpegEncodingFrameDeliverer::PaintAndDeliverNextFrame(
641 base::TimeDelta timestamp_to_paint) { 585 base::TimeDelta timestamp_to_paint) {
642 if (!client()) 586 if (!client())
643 return; 587 return;
644 588
645 auto required_sk_n32_buffer_size = VideoFrame::AllocationSize( 589 auto required_sk_n32_buffer_size = VideoFrame::AllocationSize(
646 PIXEL_FORMAT_ARGB, device_state()->format.frame_size); 590 PIXEL_FORMAT_ARGB, device_state()->format.frame_size);
647 sk_n32_buffer_.resize(required_sk_n32_buffer_size); 591 sk_n32_buffer_.resize(required_sk_n32_buffer_size);
648 memset(&sk_n32_buffer_[0], 0, required_sk_n32_buffer_size); 592 memset(&sk_n32_buffer_[0], 0, required_sk_n32_buffer_size);
649 593
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 int session_id) { 653 int session_id) {
710 DCHECK(thread_checker_.CalledOnValidThread()); 654 DCHECK(thread_checker_.CalledOnValidThread());
711 if (session_id != current_session_id_) 655 if (session_id != current_session_id_)
712 return; 656 return;
713 657
714 frame_deliverer_->PaintAndDeliverNextFrame(elapsed_time_); 658 frame_deliverer_->PaintAndDeliverNextFrame(elapsed_time_);
715 BeepAndScheduleNextCapture(expected_execution_time); 659 BeepAndScheduleNextCapture(expected_execution_time);
716 } 660 }
717 661
718 } // namespace media 662 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698