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

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

Issue 1153713006: FakeVideoCaptureDevice: Regulate framerate without drifting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: mcasas@ comments #2 Created 5 years, 6 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
« no previous file with comments | « media/video/capture/fake_video_capture_device.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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
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
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
OLDNEW
« no previous file with comments | « media/video/capture/fake_video_capture_device.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698