/*
 *  Copyright (c) 2011 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 "codec_database.h"
#include "../../../../engine_configurations.h"
#include "internal_defines.h"
#include "trace.h"

#if defined(_WIN32)
    // VS 2005: Don't warn for default initialized arrays. See help for more info.
    // Don't warn for strncpy being unsecure.
    // switch statement contains 'default' but no 'case' labels
#pragma warning(disable:4351; disable:4996; disable:4065)
#endif

// Supported codecs
#ifdef  VIDEOCODEC_VP8
    #include "vp8.h"
#endif
#ifdef  VIDEOCODEC_I420
    #include "i420.h"
#endif

namespace webrtc
{

VCMDecoderMapItem::VCMDecoderMapItem(VideoCodec* settings,
                                     WebRtc_UWord32 numberOfCores,
                                     bool requireKeyFrame)
:
_settings(settings),
_numberOfCores(numberOfCores),
_requireKeyFrame(requireKeyFrame)
{
}

VCMExtDecoderMapItem::VCMExtDecoderMapItem(VideoDecoder* externalDecoderInstance,
                                           WebRtc_UWord8 payloadType,
                                           bool internalRenderTiming)
:
_payloadType(payloadType),
_externalDecoderInstance(externalDecoderInstance),
_internalRenderTiming(internalRenderTiming)
{
}

VCMCodecDataBase::VCMCodecDataBase(WebRtc_Word32 id):
_id(id),
_numberOfCores(0),
_maxPayloadSize(kDefaultPayloadSize),
_periodicKeyFrames(false),
_currentEncIsExternal(false),
_sendCodec(),
_receiveCodec(),
_externalPayloadType(0),
_externalEncoder(NULL),
_internalSource(false),
_ptrEncoder(NULL),
_ptrDecoder(NULL),
_currentDecIsExternal(false),
_decMap(),
_decExternalMap()
{
    //
}

VCMCodecDataBase::~VCMCodecDataBase()
{
    Reset();
}

WebRtc_Word32
VCMCodecDataBase::Version(WebRtc_Word8* version,
                                WebRtc_UWord32& remainingBufferInBytes,
                                WebRtc_UWord32& position) const
{
    VCMGenericEncoder* encoder = NULL;
    VideoCodec settings;
    WebRtc_Word32 ret;
    for (int i = 0; i < VCMCodecDataBase::NumberOfCodecs(); i++)
    {
        ret = VCMCodecDataBase::Codec(i, &settings);
        if (ret < 0)
        {
            return ret;
        }
        encoder = CreateEncoder(settings.codecType);
        if (encoder == NULL)
        {
            return VCM_MEMORY;
        }
        ret = encoder->_encoder.Version(&version[position], remainingBufferInBytes);
        if (ret < 0)
        {
            return ret;
        }
        remainingBufferInBytes -= ret;
        position += ret;
        delete &encoder->_encoder;
        delete encoder;
    }
    return VCM_OK;
}

WebRtc_Word32
VCMCodecDataBase::Reset()
{
    WebRtc_Word32 ret = ResetReceiver();
    if (ret < 0)
    {
        return ret;
    }
    ret = ResetSender();
    if (ret < 0)
    {
        return ret;
    }
   return VCM_OK;
}

WebRtc_Word32
VCMCodecDataBase::ResetSender()
{
    DeleteEncoder();
    _periodicKeyFrames = false;
    return VCM_OK;
}

VCMGenericEncoder*
VCMCodecDataBase::CreateEncoder(VideoCodecType type) const
{
    switch(type)
    {
#ifdef  VIDEOCODEC_VP8
        case kVideoCodecVP8:
            return new VCMGenericEncoder(*(new VP8Encoder));
        break;
#endif
#ifdef VIDEOCODEC_I420
        case kVideoCodecI420:
            return new VCMGenericEncoder(*(new I420Encoder));
            break;
#endif
        default:
        return NULL;
        break;
    }
}

void
VCMCodecDataBase::DeleteEncoder()
{
    if (_ptrEncoder)
    {
        _ptrEncoder->Release();
        if (!_currentEncIsExternal)
        {
            delete &_ptrEncoder->_encoder;
        }
        delete _ptrEncoder;
        _ptrEncoder = NULL;
    }
}

WebRtc_UWord8
VCMCodecDataBase::NumberOfCodecs()
{
    return VCM_NUM_VIDEO_CODECS_AVAILABLE;
}

WebRtc_Word32
VCMCodecDataBase::Codec(WebRtc_UWord8 listId, VideoCodec *settings)
{
    if (settings == NULL)
    {
        return VCM_PARAMETER_ERROR;
    }

    if (listId >= VCM_NUM_VIDEO_CODECS_AVAILABLE)
    {
        return VCM_PARAMETER_ERROR;
    }
    memset(settings, 0, sizeof(VideoCodec));
    switch (listId)
    {
#ifdef VIDEOCODEC_VP8
    case VCM_VP8_IDX:
        {
            strncpy(settings->plName, "VP8", 3);
            settings->codecType = kVideoCodecVP8;
            // 96 to 127 dynamic payload types for video codecs
            settings->plType = VCM_VP8_PAYLOAD_TYPE;
            settings->startBitrate = 100;
            settings->minBitrate = VCM_MIN_BITRATE;
            settings->maxBitrate = 0;
            settings->maxFramerate = VCM_DEFAULT_FRAME_RATE;
            settings->width = VCM_DEFAULT_CODEC_WIDTH;
            settings->height = VCM_DEFAULT_CODEC_HEIGHT;
            break;
        }
#endif
#ifdef VIDEOCODEC_I420
    case VCM_I420_IDX:
        {
            strncpy(settings->plName, "I420", 4);
            settings->codecType = kVideoCodecI420;
            // 96 to 127 dynamic payload types for video codecs
            settings->plType = VCM_I420_PAYLOAD_TYPE;
            // Bitrate needed for this size and framerate
            settings->startBitrate = 3*VCM_DEFAULT_CODEC_WIDTH*
                                       VCM_DEFAULT_CODEC_HEIGHT*8*
                                       VCM_DEFAULT_FRAME_RATE/1000/2;
            settings->maxBitrate = settings->startBitrate;
            settings->maxFramerate = VCM_DEFAULT_FRAME_RATE;
            settings->width = VCM_DEFAULT_CODEC_WIDTH;
            settings->height = VCM_DEFAULT_CODEC_HEIGHT;
            settings->minBitrate = VCM_MIN_BITRATE;
            break;
        }
#endif
    default:
        {
            return VCM_PARAMETER_ERROR;
        }
    }

    return VCM_OK;
}

WebRtc_Word32
VCMCodecDataBase::Codec(VideoCodecType codecType, VideoCodec* settings)
{
    for (int i = 0; i < VCMCodecDataBase::NumberOfCodecs(); i++)
    {
        const WebRtc_Word32 ret = VCMCodecDataBase::Codec(i, settings);
        if (ret != VCM_OK)
        {
            return ret;
        }
        if (codecType == settings->codecType)
        {
            return VCM_OK;
        }
    }
    return VCM_PARAMETER_ERROR;
}

// assuming only one registered encoder - since only one used, no need for more
WebRtc_Word32
VCMCodecDataBase::RegisterSendCodec(const VideoCodec* sendCodec,
                                    WebRtc_UWord32 numberOfCores,
                                    WebRtc_UWord32 maxPayloadSize)
 {
    if (sendCodec == NULL)
    {
        return VCM_UNINITIALIZED;
    }
    if (maxPayloadSize == 0)
    {
        maxPayloadSize = kDefaultPayloadSize;
    }
    if (numberOfCores > 32)
    {
        return VCM_PARAMETER_ERROR;
    }
    if (strcmp(sendCodec->plName, "H263") == 0 &&
        (sendCodec->plType != 34))
    {
        return VCM_PARAMETER_ERROR;
    }
    if (sendCodec->plType <= 0)
    {
        return VCM_PARAMETER_ERROR;
    }
    // Make sure the start bit rate is sane...
    if (sendCodec->startBitrate > 1000000)
    {
        return VCM_PARAMETER_ERROR;
    }
    if (sendCodec->codecType == kVideoCodecUnknown)
    {
        return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
    }
    _numberOfCores = numberOfCores;
    _maxPayloadSize = maxPayloadSize;

    memcpy(&_sendCodec, sendCodec, sizeof(VideoCodec));

    if (_sendCodec.maxBitrate == 0)
    {
        // max is one bit per pixel
        _sendCodec.maxBitrate = ((WebRtc_Word32)_sendCodec.height *
                                 (WebRtc_Word32)_sendCodec.width *
                                 (WebRtc_Word32)_sendCodec.maxFramerate) / 1000;
        if (_sendCodec.startBitrate > _sendCodec.maxBitrate)
        {
            // but if the customer tries to set a higher start bit rate we will increase
            // the max accordingly
            _sendCodec.maxBitrate = _sendCodec.startBitrate;
        }
    }

    return VCM_OK;
}

WebRtc_Word32
VCMCodecDataBase::SendCodec(VideoCodec* currentSendCodec) const
{
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideoCoding, VCMId(_id), "SendCodec");

    if(_ptrEncoder == NULL)
    {
        return VCM_UNINITIALIZED;
    }
    memcpy(currentSendCodec, &_sendCodec, sizeof(VideoCodec));
    return VCM_OK;
}

VideoCodecType
VCMCodecDataBase::SendCodec() const
{
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideoCoding, VCMId(_id),
            "SendCodec type");
    if (_ptrEncoder == NULL)
    {
        return kVideoCodecUnknown;
    }
    return _sendCodec.codecType;
}

WebRtc_Word32
VCMCodecDataBase::DeRegisterExternalEncoder(WebRtc_UWord8 payloadType, bool& wasSendCodec)
{
    wasSendCodec = false;
    if (_externalPayloadType != payloadType)
    {
        return VCM_PARAMETER_ERROR;
    }
    if (_sendCodec.plType == payloadType)
    {
        //De-register as send codec if needed
        DeleteEncoder();
        memset(&_sendCodec, 0, sizeof(VideoCodec));
        _currentEncIsExternal = false;
        wasSendCodec = true;
    }
    _externalPayloadType = 0;
    _externalEncoder = NULL;
    _internalSource = false;
    return VCM_OK;
}

WebRtc_Word32
VCMCodecDataBase::RegisterExternalEncoder(VideoEncoder* externalEncoder,
                                          WebRtc_UWord8 payloadType,
                                          bool internalSource)
{
    // since only one encoder can be used at a given time,
    // only one external encoder can be registered/used
    _externalEncoder = externalEncoder;
    _externalPayloadType = payloadType;
    _internalSource = internalSource;

    return VCM_OK;
}

VCMGenericEncoder*
VCMCodecDataBase::SetEncoder(const VideoCodec* settings,
                             VCMEncodedFrameCallback* VCMencodedFrameCallback)

{
    // if encoder exists, will destroy it and create new one
    DeleteEncoder();

    if (settings->plType == _externalPayloadType)
    {
        // External encoder
        _ptrEncoder = new VCMGenericEncoder(*_externalEncoder, _internalSource);
        _currentEncIsExternal = true;
    }
    else
    {
        _ptrEncoder = CreateEncoder(settings->codecType);
        _currentEncIsExternal = false;
    }

    VCMencodedFrameCallback->SetPayloadType(settings->plType);

    if (_ptrEncoder == NULL)
    {
        return NULL;
    }

    if (_ptrEncoder->InitEncode(settings, _numberOfCores, _maxPayloadSize) < 0)
    {
        DeleteEncoder();
        return NULL;
    }
    else if (_ptrEncoder->RegisterEncodeCallback(VCMencodedFrameCallback) < 0)
    {
        DeleteEncoder();
        return NULL;
    }
    // Intentionally don't check return value since the encoder registration
    // shouldn't fail because the codec doesn't support changing the
    // periodic key frame setting.
    _ptrEncoder->SetPeriodicKeyFrames(_periodicKeyFrames);
    return _ptrEncoder;
}

WebRtc_Word32
VCMCodecDataBase::SetPeriodicKeyFrames(bool enable)
{
    _periodicKeyFrames = enable;
    if (_ptrEncoder != NULL)
    {
        return _ptrEncoder->SetPeriodicKeyFrames(_periodicKeyFrames);
    }
    return VCM_OK;
}

WebRtc_Word32
VCMCodecDataBase::RegisterReceiveCodec(const VideoCodec* receiveCodec,
                                       WebRtc_UWord32 numberOfCores,
                                       bool requireKeyFrame)
{
    WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceVideoCoding, VCMId(_id),
                 "Codec: %s, Payload type %d, Height %d, Width %d, Bitrate %d, Framerate %d.",
                 receiveCodec->plName, receiveCodec->plType,
                 receiveCodec->height, receiveCodec->width,
                 receiveCodec->startBitrate, receiveCodec->maxFramerate);

    // check if payload value already exists, if so  - erase old and insert new
    DeRegisterReceiveCodec(receiveCodec->plType);
    if (receiveCodec->codecType == kVideoCodecUnknown)
    {
        return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
    }
    VideoCodec* newReceiveCodec = new VideoCodec(*receiveCodec);
    _decMap.Insert(receiveCodec->plType,
        new VCMDecoderMapItem(newReceiveCodec, numberOfCores, requireKeyFrame));

    return VCM_OK;
}

WebRtc_Word32 VCMCodecDataBase::DeRegisterReceiveCodec(WebRtc_UWord8 payloadType)
{
    MapItem* item = _decMap.Find(payloadType);
    if (item == NULL)
    {
        return VCM_PARAMETER_ERROR;
    }
    VCMDecoderMapItem* decItem = static_cast<VCMDecoderMapItem*>(item->GetItem());
    delete decItem->_settings;
    delete decItem;
    _decMap.Erase(item);
    if (_receiveCodec.plType == payloadType)
    {
        // This codec is currently in use.
        memset(&_receiveCodec, 0, sizeof(VideoCodec));
        _currentDecIsExternal = false;
    }
    return VCM_OK;
}

WebRtc_Word32
VCMCodecDataBase::ResetReceiver()
{
    ReleaseDecoder(_ptrDecoder);
    _ptrDecoder = NULL;
    memset(&_receiveCodec, 0, sizeof(VideoCodec));
    MapItem* item = _decMap.First();
    while (item != NULL)
    {
        VCMDecoderMapItem* decItem = static_cast<VCMDecoderMapItem*>(item->GetItem());
        if (decItem != NULL)
        {
            if (decItem->_settings != NULL)
            {
                delete decItem->_settings;
            }
            delete decItem;
        }
        _decMap.Erase(item);
        item = _decMap.First();
    }
    item = _decExternalMap.First();
    while (item != NULL)
    {
        VCMExtDecoderMapItem* decItem = static_cast<VCMExtDecoderMapItem*>(item->GetItem());
        if (decItem != NULL)
        {
            delete decItem;
        }
        _decExternalMap.Erase(item);
        item = _decExternalMap.First();
    }
    _currentDecIsExternal = false;
    return VCM_OK;
}

WebRtc_Word32
VCMCodecDataBase::DeRegisterExternalDecoder(WebRtc_UWord8 payloadType)
{
    MapItem* item = _decExternalMap.Find(payloadType);
    if (item == NULL)
    {
        // Not found
        return VCM_PARAMETER_ERROR;
    }
    if (_receiveCodec.plType == payloadType)
    {
        // Release it if it was registered and in use
        ReleaseDecoder(_ptrDecoder);
        _ptrDecoder = NULL;
    }
    DeRegisterReceiveCodec(payloadType);
    VCMExtDecoderMapItem* decItem = static_cast<VCMExtDecoderMapItem*>(item->GetItem());
    delete decItem;
    _decExternalMap.Erase(item);
    return VCM_OK;
}

// Add the external encoder object to the list of external decoders.
// Won't be registered as a receive codec until RegisterReceiveCodec is called.
WebRtc_Word32
VCMCodecDataBase::RegisterExternalDecoder(VideoDecoder* externalDecoder,
                                          WebRtc_UWord8 payloadType,
                                          bool internalRenderTiming)
{
    // check if payload value already exists, if so  - erase old and insert new
    VCMExtDecoderMapItem* extDecoder = new VCMExtDecoderMapItem(externalDecoder,
                                                                payloadType,
                                                                internalRenderTiming);
    if (extDecoder == NULL)
    {
        return VCM_MEMORY;
    }
    DeRegisterExternalDecoder(payloadType);
    _decExternalMap.Insert(payloadType, extDecoder);

    return VCM_OK;
}

bool
VCMCodecDataBase::DecoderRegistered() const
{
    return (_decMap.Size() > 0);
}

WebRtc_Word32
VCMCodecDataBase::ReceiveCodec(VideoCodec* currentReceiveCodec) const
{
    if (_ptrDecoder == NULL)
    {
        return VCM_NO_FRAME_DECODED;
    }
    memcpy(currentReceiveCodec, &_receiveCodec, sizeof(VideoCodec));
    return VCM_OK;
}

VideoCodecType
VCMCodecDataBase::ReceiveCodec() const
{
    if (_ptrDecoder == NULL)
    {
        return kVideoCodecUnknown;
    }
    return _receiveCodec.codecType;
}

VCMGenericDecoder*
VCMCodecDataBase::SetDecoder(WebRtc_UWord8 payloadType, VCMDecodedFrameCallback& callback)
{
    if (payloadType == _receiveCodec.plType || payloadType == 0)
    {
        return _ptrDecoder;
    }
    // check for exisitng decoder, if exists - delete
    if (_ptrDecoder)
    {
        ReleaseDecoder(_ptrDecoder);
        _ptrDecoder = NULL;
        memset(&_receiveCodec, 0, sizeof(VideoCodec));
    }
    _ptrDecoder = CreateAndInitDecoder(payloadType, _receiveCodec, _currentDecIsExternal);
    if (_ptrDecoder == NULL)
    {
        return NULL;
    }
    if (_ptrDecoder->RegisterDecodeCompleteCallback(&callback) < 0)
    {
        ReleaseDecoder(_ptrDecoder);
        _ptrDecoder = NULL;
        memset(&_receiveCodec, 0, sizeof(VideoCodec));
        return NULL;
    }
    return _ptrDecoder;
}

VCMGenericDecoder*
VCMCodecDataBase::CreateAndInitDecoder(WebRtc_UWord8 payloadType,
                                       VideoCodec& newCodec,
                                       bool &external) const
{
    VCMDecoderMapItem* decoderItem = FindDecoderItem(payloadType);
    if (decoderItem == NULL)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCoding, VCMId(_id),
                     "Unknown payload type: %u", payloadType);
        return NULL;
    }
    VCMGenericDecoder* ptrDecoder = NULL;
    VCMExtDecoderMapItem* externalDecItem = FindExternalDecoderItem(payloadType);
    if (externalDecItem != NULL)
    {
        // External codec
        ptrDecoder = new VCMGenericDecoder(*externalDecItem->_externalDecoderInstance, _id,
                                           true);
        external = true;
    }
    else
    {
        // create decoder
        ptrDecoder = CreateDecoder(decoderItem->_settings->codecType);
        external = false;
    }
    if (ptrDecoder == NULL)
    {
        return NULL;
    }

    if (ptrDecoder->InitDecode(decoderItem->_settings,
                               decoderItem->_numberOfCores,
                               decoderItem->_requireKeyFrame) < 0)
    {
        ReleaseDecoder(ptrDecoder);
        return NULL;
    }

    SetCodecConfigParameters(*ptrDecoder, *decoderItem->_settings);

    memcpy(&newCodec, decoderItem->_settings, sizeof(VideoCodec));
    return ptrDecoder;
}

VCMGenericDecoder*
VCMCodecDataBase::CreateDecoderCopy() const
{
    if (_ptrDecoder == NULL)
    {
        return NULL;
    }
    VideoDecoder* decoderCopy = _ptrDecoder->_decoder.Copy();
    if (decoderCopy == NULL)
    {
        return NULL;
    }
    return new VCMGenericDecoder(*decoderCopy, _id, _ptrDecoder->External());
}

void
VCMCodecDataBase::CopyDecoder(const VCMGenericDecoder& decoder)
{
    VideoDecoder* decoderCopy = decoder._decoder.Copy();
    if (decoderCopy != NULL)
    {
        ReleaseDecoder(_ptrDecoder);
        _ptrDecoder = new VCMGenericDecoder(*decoderCopy, _id, decoder.External());
    }
}

bool
VCMCodecDataBase::RenderTiming() const
{
    bool renderTiming = true;
    if (_currentDecIsExternal)
    {
        VCMExtDecoderMapItem* extItem = FindExternalDecoderItem(_receiveCodec.plType);
        renderTiming = extItem->_internalRenderTiming;
    }
    return renderTiming;
}

void
VCMCodecDataBase::ReleaseDecoder(VCMGenericDecoder* decoder) const
{
    if (decoder != NULL)
    {
        decoder->Release();
        if (!decoder->External() && &decoder->_decoder != NULL)
        {
            delete &decoder->_decoder;
        }
        delete decoder;
    }
}

WebRtc_Word32
VCMCodecDataBase::SetCodecConfigParameters(WebRtc_UWord8 payloadType,
                                           const WebRtc_UWord8* buffer,
                                           WebRtc_Word32 length)
{
    VCMDecoderMapItem* decItem = FindDecoderItem(payloadType);
    if (decItem == NULL)
    {
        return VCM_PARAMETER_ERROR;
    }
    switch (decItem->_settings->codecType)
    {
    case kVideoCodecMPEG4:
    {
        memcpy(decItem->_settings->codecSpecific.MPEG4.configParameters, buffer, length);
        decItem->_settings->codecSpecific.MPEG4.configParametersSize =
                static_cast<WebRtc_UWord8>(length);
        break;
    }
    default:
        // This codec doesn't have codec config parameters
        return VCM_GENERAL_ERROR;
    }
    if (_ptrDecoder != NULL && _receiveCodec.plType == decItem->_settings->plType)
    {
        return _ptrDecoder->SetCodecConfigParameters(buffer, length);
    }
    return VCM_OK;
}

VCMDecoderMapItem*
VCMCodecDataBase::FindDecoderItem(WebRtc_UWord8 payloadType) const
{
    MapItem* item = _decMap.Find(payloadType);
    if (item != NULL)
    {
        return static_cast<VCMDecoderMapItem*>(item->GetItem());
    }
    return NULL;
}

VCMExtDecoderMapItem*
VCMCodecDataBase::FindExternalDecoderItem(WebRtc_UWord8 payloadType) const
{
    MapItem* item = _decExternalMap.Find(payloadType);
    if (item != NULL)
    {
        return static_cast<VCMExtDecoderMapItem*>(item->GetItem());
    }
    return NULL;
}

VCMGenericDecoder*
VCMCodecDataBase::CreateDecoder(VideoCodecType type) const
{
    switch(type)
    {
#ifdef VIDEOCODEC_VP8
    case kVideoCodecVP8:
        return new VCMGenericDecoder(*(new VP8Decoder), _id);
#endif
#ifdef VIDEOCODEC_I420
    case kVideoCodecI420:
         return new VCMGenericDecoder(*(new I420Decoder), _id);
#endif
    default:
        return NULL;
    }
}

void
VCMCodecDataBase::SetCodecConfigParameters(VCMGenericDecoder& decoder,
                                           const VideoCodec& settings)
{
    switch (settings.codecType)
    {
    case kVideoCodecMPEG4:
    {
        if (settings.codecSpecific.MPEG4.configParametersSize > 0)
        {
            decoder.SetCodecConfigParameters(
                                    settings.codecSpecific.MPEG4.configParameters,
                                    settings.codecSpecific.MPEG4.configParametersSize);
        }
        break;
    }
    default:
        // No codec config parameters for this codec
        return;
    }
    return;
}

}
