// 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 "content/renderer/media/stream/webmediaplayer_ms_compositor.h"

#include <stdint.h>
#include <string>
#include <utility>

#include "base/command_line.h"
#include "base/hash.h"
#include "base/message_loop/message_loop_current.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "cc/paint/skia_paint_canvas.h"
#include "content/renderer/media/stream/webmediaplayer_ms.h"
#include "content/renderer/render_thread_impl.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/media_switches.h"
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
#include "media/filters/video_renderer_algorithm.h"
#include "media/renderers/paint_canvas_video_renderer.h"
#include "services/ws/public/cpp/gpu/context_provider_command_buffer.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/blink/public/platform/web_media_stream.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/platform/web_video_frame_submitter.h"
#include "third_party/libyuv/include/libyuv/convert.h"
#include "third_party/libyuv/include/libyuv/planar_functions.h"
#include "third_party/libyuv/include/libyuv/video_common.h"
#include "third_party/skia/include/core/SkSurface.h"

namespace content {

namespace {

// This function copies |frame| to a new I420 or YV12A media::VideoFrame.
scoped_refptr<media::VideoFrame> CopyFrame(
    const scoped_refptr<media::VideoFrame>& frame,
    media::PaintCanvasVideoRenderer* video_renderer) {
  scoped_refptr<media::VideoFrame> new_frame;
  if (frame->HasTextures()) {
    DCHECK(frame->format() == media::PIXEL_FORMAT_ARGB ||
           frame->format() == media::PIXEL_FORMAT_XRGB ||
           frame->format() == media::PIXEL_FORMAT_I420 ||
           frame->format() == media::PIXEL_FORMAT_UYVY ||
           frame->format() == media::PIXEL_FORMAT_NV12);
    new_frame = media::VideoFrame::CreateFrame(
        media::PIXEL_FORMAT_I420, frame->coded_size(), frame->visible_rect(),
        frame->natural_size(), frame->timestamp());

    ws::ContextProviderCommandBuffer* const provider =
        RenderThreadImpl::current()->SharedMainThreadContextProvider().get();
    if (!provider) {
      // Return a black frame (yuv = {0, 0x80, 0x80}).
      return media::VideoFrame::CreateColorFrame(
          frame->visible_rect().size(), 0u, 0x80, 0x80, frame->timestamp());
    }

    SkBitmap bitmap;
    bitmap.allocPixels(SkImageInfo::MakeN32Premul(
        frame->visible_rect().width(), frame->visible_rect().height()));
    cc::SkiaPaintCanvas paint_canvas(bitmap);

    DCHECK(provider->ContextGL());
    video_renderer->Copy(
        frame.get(), &paint_canvas,
        media::Context3D(provider->ContextGL(), provider->GrContext()),
        provider->ContextSupport());

    SkPixmap pixmap;
    const bool result = bitmap.peekPixels(&pixmap);
    DCHECK(result) << "Error trying to access SkBitmap's pixels";

    const uint32_t source_pixel_format =
        (kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR
                                                     : libyuv::FOURCC_ARGB;
    libyuv::ConvertToI420(static_cast<const uint8_t*>(pixmap.addr(0, 0)),
                          pixmap.computeByteSize(),
                          new_frame->visible_data(media::VideoFrame::kYPlane),
                          new_frame->stride(media::VideoFrame::kYPlane),
                          new_frame->visible_data(media::VideoFrame::kUPlane),
                          new_frame->stride(media::VideoFrame::kUPlane),
                          new_frame->visible_data(media::VideoFrame::kVPlane),
                          new_frame->stride(media::VideoFrame::kVPlane),
                          0 /* crop_x */, 0 /* crop_y */, pixmap.width(),
                          pixmap.height(), new_frame->visible_rect().width(),
                          new_frame->visible_rect().height(), libyuv::kRotate0,
                          source_pixel_format);
  } else {
    DCHECK(frame->IsMappable());
    DCHECK(frame->format() == media::PIXEL_FORMAT_I420A ||
           frame->format() == media::PIXEL_FORMAT_I420);
    const gfx::Size& coded_size = frame->coded_size();
    new_frame = media::VideoFrame::CreateFrame(
        media::IsOpaque(frame->format()) ? media::PIXEL_FORMAT_I420
                                         : media::PIXEL_FORMAT_I420A,
        coded_size, frame->visible_rect(), frame->natural_size(),
        frame->timestamp());
    libyuv::I420Copy(frame->data(media::VideoFrame::kYPlane),
                     frame->stride(media::VideoFrame::kYPlane),
                     frame->data(media::VideoFrame::kUPlane),
                     frame->stride(media::VideoFrame::kUPlane),
                     frame->data(media::VideoFrame::kVPlane),
                     frame->stride(media::VideoFrame::kVPlane),
                     new_frame->data(media::VideoFrame::kYPlane),
                     new_frame->stride(media::VideoFrame::kYPlane),
                     new_frame->data(media::VideoFrame::kUPlane),
                     new_frame->stride(media::VideoFrame::kUPlane),
                     new_frame->data(media::VideoFrame::kVPlane),
                     new_frame->stride(media::VideoFrame::kVPlane),
                     coded_size.width(), coded_size.height());
    if (frame->format() == media::PIXEL_FORMAT_I420A) {
      libyuv::CopyPlane(frame->data(media::VideoFrame::kAPlane),
                        frame->stride(media::VideoFrame::kAPlane),
                        new_frame->data(media::VideoFrame::kAPlane),
                        new_frame->stride(media::VideoFrame::kAPlane),
                        coded_size.width(), coded_size.height());
    }
  }

  // Transfer metadata keys.
  new_frame->metadata()->MergeMetadataFrom(frame->metadata());
  return new_frame;
}

}  // anonymous namespace

WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
    scoped_refptr<base::SingleThreadTaskRunner>
        video_frame_compositor_task_runner,
    scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
    const blink::WebMediaStream& web_stream,
    std::unique_ptr<blink::WebVideoFrameSubmitter> submitter,
    blink::WebMediaPlayer::SurfaceLayerMode surface_layer_mode,
    const base::WeakPtr<WebMediaPlayerMS>& player)
    : RefCountedDeleteOnSequence<WebMediaPlayerMSCompositor>(
          video_frame_compositor_task_runner),
      video_frame_compositor_task_runner_(video_frame_compositor_task_runner),
      io_task_runner_(io_task_runner),
      main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
      player_(player),
      video_frame_provider_client_(nullptr),
      current_frame_rendered_(false),
      last_render_length_(base::TimeDelta::FromSecondsD(1.0 / 60.0)),
      total_frame_count_(0),
      dropped_frame_count_(0),
      stopped_(true),
      render_started_(!stopped_),
      weak_ptr_factory_(this) {
  if (surface_layer_mode != blink::WebMediaPlayer::SurfaceLayerMode::kNever) {
    submitter_ = std::move(submitter);

    video_frame_compositor_task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&WebMediaPlayerMSCompositor::InitializeSubmitter,
                       weak_ptr_factory_.GetWeakPtr()));
    update_submission_state_callback_ = media::BindToLoop(
        video_frame_compositor_task_runner_,
        base::BindRepeating(&WebMediaPlayerMSCompositor::UpdateSubmissionState,
                            weak_ptr_factory_.GetWeakPtr()));
  }

  blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
  if (!web_stream.IsNull())
    video_tracks = web_stream.VideoTracks();

  const bool remote_video =
      video_tracks.size() && video_tracks[0].Source().Remote();

  if (remote_video && !base::CommandLine::ForCurrentProcess()->HasSwitch(
                          switches::kDisableRTCSmoothnessAlgorithm)) {
    base::AutoLock auto_lock(current_frame_lock_);
    rendering_frame_buffer_.reset(new media::VideoRendererAlgorithm(
        base::Bind(&WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks,
                   base::Unretained(this)),
        &media_log_));
  }

  // Just for logging purpose.
  std::string stream_id =
      web_stream.IsNull() ? std::string() : web_stream.Id().Utf8();
  const uint32_t hash_value = base::Hash(stream_id);
  serial_ = (hash_value << 1) | (remote_video ? 1 : 0);
}

WebMediaPlayerMSCompositor::~WebMediaPlayerMSCompositor() {
  if (submitter_) {
    video_frame_compositor_task_runner_->DeleteSoon(FROM_HERE,
                                                    std::move(submitter_));
  } else {
    DCHECK(!video_frame_provider_client_)
        << "Must call StopUsingProvider() before dtor!";
  }
}

void WebMediaPlayerMSCompositor::InitializeSubmitter() {
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
  submitter_->Initialize(this);
}

void WebMediaPlayerMSCompositor::UpdateSubmissionState(bool state) {
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
  submitter_->UpdateSubmissionState(state);
}

// TODO(https://crbug/879424): Rename, since it really doesn't enable
// submission. Do this along with the VideoFrameSubmitter refactor.
void WebMediaPlayerMSCompositor::EnableSubmission(
    const viz::SurfaceId& id,
    base::TimeTicks local_surface_id_allocation_time,
    media::VideoRotation rotation,
    bool force_submit,
    bool is_opaque,
    blink::WebFrameSinkDestroyedCallback frame_sink_destroyed_callback) {
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());

  // If we're switching to |submitter_| from some other client, then tell it.
  if (video_frame_provider_client_ &&
      video_frame_provider_client_ != submitter_.get()) {
    video_frame_provider_client_->StopUsingProvider();
  }

  submitter_->SetRotation(rotation);
  submitter_->SetForceSubmit(force_submit);
  submitter_->SetIsOpaque(is_opaque);
  submitter_->EnableSubmission(id, local_surface_id_allocation_time,
                               std::move(frame_sink_destroyed_callback));
  video_frame_provider_client_ = submitter_.get();

  if (!stopped_)
    video_frame_provider_client_->StartRendering();
}

void WebMediaPlayerMSCompositor::SetForceSubmit(bool force_submit) {
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
  submitter_->SetForceSubmit(force_submit);
}

gfx::Size WebMediaPlayerMSCompositor::GetCurrentSize() {
  DCHECK(thread_checker_.CalledOnValidThread());
  base::AutoLock auto_lock(current_frame_lock_);
  return current_frame_ ? current_frame_->natural_size() : gfx::Size();
}

base::TimeDelta WebMediaPlayerMSCompositor::GetCurrentTime() {
  DCHECK(thread_checker_.CalledOnValidThread());
  base::AutoLock auto_lock(current_frame_lock_);
  return current_frame_.get() ? current_frame_->timestamp() : base::TimeDelta();
}

size_t WebMediaPlayerMSCompositor::total_frame_count() {
  base::AutoLock auto_lock(current_frame_lock_);
  DVLOG(1) << __func__ << ", " << total_frame_count_;
  DCHECK(thread_checker_.CalledOnValidThread());
  return total_frame_count_;
}

size_t WebMediaPlayerMSCompositor::dropped_frame_count() {
  base::AutoLock auto_lock(current_frame_lock_);
  DVLOG(1) << __func__ << ", " << dropped_frame_count_;
  DCHECK(thread_checker_.CalledOnValidThread());
  return dropped_frame_count_;
}

void WebMediaPlayerMSCompositor::SetVideoFrameProviderClient(
    cc::VideoFrameProvider::Client* client) {
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
  if (video_frame_provider_client_)
    video_frame_provider_client_->StopUsingProvider();

  video_frame_provider_client_ = client;
  if (video_frame_provider_client_ && !stopped_)
    video_frame_provider_client_->StartRendering();
}

void WebMediaPlayerMSCompositor::EnqueueFrame(
    scoped_refptr<media::VideoFrame> frame) {
  DCHECK(io_task_runner_->BelongsToCurrentThread());
  base::AutoLock auto_lock(current_frame_lock_);
  TRACE_EVENT_INSTANT1("media", "WebMediaPlayerMSCompositor::EnqueueFrame",
                       TRACE_EVENT_SCOPE_THREAD, "Timestamp",
                       frame->timestamp().InMicroseconds());
  ++total_frame_count_;

  // With algorithm off, just let |current_frame_| hold the incoming |frame|.
  if (!rendering_frame_buffer_) {
    RenderWithoutAlgorithm(std::move(frame));
    return;
  }

  // This is a signal frame saying that the stream is stopped.
  bool end_of_stream = false;
  if (frame->metadata()->GetBoolean(media::VideoFrameMetadata::END_OF_STREAM,
                                    &end_of_stream) &&
      end_of_stream) {
    rendering_frame_buffer_.reset();
    RenderWithoutAlgorithm(std::move(frame));
    return;
  }

  // If we detect a bad frame without |render_time|, we switch off algorithm,
  // because without |render_time|, algorithm cannot work.
  // In general, this should not happen.
  base::TimeTicks render_time;
  if (!frame->metadata()->GetTimeTicks(
          media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
    DLOG(WARNING)
        << "Incoming VideoFrames have no REFERENCE_TIME, switching off super "
           "sophisticated rendering algorithm";
    rendering_frame_buffer_.reset();
    RenderWithoutAlgorithm(std::move(frame));
    return;
  }

  // The code below handles the case where UpdateCurrentFrame() callbacks stop.
  // These callbacks can stop when the tab is hidden or the page area containing
  // the video frame is scrolled out of view.
  // Since some hardware decoders only have a limited number of output frames,
  // we must aggressively release frames in this case.
  const base::TimeTicks now = base::TimeTicks::Now();
  if (now > last_deadline_max_) {
    // Note: the frame in |rendering_frame_buffer_| with lowest index is the
    // same as |current_frame_|. Function SetCurrentFrame() handles whether
    // to increase |dropped_frame_count_| for that frame, so here we should
    // increase |dropped_frame_count_| by the count of all other frames.
    dropped_frame_count_ += rendering_frame_buffer_->frames_queued() - 1;
    rendering_frame_buffer_->Reset();
    timestamps_to_clock_times_.clear();
    RenderWithoutAlgorithm(std::move(frame));
  }

  timestamps_to_clock_times_[frame->timestamp()] = render_time;
  rendering_frame_buffer_->EnqueueFrame(frame);
}

bool WebMediaPlayerMSCompositor::UpdateCurrentFrame(
    base::TimeTicks deadline_min,
    base::TimeTicks deadline_max) {
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());

  TRACE_EVENT_BEGIN2("media", "UpdateCurrentFrame", "Actual Render Begin",
                     deadline_min.ToInternalValue(), "Actual Render End",
                     deadline_max.ToInternalValue());
  if (stopped_)
    return false;

  base::AutoLock auto_lock(current_frame_lock_);

  if (rendering_frame_buffer_)
    RenderUsingAlgorithm(deadline_min, deadline_max);

  {
    bool tracing_or_dcheck_enabled = false;
    TRACE_EVENT_CATEGORY_GROUP_ENABLED("media", &tracing_or_dcheck_enabled);
#if DCHECK_IS_ON()
    tracing_or_dcheck_enabled = true;
#endif  // DCHECK_IS_ON()
    if (tracing_or_dcheck_enabled) {
      base::TimeTicks render_time;
      if (!current_frame_->metadata()->GetTimeTicks(
              media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
        DCHECK(!rendering_frame_buffer_)
            << "VideoFrames need REFERENCE_TIME to use "
               "sophisticated video rendering algorithm.";
      }
      TRACE_EVENT_END2("media", "UpdateCurrentFrame", "Ideal Render Instant",
                       render_time.ToInternalValue(), "Serial", serial_);
    }
  }

  return !current_frame_rendered_;
}

bool WebMediaPlayerMSCompositor::HasCurrentFrame() {
  base::AutoLock auto_lock(current_frame_lock_);
  return current_frame_.get() != nullptr;
}

scoped_refptr<media::VideoFrame> WebMediaPlayerMSCompositor::GetCurrentFrame() {
  DVLOG(3) << __func__;
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
  base::AutoLock auto_lock(current_frame_lock_);
  TRACE_EVENT_INSTANT1("media", "WebMediaPlayerMSCompositor::GetCurrentFrame",
                       TRACE_EVENT_SCOPE_THREAD, "Timestamp",
                       current_frame_->timestamp().InMicroseconds());
  if (!render_started_)
    return nullptr;

  return current_frame_;
}

void WebMediaPlayerMSCompositor::PutCurrentFrame() {
  DVLOG(3) << __func__;
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
  current_frame_rendered_ = true;
}

scoped_refptr<media::VideoFrame>
WebMediaPlayerMSCompositor::GetCurrentFrameWithoutUpdatingStatistics() {
  DVLOG(3) << __func__;
  base::AutoLock auto_lock(current_frame_lock_);
  if (!render_started_)
    return nullptr;

  return current_frame_;
}

void WebMediaPlayerMSCompositor::StartRendering() {
  DCHECK(thread_checker_.CalledOnValidThread());
  {
    base::AutoLock auto_lock(current_frame_lock_);
    render_started_ = true;
  }
  video_frame_compositor_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&WebMediaPlayerMSCompositor::StartRenderingInternal,
                     this));
}

void WebMediaPlayerMSCompositor::StopRendering() {
  DCHECK(thread_checker_.CalledOnValidThread());
  video_frame_compositor_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&WebMediaPlayerMSCompositor::StopRenderingInternal, this));
}

void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopy() {
  DCHECK(thread_checker_.CalledOnValidThread());
  // Bounce this call off of IO thread to since there might still be frames
  // passed on IO thread.
  io_task_runner_->PostTask(
      FROM_HERE,
      media::BindToCurrentLoop(base::Bind(
          &WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopyInternal,
          this)));
}

void WebMediaPlayerMSCompositor::StopUsingProvider() {
  DCHECK(thread_checker_.CalledOnValidThread());
  video_frame_compositor_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&WebMediaPlayerMSCompositor::StopUsingProviderInternal,
                     this));
}

bool WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks(
    const std::vector<base::TimeDelta>& timestamps,
    std::vector<base::TimeTicks>* wall_clock_times) {
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread() ||
         thread_checker_.CalledOnValidThread() ||
         io_task_runner_->BelongsToCurrentThread());
  for (const base::TimeDelta& timestamp : timestamps) {
    DCHECK(timestamps_to_clock_times_.count(timestamp));
    wall_clock_times->push_back(timestamps_to_clock_times_[timestamp]);
  }
  return true;
}

void WebMediaPlayerMSCompositor::RenderUsingAlgorithm(
    base::TimeTicks deadline_min,
    base::TimeTicks deadline_max) {
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
  current_frame_lock_.AssertAcquired();
  last_deadline_max_ = deadline_max;
  last_render_length_ = deadline_max - deadline_min;

  size_t frames_dropped = 0;
  scoped_refptr<media::VideoFrame> frame = rendering_frame_buffer_->Render(
      deadline_min, deadline_max, &frames_dropped);
  dropped_frame_count_ += frames_dropped;

  // There is a chance we get a null |frame| here:
  // When the player gets paused, we reset |rendering_frame_buffer_|;
  // When the player gets resumed, it is possible that render gets called before
  // we get a new frame. In that case continue to render the |current_frame_|.
  if (!frame || frame == current_frame_)
    return;

  SetCurrentFrame(std::move(frame));

  const auto& end = timestamps_to_clock_times_.end();
  const auto& begin = timestamps_to_clock_times_.begin();
  auto iterator = begin;
  while (iterator != end && iterator->first < frame->timestamp())
    ++iterator;
  timestamps_to_clock_times_.erase(begin, iterator);
}

void WebMediaPlayerMSCompositor::RenderWithoutAlgorithm(
    const scoped_refptr<media::VideoFrame>& frame) {
  DCHECK(io_task_runner_->BelongsToCurrentThread());
  video_frame_compositor_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(
          &WebMediaPlayerMSCompositor::RenderWithoutAlgorithmOnCompositor, this,
          frame));
}

void WebMediaPlayerMSCompositor::RenderWithoutAlgorithmOnCompositor(
    const scoped_refptr<media::VideoFrame>& frame) {
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
  {
    base::AutoLock auto_lock(current_frame_lock_);
    SetCurrentFrame(frame);
  }
  if (video_frame_provider_client_)
    video_frame_provider_client_->DidReceiveFrame();
}

void WebMediaPlayerMSCompositor::SetCurrentFrame(
    const scoped_refptr<media::VideoFrame>& frame) {
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
  current_frame_lock_.AssertAcquired();
  TRACE_EVENT_INSTANT1("media", "WebMediaPlayerMSCompositor::SetCurrentFrame",
                       TRACE_EVENT_SCOPE_THREAD, "Timestamp",
                       frame->timestamp().InMicroseconds());

  if (!current_frame_rendered_)
    ++dropped_frame_count_;
  current_frame_rendered_ = false;

  scoped_refptr<media::VideoFrame> old_frame = std::move(current_frame_);
  current_frame_ = frame;
  CheckForFrameChanges(old_frame, frame);
}

void WebMediaPlayerMSCompositor::CheckForFrameChanges(
    const scoped_refptr<media::VideoFrame>& old_frame,
    const scoped_refptr<media::VideoFrame>& new_frame) {
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());

  const bool new_frame_is_opaque = media::IsOpaque(new_frame->format());
  media::VideoRotation new_frame_video_rotation = media::VIDEO_ROTATION_0;
  ignore_result(new_frame->metadata()->GetRotation(
      media::VideoFrameMetadata::ROTATION, &new_frame_video_rotation));
  if (!old_frame) {
    main_task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&WebMediaPlayerMS::OnFirstFrameReceived, player_,
                       new_frame_video_rotation, new_frame_is_opaque));
    return;
  }
  media::VideoRotation old_frame_video_rotation = media::VIDEO_ROTATION_0;
  ignore_result(old_frame->metadata()->GetRotation(
      media::VideoFrameMetadata::ROTATION, &old_frame_video_rotation));
  if (new_frame_video_rotation != old_frame_video_rotation) {
    main_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&WebMediaPlayerMS::OnRotationChanged, player_,
                                  new_frame_video_rotation));
    if (submitter_)
      submitter_->SetRotation(new_frame_video_rotation);
  }
  if (new_frame_is_opaque != media::IsOpaque(old_frame->format())) {
    main_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&WebMediaPlayerMS::OnOpacityChanged, player_,
                                  new_frame_is_opaque));
    if (submitter_)
      submitter_->SetIsOpaque(new_frame_is_opaque);
  }
  if (old_frame->natural_size() != new_frame->natural_size()) {
    main_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&WebMediaPlayerMS::TriggerResize, player_));
  }
  main_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&WebMediaPlayerMS::ResetCanvasCache, player_));
}

void WebMediaPlayerMSCompositor::StartRenderingInternal() {
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
  stopped_ = false;

  if (video_frame_provider_client_)
    video_frame_provider_client_->StartRendering();
}

void WebMediaPlayerMSCompositor::StopRenderingInternal() {
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
  stopped_ = true;

  // It is possible that the video gets paused and then resumed. We need to
  // reset VideoRendererAlgorithm, otherwise, VideoRendererAlgorithm will think
  // there is a very long frame in the queue and then make totally wrong
  // frame selection.
  {
    base::AutoLock auto_lock(current_frame_lock_);
    if (rendering_frame_buffer_)
      rendering_frame_buffer_->Reset();
  }

  if (video_frame_provider_client_)
    video_frame_provider_client_->StopRendering();
}

void WebMediaPlayerMSCompositor::StopUsingProviderInternal() {
  DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
  if (video_frame_provider_client_)
    video_frame_provider_client_->StopUsingProvider();
  video_frame_provider_client_ = nullptr;
}

void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopyInternal() {
  DCHECK(thread_checker_.CalledOnValidThread());
  scoped_refptr<media::VideoFrame> current_frame_ref;
  {
    base::AutoLock auto_lock(current_frame_lock_);
    if (!current_frame_ || !player_)
      return;
    current_frame_ref = current_frame_;
  }
  // Copy the frame so that rendering can show the last received frame.
  // The original frame must not be referenced when the player is paused since
  // there might be a finite number of available buffers. E.g, video that
  // originates from a video camera, HW decoded frames.
  scoped_refptr<media::VideoFrame> copied_frame =
      CopyFrame(current_frame_ref, player_->GetPaintCanvasVideoRenderer());
  // Copying frame can take time, so only set the copied frame if
  // |current_frame_| hasn't been changed.
  {
    base::AutoLock auto_lock(current_frame_lock_);
    if (current_frame_ == current_frame_ref)
      current_frame_ = std::move(copied_frame);
  }
}

void WebMediaPlayerMSCompositor::SetAlgorithmEnabledForTesting(
    bool algorithm_enabled) {
  if (!algorithm_enabled) {
    rendering_frame_buffer_.reset();
    return;
  }

  if (!rendering_frame_buffer_) {
    rendering_frame_buffer_.reset(new media::VideoRendererAlgorithm(
        base::Bind(&WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks,
                   base::Unretained(this)),
        &media_log_));
  }
}

}  // namespace content
