/*
 *  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 "rtp_receiver_video.h"

#include <cassert> //assert
#include <cstring>  // memcpy()
#include <math.h>

#include "critical_section_wrapper.h"
#include "receiver_fec.h"
#include "rtp_rtcp_impl.h"
#include "rtp_utility.h"

namespace webrtc {
WebRtc_UWord32 BitRateBPS(WebRtc_UWord16 x )
{
    return (x & 0x3fff) * WebRtc_UWord32(pow(10.0f,(2 + (x >> 14))));
}

RTPReceiverVideo::RTPReceiverVideo(const WebRtc_Word32 id,
                                   ModuleRtpRtcpImpl* owner):
    _id(id),
    _rtpRtcp(*owner),
    _criticalSectionFeedback(CriticalSectionWrapper::CreateCriticalSection()),
    _cbVideoFeedback(NULL),
    _criticalSectionReceiverVideo(
        CriticalSectionWrapper::CreateCriticalSection()),
    _completeFrame(false),
    _packetStartTimeMs(0),
    _receivedBW(),
    _estimatedBW(0),
    _currentFecFrameDecoded(false),
    _receiveFEC(NULL),
    _overUseDetector(),
    _videoBitRate(),
    _lastBitRateChange(0),
    _packetOverHead(28)
{
    memset(_receivedBW, 0,sizeof(_receivedBW));
}

RTPReceiverVideo::~RTPReceiverVideo()
{
    delete _criticalSectionFeedback;
    delete _criticalSectionReceiverVideo;
    delete _receiveFEC;
}

WebRtc_Word32
RTPReceiverVideo::Init()
{
    _completeFrame = false;
    _packetStartTimeMs = 0;
    _estimatedBW = 0;
    _currentFecFrameDecoded = false;
    _packetOverHead = 28;
    for (int i = 0; i < BW_HISTORY_SIZE; i++)
    {
        _receivedBW[i] = 0;
    }
    ResetOverUseDetector();
    return 0;
}

void
RTPReceiverVideo::ChangeUniqueId(const WebRtc_Word32 id)
{
    _id = id;
}

WebRtc_Word32
RTPReceiverVideo::RegisterIncomingVideoCallback(RtpVideoFeedback* incomingMessagesCallback)
{
    CriticalSectionScoped lock(_criticalSectionFeedback);
    _cbVideoFeedback = incomingMessagesCallback;
    return 0;
}

void
RTPReceiverVideo::UpdateBandwidthManagement(const WebRtc_UWord32 bitrateBps,
                                            const WebRtc_UWord8 fractionLost,
                                            const WebRtc_UWord16 roundTripTimeMs)
{
    CriticalSectionScoped lock(_criticalSectionFeedback);
    if(_cbVideoFeedback)
    {
        _cbVideoFeedback->OnNetworkChanged(_id,
                                           bitrateBps,
                                           fractionLost,
                                           roundTripTimeMs);
    }
}

ModuleRTPUtility::Payload* RTPReceiverVideo::RegisterReceiveVideoPayload(
    const char payloadName[RTP_PAYLOAD_NAME_SIZE],
    const WebRtc_Word8 payloadType,
    const WebRtc_UWord32 maxRate) {
  RtpVideoCodecTypes videoType = kRtpNoVideo;
  if (ModuleRTPUtility::StringCompare(payloadName, "VP8", 3)) {
    videoType = kRtpVp8Video;
  } else if (ModuleRTPUtility::StringCompare(payloadName, "I420", 4)) {
    videoType = kRtpNoVideo;
  } else if (ModuleRTPUtility::StringCompare(payloadName, "ULPFEC", 6)) {
    // store this
    if (_receiveFEC == NULL) {
      _receiveFEC = new ReceiverFEC(_id, this);
    }
    _receiveFEC->SetPayloadTypeFEC(payloadType);
    videoType = kRtpFecVideo;
  } else {
    return NULL;
  }
  ModuleRTPUtility::Payload* payload =  new ModuleRTPUtility::Payload;

  payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
  strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
  payload->typeSpecific.Video.videoCodecType = videoType;
  payload->typeSpecific.Video.maxRate = maxRate;
  payload->audio = false;
  return payload;
}

void RTPReceiverVideo::ResetOverUseDetector()
{
    _overUseDetector.Reset();
    _videoBitRate.Init();
    _lastBitRateChange = 0;
}

// called under _criticalSectionReceiverVideo
WebRtc_UWord16
RTPReceiverVideo::EstimateBandwidth(const WebRtc_UWord16 bandwidth)
{
    // received fragments
    // estimate BW

    WebRtc_UWord16 bwSort[BW_HISTORY_SIZE];
    for(int i = 0; i < BW_HISTORY_SIZE-1; i++)
    {
        _receivedBW[i] = _receivedBW[i+1];
        bwSort[i] = _receivedBW[i+1];
    }
    _receivedBW[BW_HISTORY_SIZE-1] = bandwidth;
    bwSort[BW_HISTORY_SIZE-1] = bandwidth;

    WebRtc_UWord16 temp;
    for (int i = BW_HISTORY_SIZE-1; i >= 0; i--)
    {
        for (int j = 1; j <= i; j++)
        {
            if (bwSort[j-1] > bwSort[j])
            {
                temp = bwSort[j-1];
                bwSort[j-1] = bwSort[j];
                bwSort[j] = temp;
            }
        }
    }
    int zeroCount = 0;
    for (; zeroCount < BW_HISTORY_SIZE; zeroCount++)
    {
        if (bwSort[zeroCount]!= 0)
        {
            break;
        }
    }
    WebRtc_UWord32 indexMedian = (BW_HISTORY_SIZE -1) - (BW_HISTORY_SIZE-zeroCount)/2;
    WebRtc_UWord16 bandwidthMedian = bwSort[indexMedian];

    if (bandwidthMedian > 0)
    {
        if (_estimatedBW == bandwidth)
        {
            // don't trigger a callback
            bandwidthMedian = 0;
        } else
        {
            _estimatedBW = bandwidthMedian;
        }
    } else
    {
        // can't be negative
        bandwidthMedian = 0;
    }

    return bandwidthMedian;
}

// we have no critext when calling this
// we are not allowed to have any critsects when calling CallbackOfReceivedPayloadData
WebRtc_Word32
RTPReceiverVideo::ParseVideoCodecSpecific(WebRtcRTPHeader* rtpHeader,
                                          const WebRtc_UWord8* payloadData,
                                          const WebRtc_UWord16 payloadDataLength,
                                          const RtpVideoCodecTypes videoType,
                                          const bool isRED,
                                          const WebRtc_UWord8* incomingRtpPacket,
                                          const WebRtc_UWord16 incomingRtpPacketSize,
                                          const WebRtc_Word64 nowMS)
{
    WebRtc_Word32 retVal = 0;

    _criticalSectionReceiverVideo->Enter();

    _videoBitRate.Update(payloadDataLength + rtpHeader->header.paddingLength,
                         nowMS);

    // Add headers, ideally we would like to include for instance
    // Ethernet header here as well.
    const WebRtc_UWord16 packetSize = payloadDataLength + _packetOverHead +
        rtpHeader->header.headerLength + rtpHeader->header.paddingLength;
    _overUseDetector.Update(*rtpHeader, packetSize, nowMS);

    if (isRED)
    {
        if(_receiveFEC == NULL)
        {
            _criticalSectionReceiverVideo->Leave();
            return -1;
        }
        bool oldPacket = false;
        bool FECpacket = false;
        bool wrapped = false;  // Not used; just for OldTimeStamp().

        // Check for old packets.
        if (ModuleRTPUtility::OldTimestamp(rtpHeader->header.timestamp,
                                           TimeStamp(),
                                           &wrapped))
        {
            // We have an old packet.
            // FEC receiver holds a list of packets with current timestamp.
            // Setting "oldPacket = true" will send old packets directly
            // to the jitter buffer.
            oldPacket = true;
            retVal = _receiveFEC->AddReceivedFECPacket(rtpHeader,
                                                       incomingRtpPacket,
                                                       payloadDataLength,
                                                       FECpacket,
                                                       oldPacket);
        }
        else
        {
            // Check for future packets.
            if (rtpHeader->header.timestamp != TimeStamp())
            {
                // We have a packet from next frame.
                // Force a decode with the existing packets.
                retVal = _receiveFEC->ProcessReceivedFEC(true);
                _currentFecFrameDecoded = false;
            }
            if(retVal != -1)
            {
                if (!_currentFecFrameDecoded)
                {
                    retVal = _receiveFEC->AddReceivedFECPacket(
                        rtpHeader,
                        incomingRtpPacket,
                        payloadDataLength,
                        FECpacket,
                        oldPacket);

                    if (retVal != -1 && (FECpacket ||
                        rtpHeader->header.markerBit))
                    {
                        // Only attempt a decode after receiving the
                        // last media packet or an FEC packet.
                        retVal = _receiveFEC->ProcessReceivedFEC(false);
                    }
                }else
                {
                    _receiveFEC->AddReceivedFECInfo(rtpHeader,
                                                    incomingRtpPacket,
                                                    FECpacket);
                }
            }
        }
        _criticalSectionReceiverVideo->Leave();

        if(retVal == 0 && FECpacket)
        {
            // Callback with the received FEC packet.
            // The normal packets are delivered after parsing.
            // This contains the original RTP packet header but with
            // empty payload and data length.
            rtpHeader->frameType = kFrameEmpty;
            // We need this for the routing.
            WebRtc_Word32 retVal = SetCodecType(videoType, rtpHeader);
            if(retVal != 0)
            {
                return retVal;
            }
            retVal = CallbackOfReceivedPayloadData(NULL, 0, rtpHeader);
        }
    }else
    {
        // will leave the _criticalSectionReceiverVideo critsect
        retVal = ParseVideoCodecSpecificSwitch(rtpHeader,
                                               payloadData,
                                               payloadDataLength,
                                               videoType);
    }

    // Update the remote rate control object and update the overuse
    // detector with the current rate control region.
    _criticalSectionReceiverVideo->Enter();
    const RateControlInput input(_overUseDetector.State(),
                                 _videoBitRate.BitRate(nowMS),
                                 _overUseDetector.NoiseVar());
    _criticalSectionReceiverVideo->Leave();

    // Call the callback outside critical section
    const RateControlRegion region = _rtpRtcp.OnOverUseStateUpdate(input);

    _criticalSectionReceiverVideo->Enter();
    _overUseDetector.SetRateControlRegion(region);
    _criticalSectionReceiverVideo->Leave();

    return retVal;
}

WebRtc_Word32
RTPReceiverVideo::BuildRTPheader(const WebRtcRTPHeader* rtpHeader,
                                 WebRtc_UWord8* dataBuffer) const
{
    dataBuffer[0] = static_cast<WebRtc_UWord8>(0x80);            // version 2
    dataBuffer[1] = static_cast<WebRtc_UWord8>(rtpHeader->header.payloadType);
    if (rtpHeader->header.markerBit)
    {
        dataBuffer[1] |= kRtpMarkerBitMask;  // MarkerBit is 1
    }

    ModuleRTPUtility::AssignUWord16ToBuffer(dataBuffer+2, rtpHeader->header.sequenceNumber);
    ModuleRTPUtility::AssignUWord32ToBuffer(dataBuffer+4, rtpHeader->header.timestamp);
    ModuleRTPUtility::AssignUWord32ToBuffer(dataBuffer+8, rtpHeader->header.ssrc);

    WebRtc_Word32 rtpHeaderLength = 12;

    // Add the CSRCs if any
    if (rtpHeader->header.numCSRCs > 0)
    {
        if(rtpHeader->header.numCSRCs > 16)
        {
            // error
            assert(false);
        }
        WebRtc_UWord8* ptr = &dataBuffer[rtpHeaderLength];
        for (WebRtc_UWord32 i = 0; i < rtpHeader->header.numCSRCs; ++i)
        {
            ModuleRTPUtility::AssignUWord32ToBuffer(ptr, rtpHeader->header.arrOfCSRCs[i]);
            ptr +=4;
        }
        dataBuffer[0] = (dataBuffer[0]&0xf0) | rtpHeader->header.numCSRCs;

        // Update length of header
        rtpHeaderLength += sizeof(WebRtc_UWord32)*rtpHeader->header.numCSRCs;
    }
    return rtpHeaderLength;
}

WebRtc_Word32
RTPReceiverVideo::ReceiveRecoveredPacketCallback(WebRtcRTPHeader* rtpHeader,
                                                 const WebRtc_UWord8* payloadData,
                                                 const WebRtc_UWord16 payloadDataLength)
{
     _criticalSectionReceiverVideo->Enter();

    _currentFecFrameDecoded = true;

    ModuleRTPUtility::Payload* payload = NULL;
    if (PayloadTypeToPayload(rtpHeader->header.payloadType, payload) != 0)
    {
        return -1;
    }
    // here we can re-create the original lost packet so that we can use it for the relay
    // we need to re-create the RED header too
    WebRtc_UWord8 recoveredPacket[IP_PACKET_SIZE];
    WebRtc_UWord16 rtpHeaderLength = (WebRtc_UWord16)BuildRTPheader(rtpHeader, recoveredPacket);

    const WebRtc_UWord8 REDForFECHeaderLength = 1;

    // replace pltype
    recoveredPacket[1] &= 0x80;             // reset
    recoveredPacket[1] += REDPayloadType(); // replace with RED payload type

    // add RED header
    recoveredPacket[rtpHeaderLength] = rtpHeader->header.payloadType; // f-bit always 0

    memcpy(recoveredPacket + rtpHeaderLength + REDForFECHeaderLength, payloadData, payloadDataLength);

    return ParseVideoCodecSpecificSwitch(rtpHeader,
                                         payloadData,
                                         payloadDataLength,
                                         payload->typeSpecific.Video.videoCodecType);
}

WebRtc_Word32 RTPReceiverVideo::SetCodecType(const RtpVideoCodecTypes videoType,
                                             WebRtcRTPHeader* rtpHeader) const {
  switch (videoType) {
    case kRtpNoVideo:
      rtpHeader->type.Video.codec = kRTPVideoGeneric;
      break;
    case kRtpVp8Video:
      rtpHeader->type.Video.codec = kRTPVideoVP8;
      break;
    case kRtpFecVideo:
      rtpHeader->type.Video.codec = kRTPVideoFEC;
      break;
  }
  return 0;
}

WebRtc_Word32 RTPReceiverVideo::ParseVideoCodecSpecificSwitch(
    WebRtcRTPHeader* rtpHeader,
    const WebRtc_UWord8* payloadData,
    const WebRtc_UWord16 payloadDataLength,
    const RtpVideoCodecTypes videoType) {
  WebRtc_Word32 retVal = SetCodecType(videoType, rtpHeader);
  if (retVal != 0) {
    return retVal;
  }
  // All receive functions release _criticalSectionReceiverVideo before
  // returning.
  switch (videoType) {
    case kRtpNoVideo:
      return ReceiveGenericCodec(rtpHeader, payloadData, payloadDataLength);
    case kRtpVp8Video:
      return ReceiveVp8Codec(rtpHeader, payloadData, payloadDataLength);
    case kRtpFecVideo:
      break;
  }
  _criticalSectionReceiverVideo->Leave();
  return -1;
}

WebRtc_Word32
RTPReceiverVideo::ReceiveVp8Codec(WebRtcRTPHeader* rtpHeader,
                                  const WebRtc_UWord8* payloadData,
                                  const WebRtc_UWord16 payloadDataLength)
{
    bool success;
    ModuleRTPUtility::RTPPayload parsedPacket;
    if (payloadDataLength == 0)
    {
        success = true;
        parsedPacket.info.VP8.dataLength = 0;
    } else
    {
        ModuleRTPUtility::RTPPayloadParser rtpPayloadParser(kRtpVp8Video,
                                                            payloadData,
                                                            payloadDataLength,
                                                           _id);
 
        success = rtpPayloadParser.Parse(parsedPacket);
    }
    // from here down we only work on local data
    _criticalSectionReceiverVideo->Leave();

    if (!success)
    {
        return -1;
    }
    if (parsedPacket.info.VP8.dataLength == 0)
    {
        // we have an "empty" VP8 packet, it's ok, could be one way video
        // Inform the jitter buffer about this packet.
        rtpHeader->frameType = kFrameEmpty;
        if (CallbackOfReceivedPayloadData(NULL, 0, rtpHeader) != 0)
        {
            return -1;
        }
        return 0;
    }
    rtpHeader->frameType = (parsedPacket.frameType == ModuleRTPUtility::kIFrame) ? kVideoFrameKey : kVideoFrameDelta;

    RTPVideoHeaderVP8 *toHeader = &rtpHeader->type.Video.codecHeader.VP8;
    ModuleRTPUtility::RTPPayloadVP8 *fromHeader = &parsedPacket.info.VP8;

    rtpHeader->type.Video.isFirstPacket = fromHeader->beginningOfPartition
        && (fromHeader->partitionID == 0);
    toHeader->pictureId = fromHeader->hasPictureID ? fromHeader->pictureID :
                          kNoPictureId;
    toHeader->tl0PicIdx = fromHeader->hasTl0PicIdx ? fromHeader->tl0PicIdx :
                          kNoTl0PicIdx;
    if (fromHeader->hasTID) {
      toHeader->temporalIdx = fromHeader->tID;
      toHeader->layerSync = fromHeader->layerSync;
    } else {
      toHeader->temporalIdx = kNoTemporalIdx;
      toHeader->layerSync = false;
    }
    toHeader->keyIdx = fromHeader->hasKeyIdx ? fromHeader->keyIdx : kNoKeyIdx;

    toHeader->frameWidth = fromHeader->frameWidth;
    toHeader->frameHeight = fromHeader->frameHeight;

    toHeader->partitionId = fromHeader->partitionID;
    toHeader->beginningOfPartition = fromHeader->beginningOfPartition;

    if(CallbackOfReceivedPayloadData(parsedPacket.info.VP8.data,
                                     parsedPacket.info.VP8.dataLength,
                                     rtpHeader) != 0)
    {
        return -1;
    }
    return 0;
}


WebRtc_Word32
RTPReceiverVideo::ReceiveGenericCodec(WebRtcRTPHeader* rtpHeader,
                                      const WebRtc_UWord8* payloadData,
                                      const WebRtc_UWord16 payloadDataLength)
{
    rtpHeader->frameType = kVideoFrameKey;

    if(((SequenceNumber() + 1) == rtpHeader->header.sequenceNumber) &&
        (TimeStamp() != rtpHeader->header.timestamp))
    {
        rtpHeader->type.Video.isFirstPacket = true;
    }
    _criticalSectionReceiverVideo->Leave();

    if(CallbackOfReceivedPayloadData(payloadData, payloadDataLength, rtpHeader) != 0)
    {
        return -1;
    }
    return 0;
}

void RTPReceiverVideo::SetPacketOverHead(WebRtc_UWord16 packetOverHead)
{
    _packetOverHead = packetOverHead;
}
} // namespace webrtc
