// Copyright 2020 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 "third_party/blink/renderer/modules/webcodecs/video_track_reader.h"

#include "base/threading/thread_task_runner_handle.h"
#include "media/base/video_frame.h"
#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_video_track.h"
#include "third_party/blink/renderer/modules/webcodecs/video_frame.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"

namespace blink {

VideoTrackReader::VideoTrackReader(ScriptState* script_state,
                                   MediaStreamTrack* track)
    : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)),
      started_(false),
      real_time_media_task_runner_(
          ExecutionContext::From(script_state)
              ->GetTaskRunner(TaskType::kInternalMediaRealTime)),
      track_(track) {
  UseCounter::Count(ExecutionContext::From(script_state),
                    WebFeature::kWebCodecs);

  ExecutionContext::From(script_state)
      ->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
          mojom::blink::ConsoleMessageSource::kDeprecation,
          mojom::blink::ConsoleMessageLevel::kWarning,
          "VideoTrackReader is deprecated; use MediaStreamTrackProcessor "
          "instead."));
}

void VideoTrackReader::start(V8VideoFrameOutputCallback* callback,
                             ExceptionState& exception_state) {
  DCHECK(real_time_media_task_runner_->BelongsToCurrentThread());

  if (started_) {
    exception_state.ThrowDOMException(
        DOMExceptionCode::kInvalidStateError,
        "The VideoTrackReader has already been started.");
    return;
  }

  started_ = true;
  callback_ = callback;
  ConnectToTrack(WebMediaStreamTrack(track_->Component()),
                 ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
                     &VideoTrackReader::OnFrameFromVideoTrack,
                     WrapCrossThreadPersistent(this))),
                 false /* is_sink_secure */);
}

void VideoTrackReader::stop(ExceptionState& exception_state) {
  DCHECK(real_time_media_task_runner_->BelongsToCurrentThread());

  if (!started_) {
    exception_state.ThrowDOMException(
        DOMExceptionCode::kInvalidStateError,
        "The VideoTrackReader has already been stopped.");
    return;
  }

  StopInternal();
}

void VideoTrackReader::StopInternal() {
  DCHECK(real_time_media_task_runner_->BelongsToCurrentThread());
  started_ = false;
  callback_ = nullptr;
  DisconnectFromTrack();
}

void VideoTrackReader::OnFrameFromVideoTrack(
    scoped_refptr<media::VideoFrame> media_frame,
    std::vector<scoped_refptr<media::VideoFrame>> scaled_media_frames,
    base::TimeTicks estimated_capture_time) {
  // The value of estimated_capture_time here seems to almost always be the
  // system clock and most implementations of this callback ignore it.
  // So, we will also ignore it.
  DCHECK(media_frame);
  PostCrossThreadTask(
      *real_time_media_task_runner_.get(), FROM_HERE,
      CrossThreadBindOnce(&VideoTrackReader::ExecuteCallbackOnMainThread,
                          WrapCrossThreadPersistent(this),
                          std::move(media_frame),
                          std::move(scaled_media_frames)));
}

void VideoTrackReader::ExecuteCallbackOnMainThread(
    scoped_refptr<media::VideoFrame> media_frame,
    std::vector<scoped_refptr<media::VideoFrame>> /*scaled_media_frames*/) {
  DCHECK(real_time_media_task_runner_->BelongsToCurrentThread());

  if (!callback_) {
    // We may have already been stopped.
    return;
  }

  // If |track_|'s constraints changed (e.g. the resolution changed from a call
  // to MediaStreamTrack.applyConstraints() in JS), this |media_frame| might
  // still have the old constraints, due to the thread hop.
  // We may want to invalidate |media_frames| when constraints change, but it's
  // unclear whether this is a problem for now.

  auto* context = GetExecutionContext();
  if (!context)
    return;

  // Scaled media frames are currently ignored.
  callback_->InvokeAndReportException(
      nullptr,
      MakeGarbageCollected<VideoFrame>(std::move(media_frame), context));
}

void VideoTrackReader::OnReadyStateChanged(
    WebMediaStreamSource::ReadyState state) {
  if (state == WebMediaStreamSource::kReadyStateEnded)
    StopInternal();
}

VideoTrackReader* VideoTrackReader::Create(ScriptState* script_state,
                                           MediaStreamTrack* track,
                                           ExceptionState& exception_state) {
  if (track->kind() != "video") {
    exception_state.ThrowTypeError(
        "Can only read video frames from video tracks.");
    return nullptr;
  }

  if (!script_state->ContextIsValid()) {  // when the context is detached
    exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
                                      "The context has been destroyed");

    return nullptr;
  }

  return MakeGarbageCollected<VideoTrackReader>(script_state, track);
}

void VideoTrackReader::Trace(Visitor* visitor) const {
  visitor->Trace(track_);
  visitor->Trace(callback_);
  ScriptWrappable::Trace(visitor);
  ExecutionContextLifecycleObserver::Trace(visitor);
}

}  // namespace blink
