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

#include <cstring> // memcpy
#include <cmath>   // ceil
#include <cassert>

#include "trace.h"

#if defined(_WIN32)
    #include <Windows.h> // FILETIME
    #include <WinSock.h> // timeval
    #include <MMSystem.h> //timeGetTime
#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_MAC))
    #include <sys/time.h> // gettimeofday
    #include <time.h>
#endif

#if (defined(_DEBUG) && defined(_WIN32) && (_MSC_VER >= 1400))
#include <stdio.h>
#define DEBUG_PRINT(...)        \
{                                \
    char msg[256];                \
    sprintf(msg, __VA_ARGS__);    \
    OutputDebugString(msg);        \
}
#else
// special fix for visual 2003
#define DEBUG_PRINT(exp)        ((void)0)
#endif  // defined(_DEBUG) && defined(_WIN32)

namespace webrtc {

/*
 * Time routines.
 */

#if defined(_WIN32)
    namespace ModuleRTPUtility {
        class WindowsHelpTimer
        {
        public:
            struct reference_point
            {
                FILETIME      file_time;
                LARGE_INTEGER counterMS;
            };

            WindowsHelpTimer()
            {
                // set timer accuracy to 1 ms
                timeBeginPeriod(1);

                _timeInMs = 0;
                _numWrapTimeInMs = 0;
                synchronize();
            };

            virtual ~WindowsHelpTimer()
            {
                timeEndPeriod(1);
            };

            void get_time(FILETIME& current_time)
            {
                // we can't use query performance counter due to speed stepping
                DWORD t = timeGetTime();
                // NOTE: we have a miss match in sign between _timeInMs(LONG) and t(DWORD) however we only use it here without +- etc
                volatile LONG* timeInMsPtr = &_timeInMs;
                DWORD old = InterlockedExchange(timeInMsPtr, t); // make sure that we only inc wrapper once
                if(old > t)
                {
                    // wrap
                    _numWrapTimeInMs++;
                }
                LARGE_INTEGER elapsedMS;
                elapsedMS.HighPart = _numWrapTimeInMs;
                elapsedMS.LowPart = t;

                elapsedMS.QuadPart = elapsedMS.QuadPart - _ref_point.counterMS.QuadPart;

                //
                // Translate to 100-nanoseconds intervals (FILETIME resolution) and add to
                // reference FILETIME to get current FILETIME.
                //
                ULARGE_INTEGER filetime_ref_as_ul;

                filetime_ref_as_ul.HighPart = _ref_point.file_time.dwHighDateTime;
                filetime_ref_as_ul.LowPart = _ref_point.file_time.dwLowDateTime;
                filetime_ref_as_ul.QuadPart += (ULONGLONG)((elapsedMS.QuadPart)*1000*10);
                //
                // Copy to result
                //
                current_time.dwHighDateTime = filetime_ref_as_ul.HighPart;
                current_time.dwLowDateTime = filetime_ref_as_ul.LowPart;
            };

        private:
            void synchronize()
            {
                FILETIME    ft0 = { 0, 0 },
                            ft1 = { 0, 0 };
                //
                // Spin waiting for a change in system time. Get the matching
                // performance counter value for that time.
                //
                ::GetSystemTimeAsFileTime(&ft0);
                do
                {
                    ::GetSystemTimeAsFileTime(&ft1);
                    _ref_point.counterMS.QuadPart = ::timeGetTime();
                    ::Sleep(0);
                }
                while ((ft0.dwHighDateTime == ft1.dwHighDateTime) &&
                        (ft0.dwLowDateTime == ft1.dwLowDateTime));

                _ref_point.file_time = ft1;
            }
            volatile LONG           _timeInMs;              // this needs to be long due to Windows, not an issue due to its usage
            volatile WebRtc_UWord32   _numWrapTimeInMs;
            reference_point         _ref_point;
        };

        // A clock reading times from the Windows API.
        class WindowsSystemClock : public RtpRtcpClock {
        public:
            WindowsSystemClock()
                : _helpTimer() {}

            virtual ~WindowsSystemClock() {}

            virtual WebRtc_UWord32 GetTimeInMS();

            virtual void CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac);

        private:
            WindowsHelpTimer _helpTimer;
        };
    }; // namespace ModuleRTPUtility

#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)

    namespace ModuleRTPUtility {
        // A clock reading times from the POSIX API.
        class UnixSystemClock : public RtpRtcpClock {
        public:
            UnixSystemClock() {}
            virtual ~UnixSystemClock() {}

            virtual WebRtc_UWord32 GetTimeInMS();

            virtual void CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac);
        };
    }; // namespace ModuleRTPUtility
#endif

namespace ModuleRTPUtility {

#if defined(_WIN32)
WebRtc_UWord32 WindowsSystemClock::GetTimeInMS()
{
    return timeGetTime();
}

// Use the system time (roughly synchronised to the tick, and
// extrapolated using the system performance counter.
void WindowsSystemClock::CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac)
{
    const WebRtc_UWord64 FILETIME_1970 = 0x019db1ded53e8000;

    FILETIME StartTime;
    WebRtc_UWord64 Time;
    struct timeval tv;

    // we can't use query performance counter since they can change depending on speed steping
    _helpTimer.get_time(StartTime);

    Time = (((WebRtc_UWord64) StartTime.dwHighDateTime) << 32) +
        (WebRtc_UWord64) StartTime.dwLowDateTime;

    // Convert the hecto-nano second time to tv format
    Time -= FILETIME_1970;

    tv.tv_sec = (WebRtc_UWord32) ( Time / (WebRtc_UWord64)10000000);
    tv.tv_usec = (WebRtc_UWord32) (( Time % (WebRtc_UWord64)10000000) / 10);

    double dtemp;

    secs = tv.tv_sec + NTP_JAN_1970;
    dtemp = tv.tv_usec / 1e6;

    if (dtemp >= 1)
    {
        dtemp -= 1;
        secs++;
    } else if (dtemp < -1)
    {
        dtemp += 1;
        secs--;
    }
    dtemp *= NTP_FRAC;
    frac = (WebRtc_UWord32)dtemp;
}

#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_MAC))

WebRtc_UWord32 UnixSystemClock::GetTimeInMS()
{
    struct timeval tv;
    struct timezone tz;
    WebRtc_UWord32 val;

    gettimeofday(&tv, &tz);
    val = (WebRtc_UWord32)(tv.tv_sec*1000 + tv.tv_usec/1000);
    return val;
}

// Use the system time.
void UnixSystemClock::CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac)
{
    double dtemp;
    struct timeval tv;
    struct timezone tz;
    tz.tz_minuteswest  = 0;
    tz.tz_dsttime = 0;
    gettimeofday(&tv,&tz);

    secs = tv.tv_sec + NTP_JAN_1970;
    dtemp = tv.tv_usec / 1e6;
    if (dtemp >= 1)
    {
        dtemp -= 1;
        secs++;
    } else if (dtemp < -1)
    {
        dtemp += 1;
        secs--;
    }
    dtemp *= NTP_FRAC;
    frac = (WebRtc_UWord32)dtemp;
}
#endif

RtpRtcpClock* GetSystemClock()
{
    // TODO(hellner): violates the style guide (non-POD static instance).
#if defined(_WIN32)
    static WindowsSystemClock system_clock;
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
    static UnixSystemClock system_clock;
#endif
    return &system_clock;
}

WebRtc_UWord32 GetCurrentRTP(RtpRtcpClock* clock, WebRtc_UWord32 freq)
{
    if (clock == NULL)
        clock = GetSystemClock();
    WebRtc_UWord32 secs = 0, frac = 0;
    clock->CurrentNTP(secs, frac);
    return ConvertNTPTimeToRTP(secs, frac, freq);
}

WebRtc_UWord32 ConvertNTPTimeToRTP(WebRtc_UWord32 NTPsec,
                                   WebRtc_UWord32 NTPfrac,
                                   WebRtc_UWord32 freq)
{
    float ftemp = (float)NTPfrac/(float)NTP_FRAC;
    WebRtc_UWord32 tmp = (WebRtc_UWord32)(ftemp * freq);
    return NTPsec*freq + tmp;
}

WebRtc_UWord32 ConvertNTPTimeToMS(WebRtc_UWord32 NTPsec,
                                  WebRtc_UWord32 NTPfrac)
{
    int freq = 1000;
    float ftemp = (float)NTPfrac/(float)NTP_FRAC;
    WebRtc_UWord32 tmp = (WebRtc_UWord32)(ftemp * freq);
    WebRtc_UWord32 MStime= NTPsec*freq + tmp;
    return MStime;
}

bool OldTimestamp(uint32_t newTimestamp,
                  uint32_t existingTimestamp,
                  bool* wrapped)
{
    bool tmpWrapped =
        (newTimestamp < 0x0000ffff && existingTimestamp > 0xffff0000) ||
        (newTimestamp > 0xffff0000 && existingTimestamp < 0x0000ffff);
    *wrapped = tmpWrapped;
    if (existingTimestamp > newTimestamp && !tmpWrapped)
    {
        return true;
    }
    else if (existingTimestamp <= newTimestamp && !tmpWrapped)
    {
        return false;
    }
    else if (existingTimestamp < newTimestamp && tmpWrapped)
    {
        return true;
    }
    else
    {
        return false;
    }
}

} // namespace ModuleRTPUtility

/*
 * Misc utility routines
 */

#if defined(_WIN32)
bool ModuleRTPUtility::StringCompare(const char* str1,
                                     const char* str2,
                                     const WebRtc_UWord32 length)
{
    return (_strnicmp(str1, str2, length) == 0)?true: false;
}
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
bool ModuleRTPUtility::StringCompare(const char* str1,
                                     const char* str2,
                                     const WebRtc_UWord32 length)
{
    return (strncasecmp(str1, str2, length) == 0)?true: false;
}
#endif

#if !defined(WEBRTC_LITTLE_ENDIAN) && !defined(WEBRTC_BIG_ENDIAN)
    #error Either WEBRTC_LITTLE_ENDIAN or WEBRTC_BIG_ENDIAN must be defined
#endif

/* for RTP/RTCP
    All integer fields are carried in network byte order, that is, most
    significant byte (octet) first.  AKA big-endian.
*/
void
ModuleRTPUtility::AssignUWord32ToBuffer(WebRtc_UWord8* dataBuffer, WebRtc_UWord32 value)
{
#if defined(WEBRTC_LITTLE_ENDIAN)
    dataBuffer[0] = static_cast<WebRtc_UWord8>(value>>24);
    dataBuffer[1] = static_cast<WebRtc_UWord8>(value>>16);
    dataBuffer[2] = static_cast<WebRtc_UWord8>(value>>8);
    dataBuffer[3] = static_cast<WebRtc_UWord8>(value);
#else
    WebRtc_UWord32* ptr = reinterpret_cast<WebRtc_UWord32*>(dataBuffer);
    ptr[0] = value;
#endif
}

void
ModuleRTPUtility::AssignUWord24ToBuffer(WebRtc_UWord8* dataBuffer, WebRtc_UWord32 value)
{
#if defined(WEBRTC_LITTLE_ENDIAN)
    dataBuffer[0] = static_cast<WebRtc_UWord8>(value>>16);
    dataBuffer[1] = static_cast<WebRtc_UWord8>(value>>8);
    dataBuffer[2] = static_cast<WebRtc_UWord8>(value);
#else
    dataBuffer[0] = static_cast<WebRtc_UWord8>(value);
    dataBuffer[1] = static_cast<WebRtc_UWord8>(value>>8);
    dataBuffer[2] = static_cast<WebRtc_UWord8>(value>>16);
#endif
}

void
ModuleRTPUtility::AssignUWord16ToBuffer(WebRtc_UWord8* dataBuffer, WebRtc_UWord16 value)
{
#if defined(WEBRTC_LITTLE_ENDIAN)
    dataBuffer[0] = static_cast<WebRtc_UWord8>(value>>8);
    dataBuffer[1] = static_cast<WebRtc_UWord8>(value);
#else
    WebRtc_UWord16* ptr = reinterpret_cast<WebRtc_UWord16*>(dataBuffer);
    ptr[0] = value;
#endif
}

WebRtc_UWord16
ModuleRTPUtility::BufferToUWord16(const WebRtc_UWord8* dataBuffer)
{
#if defined(WEBRTC_LITTLE_ENDIAN)
    return (dataBuffer[0] << 8) + dataBuffer[1];
#else
    return *reinterpret_cast<const WebRtc_UWord16*>(dataBuffer);
#endif
}

WebRtc_UWord32
ModuleRTPUtility::BufferToUWord24(const WebRtc_UWord8* dataBuffer)
{
    return (dataBuffer[0] << 16) + (dataBuffer[1] << 8) + dataBuffer[2];
}

WebRtc_UWord32
ModuleRTPUtility::BufferToUWord32(const WebRtc_UWord8* dataBuffer)
{
#if defined(WEBRTC_LITTLE_ENDIAN)
    return (dataBuffer[0] << 24) + (dataBuffer[1] << 16) + (dataBuffer[2] << 8) +
        dataBuffer[3];
#else
    return *reinterpret_cast<const WebRtc_UWord32*>(dataBuffer);
#endif
}

WebRtc_UWord32
ModuleRTPUtility::pow2(WebRtc_UWord8 exp)
{
    return 1 << exp;
}

void
ModuleRTPUtility::RTPPayload::SetType(RtpVideoCodecTypes videoType)
{
    type = videoType;

    switch (type)
    {
    case kRtpNoVideo:
        break;
    case kRtpVp8Video:
    {
        info.VP8.nonReferenceFrame = false;
        info.VP8.beginningOfPartition = false;
        info.VP8.partitionID = 0;
        info.VP8.hasPictureID = false;
        info.VP8.hasTl0PicIdx = false;
        info.VP8.hasTID = false;
        info.VP8.hasKeyIdx = false;
        info.VP8.pictureID = -1;
        info.VP8.tl0PicIdx = -1;
        info.VP8.tID = -1;
        info.VP8.layerSync = false;
        info.VP8.frameWidth = 0;
        info.VP8.frameHeight = 0;
        break;
    }
    default:
        break;
    }
}

ModuleRTPUtility::RTPHeaderParser::RTPHeaderParser(const WebRtc_UWord8* rtpData,
                                                   const WebRtc_UWord32 rtpDataLength):
    _ptrRTPDataBegin(rtpData),
    _ptrRTPDataEnd(rtpData ? (rtpData + rtpDataLength) : NULL)
{
}

ModuleRTPUtility::RTPHeaderParser::~RTPHeaderParser()
{
}

bool
ModuleRTPUtility::RTPHeaderParser::RTCP() const
{
    // 72 to 76 is reserved for RTP
    // 77 to 79 is not reserver but  they are not assigned we will block them
    // for RTCP 200 SR  == marker bit + 72
    // for RTCP 204 APP == marker bit + 76
    /*
    *       RTCP
    *
    * FIR      full INTRA-frame request             192     [RFC2032]   supported
    * NACK     negative acknowledgement             193     [RFC2032]
    * IJ       Extended inter-arrival jitter report 195     [RFC-ietf-avt-rtp-toffset-07.txt] http://tools.ietf.org/html/draft-ietf-avt-rtp-toffset-07
    * SR       sender report                        200     [RFC3551]   supported
    * RR       receiver report                      201     [RFC3551]   supported
    * SDES     source description                   202     [RFC3551]   supported
    * BYE      goodbye                              203     [RFC3551]   supported
    * APP      application-defined                  204     [RFC3551]   ignored
    * RTPFB    Transport layer FB message           205     [RFC4585]   supported
    * PSFB     Payload-specific FB message          206     [RFC4585]   supported
    * XR       extended report                      207     [RFC3611]   supported
    */

   /* 205       RFC 5104
    * FMT 1      NACK       supported
    * FMT 2      reserved
    * FMT 3      TMMBR      supported
    * FMT 4      TMMBN      supported
    */

    /* 206      RFC 5104
    * FMT 1:     Picture Loss Indication (PLI)                      supported
    * FMT 2:     Slice Lost Indication (SLI)
    * FMT 3:     Reference Picture Selection Indication (RPSI)
    * FMT 4:     Full Intra Request (FIR) Command                   supported
    * FMT 5:     Temporal-Spatial Trade-off Request (TSTR)
    * FMT 6:     Temporal-Spatial Trade-off Notification (TSTN)
    * FMT 7:     Video Back Channel Message (VBCM)
    * FMT 15:    Application layer FB message
    */

    const WebRtc_UWord8  payloadType = _ptrRTPDataBegin[1];

    bool RTCP = false;

    // check if this is a RTCP packet
    switch(payloadType)
    {
    case 192:
        RTCP = true;
        break;
    case 193:
        // not supported
        // pass through and check for a potential RTP packet
        break;
    case 195:
    case 200:
    case 201:
    case 202:
    case 203:
    case 204:
    case 205:
    case 206:
    case 207:
        RTCP = true;
        break;
    }
    return RTCP;
}

bool
ModuleRTPUtility::RTPHeaderParser::Parse(
    WebRtcRTPHeader& parsedPacket, RtpHeaderExtensionMap* ptrExtensionMap) const
{
    const ptrdiff_t length = _ptrRTPDataEnd - _ptrRTPDataBegin;

    if (length < 12)
    {
        return false;
    }

    const WebRtc_UWord8 V  = _ptrRTPDataBegin[0] >> 6 ;                          // Version
    const bool          P  = ((_ptrRTPDataBegin[0] & 0x20) == 0) ? false : true; // Padding
    const bool          X  = ((_ptrRTPDataBegin[0] & 0x10) == 0) ? false : true; // eXtension
    const WebRtc_UWord8 CC = _ptrRTPDataBegin[0] & 0x0f;
    const bool          M  = ((_ptrRTPDataBegin[1] & 0x80) == 0) ? false : true;

    const WebRtc_UWord8 PT = _ptrRTPDataBegin[1] & 0x7f;

    const WebRtc_UWord16 sequenceNumber = (_ptrRTPDataBegin[2] << 8) + _ptrRTPDataBegin[3];

    const WebRtc_UWord8* ptr = &_ptrRTPDataBegin[4];

    WebRtc_UWord32 RTPTimestamp = *ptr++ << 24;
    RTPTimestamp += *ptr++ << 16;
    RTPTimestamp += *ptr++ << 8;
    RTPTimestamp += *ptr++;

    WebRtc_UWord32 SSRC = *ptr++ << 24;
    SSRC += *ptr++ << 16;
    SSRC += *ptr++ << 8;
    SSRC += *ptr++;

    if (V != 2)
    {
        return false;
    }

    const WebRtc_UWord8 CSRCocts = CC * 4;

    if ((ptr + CSRCocts) > _ptrRTPDataEnd)
    {
        return false;
    }

    parsedPacket.header.markerBit      = M;
    parsedPacket.header.payloadType    = PT;
    parsedPacket.header.sequenceNumber = sequenceNumber;
    parsedPacket.header.timestamp      = RTPTimestamp;
    parsedPacket.header.ssrc           = SSRC;
    parsedPacket.header.numCSRCs       = CC;
    parsedPacket.header.paddingLength  = P ? *(_ptrRTPDataEnd - 1) : 0;

    for (unsigned int i = 0; i < CC; ++i)
    {
        WebRtc_UWord32 CSRC = *ptr++ << 24;
        CSRC += *ptr++ << 16;
        CSRC += *ptr++ << 8;
        CSRC += *ptr++;
        parsedPacket.header.arrOfCSRCs[i] = CSRC;
    }
    parsedPacket.type.Audio.numEnergy = parsedPacket.header.numCSRCs;

    parsedPacket.header.headerLength   = 12 + CSRCocts;

    // If in effect, MAY be omitted for those packets for which the offset
    // is zero.
    parsedPacket.extension.transmissionTimeOffset = 0;

    if (X)
    {
        /* RTP header extension, RFC 3550.
         0                   1                   2                   3
         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |      defined by profile       |           length              |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |                        header extension                       |
        |                             ....                              |
        */
        const ptrdiff_t remain = _ptrRTPDataEnd - ptr;
        if (remain < 4)
        {
            return false;
        }

        parsedPacket.header.headerLength += 4;

        WebRtc_UWord16 definedByProfile = *ptr++ << 8;
        definedByProfile += *ptr++;

        WebRtc_UWord16 XLen = *ptr++ << 8;
        XLen += *ptr++; // in 32 bit words
        XLen *= 4; // in octs

        if (remain < (4 + XLen))
        {
            return false;
        }
        if (definedByProfile == RTP_ONE_BYTE_HEADER_EXTENSION)
        {
            const WebRtc_UWord8* ptrRTPDataExtensionEnd = ptr + XLen;
            ParseOneByteExtensionHeader(parsedPacket,
                                        ptrExtensionMap,
                                        ptrRTPDataExtensionEnd,
                                        ptr);
        }
        parsedPacket.header.headerLength += XLen;
    }

    return true;
}

void ModuleRTPUtility::RTPHeaderParser::ParseOneByteExtensionHeader(
    WebRtcRTPHeader& parsedPacket,
    const RtpHeaderExtensionMap* ptrExtensionMap,
    const WebRtc_UWord8* ptrRTPDataExtensionEnd,
    const WebRtc_UWord8* ptr) const
{
    if (!ptrExtensionMap) {
        WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, -1, "No extension map.");
      return;
    }

    while (ptrRTPDataExtensionEnd - ptr > 0)
    {
      //  0
      //  0 1 2 3 4 5 6 7
      // +-+-+-+-+-+-+-+-+
      // |  ID   |  len  |
      // +-+-+-+-+-+-+-+-+

      const WebRtc_UWord8 id = (*ptr & 0xf0) >> 4;
      const WebRtc_UWord8 len = (*ptr & 0x0f);
      ptr++;

      if (id == 15) {
        WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, -1,
            "Ext id: 15 encountered, parsing terminated.");
        return;
      }

      RTPExtensionType type;
      if (ptrExtensionMap->GetType(id, &type) != 0) {
        WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1,
            "Failed to find extension id: %d", id);
        return;
      }

      switch (type)
      {
      case kRtpExtensionTransmissionTimeOffset:
      {
        if (len != 2)
        {
          WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, -1,
              "Incorrect transmission time offset len: %d", len);
          return;
        }
        //  0                   1                   2                   3
        //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        // |  ID   | len=2 |              transmission offset              |
        // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

        WebRtc_Word32 transmissionTimeOffset = *ptr++ << 16;
        transmissionTimeOffset += *ptr++ << 8;
        transmissionTimeOffset += *ptr++;
        parsedPacket.extension.transmissionTimeOffset = transmissionTimeOffset;
        break;
      }
      case kRtpExtensionAudioLevel:
      {
      //   --- Only used for debugging ---
      //  0                   1                   2                   3
      //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      // |  ID   | len=0 |V|   level     |      0x00     |      0x00     |
      // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      //

      // Parse out the fields but only use it for debugging for now.
      //const WebRtc_UWord8 V = (*ptr & 0x80) >> 7;
      //const WebRtc_UWord8 level = (*ptr & 0x7f);
      //DEBUG_PRINT("RTP_AUDIO_LEVEL_UNIQUE_ID: ID=%u, len=%u, V=%u, level=%u",
      //    ID, len, V, level);
        break;
      }
      default:
      {
        WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, -1,
            "Extension type not implemented.");
        return;
      }
      }
      WebRtc_UWord8 num_bytes = ParsePaddingBytes(ptrRTPDataExtensionEnd, ptr);
      ptr += num_bytes;
    }
}

WebRtc_UWord8 ModuleRTPUtility::RTPHeaderParser::ParsePaddingBytes(
    const WebRtc_UWord8* ptrRTPDataExtensionEnd,
    const WebRtc_UWord8* ptr) const {

  WebRtc_UWord8 num_zero_bytes = 0;
  while (ptrRTPDataExtensionEnd - ptr > 0) {
    if (*ptr != 0) {
      return num_zero_bytes;
    }
    ptr++;
    num_zero_bytes++;
  }
  return num_zero_bytes;
}

// RTP payload parser
ModuleRTPUtility::RTPPayloadParser::RTPPayloadParser(
        const RtpVideoCodecTypes videoType,
        const WebRtc_UWord8* payloadData,
        const WebRtc_UWord16 payloadDataLength,
        const WebRtc_Word32 id)
    :
    _id(id),
    _dataPtr(payloadData),
    _dataLength(payloadDataLength),
    _videoType(videoType)
{
}

ModuleRTPUtility::RTPPayloadParser::~RTPPayloadParser()
{
}

bool
ModuleRTPUtility::RTPPayloadParser::Parse( RTPPayload& parsedPacket) const
{
    parsedPacket.SetType(_videoType);

    switch (_videoType)
    {
    case kRtpNoVideo:
        return ParseGeneric(parsedPacket);
    case kRtpVp8Video:
        return ParseVP8(parsedPacket);
    default:
        return false;
    }
}

bool
ModuleRTPUtility::RTPPayloadParser::ParseGeneric(RTPPayload& /*parsedPacket*/) const
{
    return false;
}

//
// VP8 format:
//
// Payload descriptor
//       0 1 2 3 4 5 6 7
//      +-+-+-+-+-+-+-+-+
//      |X|R|N|S|PartID | (REQUIRED)
//      +-+-+-+-+-+-+-+-+
// X:   |I|L|T|K|  RSV  | (OPTIONAL)
//      +-+-+-+-+-+-+-+-+
// I:   |   PictureID   | (OPTIONAL)
//      +-+-+-+-+-+-+-+-+
// L:   |   TL0PICIDX   | (OPTIONAL)
//      +-+-+-+-+-+-+-+-+
// T/K: |TID:Y| KEYIDX  | (OPTIONAL)
//      +-+-+-+-+-+-+-+-+
//
// Payload header (considered part of the actual payload, sent to decoder)
//       0 1 2 3 4 5 6 7
//      +-+-+-+-+-+-+-+-+
//      |Size0|H| VER |P|
//      +-+-+-+-+-+-+-+-+
//      |      ...      |
//      +               +

bool
ModuleRTPUtility::RTPPayloadParser::ParseVP8(RTPPayload& parsedPacket) const
{
    RTPPayloadVP8 *vp8 = &parsedPacket.info.VP8;
    const WebRtc_UWord8 *dataPtr = _dataPtr;
    int dataLength = _dataLength;

    // Parse mandatory first byte of payload descriptor
    bool extension =            (*dataPtr & 0x80) ? true : false; // X bit
    vp8->nonReferenceFrame =    (*dataPtr & 0x20) ? true : false; // N bit
    vp8->beginningOfPartition = (*dataPtr & 0x10) ? true : false; // S bit
    vp8->partitionID =          (*dataPtr & 0x0F); // PartID field

    // Advance dataPtr and decrease remaining payload size
    dataPtr++;
    dataLength--;

    if (extension)
    {
        const int parsedBytes = ParseVP8Extension(vp8, dataPtr, dataLength);
        if (parsedBytes < 0) return false;
        dataPtr += parsedBytes;
        dataLength -= parsedBytes;
    }

    if (dataLength <= 0)
    {
        WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
                "Error parsing VP8 payload descriptor; payload too short");
        return false;
    }

    // Read P bit from payload header (only at beginning of first partition)
    if (dataLength > 0 && vp8->beginningOfPartition && vp8->partitionID == 0)
    {
        parsedPacket.frameType = (*dataPtr & 0x01) ? kPFrame : kIFrame;
    }
    else
    {
        parsedPacket.frameType = kPFrame;
    }
    if (0 != ParseVP8FrameSize(parsedPacket, dataPtr, dataLength))
    {
        return false;
    }
    parsedPacket.info.VP8.data       = dataPtr;
    parsedPacket.info.VP8.dataLength = dataLength;
    return true;
}

int ModuleRTPUtility::RTPPayloadParser::ParseVP8FrameSize(
      RTPPayload &parsedPacket,
      const WebRtc_UWord8 *dataPtr,
      int dataLength) const
{
    if (parsedPacket.frameType != kIFrame)
    {
        // Included in payload header for I-frames.
        return 0;
    }
    if (dataLength < 10)
    {
        // For an I-frame we should always have the uncompressed VP8 header
        // in the beginning of the partition.
        return -1;
    }
    RTPPayloadVP8 *vp8 = &parsedPacket.info.VP8;
    vp8->frameWidth = ((dataPtr[7] << 8) + dataPtr[6]) & 0x3FFF;
    vp8->frameHeight = ((dataPtr[9] << 8) + dataPtr[8]) & 0x3FFF;
    return 0;
}

int ModuleRTPUtility::RTPPayloadParser::ParseVP8Extension(
        RTPPayloadVP8 *vp8,
        const WebRtc_UWord8 *dataPtr,
        int dataLength) const
{
    int parsedBytes = 0;
    if (dataLength <= 0) return -1;
    // Optional X field is present
    vp8->hasPictureID = (*dataPtr & 0x80) ? true : false; // I bit
    vp8->hasTl0PicIdx = (*dataPtr & 0x40) ? true : false; // L bit
    vp8->hasTID =       (*dataPtr & 0x20) ? true : false; // T bit
    vp8->hasKeyIdx =    (*dataPtr & 0x10) ? true : false; // K bit

    // Advance dataPtr and decrease remaining payload size
    dataPtr++;
    parsedBytes++;
    dataLength--;

    if (vp8->hasPictureID)
    {
        if (ParseVP8PictureID(vp8, &dataPtr, &dataLength, &parsedBytes) != 0)
        {
            return -1;
        }
    }

    if (vp8->hasTl0PicIdx)
    {
        if (ParseVP8Tl0PicIdx(vp8, &dataPtr, &dataLength, &parsedBytes) != 0)
        {
            return -1;
        }
    }

    if (vp8->hasTID || vp8->hasKeyIdx)
    {
        if (ParseVP8TIDAndKeyIdx(vp8, &dataPtr, &dataLength, &parsedBytes) != 0)
        {
            return -1;
        }
    }
    return parsedBytes;
}

int
ModuleRTPUtility::RTPPayloadParser::ParseVP8PictureID(
        RTPPayloadVP8 *vp8,
        const WebRtc_UWord8 **dataPtr,
        int *dataLength,
        int *parsedBytes) const
{
    if (*dataLength <= 0) return -1;
    vp8->pictureID = (**dataPtr & 0x7F);
    if (**dataPtr & 0x80)
    {
        (*dataPtr)++;
        (*parsedBytes)++;
        if (--(*dataLength) <= 0) return -1;
        // PictureID is 15 bits
        vp8->pictureID = (vp8->pictureID << 8) + **dataPtr;
    }
    (*dataPtr)++;
    (*parsedBytes)++;
    (*dataLength)--;
    return 0;
}

int
ModuleRTPUtility::RTPPayloadParser::ParseVP8Tl0PicIdx(
        RTPPayloadVP8 *vp8,
        const WebRtc_UWord8 **dataPtr,
        int *dataLength,
        int *parsedBytes) const
{
    if (*dataLength <= 0) return -1;
    vp8->tl0PicIdx = **dataPtr;
    (*dataPtr)++;
    (*parsedBytes)++;
    (*dataLength)--;
    return 0;
}

int ModuleRTPUtility::RTPPayloadParser::ParseVP8TIDAndKeyIdx(
        RTPPayloadVP8 *vp8,
        const WebRtc_UWord8 **dataPtr,
        int *dataLength,
        int *parsedBytes) const
{
    if (*dataLength <= 0) return -1;
    if (vp8->hasTID)
    {
        vp8->tID = ((**dataPtr >> 6) & 0x03);
        vp8->layerSync = (**dataPtr & 0x20) ? true : false;  // Y bit
    }
    if (vp8->hasKeyIdx)
    {
        vp8->keyIdx = (**dataPtr & 0x1F);
    }
    (*dataPtr)++;
    (*parsedBytes)++;
    (*dataLength)--;
    return 0;
}
} // namespace webrtc
