/*
 *  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/base/logging.h"
#include "webrtc/base/trace_event.h"
#include "webrtc/modules/video_coding/include/video_coding.h"
#include "webrtc/modules/video_coding/generic_decoder.h"
#include "webrtc/modules/video_coding/internal_defines.h"
#include "webrtc/system_wrappers/include/clock.h"

namespace webrtc {

VCMDecodedFrameCallback::VCMDecodedFrameCallback(VCMTiming& timing,
                                                 Clock* clock)
:
_critSect(CriticalSectionWrapper::CreateCriticalSection()),
_clock(clock),
_receiveCallback(NULL),
_timing(timing),
_timestampMap(kDecoderFrameMemoryLength),
_lastReceivedPictureID(0)
{
}

VCMDecodedFrameCallback::~VCMDecodedFrameCallback()
{
    delete _critSect;
}

void VCMDecodedFrameCallback::SetUserReceiveCallback(
    VCMReceiveCallback* receiveCallback)
{
    CriticalSectionScoped cs(_critSect);
    _receiveCallback = receiveCallback;
}

VCMReceiveCallback* VCMDecodedFrameCallback::UserReceiveCallback()
{
    CriticalSectionScoped cs(_critSect);
    return _receiveCallback;
}

int32_t VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage) {
  return Decoded(decodedImage, -1);
}

int32_t VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage,
                                         int64_t decode_time_ms) {
    TRACE_EVENT_INSTANT1("webrtc", "VCMDecodedFrameCallback::Decoded",
                         "timestamp", decodedImage.timestamp());
    // TODO(holmer): We should improve this so that we can handle multiple
    // callbacks from one call to Decode().
    VCMFrameInformation* frameInfo;
    VCMReceiveCallback* callback;
    {
        CriticalSectionScoped cs(_critSect);
        frameInfo = _timestampMap.Pop(decodedImage.timestamp());
        callback = _receiveCallback;
    }

    if (frameInfo == NULL) {
      LOG(LS_WARNING) << "Too many frames backed up in the decoder, dropping "
                         "this one.";
      return WEBRTC_VIDEO_CODEC_OK;
    }

    const int64_t now_ms = _clock->TimeInMilliseconds();
    if (decode_time_ms < 0) {
      decode_time_ms =
          static_cast<int32_t>(now_ms - frameInfo->decodeStartTimeMs);
    }
    _timing.StopDecodeTimer(
        decodedImage.timestamp(),
        decode_time_ms,
        now_ms,
        frameInfo->renderTimeMs);

    if (callback != NULL)
    {
        decodedImage.set_render_time_ms(frameInfo->renderTimeMs);
        decodedImage.set_rotation(frameInfo->rotation);
        callback->FrameToRender(decodedImage);
    }
    return WEBRTC_VIDEO_CODEC_OK;
}

int32_t
VCMDecodedFrameCallback::ReceivedDecodedReferenceFrame(
    const uint64_t pictureId)
{
    CriticalSectionScoped cs(_critSect);
    if (_receiveCallback != NULL)
    {
        return _receiveCallback->ReceivedDecodedReferenceFrame(pictureId);
    }
    return -1;
}

int32_t
VCMDecodedFrameCallback::ReceivedDecodedFrame(const uint64_t pictureId)
{
    _lastReceivedPictureID = pictureId;
    return 0;
}

uint64_t VCMDecodedFrameCallback::LastReceivedPictureID() const
{
    return _lastReceivedPictureID;
}

void VCMDecodedFrameCallback::Map(uint32_t timestamp,
                                  VCMFrameInformation* frameInfo) {
  CriticalSectionScoped cs(_critSect);
  _timestampMap.Add(timestamp, frameInfo);
}

int32_t VCMDecodedFrameCallback::Pop(uint32_t timestamp)
{
    CriticalSectionScoped cs(_critSect);
    if (_timestampMap.Pop(timestamp) == NULL)
    {
        return VCM_GENERAL_ERROR;
    }
    return VCM_OK;
}

VCMGenericDecoder::VCMGenericDecoder(VideoDecoder* decoder, bool isExternal)
    : _callback(NULL),
      _frameInfos(),
      _nextFrameInfoIdx(0),
      _decoder(decoder),
      _codecType(kVideoCodecUnknown),
      _isExternal(isExternal),
      _keyFrameDecoded(false) {}

VCMGenericDecoder::~VCMGenericDecoder() {}

int32_t VCMGenericDecoder::InitDecode(const VideoCodec* settings,
                                      int32_t numberOfCores)
{
    TRACE_EVENT0("webrtc", "VCMGenericDecoder::InitDecode");
    _codecType = settings->codecType;

    return _decoder->InitDecode(settings, numberOfCores);
}

int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame, int64_t nowMs) {
    TRACE_EVENT1("webrtc", "VCMGenericDecoder::Decode", "timestamp",
                 frame.EncodedImage()._timeStamp);
    _frameInfos[_nextFrameInfoIdx].decodeStartTimeMs = nowMs;
    _frameInfos[_nextFrameInfoIdx].renderTimeMs = frame.RenderTimeMs();
    _frameInfos[_nextFrameInfoIdx].rotation = frame.rotation();
    _callback->Map(frame.TimeStamp(), &_frameInfos[_nextFrameInfoIdx]);

    _nextFrameInfoIdx = (_nextFrameInfoIdx + 1) % kDecoderFrameMemoryLength;
    int32_t ret = _decoder->Decode(frame.EncodedImage(), frame.MissingFrame(),
                                   frame.FragmentationHeader(),
                                   frame.CodecSpecific(), frame.RenderTimeMs());

    if (ret < WEBRTC_VIDEO_CODEC_OK)
    {
        LOG(LS_WARNING) << "Failed to decode frame with timestamp "
                        << frame.TimeStamp() << ", error code: " << ret;
        _callback->Pop(frame.TimeStamp());
        return ret;
    }
    else if (ret == WEBRTC_VIDEO_CODEC_NO_OUTPUT ||
             ret == WEBRTC_VIDEO_CODEC_REQUEST_SLI)
    {
        // No output
        _callback->Pop(frame.TimeStamp());
    }
    return ret;
}

int32_t VCMGenericDecoder::Release() {
  return _decoder->Release();
}

int32_t VCMGenericDecoder::Reset() {
  return _decoder->Reset();
}

int32_t VCMGenericDecoder::RegisterDecodeCompleteCallback(
    VCMDecodedFrameCallback* callback) {
  _callback = callback;
  return _decoder->RegisterDecodeCompleteCallback(callback);
}

bool VCMGenericDecoder::External() const {
  return _isExternal;
}

}  // namespace
