Change blimp README to use Markdown.
[chromium-blink-merge.git] / media / base / null_video_sink.cc
blob0d9746d3620af61fcf3ffba3a4b50982c026e024
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/base/null_video_sink.h"
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/location.h"
10 #include "base/single_thread_task_runner.h"
12 namespace media {
14 NullVideoSink::NullVideoSink(
15 bool clockless,
16 base::TimeDelta interval,
17 const NewFrameCB& new_frame_cb,
18 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
19 : clockless_(clockless),
20 interval_(interval),
21 new_frame_cb_(new_frame_cb),
22 task_runner_(task_runner),
23 started_(false),
24 callback_(nullptr),
25 tick_clock_(&default_tick_clock_),
26 background_render_(false) {
29 NullVideoSink::~NullVideoSink() {
30 DCHECK(!started_);
33 void NullVideoSink::Start(RenderCallback* callback) {
34 DCHECK(task_runner_->BelongsToCurrentThread());
35 DCHECK(!started_);
36 callback_ = callback;
37 started_ = true;
38 last_now_ = current_render_time_ = tick_clock_->NowTicks();
39 cancelable_worker_.Reset(
40 base::Bind(&NullVideoSink::CallRender, base::Unretained(this)));
41 task_runner_->PostTask(FROM_HERE, cancelable_worker_.callback());
44 void NullVideoSink::Stop() {
45 DCHECK(task_runner_->BelongsToCurrentThread());
46 cancelable_worker_.Cancel();
47 started_ = false;
48 if (!stop_cb_.is_null())
49 base::ResetAndReturn(&stop_cb_).Run();
52 void NullVideoSink::CallRender() {
53 DCHECK(task_runner_->BelongsToCurrentThread());
54 DCHECK(started_);
56 const base::TimeTicks end_of_interval = current_render_time_ + interval_;
57 scoped_refptr<VideoFrame> new_frame = callback_->Render(
58 current_render_time_, end_of_interval, background_render_);
59 const bool is_new_frame = new_frame != last_frame_;
60 last_frame_ = new_frame;
61 if (is_new_frame && !new_frame_cb_.is_null())
62 new_frame_cb_.Run(new_frame);
64 current_render_time_ += interval_;
66 if (clockless_) {
67 task_runner_->PostTask(FROM_HERE, cancelable_worker_.callback());
68 return;
71 const base::TimeTicks now = tick_clock_->NowTicks();
72 base::TimeDelta delay;
73 if (last_now_ == now) {
74 // The tick clock is frozen in this case, so don't advance deadline.
75 delay = interval_;
76 current_render_time_ = now;
77 } else {
78 // If we're behind, find the next nearest on time interval.
79 delay = current_render_time_ - now;
80 if (delay < base::TimeDelta())
81 delay += interval_ * (-delay / interval_ + 1);
82 current_render_time_ = now + delay;
83 last_now_ = now;
86 task_runner_->PostDelayedTask(FROM_HERE, cancelable_worker_.callback(),
87 delay);
90 void NullVideoSink::PaintFrameUsingOldRenderingPath(
91 const scoped_refptr<VideoFrame>& frame) {
92 new_frame_cb_.Run(frame);
95 } // namespace media