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/video/capture/fake_video_capture_device.h" | 5 #include "media/video/capture/fake_video_capture_device.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 for (int n = 0; n < kNumberOfFakeDevices; n++) { | 30 for (int n = 0; n < kNumberOfFakeDevices; n++) { |
31 Name name(base::StringPrintf("fake_device_%d", n), | 31 Name name(base::StringPrintf("fake_device_%d", n), |
32 base::StringPrintf("/dev/video%d", n)); | 32 base::StringPrintf("/dev/video%d", n)); |
33 device_names->push_back(name); | 33 device_names->push_back(name); |
34 } | 34 } |
35 } | 35 } |
36 | 36 |
37 void FakeVideoCaptureDevice::GetDeviceSupportedFormats( | 37 void FakeVideoCaptureDevice::GetDeviceSupportedFormats( |
38 const Name& device, | 38 const Name& device, |
39 VideoCaptureCapabilities* formats) { | 39 VideoCaptureCapabilities* formats) { |
40 VideoCaptureCapability capture_format_640x480; | 40 VideoCaptureCapability capture_format; |
41 capture_format_640x480.supported_format.frame_size.SetSize(640, 480); | 41 capture_format.color = media::PIXEL_FORMAT_I420; |
42 capture_format_640x480.supported_format.frame_rate = | 42 capture_format.width = 640; |
43 1000 / kFakeCaptureTimeoutMs; | 43 capture_format.height = 480; |
44 capture_format_640x480.supported_format.pixel_format = | 44 capture_format.frame_rate = 1000 / kFakeCaptureTimeoutMs; |
45 media::PIXEL_FORMAT_I420; | 45 formats->push_back(capture_format); |
46 formats->push_back(capture_format_640x480); | |
47 } | 46 } |
48 | 47 |
49 VideoCaptureDevice* FakeVideoCaptureDevice::Create(const Name& device_name) { | 48 VideoCaptureDevice* FakeVideoCaptureDevice::Create(const Name& device_name) { |
50 if (fail_next_create_) { | 49 if (fail_next_create_) { |
51 fail_next_create_ = false; | 50 fail_next_create_ = false; |
52 return NULL; | 51 return NULL; |
53 } | 52 } |
54 for (int n = 0; n < kNumberOfFakeDevices; ++n) { | 53 for (int n = 0; n < kNumberOfFakeDevices; ++n) { |
55 std::string possible_id = base::StringPrintf("/dev/video%d", n); | 54 std::string possible_id = base::StringPrintf("/dev/video%d", n); |
56 if (device_name.id().compare(possible_id) == 0) { | 55 if (device_name.id().compare(possible_id) == 0) { |
57 return new FakeVideoCaptureDevice(); | 56 return new FakeVideoCaptureDevice(); |
58 } | 57 } |
59 } | 58 } |
60 return NULL; | 59 return NULL; |
61 } | 60 } |
62 | 61 |
63 void FakeVideoCaptureDevice::SetFailNextCreate() { | 62 void FakeVideoCaptureDevice::SetFailNextCreate() { |
64 fail_next_create_ = true; | 63 fail_next_create_ = true; |
65 } | 64 } |
66 | 65 |
67 FakeVideoCaptureDevice::FakeVideoCaptureDevice() | 66 FakeVideoCaptureDevice::FakeVideoCaptureDevice() |
68 : state_(kIdle), | 67 : state_(kIdle), |
69 capture_thread_("CaptureThread"), | 68 capture_thread_("CaptureThread"), |
70 frame_count_(0), | 69 frame_count_(0), |
71 format_roster_index_(0) {} | 70 capabilities_roster_index_(0) { |
| 71 } |
72 | 72 |
73 FakeVideoCaptureDevice::~FakeVideoCaptureDevice() { | 73 FakeVideoCaptureDevice::~FakeVideoCaptureDevice() { |
74 // Check if the thread is running. | 74 // Check if the thread is running. |
75 // This means that the device have not been DeAllocated properly. | 75 // This means that the device have not been DeAllocated properly. |
76 DCHECK(!capture_thread_.IsRunning()); | 76 DCHECK(!capture_thread_.IsRunning()); |
77 } | 77 } |
78 | 78 |
79 void FakeVideoCaptureDevice::AllocateAndStart( | 79 void FakeVideoCaptureDevice::AllocateAndStart( |
80 const VideoCaptureParams& params, | 80 const VideoCaptureCapability& capture_format, |
81 scoped_ptr<VideoCaptureDevice::Client> client) { | 81 scoped_ptr<VideoCaptureDevice::Client> client) { |
82 if (params.allow_resolution_change) | 82 capture_format_.frame_size_type = capture_format.frame_size_type; |
83 PopulateFormatRoster(); | 83 if (capture_format.frame_size_type == VariableResolutionVideoCaptureDevice) |
| 84 PopulateCapabilitiesRoster(); |
84 | 85 |
85 if (state_ != kIdle) { | 86 if (state_ != kIdle) { |
86 return; // Wrong state. | 87 return; // Wrong state. |
87 } | 88 } |
88 | 89 |
89 client_ = client.Pass(); | 90 client_ = client.Pass(); |
90 capture_format_.pixel_format = PIXEL_FORMAT_I420; | 91 capture_format_.color = PIXEL_FORMAT_I420; |
91 if (params.requested_format.frame_size.width() > 320) { // VGA | 92 if (capture_format.width > 320) { // VGA |
92 capture_format_.frame_size.SetSize(640, 480); | 93 capture_format_.width = 640; |
| 94 capture_format_.height = 480; |
93 capture_format_.frame_rate = 30; | 95 capture_format_.frame_rate = 30; |
94 } else { // QVGA | 96 } else { // QVGA |
95 capture_format_.frame_size.SetSize(320, 240); | 97 capture_format_.width = 320; |
| 98 capture_format_.height = 240; |
96 capture_format_.frame_rate = 30; | 99 capture_format_.frame_rate = 30; |
97 } | 100 } |
98 | 101 |
99 const size_t fake_frame_size = | 102 const size_t fake_frame_size = VideoFrame::AllocationSize( |
100 VideoFrame::AllocationSize(VideoFrame::I420, capture_format_.frame_size); | 103 VideoFrame::I420, |
| 104 gfx::Size(capture_format_.width, capture_format_.height)); |
101 fake_frame_.reset(new uint8[fake_frame_size]); | 105 fake_frame_.reset(new uint8[fake_frame_size]); |
102 | 106 |
103 state_ = kCapturing; | 107 state_ = kCapturing; |
104 capture_thread_.Start(); | 108 capture_thread_.Start(); |
105 capture_thread_.message_loop()->PostTask( | 109 capture_thread_.message_loop()->PostTask( |
106 FROM_HERE, | 110 FROM_HERE, |
107 base::Bind(&FakeVideoCaptureDevice::OnCaptureTask, | 111 base::Bind(&FakeVideoCaptureDevice::OnCaptureTask, |
108 base::Unretained(this))); | 112 base::Unretained(this))); |
109 } | 113 } |
110 | 114 |
111 void FakeVideoCaptureDevice::Reallocate() { | 115 void FakeVideoCaptureDevice::Reallocate() { |
112 DCHECK_EQ(state_, kCapturing); | 116 DCHECK_EQ(state_, kCapturing); |
113 capture_format_ = | 117 capture_format_ = capabilities_roster_.at(++capabilities_roster_index_ % |
114 format_roster_.at(++format_roster_index_ % format_roster_.size()); | 118 capabilities_roster_.size()); |
115 DCHECK_EQ(capture_format_.pixel_format, PIXEL_FORMAT_I420); | 119 DCHECK_EQ(capture_format_.color, PIXEL_FORMAT_I420); |
116 DVLOG(3) << "Reallocating FakeVideoCaptureDevice, new capture resolution " | 120 DVLOG(3) << "Reallocating FakeVideoCaptureDevice, new capture resolution (" |
117 << capture_format_.frame_size.ToString(); | 121 << capture_format_.width << "x" << capture_format_.height << ")"; |
118 | 122 |
119 const size_t fake_frame_size = | 123 const size_t fake_frame_size = VideoFrame::AllocationSize( |
120 VideoFrame::AllocationSize(VideoFrame::I420, capture_format_.frame_size); | 124 VideoFrame::I420, |
| 125 gfx::Size(capture_format_.width, capture_format_.height)); |
121 fake_frame_.reset(new uint8[fake_frame_size]); | 126 fake_frame_.reset(new uint8[fake_frame_size]); |
122 } | 127 } |
123 | 128 |
124 void FakeVideoCaptureDevice::StopAndDeAllocate() { | 129 void FakeVideoCaptureDevice::StopAndDeAllocate() { |
125 if (state_ != kCapturing) { | 130 if (state_ != kCapturing) { |
126 return; // Wrong state. | 131 return; // Wrong state. |
127 } | 132 } |
128 capture_thread_.Stop(); | 133 capture_thread_.Stop(); |
129 state_ = kIdle; | 134 state_ = kIdle; |
130 } | 135 } |
131 | 136 |
132 void FakeVideoCaptureDevice::OnCaptureTask() { | 137 void FakeVideoCaptureDevice::OnCaptureTask() { |
133 if (state_ != kCapturing) { | 138 if (state_ != kCapturing) { |
134 return; | 139 return; |
135 } | 140 } |
136 | 141 |
137 const size_t frame_size = | 142 const size_t frame_size = VideoFrame::AllocationSize( |
138 VideoFrame::AllocationSize(VideoFrame::I420, capture_format_.frame_size); | 143 VideoFrame::I420, |
| 144 gfx::Size(capture_format_.width, capture_format_.height)); |
139 memset(fake_frame_.get(), 0, frame_size); | 145 memset(fake_frame_.get(), 0, frame_size); |
140 | 146 |
141 SkBitmap bitmap; | 147 SkBitmap bitmap; |
142 bitmap.setConfig(SkBitmap::kA8_Config, | 148 bitmap.setConfig(SkBitmap::kA8_Config, |
143 capture_format_.frame_size.width(), | 149 capture_format_.width, |
144 capture_format_.frame_size.height(), | 150 capture_format_.height, |
145 capture_format_.frame_size.width()), | 151 capture_format_.width); |
146 bitmap.setPixels(fake_frame_.get()); | 152 bitmap.setPixels(fake_frame_.get()); |
147 | 153 |
148 SkCanvas canvas(bitmap); | 154 SkCanvas canvas(bitmap); |
149 | 155 |
150 // Draw a sweeping circle to show an animation. | 156 // Draw a sweeping circle to show an animation. |
151 int radius = std::min(capture_format_.frame_size.width(), | 157 int radius = std::min(capture_format_.width, capture_format_.height) / 4; |
152 capture_format_.frame_size.height()) / | 158 SkRect rect = SkRect::MakeXYWH( |
153 4; | 159 capture_format_.width / 2 - radius, capture_format_.height / 2 - radius, |
154 SkRect rect = | 160 2 * radius, 2 * radius); |
155 SkRect::MakeXYWH(capture_format_.frame_size.width() / 2 - radius, | |
156 capture_format_.frame_size.height() / 2 - radius, | |
157 2 * radius, | |
158 2 * radius); | |
159 | 161 |
160 SkPaint paint; | 162 SkPaint paint; |
161 paint.setStyle(SkPaint::kFill_Style); | 163 paint.setStyle(SkPaint::kFill_Style); |
162 | 164 |
163 // Only Y plane is being drawn and this gives 50% grey on the Y | 165 // Only Y plane is being drawn and this gives 50% grey on the Y |
164 // plane. The result is a light green color in RGB space. | 166 // plane. The result is a light green color in RGB space. |
165 paint.setAlpha(128); | 167 paint.setAlpha(128); |
166 | 168 |
167 int end_angle = (frame_count_ % kFakeCaptureBeepCycle * 360) / | 169 int end_angle = (frame_count_ % kFakeCaptureBeepCycle * 360) / |
168 kFakeCaptureBeepCycle; | 170 kFakeCaptureBeepCycle; |
(...skipping 25 matching lines...) Expand all Loading... |
194 | 196 |
195 // Give the captured frame to the client. | 197 // Give the captured frame to the client. |
196 client_->OnIncomingCapturedFrame(fake_frame_.get(), | 198 client_->OnIncomingCapturedFrame(fake_frame_.get(), |
197 frame_size, | 199 frame_size, |
198 base::Time::Now(), | 200 base::Time::Now(), |
199 0, | 201 0, |
200 false, | 202 false, |
201 false, | 203 false, |
202 capture_format_); | 204 capture_format_); |
203 if (!(frame_count_ % kFakeCaptureCapabilityChangePeriod) && | 205 if (!(frame_count_ % kFakeCaptureCapabilityChangePeriod) && |
204 format_roster_.size() > 0U) { | 206 (capture_format_.frame_size_type == |
| 207 VariableResolutionVideoCaptureDevice)) { |
205 Reallocate(); | 208 Reallocate(); |
206 } | 209 } |
207 // Reschedule next CaptureTask. | 210 // Reschedule next CaptureTask. |
208 capture_thread_.message_loop()->PostDelayedTask( | 211 capture_thread_.message_loop()->PostDelayedTask( |
209 FROM_HERE, | 212 FROM_HERE, |
210 base::Bind(&FakeVideoCaptureDevice::OnCaptureTask, | 213 base::Bind(&FakeVideoCaptureDevice::OnCaptureTask, |
211 base::Unretained(this)), | 214 base::Unretained(this)), |
212 base::TimeDelta::FromMilliseconds(kFakeCaptureTimeoutMs)); | 215 base::TimeDelta::FromMilliseconds(kFakeCaptureTimeoutMs)); |
213 } | 216 } |
214 | 217 |
215 void FakeVideoCaptureDevice::PopulateFormatRoster() { | 218 void FakeVideoCaptureDevice::PopulateCapabilitiesRoster() { |
216 format_roster_.push_back( | 219 capabilities_roster_.push_back( |
217 media::VideoCaptureFormat(gfx::Size(320, 240), 30, PIXEL_FORMAT_I420)); | 220 media::VideoCaptureCapability(320, |
218 format_roster_.push_back( | 221 240, |
219 media::VideoCaptureFormat(gfx::Size(640, 480), 30, PIXEL_FORMAT_I420)); | 222 30, |
220 format_roster_.push_back( | 223 PIXEL_FORMAT_I420, |
221 media::VideoCaptureFormat(gfx::Size(800, 600), 30, PIXEL_FORMAT_I420)); | 224 VariableResolutionVideoCaptureDevice)); |
| 225 capabilities_roster_.push_back( |
| 226 media::VideoCaptureCapability(640, |
| 227 480, |
| 228 30, |
| 229 PIXEL_FORMAT_I420, |
| 230 VariableResolutionVideoCaptureDevice)); |
| 231 capabilities_roster_.push_back( |
| 232 media::VideoCaptureCapability(800, |
| 233 600, |
| 234 30, |
| 235 PIXEL_FORMAT_I420, |
| 236 VariableResolutionVideoCaptureDevice)); |
222 | 237 |
223 format_roster_index_ = 0; | 238 capabilities_roster_index_ = 0; |
224 } | 239 } |
225 | 240 |
226 } // namespace media | 241 } // namespace media |
OLD | NEW |