Commit 5dff6ac8 authored by dalecurtis's avatar dalecurtis Committed by Commit bot

Remove VideoFrameScheduler and dependents.

We did not end up using this code for video frame rendering.

BUG=none
TEST=compiles, existing tests pass.

Review URL: https://codereview.chromium.org/1111993002

Cr-Commit-Position: refs/heads/master@{#327499}
parent 91ead71d
...@@ -145,11 +145,6 @@ component("media") { ...@@ -145,11 +145,6 @@ component("media") {
"filters/source_buffer_stream.h", "filters/source_buffer_stream.h",
"filters/stream_parser_factory.cc", "filters/stream_parser_factory.cc",
"filters/stream_parser_factory.h", "filters/stream_parser_factory.h",
"filters/video_frame_scheduler.h",
"filters/video_frame_scheduler_impl.cc",
"filters/video_frame_scheduler_impl.h",
"filters/video_frame_scheduler_proxy.cc",
"filters/video_frame_scheduler_proxy.h",
"filters/vp8_bool_decoder.cc", "filters/vp8_bool_decoder.cc",
"filters/vp8_bool_decoder.h", "filters/vp8_bool_decoder.h",
"filters/vp8_parser.cc", "filters/vp8_parser.cc",
...@@ -565,8 +560,6 @@ test("media_unittests") { ...@@ -565,8 +560,6 @@ test("media_unittests") {
"filters/jpeg_parser_unittest.cc", "filters/jpeg_parser_unittest.cc",
"filters/source_buffer_stream_unittest.cc", "filters/source_buffer_stream_unittest.cc",
"filters/video_decoder_selector_unittest.cc", "filters/video_decoder_selector_unittest.cc",
"filters/video_frame_scheduler_impl_unittest.cc",
"filters/video_frame_scheduler_unittest.cc",
"filters/video_frame_stream_unittest.cc", "filters/video_frame_stream_unittest.cc",
"filters/vp8_bool_decoder_unittest.cc", "filters/vp8_bool_decoder_unittest.cc",
"filters/vp8_parser_unittest.cc", "filters/vp8_parser_unittest.cc",
...@@ -730,10 +723,6 @@ test("media_perftests") { ...@@ -730,10 +723,6 @@ test("media_perftests") {
source_set("test_support") { source_set("test_support") {
testonly = true testonly = true
sources = [ sources = [
"filters/clockless_video_frame_scheduler.cc",
"filters/clockless_video_frame_scheduler.h",
"filters/test_video_frame_scheduler.cc",
"filters/test_video_frame_scheduler.h",
"renderers/mock_gpu_video_accelerator_factories.cc", "renderers/mock_gpu_video_accelerator_factories.cc",
"renderers/mock_gpu_video_accelerator_factories.h", "renderers/mock_gpu_video_accelerator_factories.h",
"video/mock_video_decode_accelerator.cc", "video/mock_video_decode_accelerator.cc",
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/filters/clockless_video_frame_scheduler.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/message_loop/message_loop_proxy.h"
#include "media/base/video_frame.h"
namespace media {
ClocklessVideoFrameScheduler::ClocklessVideoFrameScheduler(
const DisplayCB& display_cb)
: display_cb_(display_cb) {
}
ClocklessVideoFrameScheduler::~ClocklessVideoFrameScheduler() {
}
void ClocklessVideoFrameScheduler::ScheduleVideoFrame(
const scoped_refptr<VideoFrame>& frame,
base::TimeTicks /* wall_ticks */,
const DoneCB& done_cb) {
display_cb_.Run(frame);
base::MessageLoopProxy::current()->PostTask(
FROM_HERE, base::Bind(done_cb, frame, DISPLAYED));
}
void ClocklessVideoFrameScheduler::Reset() {
}
} // namespace media
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_FILTERS_CLOCKLESS_VIDEO_FRAME_SCHEDULER_H_
#define MEDIA_FILTERS_CLOCKLESS_VIDEO_FRAME_SCHEDULER_H_
#include "media/filters/video_frame_scheduler.h"
namespace media {
// A scheduler that immediately displays frames.
class ClocklessVideoFrameScheduler : public VideoFrameScheduler {
public:
typedef base::Callback<void(const scoped_refptr<VideoFrame>&)> DisplayCB;
explicit ClocklessVideoFrameScheduler(const DisplayCB& display_cb);
~ClocklessVideoFrameScheduler() override;
// VideoFrameScheduler implementation.
void ScheduleVideoFrame(const scoped_refptr<VideoFrame>& frame,
base::TimeTicks wall_ticks,
const DoneCB& done_cb) override;
void Reset() override;
private:
DisplayCB display_cb_;
DISALLOW_COPY_AND_ASSIGN(ClocklessVideoFrameScheduler);
};
} // namespace media
#endif // MEDIA_FILTERS_CLOCKLESS_VIDEO_FRAME_SCHEDULER_H_
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/filters/test_video_frame_scheduler.h"
#include "media/base/video_frame.h"
namespace media {
TestVideoFrameScheduler::ScheduledFrame::ScheduledFrame(
const scoped_refptr<VideoFrame> frame,
base::TimeTicks wall_ticks,
const DoneCB& done_cb)
: frame(frame), wall_ticks(wall_ticks), done_cb(done_cb) {
}
TestVideoFrameScheduler::ScheduledFrame::~ScheduledFrame() {
}
TestVideoFrameScheduler::TestVideoFrameScheduler() {
}
TestVideoFrameScheduler::~TestVideoFrameScheduler() {
}
void TestVideoFrameScheduler::ScheduleVideoFrame(
const scoped_refptr<VideoFrame>& frame,
base::TimeTicks wall_ticks,
const DoneCB& done_cb) {
scheduled_frames_.push_back(ScheduledFrame(frame, wall_ticks, done_cb));
}
void TestVideoFrameScheduler::Reset() {
scheduled_frames_.clear();
}
void TestVideoFrameScheduler::DisplayFramesUpTo(base::TimeTicks wall_ticks) {
RunDoneCBForFramesUpTo(wall_ticks, DISPLAYED);
}
void TestVideoFrameScheduler::DropFramesUpTo(base::TimeTicks wall_ticks) {
RunDoneCBForFramesUpTo(wall_ticks, DROPPED);
}
void TestVideoFrameScheduler::RunDoneCBForFramesUpTo(base::TimeTicks wall_ticks,
Reason reason) {
std::vector<ScheduledFrame> done_frames;
std::vector<ScheduledFrame> remaining_frames;
for (size_t i = 0; i < scheduled_frames_.size(); ++i) {
if (scheduled_frames_[i].wall_ticks <= wall_ticks) {
done_frames.push_back(scheduled_frames_[i]);
} else {
remaining_frames.push_back(scheduled_frames_[i]);
}
}
scheduled_frames_.swap(remaining_frames);
for (size_t i = 0; i < done_frames.size(); ++i) {
done_frames[i].done_cb.Run(done_frames[i].frame, reason);
}
}
} // namespace media
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_FILTERS_TEST_VIDEO_FRAME_SCHEDULER_H_
#define MEDIA_FILTERS_TEST_VIDEO_FRAME_SCHEDULER_H_
#include <vector>
#include "media/filters/video_frame_scheduler.h"
namespace media {
// A scheduler that queues frames until told otherwise.
class TestVideoFrameScheduler : public VideoFrameScheduler {
public:
struct ScheduledFrame {
ScheduledFrame(const scoped_refptr<VideoFrame> frame,
base::TimeTicks wall_ticks,
const DoneCB& done_cb);
~ScheduledFrame();
scoped_refptr<VideoFrame> frame;
base::TimeTicks wall_ticks;
DoneCB done_cb;
};
TestVideoFrameScheduler();
~TestVideoFrameScheduler() override;
// VideoFrameScheduler implementation.
void ScheduleVideoFrame(const scoped_refptr<VideoFrame>& frame,
base::TimeTicks wall_ticks,
const DoneCB& done_cb) override;
void Reset() override;
// Displays all frames with scheduled times <= |wall_ticks|.
void DisplayFramesUpTo(base::TimeTicks wall_ticks);
// Drops all frames with scheduled times <= |wall_ticks|.
void DropFramesUpTo(base::TimeTicks wall_ticks);
const std::vector<ScheduledFrame>& scheduled_frames() const {
return scheduled_frames_;
}
private:
void RunDoneCBForFramesUpTo(base::TimeTicks wall_ticks, Reason reason);
std::vector<ScheduledFrame> scheduled_frames_;
DISALLOW_COPY_AND_ASSIGN(TestVideoFrameScheduler);
};
} // namespace media
#endif // MEDIA_FILTERS_TEST_VIDEO_FRAME_SCHEDULER_H_
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_FILTERS_VIDEO_FRAME_SCHEDULER_H_
#define MEDIA_FILTERS_VIDEO_FRAME_SCHEDULER_H_
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "media/base/media_export.h"
namespace media {
class VideoFrame;
// Defines an abstract video frame scheduler that is capable of managing the
// display of video frames at explicit times.
class MEDIA_EXPORT VideoFrameScheduler {
public:
VideoFrameScheduler() {}
virtual ~VideoFrameScheduler() {}
enum Reason {
DISPLAYED, // Frame was displayed.
DROPPED, // Frame was dropped.
};
typedef base::Callback<void(const scoped_refptr<VideoFrame>&, Reason)> DoneCB;
// Schedule |frame| to be displayed at |wall_ticks|, firing |done_cb| when
// the scheduler has finished with the frame.
//
// To avoid reentrancy issues, |done_cb| is run on a separate calling stack.
virtual void ScheduleVideoFrame(const scoped_refptr<VideoFrame>& frame,
base::TimeTicks wall_ticks,
const DoneCB& done_cb) = 0;
// Causes the scheduler to cancel any previously scheduled frames.
//
// There is no guarantee that |done_cb|'s for previously scheduled frames
// will not be run. Clients should implement callback tracking/cancellation
// if they are sensitive to old callbacks being run.
virtual void Reset() = 0;
};
} // namespace media
#endif // MEDIA_FILTERS_VIDEO_FRAME_SCHEDULER_H_
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/filters/video_frame_scheduler_impl.h"
#include <list>
#include "base/single_thread_task_runner.h"
#include "base/time/default_tick_clock.h"
#include "media/base/video_frame.h"
namespace media {
VideoFrameSchedulerImpl::VideoFrameSchedulerImpl(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
const DisplayCB& display_cb)
: task_runner_(task_runner),
display_cb_(display_cb),
tick_clock_(new base::DefaultTickClock()) {
}
VideoFrameSchedulerImpl::~VideoFrameSchedulerImpl() {
}
void VideoFrameSchedulerImpl::ScheduleVideoFrame(
const scoped_refptr<VideoFrame>& frame,
base::TimeTicks wall_ticks,
const DoneCB& done_cb) {
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(!frame->end_of_stream());
pending_frames_.push(PendingFrame(frame, wall_ticks, done_cb));
ResetTimerIfNecessary();
}
void VideoFrameSchedulerImpl::Reset() {
pending_frames_ = PendingFrameQueue();
timer_.Stop();
}
void VideoFrameSchedulerImpl::SetTickClockForTesting(
scoped_ptr<base::TickClock> tick_clock) {
tick_clock_.swap(tick_clock);
}
void VideoFrameSchedulerImpl::ResetTimerIfNecessary() {
if (pending_frames_.empty()) {
DCHECK(!timer_.IsRunning());
return;
}
// Negative times will schedule the callback to run immediately.
timer_.Stop();
timer_.Start(FROM_HERE,
pending_frames_.top().wall_ticks - tick_clock_->NowTicks(),
base::Bind(&VideoFrameSchedulerImpl::OnTimerFired,
base::Unretained(this)));
}
void VideoFrameSchedulerImpl::OnTimerFired() {
base::TimeTicks now = tick_clock_->NowTicks();
// Move all frames that have reached their deadline into a separate queue.
std::list<PendingFrame> expired_frames;
while (!pending_frames_.empty() && pending_frames_.top().wall_ticks <= now) {
expired_frames.push_back(pending_frames_.top());
pending_frames_.pop();
}
// Signal that all frames except for the last one as dropped.
while (expired_frames.size() > 1) {
expired_frames.front().done_cb.Run(expired_frames.front().frame, DROPPED);
expired_frames.pop_front();
}
// Display the last expired frame.
if (!expired_frames.empty()) {
display_cb_.Run(expired_frames.front().frame);
expired_frames.front().done_cb.Run(expired_frames.front().frame, DISPLAYED);
expired_frames.pop_front();
}
ResetTimerIfNecessary();
}
VideoFrameSchedulerImpl::PendingFrame::PendingFrame(
const scoped_refptr<VideoFrame>& frame,
base::TimeTicks wall_ticks,
const DoneCB& done_cb)
: frame(frame), wall_ticks(wall_ticks), done_cb(done_cb) {
}
VideoFrameSchedulerImpl::PendingFrame::~PendingFrame() {
}
bool VideoFrameSchedulerImpl::PendingFrame::operator<(
const PendingFrame& other) const {
// Flip the comparison as std::priority_queue<T>::top() returns the largest
// element.
//
// Assume video frames with identical timestamps contain identical content.
return wall_ticks > other.wall_ticks;
}
} // namespace media
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_FILTERS_VIDEO_FRAME_SCHEDULER_IMPL_H_
#define MEDIA_FILTERS_VIDEO_FRAME_SCHEDULER_IMPL_H_
#include <queue>
#include "base/memory/ref_counted.h"
#include "base/timer/timer.h"
#include "media/filters/video_frame_scheduler.h"
namespace base {
class SingleThreadTaskRunner;
class TickClock;
}
namespace media {
// A scheduler that uses delayed tasks on a task runner for timing the display
// of video frames.
//
// Single threaded. Calls must be on |task_runner|.
class MEDIA_EXPORT VideoFrameSchedulerImpl : public VideoFrameScheduler {
public:
typedef base::Callback<void(const scoped_refptr<VideoFrame>&)> DisplayCB;
// |task_runner| is used for scheduling the delayed tasks.
// |display_cb| is run when a frame is to be displayed.
VideoFrameSchedulerImpl(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
const DisplayCB& display_cb);
~VideoFrameSchedulerImpl() override;
// VideoFrameScheduler implementation.
void ScheduleVideoFrame(const scoped_refptr<VideoFrame>& frame,
base::TimeTicks wall_ticks,
const DoneCB& done_cb) override;
void Reset() override;
void SetTickClockForTesting(scoped_ptr<base::TickClock> tick_clock);
private:
void ResetTimerIfNecessary();
void OnTimerFired();
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
DisplayCB display_cb_;
scoped_ptr<base::TickClock> tick_clock_;
base::OneShotTimer<VideoFrameScheduler> timer_;
struct PendingFrame {
PendingFrame(const scoped_refptr<VideoFrame>& frame,
base::TimeTicks wall_ticks,
const DoneCB& done_cb);
~PendingFrame();
// For use with std::priority_queue<T>.
bool operator<(const PendingFrame& other) const;
scoped_refptr<VideoFrame> frame;
base::TimeTicks wall_ticks;
DoneCB done_cb;
};
typedef std::priority_queue<PendingFrame> PendingFrameQueue;
PendingFrameQueue pending_frames_;
DISALLOW_COPY_AND_ASSIGN(VideoFrameSchedulerImpl);
};
} // namespace media
#endif // MEDIA_FILTERS_VIDEO_FRAME_SCHEDULER_IMPL_H_
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/message_loop/message_loop.h"
#include "base/test/simple_test_tick_clock.h"
#include "media/base/test_helpers.h"
#include "media/base/video_frame.h"
#include "media/filters/video_frame_scheduler_impl.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
using testing::_;
// NOTE: millisecond-level resolution is used for times as real delayed tasks
// are posted. Don't use large values if you want to keep tests running fast.
class VideoFrameSchedulerImplTest : public testing::Test {
public:
VideoFrameSchedulerImplTest()
: scheduler_(message_loop_.message_loop_proxy(),
base::Bind(&VideoFrameSchedulerImplTest::OnDisplay,
base::Unretained(this))),
tick_clock_(new base::SimpleTestTickClock()) {
scheduler_.SetTickClockForTesting(scoped_ptr<base::TickClock>(tick_clock_));
}
virtual ~VideoFrameSchedulerImplTest() {}
MOCK_METHOD1(OnDisplay, void(const scoped_refptr<VideoFrame>&));
MOCK_METHOD2(OnFrameDone,
void(const scoped_refptr<VideoFrame>&,
VideoFrameScheduler::Reason));
void Schedule(const scoped_refptr<VideoFrame>& frame, int64 target_ms) {
scheduler_.ScheduleVideoFrame(
frame,
base::TimeTicks() + base::TimeDelta::FromMilliseconds(target_ms),
base::Bind(&VideoFrameSchedulerImplTest::OnFrameDone,
base::Unretained(this)));
}
void RunUntilTimeHasElapsed(int64 ms) {
WaitableMessageLoopEvent waiter;
message_loop_.PostDelayedTask(
FROM_HERE, waiter.GetClosure(), base::TimeDelta::FromMilliseconds(ms));
waiter.RunAndWait();
}
void AdvanceTime(int64 ms) {
tick_clock_->Advance(base::TimeDelta::FromMilliseconds(ms));
}
void Reset() {
scheduler_.Reset();
}
private:
base::MessageLoop message_loop_;
VideoFrameSchedulerImpl scheduler_;
base::SimpleTestTickClock* tick_clock_; // Owned by |scheduler_|.
DISALLOW_COPY_AND_ASSIGN(VideoFrameSchedulerImplTest);
};
TEST_F(VideoFrameSchedulerImplTest, ImmediateDisplay) {
scoped_refptr<VideoFrame> frame =
VideoFrame::CreateBlackFrame(gfx::Size(8, 8));
Schedule(frame, 0);
EXPECT_CALL(*this, OnDisplay(frame));
EXPECT_CALL(*this, OnFrameDone(frame, VideoFrameScheduler::DISPLAYED));
RunUntilTimeHasElapsed(0);
}
TEST_F(VideoFrameSchedulerImplTest, EventualDisplay) {
scoped_refptr<VideoFrame> frame =
VideoFrame::CreateBlackFrame(gfx::Size(8, 8));
Schedule(frame, 10);
// Nothing should happen.
RunUntilTimeHasElapsed(10);
// Now we should get the frame.
EXPECT_CALL(*this, OnDisplay(frame));
EXPECT_CALL(*this, OnFrameDone(frame, VideoFrameScheduler::DISPLAYED));
AdvanceTime(10);
RunUntilTimeHasElapsed(10);
}
TEST_F(VideoFrameSchedulerImplTest, DroppedFrame) {
scoped_refptr<VideoFrame> dropped =
VideoFrame::CreateBlackFrame(gfx::Size(8, 8));
scoped_refptr<VideoFrame> displayed =
VideoFrame::CreateBlackFrame(gfx::Size(8, 8));
Schedule(dropped, 10);
Schedule(displayed, 20);
// The frame past its deadline will get dropped.
EXPECT_CALL(*this, OnDisplay(displayed));
EXPECT_CALL(*this, OnFrameDone(dropped, VideoFrameScheduler::DROPPED));
EXPECT_CALL(*this, OnFrameDone(displayed, VideoFrameScheduler::DISPLAYED));
AdvanceTime(20);
RunUntilTimeHasElapsed(20);
}
TEST_F(VideoFrameSchedulerImplTest, SingleFrameLate) {
scoped_refptr<VideoFrame> frame =
VideoFrame::CreateBlackFrame(gfx::Size(8, 8));
Schedule(frame, 10);
// Despite frame being late it should still get displayed as it's the only
// one.
EXPECT_CALL(*this, OnDisplay(frame));
EXPECT_CALL(*this, OnFrameDone(frame, VideoFrameScheduler::DISPLAYED));
AdvanceTime(20);
RunUntilTimeHasElapsed(20);
}
TEST_F(VideoFrameSchedulerImplTest, ManyFramesLate) {
scoped_refptr<VideoFrame> dropped =
VideoFrame::CreateBlackFrame(gfx::Size(8, 8));
scoped_refptr<VideoFrame> displayed =
VideoFrame::CreateBlackFrame(gfx::Size(8, 8));
Schedule(dropped, 10);
Schedule(displayed, 20);
// Despite both being late, the scheduler should always displays the latest
// expired frame.
EXPECT_CALL(*this, OnDisplay(displayed));
EXPECT_CALL(*this, OnFrameDone(dropped, VideoFrameScheduler::DROPPED));
EXPECT_CALL(*this, OnFrameDone(displayed, VideoFrameScheduler::DISPLAYED));
AdvanceTime(30);
RunUntilTimeHasElapsed(30);
}
TEST_F(VideoFrameSchedulerImplTest, Reset) {
scoped_refptr<VideoFrame> frame =
VideoFrame::CreateBlackFrame(gfx::Size(8, 8));
Schedule(frame, 10);
// Despite being on time, frame callback isn't run.
EXPECT_CALL(*this, OnFrameDone(_, _)).Times(0);
AdvanceTime(10);
Reset();
RunUntilTimeHasElapsed(10);
}
} // namespace media
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/filters/video_frame_scheduler_proxy.h"
#include "base/single_thread_task_runner.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/video_frame.h"
namespace media {
VideoFrameSchedulerProxy::VideoFrameSchedulerProxy(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
const scoped_refptr<base::SingleThreadTaskRunner>& scheduler_runner,
scoped_ptr<VideoFrameScheduler> scheduler)
: task_runner_(task_runner),
scheduler_runner_(scheduler_runner),
scheduler_(scheduler.Pass()),
weak_factory_(this) {
}
VideoFrameSchedulerProxy::~VideoFrameSchedulerProxy() {
scheduler_runner_->DeleteSoon(FROM_HERE, scheduler_.release());
}
void VideoFrameSchedulerProxy::ScheduleVideoFrame(
const scoped_refptr<VideoFrame>& frame,
base::TimeTicks wall_ticks,
const DoneCB& done_cb) {
DCHECK(task_runner_->BelongsToCurrentThread());
scheduler_runner_->PostTask(
FROM_HERE,
base::Bind(&VideoFrameScheduler::ScheduleVideoFrame,
base::Unretained(scheduler_.get()),
frame,
wall_ticks,
BindToCurrentLoop(done_cb)));
}
void VideoFrameSchedulerProxy::Reset() {
DCHECK(task_runner_->BelongsToCurrentThread());
scheduler_runner_->PostTask(FROM_HERE,
base::Bind(&VideoFrameScheduler::Reset,
base::Unretained(scheduler_.get())));
}
} // namespace media
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_FILTERS_VIDEO_FRAME_SCHEDULER_PROXY_H_
#define MEDIA_FILTERS_VIDEO_FRAME_SCHEDULER_PROXY_H_
#include "base/memory/weak_ptr.h"
#include "media/filters/video_frame_scheduler.h"
namespace base {
class SingleThreadTaskRunner;
}
namespace media {
// Provides a thread-safe proxy for a VideoFrameScheduler. Typical use is to
// use a real VideoFrameScheduler on the task runner responsible for graphics
// display and provide a proxy on the task runner responsible for background
// video decoding.
class MEDIA_EXPORT VideoFrameSchedulerProxy : public VideoFrameScheduler {
public:
// |task_runner| is the runner that this object will be called on.
// |scheduler_runner| is the runner that |scheduler| will be called on.
// |scheduler| will be deleted on |scheduler_runner|.
VideoFrameSchedulerProxy(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
const scoped_refptr<base::SingleThreadTaskRunner>& scheduler_runner,
scoped_ptr<VideoFrameScheduler> scheduler);
~VideoFrameSchedulerProxy() override;
// VideoFrameScheduler implementation.
void ScheduleVideoFrame(const scoped_refptr<VideoFrame>& frame,
base::TimeTicks wall_ticks,
const DoneCB& done_cb) override;
void Reset() override;
private:
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> scheduler_runner_;
scoped_ptr<VideoFrameScheduler> scheduler_;
// NOTE: Weak pointers must be invalidated before all other member variables.
base::WeakPtrFactory<VideoFrameSchedulerProxy> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(VideoFrameSchedulerProxy);
};
} // namespace media
#endif // MEDIA_FILTERS_VIDEO_FRAME_SCHEDULER_PROXY_H_
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/bind.h"
#include "base/debug/stack_trace.h"
#include "base/run_loop.h"
#include "media/base/video_frame.h"
#include "media/filters/clockless_video_frame_scheduler.h"
#include "media/filters/test_video_frame_scheduler.h"
#include "media/filters/video_frame_scheduler_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
static void DoNothing(const scoped_refptr<VideoFrame>& frame) {
}
static void CheckForReentrancy(std::string* stack_trace,
const scoped_refptr<VideoFrame>& frame,
VideoFrameScheduler::Reason reason) {
*stack_trace = base::debug::StackTrace().ToString();
base::MessageLoop::current()->PostTask(FROM_HERE,
base::MessageLoop::QuitClosure());
}
// Type parameterized test harness for validating API contract of
// VideoFrameScheduler implementations.
//
// NOTE: C++ requires using "this" for derived class templates when referencing
// class members.
template <typename T>
class VideoFrameSchedulerTest : public testing::Test {
public:
VideoFrameSchedulerTest() {}
virtual ~VideoFrameSchedulerTest() {}
base::MessageLoop message_loop_;
T scheduler_;
private:
DISALLOW_COPY_AND_ASSIGN(VideoFrameSchedulerTest);
};
template <>
VideoFrameSchedulerTest<ClocklessVideoFrameScheduler>::VideoFrameSchedulerTest()
: scheduler_(base::Bind(&DoNothing)) {
}
template <>
VideoFrameSchedulerTest<VideoFrameSchedulerImpl>::VideoFrameSchedulerTest()
: scheduler_(message_loop_.message_loop_proxy(), base::Bind(&DoNothing)) {
}
TYPED_TEST_CASE_P(VideoFrameSchedulerTest);
TYPED_TEST_P(VideoFrameSchedulerTest, ScheduleVideoFrameIsntReentrant) {
scoped_refptr<VideoFrame> frame =
VideoFrame::CreateBlackFrame(gfx::Size(8, 8));
std::string stack_trace;
this->scheduler_.ScheduleVideoFrame(
frame, base::TimeTicks(), base::Bind(&CheckForReentrancy, &stack_trace));
EXPECT_TRUE(stack_trace.empty()) << "Reentracy detected:\n" << stack_trace;
}
REGISTER_TYPED_TEST_CASE_P(VideoFrameSchedulerTest,
ScheduleVideoFrameIsntReentrant);
INSTANTIATE_TYPED_TEST_CASE_P(ClocklessVideoFrameScheduler,
VideoFrameSchedulerTest,
ClocklessVideoFrameScheduler);
INSTANTIATE_TYPED_TEST_CASE_P(VideoFrameSchedulerImpl,
VideoFrameSchedulerTest,
VideoFrameSchedulerImpl);
INSTANTIATE_TYPED_TEST_CASE_P(TestVideoFrameScheduler,
VideoFrameSchedulerTest,
TestVideoFrameScheduler);
} // namespace media
...@@ -478,11 +478,6 @@ ...@@ -478,11 +478,6 @@
'filters/source_buffer_stream.h', 'filters/source_buffer_stream.h',
'filters/stream_parser_factory.cc', 'filters/stream_parser_factory.cc',
'filters/stream_parser_factory.h', 'filters/stream_parser_factory.h',
'filters/video_frame_scheduler.h',
'filters/video_frame_scheduler_impl.cc',
'filters/video_frame_scheduler_impl.h',
'filters/video_frame_scheduler_proxy.cc',
'filters/video_frame_scheduler_proxy.h',
'filters/vp8_bool_decoder.cc', 'filters/vp8_bool_decoder.cc',
'filters/vp8_bool_decoder.h', 'filters/vp8_bool_decoder.h',
'filters/vp8_parser.cc', 'filters/vp8_parser.cc',
...@@ -1264,8 +1259,6 @@ ...@@ -1264,8 +1259,6 @@
'filters/jpeg_parser_unittest.cc', 'filters/jpeg_parser_unittest.cc',
'filters/source_buffer_stream_unittest.cc', 'filters/source_buffer_stream_unittest.cc',
'filters/video_decoder_selector_unittest.cc', 'filters/video_decoder_selector_unittest.cc',
'filters/video_frame_scheduler_impl_unittest.cc',
'filters/video_frame_scheduler_unittest.cc',
'filters/video_frame_stream_unittest.cc', 'filters/video_frame_stream_unittest.cc',
'filters/vp8_bool_decoder_unittest.cc', 'filters/vp8_bool_decoder_unittest.cc',
'filters/vp8_parser_unittest.cc', 'filters/vp8_parser_unittest.cc',
...@@ -1527,10 +1520,6 @@ ...@@ -1527,10 +1520,6 @@
'base/test_data_util.h', 'base/test_data_util.h',
'base/test_helpers.cc', 'base/test_helpers.cc',
'base/test_helpers.h', 'base/test_helpers.h',
'filters/clockless_video_frame_scheduler.cc',
'filters/clockless_video_frame_scheduler.h',
'filters/test_video_frame_scheduler.cc',
'filters/test_video_frame_scheduler.h',
'renderers/mock_gpu_video_accelerator_factories.cc', 'renderers/mock_gpu_video_accelerator_factories.cc',
'renderers/mock_gpu_video_accelerator_factories.h', 'renderers/mock_gpu_video_accelerator_factories.h',
'video/mock_video_decode_accelerator.cc', 'video/mock_video_decode_accelerator.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment