/*
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 *
 * The Original Code is MPEG4IP.
 *
 * The Initial Developer of the Original Code is Cisco Systems Inc.
 * Portions created by Cisco Systems Inc. are
 * Copyright (C) Cisco Systems Inc. 2001.  All Rights Reserved.
 *
 * Contributor(s):
 *      Dave Mackie     dmackie@cisco.com
 */

#include "src/impl.h"

namespace mp4v2 {
namespace impl {

///////////////////////////////////////////////////////////////////////////////

/* rtp hint track operations */

MP4RtpHintTrack::MP4RtpHintTrack(MP4File& file, MP4Atom& trakAtom)
        : MP4Track(file, trakAtom)
{
    m_pRefTrack = NULL;

    m_pRtpMapProperty = NULL;
    m_pPayloadNumberProperty = NULL;
    m_pMaxPacketSizeProperty = NULL;
    m_pSnroProperty = NULL;
    m_pTsroProperty = NULL;

    m_pReadHint = NULL;
    m_pReadHintSample = NULL;
    m_readHintSampleSize = 0;

    m_pWriteHint = NULL;
    m_writeHintId = MP4_INVALID_SAMPLE_ID;
    m_writePacketId = 0;

    m_pTrpy = NULL;
    m_pNump = NULL;
    m_pTpyl = NULL;
    m_pMaxr = NULL;
    m_pDmed = NULL;
    m_pDimm = NULL;
    m_pPmax = NULL;
    m_pDmax = NULL;

    m_pMaxPdu = NULL;
    m_pAvgPdu = NULL;
    m_pMaxBitRate = NULL;
    m_pAvgBitRate = NULL;

    m_thisSec = 0;
    m_bytesThisSec = 0;
    m_bytesThisHint = 0;
    m_bytesThisPacket = 0;
}

MP4RtpHintTrack::~MP4RtpHintTrack()
{
    delete m_pReadHint; m_pReadHint = NULL;
    MP4Free( m_pReadHintSample ); m_pReadHintSample = NULL;
    delete m_pWriteHint; m_pWriteHint = NULL;
}

void MP4RtpHintTrack::InitRefTrack()
{
    if (m_pRefTrack == NULL) {
        MP4Integer32Property* pRefTrackIdProperty = NULL;
        (void)m_trakAtom.FindProperty(
            "trak.tref.hint.entries[0].trackId",
            (MP4Property**)&pRefTrackIdProperty);
        ASSERT(pRefTrackIdProperty);

        m_pRefTrack = m_File.GetTrack(pRefTrackIdProperty->GetValue());
    }
}

void MP4RtpHintTrack::InitRtpStart()
{
    number::srandom( time::getLocalTimeMilliseconds() );

    (void)m_trakAtom.FindProperty(
        "trak.udta.hnti.rtp .snro.offset",
        (MP4Property**)&m_pSnroProperty);

    if (m_pSnroProperty) {
        m_rtpSequenceStart = m_pSnroProperty->GetValue();
    } else {
        m_rtpSequenceStart = number::random32();
    }

    (void)m_trakAtom.FindProperty(
        "trak.udta.hnti.rtp .tsro.offset",
        (MP4Property**)&m_pTsroProperty);

    if (m_pTsroProperty) {
        m_rtpTimestampStart = m_pTsroProperty->GetValue();
    } else {
        m_rtpTimestampStart = number::random32();
    }
}

void MP4RtpHintTrack::ReadHint(
    MP4SampleId hintSampleId,
    uint16_t* pNumPackets)
{
    if (m_pRefTrack == NULL) {
        InitRefTrack();
        InitRtpStart();
    }

    // dispose of any old hint
    delete m_pReadHint; m_pReadHint = NULL;
    MP4Free( m_pReadHintSample ); m_pReadHintSample = NULL;
    m_readHintSampleSize = 0;

    // read the desired hint sample into memory
    ReadSample(
        hintSampleId,
        &m_pReadHintSample,
        &m_readHintSampleSize,
        &m_readHintTimestamp);

    m_File.EnableMemoryBuffer(m_pReadHintSample, m_readHintSampleSize);

    m_pReadHint = new MP4RtpHint(*this);
    m_pReadHint->Read(m_File);

    m_File.DisableMemoryBuffer();

    if (pNumPackets) {
        *pNumPackets = GetHintNumberOfPackets();
    }
}

uint16_t MP4RtpHintTrack::GetHintNumberOfPackets()
{
    if (m_pReadHint == NULL) {
        throw new Exception("no hint has been read",
                            __FILE__, __LINE__, __FUNCTION__);
    }
    return m_pReadHint->GetNumberOfPackets();
}

bool MP4RtpHintTrack::GetPacketBFrame(uint16_t packetIndex)
{
    if (m_pReadHint == NULL) {
        throw new Exception("no hint has been read",
                            __FILE__, __LINE__, __FUNCTION__);
    }
    MP4RtpPacket* pPacket =
        m_pReadHint->GetPacket(packetIndex);

    return pPacket->IsBFrame();
}

uint16_t MP4RtpHintTrack::GetPacketTransmitOffset(uint16_t packetIndex)
{
    if (m_pReadHint == NULL) {
        throw new Exception("no hint has been read",
                            __FILE__, __LINE__, __FUNCTION__);
     }

    MP4RtpPacket* pPacket =
        m_pReadHint->GetPacket(packetIndex);

    return pPacket->GetTransmitOffset();
}

void MP4RtpHintTrack::ReadPacket(
    uint16_t packetIndex,
    uint8_t** ppBytes,
    uint32_t* pNumBytes,
    uint32_t ssrc,
    bool addHeader,
    bool addPayload)
{
    if (m_pReadHint == NULL) {
        throw new Exception("no hint has been read",
                            __FILE__, __LINE__, __FUNCTION__);
    }
    if (!addHeader && !addPayload) {
        throw new Exception("no data requested",
                             __FILE__, __LINE__, __FUNCTION__);
    }

    MP4RtpPacket* pPacket =
        m_pReadHint->GetPacket(packetIndex);

    *pNumBytes = 0;
    if (addHeader) {
        *pNumBytes += 12;
    }
    if (addPayload) {
        *pNumBytes += pPacket->GetDataSize();
    }

    // if needed, allocate the packet memory
    bool buffer_malloc = false;

    if (*ppBytes == NULL) {
        *ppBytes = (uint8_t*)MP4Malloc(*pNumBytes);
        buffer_malloc = true;
    }

    try {
        uint8_t* pDest = *ppBytes;

        if (addHeader) {
            *pDest++ =
                0x80 | (pPacket->GetPBit() << 5) | (pPacket->GetXBit() << 4);

            *pDest++ =
                (pPacket->GetMBit() << 7) | pPacket->GetPayload();

            *((uint16_t*)pDest) =
                MP4V2_HTONS(m_rtpSequenceStart + pPacket->GetSequenceNumber());
            pDest += 2;

            *((uint32_t*)pDest) =
                MP4V2_HTONL(m_rtpTimestampStart + (uint32_t)m_readHintTimestamp);
            pDest += 4;

            *((uint32_t*)pDest) =
                MP4V2_HTONL(ssrc);
            pDest += 4;
        }

        if (addPayload) {
            pPacket->GetData(pDest);
        }
    }
    catch (Exception* x) {
        if (buffer_malloc) {
            MP4Free(*ppBytes);
            *ppBytes = NULL;
        }
        throw x;
    }

    log.hexDump(0, MP4_LOG_VERBOSE1, *ppBytes, *pNumBytes,
                "\"%s\": %u ", GetFile().GetFilename().c_str(),
                packetIndex);
}

MP4Timestamp MP4RtpHintTrack::GetRtpTimestampStart()
{
    if (m_pRefTrack == NULL) {
        InitRefTrack();
        InitRtpStart();
    }

    return m_rtpTimestampStart;
}

void MP4RtpHintTrack::SetRtpTimestampStart(MP4Timestamp start)
{
    if (!m_pTsroProperty) {
        MP4Atom* pTsroAtom =
            m_File.AddDescendantAtoms(&m_trakAtom, "udta.hnti.rtp .tsro");

        ASSERT(pTsroAtom);

        (void)pTsroAtom->FindProperty("offset",
                                      (MP4Property**)&m_pTsroProperty);

        ASSERT(m_pTsroProperty);
    }

    m_pTsroProperty->SetValue(start);
    m_rtpTimestampStart = start;
}

void MP4RtpHintTrack::InitPayload()
{
    if (m_pRtpMapProperty == NULL) {
        (void)m_trakAtom.FindProperty(
            "trak.udta.hinf.payt.rtpMap",
            (MP4Property**)&m_pRtpMapProperty);
    }

    if (m_pPayloadNumberProperty == NULL) {
        (void)m_trakAtom.FindProperty(
            "trak.udta.hinf.payt.payloadNumber",
            (MP4Property**)&m_pPayloadNumberProperty);
    }

    if (m_pMaxPacketSizeProperty == NULL) {
        (void)m_trakAtom.FindProperty(
            "trak.mdia.minf.stbl.stsd.rtp .maxPacketSize",
            (MP4Property**)&m_pMaxPacketSizeProperty);
    }
}

void MP4RtpHintTrack::GetPayload(
    char** ppPayloadName,
    uint8_t* pPayloadNumber,
    uint16_t* pMaxPayloadSize,
    char **ppEncodingParams)
{
    const char* pRtpMap;
    const char* pSlash;
    uint32_t length;
    InitPayload();

    if (ppPayloadName || ppEncodingParams) {
        if (ppPayloadName)
            *ppPayloadName = NULL;
        if (ppEncodingParams)
            *ppEncodingParams = NULL;
        if (m_pRtpMapProperty) {
            pRtpMap = m_pRtpMapProperty->GetValue();
            pSlash = strchr(pRtpMap, '/');

            if (pSlash) {
                length = pSlash - pRtpMap;
            } else {
                length = (uint32_t)strlen(pRtpMap);
            }

            if (ppPayloadName) {
                *ppPayloadName = (char*)MP4Calloc(length + 1);
                strncpy(*ppPayloadName, pRtpMap, length);
            }
            if (pSlash && ppEncodingParams) {
                pSlash++;
                pSlash = strchr(pSlash, '/');
                if (pSlash != NULL) {
                    pSlash++;
                    if (*pSlash != '\0') {
                        length = (uint32_t)strlen(pRtpMap) - (pSlash - pRtpMap);
                        *ppEncodingParams = (char *)MP4Calloc(length + 1);
                        strncpy(*ppEncodingParams, pSlash, length);
                    }
                }
            }
        }
    }

    if (pPayloadNumber) {
        if (m_pPayloadNumberProperty) {
            *pPayloadNumber = m_pPayloadNumberProperty->GetValue();
        } else {
            *pPayloadNumber = 0;
        }
    }

    if (pMaxPayloadSize) {
        if (m_pMaxPacketSizeProperty) {
            *pMaxPayloadSize = m_pMaxPacketSizeProperty->GetValue();
        } else {
            *pMaxPayloadSize = 0;
        }
    }
}

void MP4RtpHintTrack::SetPayload(
    const char* payloadName,
    uint8_t payloadNumber,
    uint16_t maxPayloadSize,
    const char *encoding_parms,
    bool include_rtp_map,
    bool include_mpeg4_esid)
{
    InitRefTrack();
    InitPayload();

    ASSERT(m_pRtpMapProperty);
    ASSERT(m_pPayloadNumberProperty);
    ASSERT(m_pMaxPacketSizeProperty);

    size_t len = strlen(payloadName) + 16;
    if (encoding_parms != NULL) {
        size_t temp = strlen(encoding_parms);
        if (temp == 0) {
            encoding_parms = NULL;
        } else {
            len += temp;
        }
    }

    char* rtpMapBuf = (char*)MP4Malloc(len);
    snprintf(rtpMapBuf, len, "%s/%u%c%s",
             payloadName,
             GetTimeScale(),
             encoding_parms != NULL ? '/' : '\0',
             encoding_parms == NULL ? "" : encoding_parms);
    m_pRtpMapProperty->SetValue(rtpMapBuf);

    m_pPayloadNumberProperty->SetValue(payloadNumber);

    if (maxPayloadSize == 0) {
        maxPayloadSize = 1460;
    }
    m_pMaxPacketSizeProperty->SetValue(maxPayloadSize);

    // set sdp media type
    const char* sdpMediaType;
    if (!strcmp(m_pRefTrack->GetType(), MP4_AUDIO_TRACK_TYPE)) {
        sdpMediaType = "audio";
    } else if (!strcmp(m_pRefTrack->GetType(), MP4_VIDEO_TRACK_TYPE)) {
        sdpMediaType = "video";
    } else if (!strcmp(m_pRefTrack->GetType(), MP4_CNTL_TRACK_TYPE)) {
        sdpMediaType = "control";
    } else {
        sdpMediaType = "application";
    }

    uint32_t maxlen =
        (uint32_t)strlen(sdpMediaType) + (uint32_t)strlen(rtpMapBuf) + 256;
    char* sdpBuf = (char*)MP4Malloc(maxlen);
    uint32_t buflen;
    buflen = snprintf(sdpBuf, maxlen,
                      "m=%s 0 RTP/AVP %u\015\012"
                      "a=control:trackID=%u\015\012",
                      sdpMediaType, payloadNumber,
                      m_trackId);
    if (include_rtp_map) {
        buflen += snprintf(sdpBuf + buflen, maxlen - buflen,
                           "a=rtpmap:%u %s\015\012",
                           payloadNumber, rtpMapBuf);
    }
    if (include_mpeg4_esid) {
        snprintf(sdpBuf + buflen, maxlen - buflen,
                 "a=mpeg4-esid:%u\015\012",
                 m_pRefTrack->GetId());
    }

    MP4StringProperty* pSdpProperty = NULL;
    (void)m_trakAtom.FindProperty("trak.udta.hnti.sdp .sdpText",
                                    (MP4Property**)&pSdpProperty);
    ASSERT(pSdpProperty);
    pSdpProperty->SetValue(sdpBuf);

    // cleanup
    MP4Free(rtpMapBuf);
    MP4Free(sdpBuf);
}

void MP4RtpHintTrack::AddHint(bool isBFrame, uint32_t timestampOffset)
{
    // on first hint, need to lookup the reference track
    if (m_writeHintId == MP4_INVALID_SAMPLE_ID) {
        InitRefTrack();
        InitStats();
    }

    if (m_pWriteHint) {
        throw new Exception("unwritten hint is still pending", __FILE__, __LINE__, __FUNCTION__);
    }

    m_pWriteHint = new MP4RtpHint(*this);
    m_pWriteHint->SetBFrame(isBFrame);
    m_pWriteHint->SetTimestampOffset(timestampOffset);

    m_bytesThisHint = 0;
    m_writeHintId++;
}

void MP4RtpHintTrack::AddPacket(bool setMbit, int32_t transmitOffset)
{
    if (m_pWriteHint == NULL) {
        throw new Exception("no hint pending", __FILE__, __LINE__, __FUNCTION__);
    }

    MP4RtpPacket* pPacket = m_pWriteHint->AddPacket();

    ASSERT(m_pPayloadNumberProperty);

    pPacket->Set(
        m_pPayloadNumberProperty->GetValue(),
        m_writePacketId++,
        setMbit);
    pPacket->SetTransmitOffset(transmitOffset);

    m_bytesThisHint += 12;
    if (m_bytesThisPacket > m_pPmax->GetValue()) {
        m_pPmax->SetValue(m_bytesThisPacket);
    }
    m_bytesThisPacket = 12;
    m_pNump->IncrementValue();
    m_pTrpy->IncrementValue(12); // RTP packet header size
}

void MP4RtpHintTrack::AddImmediateData(
    const uint8_t* pBytes,
    uint32_t numBytes)
{
    if (m_pWriteHint == NULL) {
        throw new Exception("no hint pending", __FILE__, __LINE__, __FUNCTION__ );
    }

    MP4RtpPacket* pPacket = m_pWriteHint->GetCurrentPacket();
    if (pPacket == NULL) {
        throw new Exception("no packet pending", __FILE__, __LINE__, __FUNCTION__);
    }

    if (pBytes == NULL || numBytes == 0) {
        throw new Exception("no data",
                            __FILE__, __LINE__, __FUNCTION__ );
    }
    if (numBytes > 14) {
        throw new Exception("data size is larger than 14 bytes",
                            __FILE__, __LINE__, __FUNCTION__ );
    }

    MP4RtpImmediateData* pData = new MP4RtpImmediateData(*pPacket);
    pData->Set(pBytes, numBytes);

    pPacket->AddData(pData);

    m_bytesThisHint += numBytes;
    m_bytesThisPacket += numBytes;
    m_pDimm->IncrementValue(numBytes);
    m_pTpyl->IncrementValue(numBytes);
    m_pTrpy->IncrementValue(numBytes);
}

void MP4RtpHintTrack::AddSampleData(
    MP4SampleId sampleId,
    uint32_t dataOffset,
    uint32_t dataLength)
{
    if (m_pWriteHint == NULL) {
        throw new Exception("no hint pending", __FILE__, __LINE__, __FUNCTION__ );
    }

    MP4RtpPacket* pPacket = m_pWriteHint->GetCurrentPacket();
    if (pPacket == NULL) {
        throw new Exception("no packet pending", __FILE__, __LINE__, __FUNCTION__ );
    }

    MP4RtpSampleData* pData = new MP4RtpSampleData(*pPacket);

    pData->SetReferenceSample(sampleId, dataOffset, dataLength);

    pPacket->AddData(pData);

    m_bytesThisHint += dataLength;
    m_bytesThisPacket += dataLength;
    m_pDmed->IncrementValue(dataLength);
    m_pTpyl->IncrementValue(dataLength);
    m_pTrpy->IncrementValue(dataLength);
}

void MP4RtpHintTrack::AddESConfigurationPacket()
{
    if (m_pWriteHint == NULL) {
        throw new Exception("no hint pending", __FILE__, __LINE__, __FUNCTION__ );
    }

    uint8_t* pConfig = NULL;
    uint32_t configSize = 0;

    m_File.GetTrackESConfiguration(m_pRefTrack->GetId(),
                                   &pConfig, &configSize);

    if (pConfig == NULL) {
        return;
    }

    ASSERT(m_pMaxPacketSizeProperty);

    if (configSize > m_pMaxPacketSizeProperty->GetValue()) {
        throw new Exception("ES configuration is too large for RTP payload", __FILE__, __LINE__, __FUNCTION__ );
    }

    AddPacket(false);

    MP4RtpPacket* pPacket = m_pWriteHint->GetCurrentPacket();
    ASSERT(pPacket);

    // This is ugly!
    // To get the ES configuration data somewhere known
    // we create a sample data reference that points to
    // this hint track (not the media track)
    // and this sample of the hint track
    // the offset into this sample is filled in during the write process
    MP4RtpSampleData* pData = new MP4RtpSampleData(*pPacket);

    pData->SetEmbeddedImmediate(m_writeSampleId, pConfig, configSize);

    pPacket->AddData(pData);

    m_bytesThisHint += configSize;
    m_bytesThisPacket += configSize;
    m_pTpyl->IncrementValue(configSize);
    m_pTrpy->IncrementValue(configSize);
}

void MP4RtpHintTrack::WriteHint(MP4Duration duration, bool isSyncSample)
{
    if (m_pWriteHint == NULL) {
        throw new Exception("no hint pending", __FILE__, __LINE__, __FUNCTION__ );
    }

    uint8_t* pBytes;
    uint64_t numBytes;

    m_File.EnableMemoryBuffer();

    m_pWriteHint->Write(m_File);

    m_File.DisableMemoryBuffer(&pBytes, &numBytes);

    WriteSample(pBytes, numBytes, duration, 0, isSyncSample);

    MP4Free(pBytes);

    // update statistics
    if (m_bytesThisPacket > m_pPmax->GetValue()) {
        m_pPmax->SetValue(m_bytesThisPacket);
    }

    if (duration > m_pDmax->GetValue()) {
        m_pDmax->SetValue(duration);
    }

    MP4Timestamp startTime;

    GetSampleTimes(m_writeHintId, &startTime, NULL);

    if (startTime < m_thisSec + GetTimeScale()) {
        m_bytesThisSec += m_bytesThisHint;
    } else {
        if (m_bytesThisSec > m_pMaxr->GetValue()) {
            m_pMaxr->SetValue(m_bytesThisSec);
        }
        m_thisSec = startTime - (startTime % GetTimeScale());
        m_bytesThisSec = m_bytesThisHint;
    }

    // cleanup
    delete m_pWriteHint;
    m_pWriteHint = NULL;
}

void MP4RtpHintTrack::FinishWrite(uint32_t option)
{
    if (m_writeHintId != MP4_INVALID_SAMPLE_ID) {
        m_pMaxPdu->SetValue(m_pPmax->GetValue());
        if (m_pNump->GetValue()) {
            m_pAvgPdu->SetValue(m_pTrpy->GetValue() / m_pNump->GetValue());
        }

        m_pMaxBitRate->SetValue(m_pMaxr->GetValue() * 8);
        if (GetDuration()) {
            m_pAvgBitRate->SetValue(
                m_pTrpy->GetValue() * 8 * GetTimeScale() / GetDuration());
        }
    }

    MP4Track::FinishWrite();
}

void MP4RtpHintTrack::InitStats()
{
    MP4Atom* pHinfAtom = m_trakAtom.FindAtom("trak.udta.hinf");

    ASSERT(pHinfAtom);

    (void)pHinfAtom->FindProperty("hinf.trpy.bytes", (MP4Property**)&m_pTrpy);
    (void)pHinfAtom->FindProperty("hinf.nump.packets", (MP4Property**)&m_pNump);
    (void)pHinfAtom->FindProperty("hinf.tpyl.bytes", (MP4Property**)&m_pTpyl);
    (void)pHinfAtom->FindProperty("hinf.maxr.bytes", (MP4Property**)&m_pMaxr);
    (void)pHinfAtom->FindProperty("hinf.dmed.bytes", (MP4Property**)&m_pDmed);
    (void)pHinfAtom->FindProperty("hinf.dimm.bytes", (MP4Property**)&m_pDimm);
    (void)pHinfAtom->FindProperty("hinf.pmax.bytes", (MP4Property**)&m_pPmax);
    (void)pHinfAtom->FindProperty("hinf.dmax.milliSecs", (MP4Property**)&m_pDmax);

    MP4Atom* pHmhdAtom = m_trakAtom.FindAtom("trak.mdia.minf.hmhd");

    ASSERT(pHmhdAtom);

    (void)pHmhdAtom->FindProperty("hmhd.maxPduSize", (MP4Property**)&m_pMaxPdu);
    (void)pHmhdAtom->FindProperty("hmhd.avgPduSize", (MP4Property**)&m_pAvgPdu);
    (void)pHmhdAtom->FindProperty("hmhd.maxBitRate", (MP4Property**)&m_pMaxBitRate);
    (void)pHmhdAtom->FindProperty("hmhd.avgBitRate", (MP4Property**)&m_pAvgBitRate);

    MP4Integer32Property* pMaxrPeriod = NULL;
    (void)pHinfAtom->FindProperty("hinf.maxr.granularity",
                                  (MP4Property**)&pMaxrPeriod);
    if (pMaxrPeriod) {
        pMaxrPeriod->SetValue(1000);    // 1 second
    }
}


MP4RtpHint::MP4RtpHint(MP4RtpHintTrack& track)
    : m_track(track)
{
    AddProperty( /* 0 */
        new MP4Integer16Property(this->GetTrack().GetTrakAtom(), "packetCount"));
    AddProperty( /* 1 */
        new MP4Integer16Property(this->GetTrack().GetTrakAtom(), "reserved"));
}

MP4RtpHint::~MP4RtpHint()
{
    for (uint32_t i = 0; i < m_rtpPackets.Size(); i++) {
        delete m_rtpPackets[i];
    }
}

MP4RtpPacket* MP4RtpHint::AddPacket()
{
    MP4RtpPacket* pPacket = new MP4RtpPacket(*this);
    m_rtpPackets.Add(pPacket);

    // packetCount property
    ((MP4Integer16Property*)m_pProperties[0])->IncrementValue();

    pPacket->SetBFrame(m_isBFrame);
    pPacket->SetTimestampOffset(m_timestampOffset);

    return pPacket;
}

void MP4RtpHint::Read(MP4File& file)
{
    // call base class Read for required properties
    MP4Container::Read(file);

    uint16_t numPackets =
        ((MP4Integer16Property*)m_pProperties[0])->GetValue();

    for (uint16_t i = 0; i < numPackets; i++) {
        MP4RtpPacket* pPacket = new MP4RtpPacket(*this);

        m_rtpPackets.Add(pPacket);

        pPacket->Read(file);
    }

    if (log.verbosity >= MP4_LOG_VERBOSE1) {
        log.verbose1f("\"%s\": ReadHint:", GetTrack().GetFile().GetFilename().c_str());
        Dump(10, false);
    }
}

void MP4RtpHint::Write(MP4File& file)
{
    uint64_t hintStartPos = file.GetPosition();

    MP4Container::Write(file);

    uint64_t packetStartPos = file.GetPosition();

    uint32_t i;

    // first write out packet (and data) entries
    for (i = 0; i < m_rtpPackets.Size(); i++) {
        m_rtpPackets[i]->Write(file);
    }

    // now let packets write their extra data into the hint sample
    for (i = 0; i < m_rtpPackets.Size(); i++) {
        m_rtpPackets[i]->WriteEmbeddedData(file, hintStartPos);
    }

    uint64_t endPos = file.GetPosition();

    file.SetPosition(packetStartPos);

    // finally rewrite the packet and data entries
    // which now contain the correct offsets for the embedded data
    for (i = 0; i < m_rtpPackets.Size(); i++) {
        m_rtpPackets[i]->Write(file);
    }

    file.SetPosition(endPos);

    if (log.verbosity >= MP4_LOG_VERBOSE1) {
        log.verbose1f("\"%s\": WriteRtpHint:", GetTrack().GetFile().GetFilename().c_str());
        Dump(14, false);
    }
}

void MP4RtpHint::Dump(uint8_t indent, bool dumpImplicits)
{
    MP4Container::Dump(indent, dumpImplicits);

    for (uint32_t i = 0; i < m_rtpPackets.Size(); i++) {
        log.dump(indent, MP4_LOG_VERBOSE1,"\"%s\": RtpPacket: %u",
                 GetTrack().GetFile().GetFilename().c_str(), i);
        m_rtpPackets[i]->Dump(indent + 1, dumpImplicits);
    }
}

MP4RtpPacket::MP4RtpPacket(MP4RtpHint& hint)
    : m_hint(hint)
{
    AddProperty( /* 0 */
        new MP4Integer32Property(this->GetHint().GetTrack().GetTrakAtom(), "relativeXmitTime"));
    AddProperty( /* 1 */
        new MP4BitfieldProperty(this->GetHint().GetTrack().GetTrakAtom(), "reserved1", 2));
    AddProperty( /* 2 */
        new MP4BitfieldProperty(this->GetHint().GetTrack().GetTrakAtom(), "Pbit", 1));
    AddProperty( /* 3 */
        new MP4BitfieldProperty(this->GetHint().GetTrack().GetTrakAtom(), "Xbit", 1));
    AddProperty( /* 4 */
        new MP4BitfieldProperty(this->GetHint().GetTrack().GetTrakAtom(), "reserved2", 4));
    AddProperty( /* 5 */
        new MP4BitfieldProperty(this->GetHint().GetTrack().GetTrakAtom(), "Mbit", 1));
    AddProperty( /* 6 */
        new MP4BitfieldProperty(this->GetHint().GetTrack().GetTrakAtom(), "payloadType", 7));
    AddProperty( /* 7  */
        new MP4Integer16Property(this->GetHint().GetTrack().GetTrakAtom(), "sequenceNumber"));
    AddProperty( /* 8 */
        new MP4BitfieldProperty(this->GetHint().GetTrack().GetTrakAtom(), "reserved3", 13));
    AddProperty( /* 9 */
        new MP4BitfieldProperty(this->GetHint().GetTrack().GetTrakAtom(), "extraFlag", 1));
    AddProperty( /* 10 */
        new MP4BitfieldProperty(this->GetHint().GetTrack().GetTrakAtom(), "bFrameFlag", 1));
    AddProperty( /* 11 */
        new MP4BitfieldProperty(this->GetHint().GetTrack().GetTrakAtom(), "repeatFlag", 1));
    AddProperty( /* 12 */
        new MP4Integer16Property(this->GetHint().GetTrack().GetTrakAtom(), "entryCount"));
}

MP4RtpPacket::~MP4RtpPacket()
{
    for (uint32_t i = 0; i < m_rtpData.Size(); i++) {
        delete m_rtpData[i];
    }
}

void MP4RtpPacket::AddExtraProperties()
{
    AddProperty( /* 13 */
        new MP4Integer32Property(this->GetHint().GetTrack().GetTrakAtom(), "extraInformationLength"));

    // This is a bit of a hack, since the tlv entries are really defined
    // as atoms but there is only one type defined now, rtpo, and getting
    // our atom code hooked up here would be a major pain with little gain

    AddProperty( /* 14 */
        new MP4Integer32Property(this->GetHint().GetTrack().GetTrakAtom(), "tlvLength"));
    AddProperty( /* 15 */
        new MP4StringProperty(this->GetHint().GetTrack().GetTrakAtom(), "tlvType"));
    AddProperty( /* 16 */
        new MP4Integer32Property(this->GetHint().GetTrack().GetTrakAtom(), "timestampOffset"));

    ((MP4Integer32Property*)m_pProperties[13])->SetValue(16);
    ((MP4Integer32Property*)m_pProperties[14])->SetValue(12);
    ((MP4StringProperty*)m_pProperties[15])->SetFixedLength(4);
    ((MP4StringProperty*)m_pProperties[15])->SetValue("rtpo");
}

void MP4RtpPacket::Read(MP4File& file)
{
    // call base class Read for required properties
    MP4Container::Read(file);

    // read extra info if present
    // we only support the rtpo field!
    if (((MP4BitfieldProperty*)m_pProperties[9])->GetValue() == 1) {
        ReadExtra(file);
    }

    uint16_t numDataEntries =
        ((MP4Integer16Property*)m_pProperties[12])->GetValue();

    // read data entries
    for (uint16_t i = 0; i < numDataEntries; i++) {
        uint8_t dataType;
        file.PeekBytes(&dataType, 1);

        MP4RtpData* pData;

        switch (dataType) {
        case 0:
            pData = new MP4RtpNullData(*this);
            break;
        case 1:
            pData = new MP4RtpImmediateData(*this);
            break;
        case 2:
            pData = new MP4RtpSampleData(*this);
            break;
        case 3:
            pData = new MP4RtpSampleDescriptionData(*this);
            break;
        default:
            throw new Exception("unknown packet data entry type", __FILE__, __LINE__, __FUNCTION__ );
        }

        m_rtpData.Add(pData);

        // read data entry's properties
        pData->Read(file);
    }
}

void MP4RtpPacket::ReadExtra(MP4File& file)
{
    AddExtraProperties();

    int32_t extraLength = (int32_t)file.ReadUInt32();

    if (extraLength < 4) {
        throw new Exception("bad packet extra info length", __FILE__, __LINE__, __FUNCTION__ );
    }
    extraLength -= 4;

    while (extraLength > 0) {
        uint32_t entryLength = file.ReadUInt32();
        uint32_t entryTag = file.ReadUInt32();

        if (entryLength < 8) {
            throw new Exception("bad packet extra info entry length", __FILE__, __LINE__, __FUNCTION__ );
        }

        if (entryTag == STRTOINT32("rtpo") && entryLength == 12) {
            // read the rtp timestamp offset
            m_pProperties[16]->Read(file);
        } else {
            // ignore it, LATER carry it along
            file.SetPosition(file.GetPosition() + entryLength - 8);
        }

        extraLength -= entryLength;
    }

    if (extraLength < 0) {
        throw new Exception("invalid packet extra info length", __FILE__, __LINE__, __FUNCTION__ );
    }
}

void MP4RtpPacket::Set(uint8_t payloadNumber,
                       uint32_t packetId, bool setMbit)
{
    ((MP4BitfieldProperty*)m_pProperties[5])->SetValue(setMbit);
    ((MP4BitfieldProperty*)m_pProperties[6])->SetValue(payloadNumber);
    ((MP4Integer16Property*)m_pProperties[7])->SetValue(packetId);
}

int32_t MP4RtpPacket::GetTransmitOffset()
{
    return ((MP4Integer32Property*)m_pProperties[0])->GetValue();
}

void MP4RtpPacket::SetTransmitOffset(int32_t transmitOffset)
{
    ((MP4Integer32Property*)m_pProperties[0])->SetValue(transmitOffset);
}

bool MP4RtpPacket::GetPBit()
{
    return ((MP4BitfieldProperty*)m_pProperties[2])->GetValue();
}

bool MP4RtpPacket::GetXBit()
{
    return ((MP4BitfieldProperty*)m_pProperties[3])->GetValue();
}

bool MP4RtpPacket::GetMBit()
{
    return ((MP4BitfieldProperty*)m_pProperties[5])->GetValue();
}

uint8_t MP4RtpPacket::GetPayload()
{
    return ((MP4BitfieldProperty*)m_pProperties[6])->GetValue();
}

uint16_t MP4RtpPacket::GetSequenceNumber()
{
    return ((MP4Integer16Property*)m_pProperties[7])->GetValue();
}

bool MP4RtpPacket::IsBFrame()
{
    return ((MP4BitfieldProperty*)m_pProperties[10])->GetValue();
}

void MP4RtpPacket::SetBFrame(bool isBFrame)
{
    ((MP4BitfieldProperty*)m_pProperties[10])->SetValue(isBFrame);
}

void MP4RtpPacket::SetTimestampOffset(uint32_t timestampOffset)
{
    if (timestampOffset == 0) {
        return;
    }

    ASSERT(((MP4BitfieldProperty*)m_pProperties[9])->GetValue() == 0);

    // set X bit
    ((MP4BitfieldProperty*)m_pProperties[9])->SetValue(1);

    AddExtraProperties();

    ((MP4Integer32Property*)m_pProperties[16])->SetValue(timestampOffset);
}

void MP4RtpPacket::AddData(MP4RtpData* pData)
{
    m_rtpData.Add(pData);

    // increment entry count property
    ((MP4Integer16Property*)m_pProperties[12])->IncrementValue();
}

uint32_t MP4RtpPacket::GetDataSize()
{
    uint32_t totalDataSize = 0;

    for (uint32_t i = 0; i < m_rtpData.Size(); i++) {
        totalDataSize += m_rtpData[i]->GetDataSize();
    }

    return totalDataSize;
}

void MP4RtpPacket::GetData(uint8_t* pDest)
{
    for (uint32_t i = 0; i < m_rtpData.Size(); i++) {
        m_rtpData[i]->GetData(pDest);
        pDest += m_rtpData[i]->GetDataSize();
    }
}

void MP4RtpPacket::Write(MP4File& file)
{
    MP4Container::Write(file);

    for (uint32_t i = 0; i < m_rtpData.Size(); i++) {
        m_rtpData[i]->Write(file);
    }
}

void MP4RtpPacket::WriteEmbeddedData(MP4File& file, uint64_t startPos)
{
    for (uint32_t i = 0; i < m_rtpData.Size(); i++) {
        m_rtpData[i]->WriteEmbeddedData(file, startPos);
    }
}

void MP4RtpPacket::Dump(uint8_t indent, bool dumpImplicits)
{
    MP4Container::Dump(indent, dumpImplicits);

    for (uint32_t i = 0; i < m_rtpData.Size(); i++) {
        log.dump(indent, MP4_LOG_VERBOSE1, "\"%s\": RtpData: %u",
                 GetHint().GetTrack().GetFile().GetFilename().c_str(), i);
        m_rtpData[i]->Dump(indent + 1, dumpImplicits);
    }
}

MP4RtpData::MP4RtpData(MP4RtpPacket& packet)
    : m_packet(packet)
{
    AddProperty( /* 0 */
        new MP4Integer8Property(this->GetPacket().GetHint().GetTrack().GetTrakAtom(), "type"));
}

MP4Track* MP4RtpData::FindTrackFromRefIndex(uint8_t refIndex)
{
    MP4Track* pTrack;

    if (refIndex == (uint8_t)-1) {
        // ourselves
        pTrack = &GetPacket().GetHint().GetTrack();
    } else if (refIndex == 0) {
        // our reference track
        pTrack = GetPacket().GetHint().GetTrack().GetRefTrack();
    } else {
        // some other track
        MP4RtpHintTrack* pHintTrack =
            &GetPacket().GetHint().GetTrack();

        MP4Atom& trakAtom = pHintTrack->GetTrakAtom();

        MP4Integer32Property* pTrackIdProperty = NULL;
        (void)trakAtom.FindProperty(
            "trak.tref.hint.entries",
            (MP4Property**)&pTrackIdProperty);
        ASSERT(pTrackIdProperty);

        uint32_t refTrackId =
            pTrackIdProperty->GetValue(refIndex - 1);

        pTrack = pHintTrack->GetFile().GetTrack(refTrackId);
    }

    return pTrack;
}

MP4RtpNullData::MP4RtpNullData(MP4RtpPacket& packet)
        : MP4RtpData(packet)
{
    ((MP4Integer8Property*)m_pProperties[0])->SetValue(0);

    AddProperty( /* 1 */
        new MP4BytesProperty(this->GetPacket().GetHint().GetTrack().GetTrakAtom(), "pad", 15));

    ((MP4BytesProperty*)m_pProperties[1])->SetFixedSize(15);
}

MP4RtpImmediateData::MP4RtpImmediateData(MP4RtpPacket& packet)
        : MP4RtpData(packet)
{
    ((MP4Integer8Property*)m_pProperties[0])->SetValue(1);

    AddProperty( /* 1 */
        new MP4Integer8Property(this->GetPacket().GetHint().GetTrack().GetTrakAtom(), "count"));
    AddProperty( /* 2 */
        new MP4BytesProperty(this->GetPacket().GetHint().GetTrack().GetTrakAtom(), "data", 14));

    ((MP4BytesProperty*)m_pProperties[2])->SetFixedSize(14);
}

void MP4RtpImmediateData::Set(const uint8_t* pBytes, uint8_t numBytes)
{
    ((MP4Integer8Property*)m_pProperties[1])->SetValue(numBytes);
    ((MP4BytesProperty*)m_pProperties[2])->SetValue(pBytes, numBytes);
}

uint16_t MP4RtpImmediateData::GetDataSize()
{
    return ((MP4Integer8Property*)m_pProperties[1])->GetValue();
}

void MP4RtpImmediateData::GetData(uint8_t* pDest)
{
    uint8_t* pValue;
    uint32_t valueSize;
    ((MP4BytesProperty*)m_pProperties[2])->GetValue(&pValue, &valueSize);

    memcpy(pDest, pValue, GetDataSize());
    MP4Free(pValue);
}

MP4RtpSampleData::MP4RtpSampleData(MP4RtpPacket& packet)
        : MP4RtpData(packet)
{
    ((MP4Integer8Property*)m_pProperties[0])->SetValue(2);

    AddProperty( /* 1 */
        new MP4Integer8Property(this->GetPacket().GetHint().GetTrack().GetTrakAtom(), "trackRefIndex"));
    AddProperty( /* 2 */
        new MP4Integer16Property(this->GetPacket().GetHint().GetTrack().GetTrakAtom(), "length"));
    AddProperty( /* 3 */
        new MP4Integer32Property(this->GetPacket().GetHint().GetTrack().GetTrakAtom(), "sampleNumber"));
    AddProperty( /* 4 */
        new MP4Integer32Property(this->GetPacket().GetHint().GetTrack().GetTrakAtom(), "sampleOffset"));
    AddProperty( /* 5 */
        new MP4Integer16Property(this->GetPacket().GetHint().GetTrack().GetTrakAtom(), "bytesPerBlock"));
    AddProperty( /* 6 */
        new MP4Integer16Property(this->GetPacket().GetHint().GetTrack().GetTrakAtom(), "samplesPerBlock"));

    ((MP4Integer16Property*)m_pProperties[5])->SetValue(1);
    ((MP4Integer16Property*)m_pProperties[6])->SetValue(1);

    m_pRefData = NULL;
    m_pRefTrack = NULL;
    m_refSampleId = MP4_INVALID_SAMPLE_ID;
    m_refSampleOffset = 0;
}

void MP4RtpSampleData::SetEmbeddedImmediate(MP4SampleId sampleId,
        uint8_t* pData, uint16_t dataLength)
{
    ((MP4Integer8Property*)m_pProperties[1])->SetValue((uint8_t)-1);
    ((MP4Integer16Property*)m_pProperties[2])->SetValue(dataLength);
    ((MP4Integer32Property*)m_pProperties[3])->SetValue(sampleId);
    ((MP4Integer32Property*)m_pProperties[4])->SetValue(0);
    CHECK_AND_FREE(m_pRefData);
    m_pRefData = pData;
}

void MP4RtpSampleData::SetReferenceSample(
    MP4SampleId refSampleId, uint32_t refSampleOffset,
    uint16_t sampleLength)
{
    ((MP4Integer8Property*)m_pProperties[1])->SetValue(0);
    ((MP4Integer16Property*)m_pProperties[2])->SetValue(sampleLength);
    ((MP4Integer32Property*)m_pProperties[3])->SetValue(refSampleId);
    ((MP4Integer32Property*)m_pProperties[4])->SetValue(refSampleOffset);
}

void MP4RtpSampleData::SetEmbeddedSample(
    MP4SampleId sampleId, MP4Track* pRefTrack,
    MP4SampleId refSampleId, uint32_t refSampleOffset,
    uint16_t sampleLength)
{
    ((MP4Integer8Property*)m_pProperties[1])->SetValue((uint8_t)-1);
    ((MP4Integer16Property*)m_pProperties[2])->SetValue(sampleLength);
    ((MP4Integer32Property*)m_pProperties[3])->SetValue(sampleId);
    ((MP4Integer32Property*)m_pProperties[4])->SetValue(0);
    m_pRefTrack = pRefTrack;
    m_refSampleId = refSampleId;
    m_refSampleOffset = refSampleOffset;
}

uint16_t MP4RtpSampleData::GetDataSize()
{
    return ((MP4Integer16Property*)m_pProperties[2])->GetValue();
}

void MP4RtpSampleData::GetData(uint8_t* pDest)
{
    uint8_t trackRefIndex =
        ((MP4Integer8Property*)m_pProperties[1])->GetValue();

    MP4Track* pSampleTrack =
        FindTrackFromRefIndex(trackRefIndex);

    pSampleTrack->ReadSampleFragment(
        ((MP4Integer32Property*)m_pProperties[3])->GetValue(),  // sampleId
        ((MP4Integer32Property*)m_pProperties[4])->GetValue(),  // sampleOffset
        ((MP4Integer16Property*)m_pProperties[2])->GetValue(),  // sampleLength
        pDest);
}

void MP4RtpSampleData::WriteEmbeddedData(MP4File& file, uint64_t startPos)
{
    // if not using embedded data, nothing to do
    if (((MP4Integer8Property*)m_pProperties[1])->GetValue() != (uint8_t)-1) {
        return;
    }

    // figure out the offset within this hint sample for this embedded data
    uint64_t offset = file.GetPosition() - startPos;
    ASSERT(offset <= 0xFFFFFFFF);
    ((MP4Integer32Property*)m_pProperties[4])->SetValue((uint32_t)offset);

    uint16_t length = ((MP4Integer16Property*)m_pProperties[2])->GetValue();

    if (m_pRefData) {
        file.WriteBytes(m_pRefData, length);
        return;
    }

    if (m_refSampleId != MP4_INVALID_SAMPLE_ID) {
        uint8_t* pSample = NULL;
        uint32_t sampleSize = 0;

        ASSERT(m_pRefTrack);
        m_pRefTrack->ReadSample(m_refSampleId, &pSample, &sampleSize);

        ASSERT(m_refSampleOffset + length <= sampleSize);

        file.WriteBytes(&pSample[m_refSampleOffset], length);

        MP4Free(pSample);
        return;
    }
}

MP4RtpSampleDescriptionData::MP4RtpSampleDescriptionData(MP4RtpPacket& packet)
        : MP4RtpData(packet)
{
    ((MP4Integer8Property*)m_pProperties[0])->SetValue(3);

    AddProperty( /* 1 */
        new MP4Integer8Property(this->GetPacket().GetHint().GetTrack().GetTrakAtom(), "trackRefIndex"));
    AddProperty( /* 2 */
        new MP4Integer16Property(this->GetPacket().GetHint().GetTrack().GetTrakAtom(), "length"));
    AddProperty( /* 3 */
        new MP4Integer32Property(this->GetPacket().GetHint().GetTrack().GetTrakAtom(), "sampleDescriptionIndex"));
    AddProperty( /* 4 */
        new MP4Integer32Property(this->GetPacket().GetHint().GetTrack().GetTrakAtom(), "sampleDescriptionOffset"));
    AddProperty( /* 5 */
        new MP4Integer32Property(this->GetPacket().GetHint().GetTrack().GetTrakAtom(), "reserved"));
}

void MP4RtpSampleDescriptionData::Set(uint32_t sampleDescrIndex,
                                      uint32_t offset, uint16_t length)
{
    ((MP4Integer16Property*)m_pProperties[2])->SetValue(length);
    ((MP4Integer32Property*)m_pProperties[3])->SetValue(sampleDescrIndex);
    ((MP4Integer32Property*)m_pProperties[4])->SetValue(offset);
}

uint16_t MP4RtpSampleDescriptionData::GetDataSize()
{
    return ((MP4Integer16Property*)m_pProperties[2])->GetValue();
}

void MP4RtpSampleDescriptionData::GetData(uint8_t* pDest)
{
    // we start with the index into our track references
    uint8_t trackRefIndex =
        ((MP4Integer8Property*)m_pProperties[1])->GetValue();

    // from which we can find the track structure
    MP4Track* pSampleTrack =
        FindTrackFromRefIndex(trackRefIndex);

    // next find the desired atom in the track's sample description table
    uint32_t sampleDescrIndex =
        ((MP4Integer32Property*)m_pProperties[3])->GetValue();

    MP4Atom& trakAtom =
        pSampleTrack->GetTrakAtom();

    char sdName[64];
    snprintf(sdName, 64, "trak.mdia.minf.stbl.stsd.*[%u]", sampleDescrIndex);

    MP4Atom* pSdAtom =
        trakAtom.FindAtom(sdName);

    // bad reference
    if (pSdAtom == NULL) {
        throw new Exception("invalid sample description index", __FILE__, __LINE__, __FUNCTION__ );
    }

    // check validity of the upcoming copy
    uint16_t length =
        ((MP4Integer16Property*)m_pProperties[2])->GetValue();
    uint32_t offset =
        ((MP4Integer32Property*)m_pProperties[4])->GetValue();

    if (offset + length > pSdAtom->GetSize()) {
        throw new Exception("offset and/or length are too large",
                            __FILE__, __LINE__, __FUNCTION__);
    }

    // now we use the raw file to get the desired bytes

    MP4File& file = GetPacket().GetHint().GetTrack().GetFile();

    uint64_t orgPos = file.GetPosition();

    // It's not entirely clear from the spec whether the offset is from
    // the start of the sample descirption atom, or the start of the atom's
    // data. I believe it is the former, but the commented out code will
    // realize the latter interpretation if I turn out to be wrong.
    uint64_t dataPos = pSdAtom->GetStart();
    //uint64_t dataPos = pSdAtom->GetEnd() - pSdAtom->GetSize();

    file.SetPosition(dataPos + offset);

    file.ReadBytes(pDest, length);

    file.SetPosition(orgPos);
}

///////////////////////////////////////////////////////////////////////////////

}
} // namespace mp4v2::impl
