/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "video/render/incoming_video_stream.h"

#include <cstdint>
#include <memory>
#include <optional>
#include <utility>

#include "api/environment/environment.h"
#include "api/sequence_checker.h"
#include "api/task_queue/task_queue_factory.h"
#include "api/units/time_delta.h"
#include "api/video/video_frame.h"
#include "api/video/video_sink_interface.h"
#include "rtc_base/checks.h"
#include "rtc_base/race_checker.h"
#include "rtc_base/trace_event.h"
#include "video/render/video_render_frames.h"

namespace webrtc {

IncomingVideoStream::IncomingVideoStream(
    const Environment& env,
    int32_t delay_ms,
    VideoSinkInterface<VideoFrame>* callback)
    : render_buffers_(env, delay_ms),
      callback_(callback),
      incoming_render_queue_(env.task_queue_factory().CreateTaskQueue(
          "IncomingVideoStreamQueue",
          env.field_trials().IsEnabled("WebRTC-MediaTaskQueuePriorities")
              ? TaskQueueFactory::Priority::kVideo
              : TaskQueueFactory::Priority::kHigh)) {}

IncomingVideoStream::~IncomingVideoStream() {
  RTC_DCHECK(main_thread_checker_.IsCurrent());
  // The queue must be destroyed before its pointer is invalidated to avoid race
  // between destructor and posting task to the task queue from itself.
  // std::unique_ptr destructor does the same two operations in reverse order as
  // it doesn't expect member would be used after its destruction has started.
  incoming_render_queue_.get_deleter()(incoming_render_queue_.get());
  incoming_render_queue_.release();
}

void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) {
  TRACE_EVENT0("webrtc", "IncomingVideoStream::OnFrame");
  RTC_CHECK_RUNS_SERIALIZED(&decoder_race_checker_);
  RTC_DCHECK(!incoming_render_queue_->IsCurrent());
  // TODO(srte): Using video_frame = std::move(video_frame) would move the frame
  // into the lambda instead of copying it, but it doesn't work unless we change
  // OnFrame to take its frame argument by value instead of const reference.
  incoming_render_queue_->PostTask([this, video_frame = video_frame]() mutable {
    RTC_DCHECK_RUN_ON(incoming_render_queue_.get());
    if (render_buffers_.AddFrame(std::move(video_frame)) == 1)
      Dequeue();
  });
}

void IncomingVideoStream::Dequeue() {
  TRACE_EVENT0("webrtc", "IncomingVideoStream::Dequeue");
  RTC_DCHECK_RUN_ON(incoming_render_queue_.get());
  std::optional<VideoFrame> frame_to_render = render_buffers_.FrameToRender();
  if (frame_to_render)
    callback_->OnFrame(*frame_to_render);

  if (render_buffers_.HasPendingFrames()) {
    uint32_t wait_time = render_buffers_.TimeToNextFrameRelease();
    incoming_render_queue_->PostDelayedHighPrecisionTask(
        [this]() { Dequeue(); }, TimeDelta::Millis(wait_time));
  }
}

}  // namespace webrtc
