summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authormagjed <magjed@chromium.org>2015-06-10 05:12:21 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-10 12:13:00 +0000
commit592dfd1e550e16fbfcd9840e5dd6a244fbb022cc (patch)
treeac79b1dc807962c2e400acc69977aac0e27bb0cd /media
parentfb7186b3d00c9c733f99fa3467096cf4e86459e2 (diff)
downloadchromium_src-592dfd1e550e16fbfcd9840e5dd6a244fbb022cc.zip
chromium_src-592dfd1e550e16fbfcd9840e5dd6a244fbb022cc.tar.gz
chromium_src-592dfd1e550e16fbfcd9840e5dd6a244fbb022cc.tar.bz2
FakeVideoCaptureDevice: Regulate framerate without drifting
We currently rely on PostDelayedTask with a constant frame interval to get a specified frame rate. This CL dynamically adapts the delay to PostDelayedTask to keep the frame rate in sync. This CL is similar to https://codereview.chromium.org/1162903004/. BUG=492189 Review URL: https://codereview.chromium.org/1153713006 Cr-Commit-Position: refs/heads/master@{#333723}
Diffstat (limited to 'media')
-rw-r--r--media/video/capture/fake_video_capture_device.cc37
-rw-r--r--media/video/capture/fake_video_capture_device.h10
2 files changed, 34 insertions, 13 deletions
diff --git a/media/video/capture/fake_video_capture_device.cc b/media/video/capture/fake_video_capture_device.cc
index 12a8a30..613d8a5 100644
--- a/media/video/capture/fake_video_capture_device.cc
+++ b/media/video/capture/fake_video_capture_device.cc
@@ -4,6 +4,7 @@
#include "media/video/capture/fake_video_capture_device.h"
+#include <algorithm>
#include "base/bind.h"
#include "base/strings/stringprintf.h"
@@ -104,6 +105,7 @@ void FakeVideoCaptureDevice::AllocateAndStart(
fake_frame_.reset(new uint8[VideoFrame::AllocationSize(
VideoFrame::I420, capture_format_.frame_size)]);
BeepAndScheduleNextCapture(
+ base::TimeTicks::Now(),
base::Bind(&FakeVideoCaptureDevice::CaptureUsingOwnBuffers,
weak_factory_.GetWeakPtr()));
} else if (device_type_ == USING_CLIENT_BUFFERS_I420 ||
@@ -111,11 +113,13 @@ void FakeVideoCaptureDevice::AllocateAndStart(
DVLOG(1) << "starting with " << (device_type_ == USING_CLIENT_BUFFERS_I420
? "Client buffers"
: "GpuMemoryBuffers");
- BeepAndScheduleNextCapture(base::Bind(
- &FakeVideoCaptureDevice::CaptureUsingClientBuffers,
- weak_factory_.GetWeakPtr(), (device_type_ == USING_CLIENT_BUFFERS_I420
- ? PIXEL_FORMAT_I420
- : PIXEL_FORMAT_GPUMEMORYBUFFER)));
+ BeepAndScheduleNextCapture(
+ base::TimeTicks::Now(),
+ base::Bind(&FakeVideoCaptureDevice::CaptureUsingClientBuffers,
+ weak_factory_.GetWeakPtr(),
+ (device_type_ == USING_CLIENT_BUFFERS_I420
+ ? PIXEL_FORMAT_I420
+ : PIXEL_FORMAT_GPUMEMORYBUFFER)));
} else {
client_->OnError("Unknown Fake Video Capture Device type.");
}
@@ -126,7 +130,8 @@ void FakeVideoCaptureDevice::StopAndDeAllocate() {
client_.reset();
}
-void FakeVideoCaptureDevice::CaptureUsingOwnBuffers() {
+void FakeVideoCaptureDevice::CaptureUsingOwnBuffers(
+ base::TimeTicks expected_execution_time) {
DCHECK(thread_checker_.CalledOnValidThread());
const size_t frame_size = capture_format_.ImageAllocationSize();
memset(fake_frame_.get(), 0, frame_size);
@@ -157,12 +162,14 @@ void FakeVideoCaptureDevice::CaptureUsingOwnBuffers() {
base::TimeTicks::Now());
}
BeepAndScheduleNextCapture(
+ expected_execution_time,
base::Bind(&FakeVideoCaptureDevice::CaptureUsingOwnBuffers,
weak_factory_.GetWeakPtr()));
}
void FakeVideoCaptureDevice::CaptureUsingClientBuffers(
- VideoPixelFormat pixel_format) {
+ VideoPixelFormat pixel_format,
+ base::TimeTicks expected_execution_time) {
DCHECK(thread_checker_.CalledOnValidThread());
scoped_ptr<VideoCaptureDevice::Client::Buffer> capture_buffer(
@@ -191,19 +198,29 @@ void FakeVideoCaptureDevice::CaptureUsingClientBuffers(
}
BeepAndScheduleNextCapture(
+ expected_execution_time,
base::Bind(&FakeVideoCaptureDevice::CaptureUsingClientBuffers,
weak_factory_.GetWeakPtr(), pixel_format));
}
void FakeVideoCaptureDevice::BeepAndScheduleNextCapture(
- const base::Closure& next_capture) {
+ base::TimeTicks expected_execution_time,
+ const base::Callback<void(base::TimeTicks)>& next_capture) {
// Generate a synchronized beep sound every so many frames.
if (frame_count_++ % kFakeCaptureBeepCycle == 0)
FakeAudioInputStream::BeepOnce();
// Reschedule next CaptureTask.
- base::MessageLoop::current()->PostDelayedTask(FROM_HERE, next_capture,
- base::TimeDelta::FromMilliseconds(kFakeCapturePeriodMs));
+ const base::TimeTicks current_time = base::TimeTicks::Now();
+ const base::TimeDelta frame_interval =
+ base::TimeDelta::FromMilliseconds(kFakeCapturePeriodMs);
+ // Don't accumulate any debt if we are lagging behind - just post the next
+ // frame immediately and continue as normal.
+ const base::TimeTicks next_execution_time =
+ std::max(current_time, expected_execution_time + frame_interval);
+ const base::TimeDelta delay = next_execution_time - current_time;
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE, base::Bind(next_capture, next_execution_time), delay);
}
} // namespace media
diff --git a/media/video/capture/fake_video_capture_device.h b/media/video/capture/fake_video_capture_device.h
index f4a19f9..3cf45a8 100644
--- a/media/video/capture/fake_video_capture_device.h
+++ b/media/video/capture/fake_video_capture_device.h
@@ -15,6 +15,7 @@
#include "base/memory/weak_ptr.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
+#include "base/time/time.h"
#include "media/video/capture/video_capture_device.h"
namespace media {
@@ -41,9 +42,12 @@ class MEDIA_EXPORT FakeVideoCaptureDevice : public VideoCaptureDevice {
private:
static const int kFakeCapturePeriodMs = 50;
- void CaptureUsingOwnBuffers();
- void CaptureUsingClientBuffers(VideoPixelFormat pixel_format);
- void BeepAndScheduleNextCapture(const base::Closure& next_capture);
+ void CaptureUsingOwnBuffers(base::TimeTicks expected_execution_time);
+ void CaptureUsingClientBuffers(VideoPixelFormat pixel_format,
+ base::TimeTicks expected_execution_time);
+ void BeepAndScheduleNextCapture(
+ base::TimeTicks expected_execution_time,
+ const base::Callback<void(base::TimeTicks)>& next_capture);
// |thread_checker_| is used to check that all methods are called in the
// correct thread that owns the object.