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

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

Powered by Google App Engine
This is Rietveld 408576698