/*
 *  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 "webrtc/common_video/include/incoming_video_stream.h"

#include "webrtc/base/timeutils.h"
#include "webrtc/common_video/video_render_frames.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/event_wrapper.h"

namespace webrtc {

IncomingVideoStream::IncomingVideoStream(
    int32_t delay_ms,
    rtc::VideoSinkInterface<VideoFrame>* callback)
    : incoming_render_thread_(&IncomingVideoStreamThreadFun,
                              this,
                              "IncomingVideoStreamThread"),
      deliver_buffer_event_(EventTimerWrapper::Create()),
      external_callback_(callback),
      render_buffers_(new VideoRenderFrames(delay_ms)) {
  RTC_DCHECK(external_callback_);

  render_thread_checker_.DetachFromThread();
  decoder_thread_checker_.DetachFromThread();

  incoming_render_thread_.Start();
  incoming_render_thread_.SetPriority(rtc::kRealtimePriority);
  deliver_buffer_event_->StartTimer(false, kEventStartupTimeMs);
}

IncomingVideoStream::~IncomingVideoStream() {
  RTC_DCHECK(main_thread_checker_.CalledOnValidThread());

  {
    rtc::CritScope cs(&buffer_critsect_);
    render_buffers_.reset();
  }

  deliver_buffer_event_->Set();
  incoming_render_thread_.Stop();
  deliver_buffer_event_->StopTimer();
}

void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) {
  RTC_DCHECK_RUN_ON(&decoder_thread_checker_);

  // Hand over or insert frame.
  rtc::CritScope csB(&buffer_critsect_);
  if (render_buffers_->AddFrame(video_frame) == 1) {
    deliver_buffer_event_->Set();
  }
}

bool IncomingVideoStream::IncomingVideoStreamThreadFun(void* obj) {
  return static_cast<IncomingVideoStream*>(obj)->IncomingVideoStreamProcess();
}

bool IncomingVideoStream::IncomingVideoStreamProcess() {
  RTC_DCHECK_RUN_ON(&render_thread_checker_);

  if (kEventError != deliver_buffer_event_->Wait(kEventMaxWaitTimeMs)) {
    // Get a new frame to render and the time for the frame after this one.
    rtc::Optional<VideoFrame> frame_to_render;
    uint32_t wait_time;
    {
      rtc::CritScope cs(&buffer_critsect_);
      if (!render_buffers_.get()) {
        // Terminating
        return false;
      }
      frame_to_render = render_buffers_->FrameToRender();
      wait_time = render_buffers_->TimeToNextFrameRelease();
    }

    // Set timer for next frame to render.
    if (wait_time > kEventMaxWaitTimeMs) {
      wait_time = kEventMaxWaitTimeMs;
    }

    deliver_buffer_event_->StartTimer(false, wait_time);

    if (frame_to_render) {
      external_callback_->OnFrame(*frame_to_render);
    }
  }
  return true;
}

}  // namespace webrtc
