/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "ARTPSource"
#include <utils/Log.h>

#include "ARTPSource.h"

#include "AAMRAssembler.h"
#include "AAVCAssembler.h"
#include "AHEVCAssembler.h"
#include "AH263Assembler.h"
#include "AMPEG2TSAssembler.h"
#include "AMPEG4AudioAssembler.h"
#include "AMPEG4ElementaryAssembler.h"
#include "ARawAudioAssembler.h"
#include "ASessionDescription.h"

#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>

#include <strings.h>

namespace android {

static uint32_t kSourceID = 0xdeadbeef;

ARTPSource::ARTPSource(
        uint32_t id,
        const sp<ASessionDescription> &sessionDesc, size_t index,
        const sp<AMessage> &notify)
    : mFirstRtpTime(0),
      mFirstSysTime(0),
      mClockRate(0),
      mSysAnchorTime(0),
      mLastSysAnchorTimeUpdatedUs(0),
      mFirstSsrc(0),
      mHighestNackNumber(0),
      mID(id),
      mHighestSeqNumber(0),
      mPrevExpected(0),
      mBaseSeqNumber(0),
      mNumBuffersReceived(0),
      mPrevNumBuffersReceived(0),
      mPrevExpectedForRR(0),
      mPrevNumBuffersReceivedForRR(0),
      mLatestRtpTime(0),
      mStaticJbTimeMs(kStaticJitterTimeMs),
      mLastSrRtpTime(0),
      mLastSrNtpTime(0),
      mLastSrUpdateTimeUs(0),
      mIsFirstRtpRtcpGap(true),
      mAvgRtpRtcpGapMs(0),
      mAvgUnderlineDelayMs(0),
      mIssueFIRRequests(false),
      mIssueFIRByAssembler(false),
      mLastFIRRequestUs(-1),
      mNextFIRSeqNo((rand() * 256.0) / RAND_MAX),
      mNotify(notify) {
    unsigned long PT;
    AString desc;
    AString params;
    sessionDesc->getFormatType(index, &PT, &desc, &params);

    if (!strncmp(desc.c_str(), "H264/", 5)) {
        mAssembler = new AAVCAssembler(notify);
        mIssueFIRRequests = true;
    } else if (!strncmp(desc.c_str(), "H265/", 5)) {
        mAssembler = new AHEVCAssembler(notify);
        mIssueFIRRequests = true;
    } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) {
        mAssembler = new AMPEG4AudioAssembler(notify, params);
    } else if (!strncmp(desc.c_str(), "H263-1998/", 10)
            || !strncmp(desc.c_str(), "H263-2000/", 10)) {
        mAssembler = new AH263Assembler(notify);
        mIssueFIRRequests = true;
    } else if (!strncmp(desc.c_str(), "AMR/", 4)) {
        mAssembler = new AAMRAssembler(notify, false /* isWide */, params);
    } else  if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
        mAssembler = new AAMRAssembler(notify, true /* isWide */, params);
    } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)
            || !strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) {
        mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params);
        mIssueFIRRequests = true;
    } else if (ARawAudioAssembler::Supports(desc.c_str())) {
        mAssembler = new ARawAudioAssembler(notify, desc.c_str(), params);
    } else if (!strncasecmp(desc.c_str(), "MP2T/", 5)) {
        mAssembler = new AMPEG2TSAssembler(notify, desc.c_str(), params);
    } else {
        TRESPASS();
    }

    if (mAssembler != NULL && !mAssembler->initCheck()) {
        mAssembler.clear();
    }

    int32_t clockRate, numChannels;
    ASessionDescription::ParseFormatDesc(desc.c_str(), &clockRate, &numChannels);
    mClockRate = clockRate;
    mLastJbAlarmTimeUs = 0;
    mJitterCalc = new JitterCalc(mClockRate);
}

static uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) {
    return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1;
}

void ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) {
    if (mAssembler != NULL && queuePacket(buffer)) {
        mAssembler->onPacketReceived(this);
    }
}

void ARTPSource::processRTPPacket() {
    if (mAssembler != NULL && !mQueue.empty()) {
        mAssembler->onPacketReceived(this);
    }
}

void ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) {
    mLastSrRtpTime = rtpTime;
    mLastSrNtpTime = ntpTime;
    mLastSrUpdateTimeUs = ALooper::GetNowUs();

    sp<AMessage> notify = mNotify->dup();
    notify->setInt32("time-update", true);
    notify->setInt32("rtp-time", rtpTime);
    notify->setInt64("ntp-time", ntpTime);
    notify->setInt32("rtcp-event", 1);
    notify->setInt32("payload-type", RTCP_SR);
    notify->setInt64("recv-time-us", mLastSrUpdateTimeUs);
    notify->post();
}

void ARTPSource::timeReset() {
    mFirstRtpTime = 0;
    mFirstSysTime = 0;
    mSysAnchorTime = 0;
    mLastSysAnchorTimeUpdatedUs = 0;
    mFirstSsrc = 0;
    mHighestNackNumber = 0;
    mHighestSeqNumber = 0;
    mPrevExpected = 0;
    mBaseSeqNumber = 0;
    mNumBuffersReceived = 0;
    mPrevNumBuffersReceived = 0;
    mPrevExpectedForRR = 0;
    mPrevNumBuffersReceivedForRR = 0;
    mLatestRtpTime = 0;
    mLastSrRtpTime = 0;
    mLastSrNtpTime = 0;
    mLastSrUpdateTimeUs = 0;
    mIsFirstRtpRtcpGap = true;
    mAvgRtpRtcpGapMs = 0;
    mAvgUnderlineDelayMs = 0;
    mIssueFIRByAssembler = false;
    mLastFIRRequestUs = -1;
}

void ARTPSource::calcTimeGapRtpRtcp(const sp<ABuffer> &buffer, int64_t nowUs) {
    if (mLastSrUpdateTimeUs == 0) {
        return;
    }

    int64_t elapsedMs = (nowUs - mLastSrUpdateTimeUs) / 1000;
    int64_t elapsedRtpTime = (elapsedMs * (mClockRate / 1000));
    uint32_t rtpTime;
    CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));

    int64_t anchorRtpTime = mLastSrRtpTime + elapsedRtpTime;
    int64_t rtpTimeGap = anchorRtpTime - rtpTime;
    // rtpTime can not be faster than it's anchor time.
    // because rtpTime(of rtp packet) represents it's a frame captured time and
    // anchorRtpTime(of rtcp:sr packet) represents it's a rtp packetized time.
    if (rtpTimeGap < 0 || rtpTimeGap > (mClockRate * 60)) {
        // ignore invalid delay gap such as negative delay or later than 1 min.
        return;
    }

    int64_t rtpTimeGapMs = (rtpTimeGap * 1000 / mClockRate);
    if (mIsFirstRtpRtcpGap) {
        mIsFirstRtpRtcpGap = false;
        mAvgRtpRtcpGapMs = rtpTimeGapMs;
    } else {
        // This is measuring avg rtp timestamp distance between rtp and rtcp:sr packet.
        // Rtp timestamp of rtp packet represents it's raw frame captured time.
        // Rtp timestamp of rtcp:sr packet represents it's packetization time.
        // So that, this value is showing how much time delayed to be a rtp packet
        // from a raw frame captured time.
        // This value maybe referred to know a/v sync and sender's own delay of this media stream.
        mAvgRtpRtcpGapMs = ((mAvgRtpRtcpGapMs * 15) + rtpTimeGapMs) / 16;
    }
}

void ARTPSource::calcUnderlineDelay(const sp<ABuffer> &buffer, int64_t nowUs) {
    int64_t elapsedMs = (nowUs - mSysAnchorTime) / 1000;
    int64_t elapsedRtpTime = (elapsedMs * (mClockRate / 1000));
    int64_t expectedRtpTime = mFirstRtpTime + elapsedRtpTime;

    int32_t rtpTime;
    CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
    int32_t delayMs = (expectedRtpTime - rtpTime) / (mClockRate / 1000);

    mAvgUnderlineDelayMs = ((mAvgUnderlineDelayMs * 15) + delayMs) / 16;
}

void ARTPSource::adjustAnchorTimeIfRequired(int64_t nowUs) {
    if (nowUs - mLastSysAnchorTimeUpdatedUs < 1000000L) {
        return;
    }

    if (mAvgUnderlineDelayMs < -30) {
        // adjust underline delay a quarter of desired delay like step by step.
        mSysAnchorTime += (int64_t)(mAvgUnderlineDelayMs * 1000 / 4);
        ALOGD("anchor time updated: original(%lld), anchor(%lld), diffMs(%lld)",
                (long long)mFirstSysTime, (long long)mSysAnchorTime,
                (long long)(mFirstSysTime - mSysAnchorTime) / 1000);

        mAvgUnderlineDelayMs = 0;
        mLastSysAnchorTimeUpdatedUs = nowUs;

        // reset a jitter stastics since an anchor time adjusted.
        mJitterCalc->init(mFirstRtpTime, mSysAnchorTime, 0, mStaticJbTimeMs * 1000);
    }
}

bool ARTPSource::queuePacket(const sp<ABuffer> &buffer) {
    int64_t nowUs = ALooper::GetNowUs();
    uint32_t seqNum = (uint32_t)buffer->int32Data();
    int32_t ssrc = 0, rtpTime = 0;

    buffer->meta()->findInt32("ssrc", &ssrc);
    CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
    mLatestRtpTime = rtpTime;

    if (mNumBuffersReceived++ == 0 && mFirstSysTime == 0) {
        mFirstSysTime = nowUs;
        mSysAnchorTime = nowUs;
        mLastSysAnchorTimeUpdatedUs = nowUs;
        mHighestSeqNumber = seqNum;
        mBaseSeqNumber = seqNum;
        mFirstRtpTime = rtpTime;
        mFirstSsrc = ssrc;
        ALOGD("first-rtp arrived: first-rtp-time=%u, sys-time=%lld, seq-num=%u, ssrc=%d",
                mFirstRtpTime, (long long)mFirstSysTime, mHighestSeqNumber, mFirstSsrc);
        mJitterCalc->init(mFirstRtpTime, mFirstSysTime, 0, mStaticJbTimeMs * 1000);
        if (mQueue.size() > 0) {
            ALOGD("clearing buffers which belonged to previous timeline"
                    " since a base timeline has been changed.");
            mQueue.clear();
        }
        mQueue.push_back(buffer);
        return true;
    }

    if (mFirstSsrc != ssrc) {
        ALOGW("Discarding a buffer due to unexpected ssrc");
        return false;
    }

    calcTimeGapRtpRtcp(buffer, nowUs);
    calcUnderlineDelay(buffer, nowUs);
    adjustAnchorTimeIfRequired(nowUs);

    // Only the lower 16-bit of the sequence numbers are transmitted,
    // derive the high-order bits by choosing the candidate closest
    // to the highest sequence number (extended to 32 bits) received so far.

    uint32_t seq1 = seqNum | (mHighestSeqNumber & 0xffff0000);

    // non-overflowing version of:
    // uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000);
    uint32_t seq2 = seqNum | (((mHighestSeqNumber >> 16) + 1) << 16);

    // non-underflowing version of:
    // uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000);
    uint32_t seq3 = seqNum | ((((mHighestSeqNumber >> 16) | 0x10000) - 1) << 16);

    uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber);
    uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber);
    uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber);

    if (diff1 < diff2) {
        if (diff1 < diff3) {
            // diff1 < diff2 ^ diff1 < diff3
            seqNum = seq1;
        } else {
            // diff3 <= diff1 < diff2
            seqNum = seq3;
        }
    } else if (diff2 < diff3) {
        // diff2 <= diff1 ^ diff2 < diff3
        seqNum = seq2;
    } else {
        // diff3 <= diff2 <= diff1
        seqNum = seq3;
    }

    if (seqNum > mHighestSeqNumber) {
        mHighestSeqNumber = seqNum;
    }

    buffer->setInt32Data(seqNum);

    List<sp<ABuffer> >::iterator it = mQueue.begin();
    while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) {
        ++it;
    }

    if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) {
        ALOGW("Discarding duplicate buffer");
        return false;
    }

    mQueue.insert(it, buffer);

    return true;
}

void ARTPSource::byeReceived() {
    if (mAssembler != NULL) {
        mAssembler->onByeReceived();
    }
}

void ARTPSource::addFIR(const sp<ABuffer> &buffer) {
    if (!mIssueFIRRequests && !mIssueFIRByAssembler) {
        return;
    }

    bool send = false;
    int64_t nowUs = ALooper::GetNowUs();
    int64_t usecsSinceLastFIR = nowUs - mLastFIRRequestUs;
    if (mLastFIRRequestUs < 0) {
        // A first FIR, just send it.
        send = true;
    }  else if (mIssueFIRByAssembler && (usecsSinceLastFIR > 1000000)) {
        // A FIR issued by Assembler.
        // Send it if last FIR is not sent within a sec.
        send = true;
    } else if (mIssueFIRRequests && (usecsSinceLastFIR > 5000000)) {
        // A FIR issued periodically regardless packet loss.
        // Send it if last FIR is not sent within 5 secs.
        send = true;
    }

    if (!send) {
        return;
    }

    mLastFIRRequestUs = nowUs;

    if (buffer->size() + 20 > buffer->capacity()) {
        ALOGW("RTCP buffer too small to accommodate FIR.");
        return;
    }

    uint8_t *data = buffer->data() + buffer->size();

    data[0] = 0x80 | 4;
    data[1] = 206;  // PSFB
    data[2] = 0;
    data[3] = 4;    // total (4+1) * sizeof(int32_t) = 20 bytes
    data[4] = kSourceID >> 24;
    data[5] = (kSourceID >> 16) & 0xff;
    data[6] = (kSourceID >> 8) & 0xff;
    data[7] = kSourceID & 0xff;

    data[8] = 0x00;  // SSRC of media source (unused)
    data[9] = 0x00;
    data[10] = 0x00;
    data[11] = 0x00;

    data[12] = mID >> 24;
    data[13] = (mID >> 16) & 0xff;
    data[14] = (mID >> 8) & 0xff;
    data[15] = mID & 0xff;

    data[16] = mNextFIRSeqNo++;  // Seq Nr.

    data[17] = 0x00;  // Reserved
    data[18] = 0x00;
    data[19] = 0x00;

    buffer->setRange(buffer->offset(), buffer->size() + (data[3] + 1) * sizeof(int32_t));

    mIssueFIRByAssembler = false;

    ALOGV("Added FIR request.");
}

void ARTPSource::addReceiverReport(const sp<ABuffer> &buffer) {
    if (buffer->size() + 32 > buffer->capacity()) {
        ALOGW("RTCP buffer too small to accommodate RR.");
        return;
    }

    uint8_t fraction = 0;

    // According to appendix A.3 in RFC 3550
    uint32_t expected = mHighestSeqNumber - mBaseSeqNumber + 1;
    int64_t intervalExpected = expected - mPrevExpectedForRR;
    int64_t intervalReceived = mNumBuffersReceived - mPrevNumBuffersReceivedForRR;
    int64_t intervalPacketLost = intervalExpected - intervalReceived;

    if (intervalExpected > 0 && intervalPacketLost > 0) {
        fraction = (intervalPacketLost << 8) / intervalExpected;
    }

    mPrevExpectedForRR = expected;
    mPrevNumBuffersReceivedForRR = mNumBuffersReceived;
    int32_t cumulativePacketLost = (int32_t)expected - mNumBuffersReceived;

    uint8_t *data = buffer->data() + buffer->size();

    data[0] = 0x80 | 1;
    data[1] = 201;  // RR
    data[2] = 0;
    data[3] = 7;    // total (7+1) * sizeof(int32_t) = 32 bytes
    data[4] = kSourceID >> 24;
    data[5] = (kSourceID >> 16) & 0xff;
    data[6] = (kSourceID >> 8) & 0xff;
    data[7] = kSourceID & 0xff;

    data[8] = mID >> 24;
    data[9] = (mID >> 16) & 0xff;
    data[10] = (mID >> 8) & 0xff;
    data[11] = mID & 0xff;

    data[12] = fraction;  // fraction lost

    data[13] = cumulativePacketLost >> 16;  // cumulative lost
    data[14] = (cumulativePacketLost >> 8) & 0xff;
    data[15] = cumulativePacketLost & 0xff;

    data[16] = mHighestSeqNumber >> 24;
    data[17] = (mHighestSeqNumber >> 16) & 0xff;
    data[18] = (mHighestSeqNumber >> 8) & 0xff;
    data[19] = mHighestSeqNumber & 0xff;

    uint32_t jitterTime = 0;
    data[20] = jitterTime >> 24;    // Interarrival jitter
    data[21] = (jitterTime >> 16) & 0xff;
    data[22] = (jitterTime >> 8) & 0xff;
    data[23] = jitterTime & 0xff;

    uint32_t LSR = 0;
    uint32_t DLSR = 0;
    if (mLastSrNtpTime != 0) {
        LSR = (mLastSrNtpTime >> 16) & 0xffffffff;

        DLSR = (uint32_t)
            ((ALooper::GetNowUs() - mLastSrUpdateTimeUs) * 65536.0 / 1E6);
    }

    data[24] = LSR >> 24;
    data[25] = (LSR >> 16) & 0xff;
    data[26] = (LSR >> 8) & 0xff;
    data[27] = LSR & 0xff;

    data[28] = DLSR >> 24;
    data[29] = (DLSR >> 16) & 0xff;
    data[30] = (DLSR >> 8) & 0xff;
    data[31] = DLSR & 0xff;

    buffer->setRange(buffer->offset(), buffer->size() + (data[3] + 1) * sizeof(int32_t));
}

void ARTPSource::addTMMBR(const sp<ABuffer> &buffer, int32_t targetBitrate) {
    if (buffer->size() + 20 > buffer->capacity()) {
        ALOGW("RTCP buffer too small to accommodate RR.");
        return;
    }

    if (targetBitrate <= 0) {
        return;
    }

    uint8_t *data = buffer->data() + buffer->size();

    data[0] = 0x80 | 3; // TMMBR
    data[1] = 205;      // TSFB
    data[2] = 0;
    data[3] = 4;        // total (4+1) * sizeof(int32_t) = 20 bytes
    data[4] = kSourceID >> 24;
    data[5] = (kSourceID >> 16) & 0xff;
    data[6] = (kSourceID >> 8) & 0xff;
    data[7] = kSourceID & 0xff;

    *(int32_t*)(&data[8]) = 0;  // 4 bytes blank

    data[12] = mID >> 24;
    data[13] = (mID >> 16) & 0xff;
    data[14] = (mID >> 8) & 0xff;
    data[15] = mID & 0xff;

    // Find the first bit '1' from left & right side of the value.
    int32_t leftEnd = 31 - __builtin_clz(targetBitrate);
    int32_t rightEnd = ffs(targetBitrate) - 1;

    // Mantissa have only 17bit space by RTCP specification.
    if ((leftEnd - rightEnd) > 16) {
        rightEnd = leftEnd - 16;
    }
    int32_t mantissa = targetBitrate >> rightEnd;

    data[16] = ((rightEnd << 2) & 0xfc) | ((mantissa & 0x18000) >> 15);
    data[17] =                             (mantissa & 0x07f80) >> 7;
    data[18] =                             (mantissa & 0x0007f) << 1;
    data[19] = 40;              // 40 bytes overhead;

    buffer->setRange(buffer->offset(), buffer->size() + (data[3] + 1) * sizeof(int32_t));

    ALOGI("UE -> Op Req Rx bitrate : %d ", mantissa << rightEnd);
}

int ARTPSource::addNACK(const sp<ABuffer> &buffer) {
    constexpr size_t kMaxFCIs = 10; // max number of FCIs
    if (buffer->size() + (3 + kMaxFCIs) * sizeof(int32_t) > buffer->capacity()) {
        ALOGW("RTCP buffer too small to accommodate NACK.");
        return -1;
    }

    uint8_t *data = buffer->data() + buffer->size();

    data[0] = 0x80 | 1; // Generic NACK
    data[1] = 205;      // TSFB
    data[2] = 0;
    data[3] = 0;        // will be decided later
    data[4] = kSourceID >> 24;
    data[5] = (kSourceID >> 16) & 0xff;
    data[6] = (kSourceID >> 8) & 0xff;
    data[7] = kSourceID & 0xff;

    data[8] = mID >> 24;
    data[9] = (mID >> 16) & 0xff;
    data[10] = (mID >> 8) & 0xff;
    data[11] = mID & 0xff;

    List<int> list;
    List<int>::iterator it;
    getSeqNumToNACK(list, kMaxFCIs);
    size_t cnt = 0;

    int *FCI = (int *)(data + 12);
    for (it = list.begin(); it != list.end() && cnt < kMaxFCIs; it++) {
        *(FCI + cnt) = *it;
        cnt++;
    }

    data[3] = (3 + cnt) - 1;  // total (3 + #ofFCI) * sizeof(int32_t) byte

    buffer->setRange(buffer->offset(), buffer->size() + (data[3] + 1) * sizeof(int32_t));

    return cnt;
}

int ARTPSource::getSeqNumToNACK(List<int>& list, int size) {
    AutoMutex _l(mMapLock);
    int cnt = 0;

    std::map<uint16_t, infoNACK>::iterator it;
    for(it = mNACKMap.begin(); it != mNACKMap.end() && cnt < size; it++) {
        infoNACK &info_it = it->second;
        if (info_it.needToNACK) {
            info_it.needToNACK = false;
            // switch LSB to MSB for sending N/W
            uint32_t FCI;
            uint8_t *temp = (uint8_t *)&FCI;
            temp[0] = (info_it.seqNum >> 8) & 0xff;
            temp[1] = (info_it.seqNum)      & 0xff;
            temp[2] = (info_it.mask >> 8)   & 0xff;
            temp[3] = (info_it.mask)        & 0xff;

            list.push_back(FCI);
            cnt++;
        }
    }

    return cnt;
}

void ARTPSource::setSeqNumToNACK(uint16_t seqNum, uint16_t mask, uint16_t nowJitterHeadSeqNum) {
    AutoMutex _l(mMapLock);
    infoNACK info = {seqNum, mask, nowJitterHeadSeqNum, true};
    std::map<uint16_t, infoNACK>::iterator it;

    it = mNACKMap.find(seqNum);
    if (it != mNACKMap.end()) {
        infoNACK &info_it = it->second;
        // renew if (mask or head seq) is changed
        if ((info_it.mask != mask) || (info_it.nowJitterHeadSeqNum != nowJitterHeadSeqNum)) {
            info_it = info;
        }
    } else {
        mNACKMap[seqNum] = info;
    }

    // delete all NACK far from current Jitter's first sequence number
    it = mNACKMap.begin();
    while (it != mNACKMap.end()) {
        infoNACK &info_it = it->second;

        int diff = nowJitterHeadSeqNum - info_it.nowJitterHeadSeqNum;
        if (diff > 100) {
            ALOGV("Delete %d pkt from NACK map ", info_it.seqNum);
            it = mNACKMap.erase(it);
        } else {
            it++;
        }
    }

}

uint32_t ARTPSource::getSelfID() {
    return kSourceID;
}

void ARTPSource::setSelfID(const uint32_t selfID) {
    kSourceID = selfID;
}

void ARTPSource::setPeriodicFIR(bool enable) {
    ALOGD("setPeriodicFIR %d", enable);
    mIssueFIRRequests = enable;
}

int32_t ARTPSource::getStaticJitterTimeMs() {
    return mStaticJbTimeMs;
}

int32_t ARTPSource::getBaseJitterTimeMs() {
    return mJitterCalc->getBaseJitterMs();
}

int32_t ARTPSource::getInterArrivalJitterTimeMs() {
    return mJitterCalc->getInterArrivalJitterMs();
}

void ARTPSource::setStaticJitterTimeMs(const uint32_t jbTimeMs) {
    mStaticJbTimeMs = jbTimeMs;
}

void ARTPSource::putBaseJitterData(uint32_t timeStamp, int64_t arrivalTime) {
    mJitterCalc->putBaseData(timeStamp, arrivalTime);
}

void ARTPSource::putInterArrivalJitterData(uint32_t timeStamp, int64_t arrivalTime) {
    mJitterCalc->putInterArrivalData(timeStamp, arrivalTime);
}

void ARTPSource::setJbTimer(const sp<AMessage> timer) {
    mJbTimer = timer;
}

void ARTPSource::setJbAlarmTime(int64_t nowTimeUs, int64_t alarmAfterUs) {
    if (mJbTimer == NULL) {
        return;
    }
    int64_t alarmTimeUs = nowTimeUs + alarmAfterUs;
    bool alarm = false;
    if (mLastJbAlarmTimeUs <= nowTimeUs) {
        // no more alarm in pending.
        mLastJbAlarmTimeUs = nowTimeUs + alarmAfterUs;
        alarm = true;
    } else if (mLastJbAlarmTimeUs > alarmTimeUs + 5000L) {
        // bring an alarm forward more than 5ms.
        mLastJbAlarmTimeUs = alarmTimeUs;
        alarm = true;
    } else {
        // would not set alarm if it is close with before one.
    }

    if (alarm) {
        sp<AMessage> notify = mJbTimer->dup();
        notify->setObject("source", this);
        notify->post(alarmAfterUs);
    }
}

bool ARTPSource::isNeedToEarlyNotify() {
    uint32_t expected = mHighestSeqNumber - mBaseSeqNumber + 1;
    int32_t intervalExpectedInNow = expected - mPrevExpected;
    int32_t intervalReceivedInNow = mNumBuffersReceived - mPrevNumBuffersReceived;

    if (intervalExpectedInNow - intervalReceivedInNow > 5)
        return true;
    return false;
}

void ARTPSource::notifyPktInfo(int32_t bitrate, int64_t nowUs, bool isRegular) {
    int32_t payloadType = isRegular ? RTP_QUALITY : RTP_QUALITY_EMC;

    sp<AMessage> notify = mNotify->dup();
    notify->setInt32("rtcp-event", 1);
    notify->setInt32("payload-type", payloadType);
    notify->setInt32("feedback-type", 0);
    // sending target bitrate up to application to share rtp quality.
    notify->setInt32("bit-rate", bitrate);
    notify->setInt32("highest-seq-num", mHighestSeqNumber);
    notify->setInt32("base-seq-num", mBaseSeqNumber);
    notify->setInt32("prev-expected", mPrevExpected);
    notify->setInt32("num-buf-recv", mNumBuffersReceived);
    notify->setInt32("prev-num-buf-recv", mPrevNumBuffersReceived);
    notify->setInt32("latest-rtp-time", mLatestRtpTime);
    notify->setInt64("recv-time-us", nowUs);
    notify->setInt32("rtp-jitter-time-ms",
            std::max(getBaseJitterTimeMs(), getStaticJitterTimeMs()));
    notify->setInt32("rtp-rtcpsr-time-gap-ms", (int32_t)mAvgRtpRtcpGapMs);
    notify->post();

    if (isRegular) {
        uint32_t expected = mHighestSeqNumber - mBaseSeqNumber + 1;
        mPrevExpected = expected;
        mPrevNumBuffersReceived = mNumBuffersReceived;
    }
}

void ARTPSource::onIssueFIRByAssembler() {
    mIssueFIRByAssembler = true;
}

void ARTPSource::noticeAbandonBuffer(int cnt) {
    mNumBuffersReceived -= cnt;
}
}  // namespace android
