/*
 *  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_coding/main/interface/video_coding.h"
#include "webrtc/modules/video_coding/main/source/generic_decoder.h"
#include "webrtc/modules/video_coding/main/source/internal_defines.h"
#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/logging.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) {
    // 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 = static_cast<VCMFrameInformation*>(
            _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;
    }

    _timing.StopDecodeTimer(
        decodedImage.timestamp(),
        frameInfo->decodeStartTimeMs,
        _clock->TimeInMilliseconds(),
        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;
}

int32_t VCMDecodedFrameCallback::Map(uint32_t timestamp, VCMFrameInformation* frameInfo)
{
    CriticalSectionScoped cs(_critSect);
    return _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)
{
    _codecType = settings->codecType;

    return _decoder.InitDecode(settings, numberOfCores);
}

int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame,
                                        int64_t nowMs)
{
    _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
