/*
 *  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/modules/video_render/video_render_frames.h"

#include <assert.h>

#include "webrtc/common_video/interface/texture_video_frame.h"
#include "webrtc/modules/interface/module_common_types.h"
#include "webrtc/system_wrappers/interface/tick_util.h"
#include "webrtc/system_wrappers/interface/trace.h"

namespace webrtc {

const uint32_t KEventMaxWaitTimeMs = 200;
const uint32_t kMinRenderDelayMs = 10;
const uint32_t kMaxRenderDelayMs= 500;

VideoRenderFrames::VideoRenderFrames()
    : render_delay_ms_(10) {
}

VideoRenderFrames::~VideoRenderFrames() {
  ReleaseAllFrames();
}

int32_t VideoRenderFrames::AddFrame(I420VideoFrame* new_frame) {
  const int64_t time_now = TickTime::MillisecondTimestamp();

  // Drop old frames only when there are other frames in the queue, otherwise, a
  // really slow system never renders any frames.
  if (!incoming_frames_.empty() &&
      new_frame->render_time_ms() + KOldRenderTimestampMS < time_now) {
    WEBRTC_TRACE(kTraceWarning,
                 kTraceVideoRenderer,
                 -1,
                 "%s: too old frame, timestamp=%u.",
                 __FUNCTION__,
                 new_frame->timestamp());
    return -1;
  }

  if (new_frame->render_time_ms() > time_now + KFutureRenderTimestampMS) {
    WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, -1,
                 "%s: frame too long into the future, timestamp=%u.",
                 __FUNCTION__, new_frame->timestamp());
    return -1;
  }

  if (new_frame->native_handle() != NULL) {
    incoming_frames_.push_back(new_frame->CloneFrame());
    return static_cast<int32_t>(incoming_frames_.size());
  }

  // Get an empty frame
  I420VideoFrame* frame_to_add = NULL;
  if (!empty_frames_.empty()) {
    frame_to_add = empty_frames_.front();
    empty_frames_.pop_front();
  }
  if (!frame_to_add) {
    if (empty_frames_.size() + incoming_frames_.size() >
        KMaxNumberOfFrames) {
      // Already allocated too many frames.
      WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer,
                   -1, "%s: too many frames, timestamp=%u, limit=%d",
                   __FUNCTION__, new_frame->timestamp(), KMaxNumberOfFrames);
      return -1;
    }

    // Allocate new memory.
    WEBRTC_TRACE(kTraceMemory, kTraceVideoRenderer, -1,
                 "%s: allocating buffer %d", __FUNCTION__,
                 empty_frames_.size() + incoming_frames_.size());

    frame_to_add = new I420VideoFrame();
    if (!frame_to_add) {
      WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, -1,
                   "%s: could not create new frame for", __FUNCTION__);
      return -1;
    }
  }

  frame_to_add->CreateEmptyFrame(new_frame->width(), new_frame->height(),
                                 new_frame->stride(kYPlane),
                                 new_frame->stride(kUPlane),
                                 new_frame->stride(kVPlane));
  // TODO(mflodman) Change this!
  // Remove const ness. Copying will be costly.
  frame_to_add->SwapFrame(new_frame);
  incoming_frames_.push_back(frame_to_add);

  return static_cast<int32_t>(incoming_frames_.size());
}

I420VideoFrame* VideoRenderFrames::FrameToRender() {
  I420VideoFrame* render_frame = NULL;
  FrameList::iterator iter = incoming_frames_.begin();
  while(iter != incoming_frames_.end()) {
    I420VideoFrame* oldest_frame_in_list = *iter;
    if (oldest_frame_in_list->render_time_ms() <=
        TickTime::MillisecondTimestamp() + render_delay_ms_) {
      // This is the oldest one so far and it's OK to render.
      if (render_frame) {
        // This one is older than the newly found frame, remove this one.
        ReturnFrame(render_frame);
      }
      render_frame = oldest_frame_in_list;
      iter = incoming_frames_.erase(iter);
    } else {
      // We can't release this one yet, we're done here.
      break;
    }
  }
  return render_frame;
}

int32_t VideoRenderFrames::ReturnFrame(I420VideoFrame* old_frame) {
  // No need to reuse texture frames because they do not allocate memory.
  if (old_frame->native_handle() == NULL) {
    old_frame->set_timestamp(0);
    old_frame->set_render_time_ms(0);
    empty_frames_.push_back(old_frame);
  } else {
    delete old_frame;
  }
  return 0;
}

int32_t VideoRenderFrames::ReleaseAllFrames() {
  for (FrameList::iterator iter = incoming_frames_.begin();
       iter != incoming_frames_.end(); ++iter) {
      delete *iter;
  }
  incoming_frames_.clear();

  for (FrameList::iterator iter = empty_frames_.begin();
       iter != empty_frames_.end(); ++iter) {
      delete *iter;
  }
  empty_frames_.clear();
  return 0;
}

uint32_t VideoRenderFrames::TimeToNextFrameRelease() {
  if (incoming_frames_.empty()) {
    return KEventMaxWaitTimeMs;
  }
  I420VideoFrame* oldest_frame = incoming_frames_.front();
  int64_t time_to_release = oldest_frame->render_time_ms() - render_delay_ms_
      - TickTime::MillisecondTimestamp();
  if (time_to_release < 0) {
    time_to_release = 0;
  }
  return static_cast<uint32_t>(time_to_release);
}

int32_t VideoRenderFrames::SetRenderDelay(
    const uint32_t render_delay) {
  if (render_delay < kMinRenderDelayMs ||
      render_delay > kMaxRenderDelayMs) {
    WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer,
                 -1, "%s(%d): Invalid argument.", __FUNCTION__,
                 render_delay);
    return -1;
  }

  render_delay_ms_ = render_delay;
  return 0;
}

}  // namespace webrtc
