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

#include "critical_section_wrapper.h"
#include "trace.h"

#include "rtp_utility.h"

#include <string.h> // memcpy
#include <cassert>  // assert
#include <cstdlib>  // srand

#include "rtp_format_vp8.h"

namespace webrtc {
enum { REDForFECHeaderLength = 1 };

RTPSenderVideo::RTPSenderVideo(const WebRtc_Word32 id,
                               RtpRtcpClock* clock,
                               RTPSenderInterface* rtpSender) :
    _id(id),
    _rtpSender(*rtpSender),
    _sendVideoCritsect(CriticalSectionWrapper::CreateCriticalSection()),

    _videoType(kRtpNoVideo),
    _videoCodecInformation(NULL),
    _maxBitrate(0),
    _retransmissionSettings(kRetransmitBaseLayer),

    // Generic FEC
    _fec(id),
    _fecEnabled(false),
    _payloadTypeRED(-1),
    _payloadTypeFEC(-1),
    _codeRateKey(0),
    _codeRateDelta(0),
    _useUepProtectionKey(false),
    _useUepProtectionDelta(false),
    _fecProtectionFactor(0),
    _fecUseUepProtection(false),
    _numberFirstPartition(0),
    _fecOverheadRate(clock),
    _videoBitrate(clock) {
}

RTPSenderVideo::~RTPSenderVideo()
{
    if(_videoCodecInformation)
    {
        delete _videoCodecInformation;
    }
    delete _sendVideoCritsect;
}

WebRtc_Word32
RTPSenderVideo::Init()
{
    CriticalSectionScoped cs(_sendVideoCritsect);

    _retransmissionSettings = kRetransmitBaseLayer;
    _fecEnabled = false;
    _payloadTypeRED = -1;
    _payloadTypeFEC = -1;
    _codeRateKey = 0;
    _codeRateDelta = 0;
    _useUepProtectionKey = false;
    _useUepProtectionDelta = false;
    _fecProtectionFactor = 0;
    _fecUseUepProtection = false;
    _numberFirstPartition = 0;
    _fecOverheadRate.Init();
    return 0;
}

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

void
RTPSenderVideo::SetVideoCodecType(RtpVideoCodecTypes videoType)
{
    CriticalSectionScoped cs(_sendVideoCritsect);
    _videoType = videoType;
}

RtpVideoCodecTypes
RTPSenderVideo::VideoCodecType() const
{
    return _videoType;
}

WebRtc_Word32 RTPSenderVideo::RegisterVideoPayload(
    const char payloadName[RTP_PAYLOAD_NAME_SIZE],
    const WebRtc_Word8 payloadType,
    const WebRtc_UWord32 maxBitRate,
    ModuleRTPUtility::Payload*& payload) {
  CriticalSectionScoped cs(_sendVideoCritsect);

  RtpVideoCodecTypes videoType = kRtpNoVideo;
  if (ModuleRTPUtility::StringCompare(payloadName, "VP8",3)) {
    videoType = kRtpVp8Video;
  } else if (ModuleRTPUtility::StringCompare(payloadName, "I420", 4)) {
    videoType = kRtpNoVideo;
  } else {
    return -1;
  }
  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 = maxBitRate;
  payload->audio = false;
  return 0;
}

struct RtpPacket
{
    WebRtc_UWord16 rtpHeaderLength;
    ForwardErrorCorrection::Packet* pkt;
};

WebRtc_Word32
RTPSenderVideo::SendVideoPacket(const FrameType frameType,
                                const WebRtc_UWord8* dataBuffer,
                                const WebRtc_UWord16 payloadLength,
                                const WebRtc_UWord16 rtpHeaderLength,
                                StorageType storage)
{
    if(_fecEnabled)
    {
        WebRtc_Word32 retVal = 0;

        const bool markerBit = (dataBuffer[1] & kRtpMarkerBitMask)?true:false;
        RtpPacket* ptrGenericFEC = new RtpPacket;
        ptrGenericFEC->pkt = new ForwardErrorCorrection::Packet;
        ptrGenericFEC->pkt->length = payloadLength + rtpHeaderLength;
        ptrGenericFEC->rtpHeaderLength = rtpHeaderLength;
        memcpy(ptrGenericFEC->pkt->data, dataBuffer,
               ptrGenericFEC->pkt->length);

        // Add packet to FEC list
        _rtpPacketListFec.push_back(ptrGenericFEC);
        // FEC can only protect up to kMaxMediaPackets packets
        if (static_cast<int>(_mediaPacketListFec.size()) <
            ForwardErrorCorrection::kMaxMediaPackets)
        {
            _mediaPacketListFec.push_back(ptrGenericFEC->pkt);
        }

        // Last packet in frame
        if (markerBit)
        {

            // Retain the RTP header of the last media packet to construct FEC
            // packet RTP headers.
            ForwardErrorCorrection::Packet lastMediaRtpHeader;
            memcpy(lastMediaRtpHeader.data,
                   ptrGenericFEC->pkt->data,
                   ptrGenericFEC->rtpHeaderLength);

            lastMediaRtpHeader.length = ptrGenericFEC->rtpHeaderLength;
            // Replace payload and clear marker bit.
            lastMediaRtpHeader.data[1] = _payloadTypeRED;

            // Number of first partition packets cannot exceed kMaxMediaPackets
            if (_numberFirstPartition >
                ForwardErrorCorrection::kMaxMediaPackets)
            {
                _numberFirstPartition =
                    ForwardErrorCorrection::kMaxMediaPackets;
            }

            std::list<ForwardErrorCorrection::Packet*> fecPacketList;
            retVal = _fec.GenerateFEC(_mediaPacketListFec,
                                      _fecProtectionFactor,
                                      _numberFirstPartition,
                                      _fecUseUepProtection,
                                      &fecPacketList);

            int fecOverheadSent = 0;
            int videoSent = 0;

            while(!_rtpPacketListFec.empty())
            {
                WebRtc_UWord8 newDataBuffer[IP_PACKET_SIZE];
                memset(newDataBuffer, 0, sizeof(newDataBuffer));

                RtpPacket* packetToSend = _rtpPacketListFec.front();

                // Copy RTP header
                memcpy(newDataBuffer, packetToSend->pkt->data,
                       packetToSend->rtpHeaderLength);

                // Get codec pltype
                WebRtc_UWord8 payloadType = newDataBuffer[1] & 0x7f;

                // Replace pltype
                newDataBuffer[1] &= 0x80;            // reset
                newDataBuffer[1] += _payloadTypeRED; // replace

                // Add RED header
                // f-bit always 0
                newDataBuffer[packetToSend->rtpHeaderLength] = payloadType;

                // Copy payload data
                memcpy(newDataBuffer + packetToSend->rtpHeaderLength +
                           REDForFECHeaderLength,
                       packetToSend->pkt->data + packetToSend->rtpHeaderLength,
                       packetToSend->pkt->length -
                           packetToSend->rtpHeaderLength);

                _rtpPacketListFec.pop_front();
                _mediaPacketListFec.pop_front();

                // Send normal packet with RED header
                int packetSuccess = _rtpSender.SendToNetwork(
                    newDataBuffer,
                    packetToSend->pkt->length - packetToSend->rtpHeaderLength +
                    REDForFECHeaderLength,
                    packetToSend->rtpHeaderLength,
                    storage);

                retVal |= packetSuccess;

                if (packetSuccess == 0)
                {
                    videoSent += packetToSend->pkt->length +
                        REDForFECHeaderLength;
                }

                delete packetToSend->pkt;
                delete packetToSend;
                packetToSend = NULL;
            }
            assert(_mediaPacketListFec.empty());
            assert(_rtpPacketListFec.empty());

            while(!fecPacketList.empty())
            {
                WebRtc_UWord8 newDataBuffer[IP_PACKET_SIZE];

                // Build FEC packets
                ForwardErrorCorrection::Packet* packetToSend = fecPacketList.front();

                // The returned FEC packets have no RTP headers.
                // Copy the last media packet's modified RTP header.
                memcpy(newDataBuffer, lastMediaRtpHeader.data,
                       lastMediaRtpHeader.length);

                // Add sequence number
                ModuleRTPUtility::AssignUWord16ToBuffer(
                    &newDataBuffer[2], _rtpSender.IncrementSequenceNumber());

                // Add RED header
                // f-bit always 0
                newDataBuffer[lastMediaRtpHeader.length] = _payloadTypeFEC;

                // Copy payload data
                memcpy(newDataBuffer + lastMediaRtpHeader.length +
                           REDForFECHeaderLength,
                       packetToSend->data,
                       packetToSend->length);

                fecPacketList.pop_front();

                // Invalid FEC packet
                assert(packetToSend->length != 0);

                StorageType storage = kDontRetransmit;
                if (_retransmissionSettings & kRetransmitFECPackets) {
                  storage = kAllowRetransmission;
                }

                // No marker bit on FEC packets, last media packet have the
                // marker send FEC packet with RED header
                int packetSuccess = _rtpSender.SendToNetwork(
                        newDataBuffer,
                        packetToSend->length + REDForFECHeaderLength,
                        lastMediaRtpHeader.length,
                        storage);

                retVal |= packetSuccess;

                if (packetSuccess == 0)
                {
                    fecOverheadSent += packetToSend->length +
                      REDForFECHeaderLength + lastMediaRtpHeader.length;
                }
            }
            _videoBitrate.Update(videoSent);
            _fecOverheadRate.Update(fecOverheadSent);
        }
        return retVal;
    }
    int retVal = _rtpSender.SendToNetwork(dataBuffer,
                                          payloadLength,
                                          rtpHeaderLength,
                                          storage);
    if (retVal == 0)
    {
        _videoBitrate.Update(payloadLength + rtpHeaderLength);
    }
    return retVal;
}

WebRtc_Word32
RTPSenderVideo::SendRTPIntraRequest()
{
    // RFC 2032
    // 5.2.1.  Full intra-frame Request (FIR) packet

    WebRtc_UWord16 length = 8;
    WebRtc_UWord8 data[8];
    data[0] = 0x80;
    data[1] = 192;
    data[2] = 0;
    data[3] = 1; // length

    ModuleRTPUtility::AssignUWord32ToBuffer(data+4, _rtpSender.SSRC());

    return _rtpSender.SendToNetwork(data, 0, length, kAllowRetransmission);
}

WebRtc_Word32
RTPSenderVideo::SetGenericFECStatus(const bool enable,
                                    const WebRtc_UWord8 payloadTypeRED,
                                    const WebRtc_UWord8 payloadTypeFEC)
{
    _fecEnabled = enable;
    _payloadTypeRED = payloadTypeRED;
    _payloadTypeFEC = payloadTypeFEC;
    _codeRateKey = 0;
    _codeRateDelta = 0;
    _useUepProtectionKey = false;
    _useUepProtectionDelta = false;
    return 0;
}

WebRtc_Word32
RTPSenderVideo::GenericFECStatus(bool& enable,
                                 WebRtc_UWord8& payloadTypeRED,
                                 WebRtc_UWord8& payloadTypeFEC) const
{
    enable = _fecEnabled;
    payloadTypeRED = _payloadTypeRED;
    payloadTypeFEC = _payloadTypeFEC;
    return 0;
}

WebRtc_UWord16
RTPSenderVideo::FECPacketOverhead() const
{
    if (_fecEnabled)
    {
        return ForwardErrorCorrection::PacketOverhead() +
            REDForFECHeaderLength;
    }
    return 0;
}

WebRtc_Word32
RTPSenderVideo::SetFECCodeRate(const WebRtc_UWord8 keyFrameCodeRate,
                               const WebRtc_UWord8 deltaFrameCodeRate)
{
    _codeRateKey = keyFrameCodeRate;
    _codeRateDelta = deltaFrameCodeRate;
    return 0;
}

WebRtc_Word32
RTPSenderVideo::SetFECUepProtection(const bool keyUseUepProtection,
                                    const bool deltaUseUepProtection)
{
    _useUepProtectionKey = keyUseUepProtection;
    _useUepProtectionDelta = deltaUseUepProtection;
    return 0;
}

WebRtc_Word32
RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType,
                          const FrameType frameType,
                          const WebRtc_Word8 payloadType,
                          const WebRtc_UWord32 captureTimeStamp,
                          const WebRtc_UWord8* payloadData,
                          const WebRtc_UWord32 payloadSize,
                          const RTPFragmentationHeader* fragmentation,
                          VideoCodecInformation* codecInfo,
                          const RTPVideoTypeHeader* rtpTypeHdr)
{
    if( payloadSize == 0)
    {
        return -1;
    }

    if (frameType == kVideoFrameKey)
    {
        _fecProtectionFactor = _codeRateKey;
        _fecUseUepProtection = _useUepProtectionKey;
    } else if (videoType == kRtpVp8Video && rtpTypeHdr->VP8.temporalIdx > 0)
    {
        // In current version, we only apply FEC on the base layer.
        _fecProtectionFactor = 0;
        _fecUseUepProtection = false;
    } else
    {
        _fecProtectionFactor = _codeRateDelta;
        _fecUseUepProtection = _useUepProtectionDelta;
    }

    // Default setting for number of first partition packets:
    // Will be extracted in SendVP8 for VP8 codec; other codecs use 0
    _numberFirstPartition = 0;

    WebRtc_Word32 retVal = -1;
    switch(videoType)
    {
    case kRtpNoVideo:
        retVal = SendGeneric(payloadType,captureTimeStamp, payloadData,
                             payloadSize);
        break;
    case kRtpVp8Video:
        retVal = SendVP8(frameType, payloadType, captureTimeStamp,
                payloadData, payloadSize, fragmentation, rtpTypeHdr);
        break;
    default:
        assert(false);
        break;
    }
    if(retVal <= 0)
    {
        return retVal;
    }
    return 0;
}

WebRtc_Word32
RTPSenderVideo::SendGeneric(const WebRtc_Word8 payloadType,
                            const WebRtc_UWord32 captureTimeStamp,
                            const WebRtc_UWord8* payloadData,
                            const WebRtc_UWord32 payloadSize)
{
    WebRtc_UWord16 payloadBytesInPacket = 0;
    WebRtc_UWord32 bytesSent = 0;
    WebRtc_Word32 payloadBytesToSend = payloadSize;

    const WebRtc_UWord8* data = payloadData;
    WebRtc_UWord16 rtpHeaderLength = _rtpSender.RTPHeaderLength();
    WebRtc_UWord16 maxLength = _rtpSender.MaxPayloadLength() -
        FECPacketOverhead() - rtpHeaderLength;
    WebRtc_UWord8 dataBuffer[IP_PACKET_SIZE];

    // Fragment packet into packets of max MaxPayloadLength bytes payload.
    while (payloadBytesToSend > 0)
    {
        if (payloadBytesToSend > maxLength)
        {
            payloadBytesInPacket = maxLength;
            payloadBytesToSend -= payloadBytesInPacket;
            // MarkerBit is 0
            if(_rtpSender.BuildRTPheader(dataBuffer,
                                         payloadType,
                                         false,
                                         captureTimeStamp) != rtpHeaderLength)
            {
                return -1;
           }
        }
        else
        {
            payloadBytesInPacket = (WebRtc_UWord16)payloadBytesToSend;
            payloadBytesToSend = 0;
            // MarkerBit is 1
            if(_rtpSender.BuildRTPheader(dataBuffer, payloadType, true,
                                         captureTimeStamp) != rtpHeaderLength)
            {
                return -1;
            }
        }

        // Put payload in packet
        memcpy(&dataBuffer[rtpHeaderLength], &data[bytesSent],
               payloadBytesInPacket);
        bytesSent += payloadBytesInPacket;

        if(-1 == SendVideoPacket(kVideoFrameKey,
                                 dataBuffer,
                                 payloadBytesInPacket,
                                 rtpHeaderLength,
                                 kAllowRetransmission))
        {
            return -1;
        }
    }
    return 0;
}

VideoCodecInformation*
RTPSenderVideo::CodecInformationVideo()
{
    return _videoCodecInformation;
}

void
RTPSenderVideo::SetMaxConfiguredBitrateVideo(const WebRtc_UWord32 maxBitrate)
{
    _maxBitrate = maxBitrate;
}

WebRtc_UWord32
RTPSenderVideo::MaxConfiguredBitrateVideo() const
{
    return _maxBitrate;
}

WebRtc_Word32
RTPSenderVideo::SendVP8(const FrameType frameType,
                        const WebRtc_Word8 payloadType,
                        const WebRtc_UWord32 captureTimeStamp,
                        const WebRtc_UWord8* payloadData,
                        const WebRtc_UWord32 payloadSize,
                        const RTPFragmentationHeader* fragmentation,
                        const RTPVideoTypeHeader* rtpTypeHdr)
{
    const WebRtc_UWord16 rtpHeaderLength = _rtpSender.RTPHeaderLength();

    WebRtc_Word32 payloadBytesToSend = payloadSize;
    const WebRtc_UWord8* data = payloadData;

    WebRtc_UWord16 maxPayloadLengthVP8 = _rtpSender.MaxDataPayloadLength();

    assert(rtpTypeHdr);
    RtpFormatVp8 packetizer(data, payloadBytesToSend, rtpTypeHdr->VP8,
                            maxPayloadLengthVP8, *fragmentation, kAggregate);

    StorageType storage = kAllowRetransmission;
    if (rtpTypeHdr->VP8.temporalIdx == 0 &&
        !(_retransmissionSettings & kRetransmitBaseLayer)) {
      storage = kDontRetransmit;
    }
    if (rtpTypeHdr->VP8.temporalIdx > 0 &&
        !(_retransmissionSettings & kRetransmitHigherLayers)) {
      storage = kDontRetransmit;
    }

    bool last = false;
    _numberFirstPartition = 0;
    while (!last)
    {
        // Write VP8 Payload Descriptor and VP8 payload.
        WebRtc_UWord8 dataBuffer[IP_PACKET_SIZE] = {0};
        int payloadBytesInPacket = 0;
        int packetStartPartition =
            packetizer.NextPacket(&dataBuffer[rtpHeaderLength],
                                  &payloadBytesInPacket, &last);
        if (packetStartPartition == 0)
        {
            ++_numberFirstPartition;
        }
        else if (packetStartPartition < 0)
        {
            return -1;
        }

        // Write RTP header.
        // Set marker bit true if this is the last packet in frame.
        _rtpSender.BuildRTPheader(dataBuffer, payloadType, last,
            captureTimeStamp);
        if (-1 == SendVideoPacket(frameType, dataBuffer, payloadBytesInPacket,
            rtpHeaderLength, storage))
        {
          WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
                       "RTPSenderVideo::SendVP8 failed to send packet number"
                       " %d", _rtpSender.SequenceNumber());
        }
    }
    return 0;
}

void RTPSenderVideo::ProcessBitrate() {
  _videoBitrate.Process();
  _fecOverheadRate.Process();
}

WebRtc_UWord32 RTPSenderVideo::VideoBitrateSent() const {
  return _videoBitrate.BitrateLast();
}

WebRtc_UWord32 RTPSenderVideo::FecOverheadRate() const {
  return _fecOverheadRate.BitrateLast();
}

int RTPSenderVideo::SelectiveRetransmissions() const {
  return _retransmissionSettings;
}

int RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) {
  _retransmissionSettings = settings;
  return 0;
}

} // namespace webrtc
