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