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 <algorithm> |
7 | 8 |
8 #include "base/bind.h" | 9 #include "base/bind.h" |
9 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
10 #include "media/audio/fake_audio_input_stream.h" | 11 #include "media/audio/fake_audio_input_stream.h" |
11 #include "media/base/video_frame.h" | 12 #include "media/base/video_frame.h" |
12 #include "third_party/skia/include/core/SkBitmap.h" | 13 #include "third_party/skia/include/core/SkBitmap.h" |
13 #include "third_party/skia/include/core/SkCanvas.h" | 14 #include "third_party/skia/include/core/SkCanvas.h" |
14 #include "third_party/skia/include/core/SkPaint.h" | 15 #include "third_party/skia/include/core/SkPaint.h" |
15 | 16 |
16 namespace media { | 17 namespace media { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 else if (params.requested_format.frame_size.width() > 320) | 98 else if (params.requested_format.frame_size.width() > 320) |
98 capture_format_.frame_size.SetSize(640, 480); | 99 capture_format_.frame_size.SetSize(640, 480); |
99 else | 100 else |
100 capture_format_.frame_size.SetSize(320, 240); | 101 capture_format_.frame_size.SetSize(320, 240); |
101 | 102 |
102 if (device_type_ == USING_OWN_BUFFERS || | 103 if (device_type_ == USING_OWN_BUFFERS || |
103 device_type_ == USING_OWN_BUFFERS_TRIPLANAR) { | 104 device_type_ == USING_OWN_BUFFERS_TRIPLANAR) { |
104 fake_frame_.reset(new uint8[VideoFrame::AllocationSize( | 105 fake_frame_.reset(new uint8[VideoFrame::AllocationSize( |
105 VideoFrame::I420, capture_format_.frame_size)]); | 106 VideoFrame::I420, capture_format_.frame_size)]); |
106 BeepAndScheduleNextCapture( | 107 BeepAndScheduleNextCapture( |
| 108 base::TimeTicks::Now(), |
107 base::Bind(&FakeVideoCaptureDevice::CaptureUsingOwnBuffers, | 109 base::Bind(&FakeVideoCaptureDevice::CaptureUsingOwnBuffers, |
108 weak_factory_.GetWeakPtr())); | 110 weak_factory_.GetWeakPtr())); |
109 } else if (device_type_ == USING_CLIENT_BUFFERS_I420 || | 111 } else if (device_type_ == USING_CLIENT_BUFFERS_I420 || |
110 device_type_ == USING_CLIENT_BUFFERS_GPU) { | 112 device_type_ == USING_CLIENT_BUFFERS_GPU) { |
111 DVLOG(1) << "starting with " << (device_type_ == USING_CLIENT_BUFFERS_I420 | 113 DVLOG(1) << "starting with " << (device_type_ == USING_CLIENT_BUFFERS_I420 |
112 ? "Client buffers" | 114 ? "Client buffers" |
113 : "GpuMemoryBuffers"); | 115 : "GpuMemoryBuffers"); |
114 BeepAndScheduleNextCapture(base::Bind( | 116 BeepAndScheduleNextCapture( |
115 &FakeVideoCaptureDevice::CaptureUsingClientBuffers, | 117 base::TimeTicks::Now(), |
116 weak_factory_.GetWeakPtr(), (device_type_ == USING_CLIENT_BUFFERS_I420 | 118 base::Bind(&FakeVideoCaptureDevice::CaptureUsingClientBuffers, |
117 ? PIXEL_FORMAT_I420 | 119 weak_factory_.GetWeakPtr(), |
118 : PIXEL_FORMAT_GPUMEMORYBUFFER))); | 120 (device_type_ == USING_CLIENT_BUFFERS_I420 |
| 121 ? PIXEL_FORMAT_I420 |
| 122 : PIXEL_FORMAT_GPUMEMORYBUFFER))); |
119 } else { | 123 } else { |
120 client_->OnError("Unknown Fake Video Capture Device type."); | 124 client_->OnError("Unknown Fake Video Capture Device type."); |
121 } | 125 } |
122 } | 126 } |
123 | 127 |
124 void FakeVideoCaptureDevice::StopAndDeAllocate() { | 128 void FakeVideoCaptureDevice::StopAndDeAllocate() { |
125 DCHECK(thread_checker_.CalledOnValidThread()); | 129 DCHECK(thread_checker_.CalledOnValidThread()); |
126 client_.reset(); | 130 client_.reset(); |
127 } | 131 } |
128 | 132 |
129 void FakeVideoCaptureDevice::CaptureUsingOwnBuffers() { | 133 void FakeVideoCaptureDevice::CaptureUsingOwnBuffers( |
| 134 base::TimeTicks expected_execution_time) { |
130 DCHECK(thread_checker_.CalledOnValidThread()); | 135 DCHECK(thread_checker_.CalledOnValidThread()); |
131 const size_t frame_size = capture_format_.ImageAllocationSize(); | 136 const size_t frame_size = capture_format_.ImageAllocationSize(); |
132 memset(fake_frame_.get(), 0, frame_size); | 137 memset(fake_frame_.get(), 0, frame_size); |
133 | 138 |
134 DrawPacman(false /* use_argb */, | 139 DrawPacman(false /* use_argb */, |
135 fake_frame_.get(), | 140 fake_frame_.get(), |
136 frame_count_, | 141 frame_count_, |
137 kFakeCapturePeriodMs, | 142 kFakeCapturePeriodMs, |
138 capture_format_.frame_size); | 143 capture_format_.frame_size); |
139 | 144 |
(...skipping 10 matching lines...) Expand all Loading... |
150 fake_frame_.get() + capture_format_.frame_size.GetArea(), | 155 fake_frame_.get() + capture_format_.frame_size.GetArea(), |
151 fake_frame_.get() + capture_format_.frame_size.GetArea() * 5 / 4, | 156 fake_frame_.get() + capture_format_.frame_size.GetArea() * 5 / 4, |
152 capture_format_.frame_size.width(), | 157 capture_format_.frame_size.width(), |
153 capture_format_.frame_size.width() / 2, | 158 capture_format_.frame_size.width() / 2, |
154 capture_format_.frame_size.width() / 2, | 159 capture_format_.frame_size.width() / 2, |
155 capture_format_, | 160 capture_format_, |
156 0 /* rotation */, | 161 0 /* rotation */, |
157 base::TimeTicks::Now()); | 162 base::TimeTicks::Now()); |
158 } | 163 } |
159 BeepAndScheduleNextCapture( | 164 BeepAndScheduleNextCapture( |
| 165 expected_execution_time, |
160 base::Bind(&FakeVideoCaptureDevice::CaptureUsingOwnBuffers, | 166 base::Bind(&FakeVideoCaptureDevice::CaptureUsingOwnBuffers, |
161 weak_factory_.GetWeakPtr())); | 167 weak_factory_.GetWeakPtr())); |
162 } | 168 } |
163 | 169 |
164 void FakeVideoCaptureDevice::CaptureUsingClientBuffers( | 170 void FakeVideoCaptureDevice::CaptureUsingClientBuffers( |
165 VideoPixelFormat pixel_format) { | 171 VideoPixelFormat pixel_format, |
| 172 base::TimeTicks expected_execution_time) { |
166 DCHECK(thread_checker_.CalledOnValidThread()); | 173 DCHECK(thread_checker_.CalledOnValidThread()); |
167 | 174 |
168 scoped_ptr<VideoCaptureDevice::Client::Buffer> capture_buffer( | 175 scoped_ptr<VideoCaptureDevice::Client::Buffer> capture_buffer( |
169 client_->ReserveOutputBuffer(pixel_format, capture_format_.frame_size)); | 176 client_->ReserveOutputBuffer(pixel_format, capture_format_.frame_size)); |
170 DLOG_IF(ERROR, !capture_buffer) << "Couldn't allocate Capture Buffer"; | 177 DLOG_IF(ERROR, !capture_buffer) << "Couldn't allocate Capture Buffer"; |
171 | 178 |
172 if (capture_buffer.get()) { | 179 if (capture_buffer.get()) { |
173 uint8_t* const data_ptr = static_cast<uint8_t*>(capture_buffer->data()); | 180 uint8_t* const data_ptr = static_cast<uint8_t*>(capture_buffer->data()); |
174 DCHECK(data_ptr) << "Buffer has NO backing memory"; | 181 DCHECK(data_ptr) << "Buffer has NO backing memory"; |
175 DCHECK_EQ(capture_buffer->GetType(), gfx::SHARED_MEMORY_BUFFER); | 182 DCHECK_EQ(capture_buffer->GetType(), gfx::SHARED_MEMORY_BUFFER); |
176 memset(data_ptr, 0, capture_buffer->size()); | 183 memset(data_ptr, 0, capture_buffer->size()); |
177 | 184 |
178 DrawPacman( | 185 DrawPacman( |
179 (pixel_format == media::PIXEL_FORMAT_GPUMEMORYBUFFER), /* use_argb */ | 186 (pixel_format == media::PIXEL_FORMAT_GPUMEMORYBUFFER), /* use_argb */ |
180 data_ptr, | 187 data_ptr, |
181 frame_count_, | 188 frame_count_, |
182 kFakeCapturePeriodMs, | 189 kFakeCapturePeriodMs, |
183 capture_format_.frame_size); | 190 capture_format_.frame_size); |
184 | 191 |
185 // Give the captured frame to the client. | 192 // Give the captured frame to the client. |
186 const VideoCaptureFormat format(capture_format_.frame_size, | 193 const VideoCaptureFormat format(capture_format_.frame_size, |
187 capture_format_.frame_rate, | 194 capture_format_.frame_rate, |
188 pixel_format); | 195 pixel_format); |
189 client_->OnIncomingCapturedBuffer(capture_buffer.Pass(), format, | 196 client_->OnIncomingCapturedBuffer(capture_buffer.Pass(), format, |
190 base::TimeTicks::Now()); | 197 base::TimeTicks::Now()); |
191 } | 198 } |
192 | 199 |
193 BeepAndScheduleNextCapture( | 200 BeepAndScheduleNextCapture( |
| 201 expected_execution_time, |
194 base::Bind(&FakeVideoCaptureDevice::CaptureUsingClientBuffers, | 202 base::Bind(&FakeVideoCaptureDevice::CaptureUsingClientBuffers, |
195 weak_factory_.GetWeakPtr(), pixel_format)); | 203 weak_factory_.GetWeakPtr(), pixel_format)); |
196 } | 204 } |
197 | 205 |
198 void FakeVideoCaptureDevice::BeepAndScheduleNextCapture( | 206 void FakeVideoCaptureDevice::BeepAndScheduleNextCapture( |
199 const base::Closure& next_capture) { | 207 base::TimeTicks expected_execution_time, |
| 208 const base::Callback<void(base::TimeTicks)>& next_capture) { |
200 // Generate a synchronized beep sound every so many frames. | 209 // Generate a synchronized beep sound every so many frames. |
201 if (frame_count_++ % kFakeCaptureBeepCycle == 0) | 210 if (frame_count_++ % kFakeCaptureBeepCycle == 0) |
202 FakeAudioInputStream::BeepOnce(); | 211 FakeAudioInputStream::BeepOnce(); |
203 | 212 |
204 // Reschedule next CaptureTask. | 213 // Reschedule next CaptureTask. |
205 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, next_capture, | 214 const base::TimeTicks current_time = base::TimeTicks::Now(); |
206 base::TimeDelta::FromMilliseconds(kFakeCapturePeriodMs)); | 215 const base::TimeDelta frame_interval = |
| 216 base::TimeDelta::FromMilliseconds(kFakeCapturePeriodMs); |
| 217 // Don't accumulate any debt if we are lagging behind - just post the next |
| 218 // frame immediately and continue as normal. |
| 219 const base::TimeTicks next_execution_time = |
| 220 std::max(current_time, expected_execution_time + frame_interval); |
| 221 const base::TimeDelta delay = next_execution_time - current_time; |
| 222 base::MessageLoop::current()->PostDelayedTask( |
| 223 FROM_HERE, base::Bind(next_capture, next_execution_time), delay); |
207 } | 224 } |
208 | 225 |
209 } // namespace media | 226 } // namespace media |
OLD | NEW |