123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- // Copyright 2015 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/base/null_video_sink.h"
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/location.h"
- #include "base/task/single_thread_task_runner.h"
- namespace media {
- NullVideoSink::NullVideoSink(
- bool clockless,
- base::TimeDelta interval,
- const NewFrameCB& new_frame_cb,
- const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
- : clockless_(clockless),
- interval_(interval),
- new_frame_cb_(new_frame_cb),
- task_runner_(task_runner),
- started_(false),
- callback_(nullptr),
- tick_clock_(base::DefaultTickClock::GetInstance()),
- background_render_(false) {}
- NullVideoSink::~NullVideoSink() {
- DCHECK(!started_);
- }
- void NullVideoSink::Start(RenderCallback* callback) {
- DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(!started_);
- callback_ = callback;
- started_ = true;
- last_now_ = current_render_time_ = tick_clock_->NowTicks();
- cancelable_worker_.Reset(
- base::BindRepeating(&NullVideoSink::CallRender, base::Unretained(this)));
- task_runner_->PostTask(FROM_HERE, cancelable_worker_.callback());
- }
- void NullVideoSink::Stop() {
- DCHECK(task_runner_->BelongsToCurrentThread());
- cancelable_worker_.Cancel();
- started_ = false;
- if (stop_cb_)
- std::move(stop_cb_).Run();
- }
- void NullVideoSink::CallRender() {
- DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(started_);
- const base::TimeTicks end_of_interval = current_render_time_ + interval_;
- scoped_refptr<VideoFrame> new_frame = callback_->Render(
- current_render_time_, end_of_interval,
- background_render_
- ? VideoRendererSink::RenderCallback::RenderingMode::kBackground
- : VideoRendererSink::RenderCallback::RenderingMode::kNormal);
- DCHECK(new_frame);
- const bool is_new_frame = new_frame != last_frame_;
- last_frame_ = new_frame;
- if (is_new_frame && new_frame_cb_)
- new_frame_cb_.Run(new_frame);
- current_render_time_ += interval_;
- if (clockless_) {
- task_runner_->PostTask(FROM_HERE, cancelable_worker_.callback());
- return;
- }
- const base::TimeTicks now = tick_clock_->NowTicks();
- base::TimeDelta delay;
- if (last_now_ == now) {
- // The tick clock is frozen in this case, so don't advance deadline.
- delay = interval_;
- current_render_time_ = now;
- } else {
- // If we're behind, find the next nearest on time interval.
- delay = current_render_time_ - now;
- if (delay.is_negative())
- delay = interval_ + (delay % interval_);
- current_render_time_ = now + delay;
- last_now_ = now;
- }
- task_runner_->PostDelayedTask(FROM_HERE, cancelable_worker_.callback(),
- delay);
- }
- void NullVideoSink::PaintSingleFrame(scoped_refptr<VideoFrame> frame,
- bool repaint_duplicate_frame) {
- if (!repaint_duplicate_frame && frame == last_frame_)
- return;
- last_frame_ = frame;
- if (new_frame_cb_)
- new_frame_cb_.Run(std::move(frame));
- }
- } // namespace media
|