Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0cbbad64 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes from topic "av_rtp_measure"

* changes:
  VT: Change kStaticBuffer to 100ms except for ViLTE
  VT: Adjust an anchor time if packet comes too early.
  VT: provide last cvo value if it's not present.
  VT: Push incomplete packets unconditionally into decoder
  VT: process packets right after jbtime expired
  VT: Send more RTP SR information to upper layer
  VT: Corrects RTP/NTP timestamps of RTCP:SR(Sender Report).
parents 304942fa a03269ea
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -2854,10 +2854,43 @@ void NuPlayer::sendIMSRxNotice(const sp<AMessage> &msg) {

    CHECK(msg->findInt32("payload-type", &payloadType));

    int32_t rtpSeq = 0, rtpTime = 0;
    int64_t ntpTime = 0, recvTimeUs = 0;

    Parcel in;
    in.writeInt32(payloadType);

    switch (payloadType) {
        case ARTPSource::RTP_FIRST_PACKET:
        {
            CHECK(msg->findInt32("rtp-time", &rtpTime));
            CHECK(msg->findInt32("rtp-seq-num", &rtpSeq));
            CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
            in.writeInt32(rtpTime);
            in.writeInt32(rtpSeq);
            in.writeInt32(recvTimeUs >> 32);
            in.writeInt32(recvTimeUs & 0xFFFFFFFF);
            break;
        }
        case ARTPSource::RTCP_FIRST_PACKET:
        {
            CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
            in.writeInt32(recvTimeUs >> 32);
            in.writeInt32(recvTimeUs & 0xFFFFFFFF);
            break;
        }
        case ARTPSource::RTCP_SR:
        {
            CHECK(msg->findInt32("rtp-time", &rtpTime));
            CHECK(msg->findInt64("ntp-time", &ntpTime));
            CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
            in.writeInt32(rtpTime);
            in.writeInt32(ntpTime >> 32);
            in.writeInt32(ntpTime & 0xFFFFFFFF);
            in.writeInt32(recvTimeUs >> 32);
            in.writeInt32(recvTimeUs & 0xFFFFFFFF);
            break;
        }
        case ARTPSource::RTCP_TSFB:   // RTCP TSFB
        case ARTPSource::RTCP_PSFB:   // RTCP PSFB
        case ARTPSource::RTP_AUTODOWN:
@@ -2880,6 +2913,8 @@ void NuPlayer::sendIMSRxNotice(const sp<AMessage> &msg) {
            int32_t feedbackType, bitrate;
            int32_t highestSeqNum, baseSeqNum, prevExpected;
            int32_t numBufRecv, prevNumBufRecv;
            int32_t latestRtpTime, jbTimeMs, rtpRtcpSrTimeGapMs;
            int64_t recvTimeUs;
            CHECK(msg->findInt32("feedback-type", &feedbackType));
            CHECK(msg->findInt32("bit-rate", &bitrate));
            CHECK(msg->findInt32("highest-seq-num", &highestSeqNum));
@@ -2887,6 +2922,10 @@ void NuPlayer::sendIMSRxNotice(const sp<AMessage> &msg) {
            CHECK(msg->findInt32("prev-expected", &prevExpected));
            CHECK(msg->findInt32("num-buf-recv", &numBufRecv));
            CHECK(msg->findInt32("prev-num-buf-recv", &prevNumBufRecv));
            CHECK(msg->findInt32("latest-rtp-time", &latestRtpTime));
            CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
            CHECK(msg->findInt32("rtp-jitter-time-ms", &jbTimeMs));
            CHECK(msg->findInt32("rtp-rtcpsr-time-gap-ms", &rtpRtcpSrTimeGapMs));
            in.writeInt32(feedbackType);
            in.writeInt32(bitrate);
            in.writeInt32(highestSeqNum);
@@ -2894,6 +2933,11 @@ void NuPlayer::sendIMSRxNotice(const sp<AMessage> &msg) {
            in.writeInt32(prevExpected);
            in.writeInt32(numBufRecv);
            in.writeInt32(prevNumBufRecv);
            in.writeInt32(latestRtpTime);
            in.writeInt32(recvTimeUs >> 32);
            in.writeInt32(recvTimeUs & 0xFFFFFFFF);
            in.writeInt32(jbTimeMs);
            in.writeInt32(rtpRtcpSrTimeGapMs);
            break;
        }
        case ARTPSource::RTP_CVO:
+2 −12
Original line number Diff line number Diff line
@@ -395,23 +395,13 @@ void NuPlayer::RTPSource::onMessageReceived(const sp<AMessage> &msg) {
                CHECK(msg->findInt64("ntp-time", (int64_t *)&ntpTime));

                onTimeUpdate(trackIndex, rtpTime, ntpTime);
                break;
            }

            int32_t firstRTCP;
            if (msg->findInt32("first-rtcp", &firstRTCP)) {
                // There won't be an access unit here, it's just a notification
                // that the data communication worked since we got the first
                // rtcp packet.
                ALOGV("first-rtcp");
                break;
            }

            int32_t IMSRxNotice;
            if (msg->findInt32("rtcp-event", &IMSRxNotice)) {
                int32_t payloadType, feedbackType;
                int32_t payloadType = 0, feedbackType = 0;
                CHECK(msg->findInt32("payload-type", &payloadType));
                CHECK(msg->findInt32("feedback-type", &feedbackType));
                msg->findInt32("feedback-type", &feedbackType);

                sp<AMessage> notify = dupNotify();
                notify->setInt32("what", kWhatIMSRxNotice);
+49 −61
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ AAVCAssembler::AAVCAssembler(const sp<AMessage> &notify)
      mNextExpectedSeqNo(0),
      mAccessUnitDamaged(false),
      mFirstIFrameProvided(false),
      mLastCvo(-1),
      mLastIFrameProvidedAtMs(0),
      mLastRtpTimeJitterDataUs(0),
      mWidth(0),
@@ -137,7 +138,7 @@ ARTPAssembler::AssemblyStatus AAVCAssembler::addNALUnit(
    }
    source->putInterArrivalJitterData(rtpTime, nowTimeUs);

    const int64_t startTimeMs = source->mFirstSysTime / 1000;
    const int64_t startTimeMs = source->mSysAnchorTime / 1000;
    const int64_t nowTimeMs = nowTimeUs / 1000;
    const int32_t staticJitterTimeMs = source->getStaticJitterTimeMs();
    const int32_t baseJitterTimeMs = source->getBaseJitterTimeMs();
@@ -195,33 +196,38 @@ ARTPAssembler::AssemblyStatus AAVCAssembler::addNALUnit(

    if (!isExpired) {
        ALOGV("buffering in jitter buffer.");
        // set an alarm for jitter buffer time expiration.
        // adding 1ms because jitter buffer time is keep changing.
        int64_t expTimeUs = (RtpToMs(std::abs(diffTimeRtp), clockRate) + 1) * 1000;
        source->setJbAlarmTime(nowTimeUs, expTimeUs);
        return NOT_ENOUGH_DATA;
    }

    if (isFirstLineBroken) {
        if (isSecondLineBroken) {
        int64_t totalDiffTimeMs = RtpToMs(diffTimeRtp + jitterTimeRtp, clockRate);
            ALOGE("buffer too late... \t RTP diff from exp =%lld \t MS diff from stamp = %lld\t\t"
        String8 info;
        info.appendFormat("RTP diff from exp =%lld \t MS diff from stamp = %lld\t\t"
                    "Seq# %d \t ExpSeq# %d \t"
                    "JitterMs %d + (%d + %d * %.3f)",
                    (long long)diffTimeRtp, (long long)totalDiffTimeMs,
                    buffer->int32Data(), mNextExpectedSeqNo,
                    jitterTimeMs, tryJbTimeMs, dynamicJbTimeMs, JITTER_MULTIPLE);
        if (isSecondLineBroken) {
            ALOGE("%s", info.string());
            printNowTimeMs(startTimeMs, nowTimeMs, playedTimeMs);
            printRTPTime(rtpTime, playedTimeRtp, expiredTimeRtp, isExpired);

            mNextExpectedSeqNo = pickProperSeq(queue, firstRTPTime, playedTimeRtp, jitterTimeRtp);
        }  else {
            ALOGW("=== WARNING === buffer arrived after %d + %d = %d ms === WARNING === ",
                    jitterTimeMs, tryJbTimeMs, jitterTimeMs + tryJbTimeMs);
            ALOGW("%s", info.string());
        }
    }

    if (mNextExpectedSeqNoValid) {
        int32_t size = queue->size();
        mNextExpectedSeqNo = pickStartSeq(queue, firstRTPTime, playedTimeRtp, jitterTimeRtp);
        int32_t cntRemove = deleteUnitUnderSeq(queue, mNextExpectedSeqNo);

        if (cntRemove > 0) {
            int32_t size = queue->size();
            source->noticeAbandonBuffer(cntRemove);
            ALOGW("delete %d of %d buffers", cntRemove, size);
        }
@@ -441,7 +447,6 @@ ARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit(
    uint32_t rtpTimeStartAt;
    CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTimeStartAt));
    uint32_t startSeqNo = buffer->int32Data();
    bool pFrame = nalType == 0x1;

    if (data[1] & 0x40) {
        // Huh? End bit also set on the first buffer.
@@ -451,8 +456,6 @@ ARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit(
        complete = true;
    } else {
        List<sp<ABuffer> >::iterator it = ++queue->begin();
        int32_t connected = 1;
        bool snapped = false;
        while (it != queue->end()) {
            ALOGV("sequence length %zu", totalCount);

@@ -463,33 +466,26 @@ ARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit(

            if ((uint32_t)buffer->int32Data() != expectedSeqNo) {
                ALOGD("sequence not complete, expected seqNo %u, got %u, nalType %u",
                     expectedSeqNo, (unsigned)buffer->int32Data(), nalType);
                snapped = true;

                if (!pFrame) {
                    return WRONG_SEQUENCE_NUMBER;
                }
            }

            if (!snapped) {
                connected++;
                     expectedSeqNo, (uint32_t)buffer->int32Data(), nalType);
            }

            uint32_t rtpTime;
            CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
            if (size < 2
                    || data[0] != indicator
            if (size < 2) {
                ALOGV("Ignoring malformed FU buffer.");
                it = queue->erase(it);
                continue;
            }
            if (data[0] != indicator
                    || (data[1] & 0x1f) != nalType
                    || (data[1] & 0x80)
                    || rtpTime != rtpTimeStartAt) {
                ALOGV("Ignoring malformed FU buffer.");

                // Delete the whole start of the FU.

                mNextExpectedSeqNo = expectedSeqNo + 1;
                deleteUnitUnderSeq(queue, mNextExpectedSeqNo);

                return MALFORMED_PACKET;
                // Assembler already have given enough time by jitter buffer
                ALOGD("Seems another frame. Incomplete frame [%d ~ %d) \t %d FUs",
                        startSeqNo, expectedSeqNo, (int)queue->distance(queue->begin(), it));
                expectedSeqNo = (uint32_t)buffer->int32Data();
                complete = true;
                break;
            }

            totalSize += size - 2;
@@ -498,14 +494,6 @@ ARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit(
            expectedSeqNo = (uint32_t)buffer->int32Data() + 1;

            if (data[1] & 0x40) {
                if (pFrame && !recycleUnit(startSeqNo, expectedSeqNo,
                            connected, totalCount, 0.5f)) {
                    mNextExpectedSeqNo = expectedSeqNo;
                    deleteUnitUnderSeq(queue, mNextExpectedSeqNo);

                    return MALFORMED_PACKET;
                }

                // This is the last fragment.
                complete = true;
                break;
@@ -557,6 +545,9 @@ ARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit(

    if (cvo >= 0) {
        unit->meta()->setInt32("cvo", cvo);
        mLastCvo = cvo;
    } else if (mLastCvo >= 0) {
        unit->meta()->setInt32("cvo", mLastCvo);
    }
    if (source != nullptr) {
        unit->meta()->setObject("source", source);
@@ -621,35 +612,32 @@ void AAVCAssembler::submitAccessUnit() {
    msg->post();
}

int32_t AAVCAssembler::pickProperSeq(const Queue *queue,
int32_t AAVCAssembler::pickStartSeq(const Queue *queue,
        uint32_t first, int64_t play, int64_t jit) {
    // pick the first sequence number has the start bit.
    sp<ABuffer> buffer = *(queue->begin());
    int32_t nextSeqNo = buffer->int32Data();
    int32_t firstSeqNo = buffer->int32Data();

    Queue::const_iterator it = queue->begin();
    while (it != queue->end()) {
        int64_t rtpTime = findRTPTime(first, *it);
        // if pkt in time exists, that should be the next pivot
    // This only works for FU-A type & non-start sequence
    unsigned nalType = buffer->data()[0] & 0x1f;
    if (nalType != 28 || buffer->data()[1] & 0x80) {
        return firstSeqNo;
    }

    for (auto it : *queue) {
        const uint8_t *data = it->data();
        int64_t rtpTime = findRTPTime(first, it);
        if (rtpTime + jit >= play) {
            nextSeqNo = (*it)->int32Data();
            break;
        }
        it++;
        if ((data[1] & 0x80)) {
            const int32_t seqNo = it->int32Data();
            ALOGE("finding [HEAD] pkt. \t Seq# (%d ~ )[%d", firstSeqNo, seqNo);
            firstSeqNo = seqNo;
            break;
        }
    return nextSeqNo;
    }

bool AAVCAssembler::recycleUnit(uint32_t start, uint32_t end, uint32_t connected,
        size_t avail, float goodRatio) {
    float total = end - start;
    float valid = connected;
    float exist = avail;
    bool isRecycle = (valid / total) >= goodRatio;

    ALOGV("checking p-frame losses.. recvBufs %f valid %f diff %f recycle? %d",
            exist, valid, total, isRecycle);

    return isRecycle;
    return firstSeqNo;
}

int32_t AAVCAssembler::deleteUnitUnderSeq(Queue *queue, uint32_t seq) {
+3 −3
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@

#include <utils/List.h>
#include <utils/RefBase.h>
#include <utils/String8.h>

namespace android {

@@ -47,6 +48,7 @@ private:
    uint32_t mNextExpectedSeqNo;
    bool mAccessUnitDamaged;
    bool mFirstIFrameProvided;
    int32_t mLastCvo;
    uint64_t mLastIFrameProvidedAtMs;
    int64_t mLastRtpTimeJitterDataUs;
    int32_t mWidth;
@@ -64,9 +66,7 @@ private:

    void submitAccessUnit();

    int32_t pickProperSeq(const Queue *q, uint32_t first, int64_t play, int64_t jit);
    bool recycleUnit(uint32_t start, uint32_t end, uint32_t connected,
            size_t avail, float goodRatio);
    int32_t pickStartSeq(const Queue *q, uint32_t first, int64_t play, int64_t jit);
    int32_t deleteUnitUnderSeq(Queue *q, uint32_t seq);

    DISALLOW_EVIL_CONSTRUCTORS(AAVCAssembler);
+49 −60
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ AHEVCAssembler::AHEVCAssembler(const sp<AMessage> &notify)
      mNextExpectedSeqNo(0),
      mAccessUnitDamaged(false),
      mFirstIFrameProvided(false),
      mLastCvo(-1),
      mLastIFrameProvidedAtMs(0),
      mLastRtpTimeJitterDataUs(0),
      mWidth(0),
@@ -147,7 +148,7 @@ ARTPAssembler::AssemblyStatus AHEVCAssembler::addNALUnit(
    }
    source->putInterArrivalJitterData(rtpTime, nowTimeUs);

    const int64_t startTimeMs = source->mFirstSysTime / 1000;
    const int64_t startTimeMs = source->mSysAnchorTime / 1000;
    const int64_t nowTimeMs = nowTimeUs / 1000;
    const int32_t staticJitterTimeMs = source->getStaticJitterTimeMs();
    const int32_t baseJitterTimeMs = source->getBaseJitterTimeMs();
@@ -205,33 +206,38 @@ ARTPAssembler::AssemblyStatus AHEVCAssembler::addNALUnit(

    if (!isExpired) {
        ALOGV("buffering in jitter buffer.");
        // set an alarm for jitter buffer time expiration.
        // adding 1ms because jitter buffer time is keep changing.
        int64_t expTimeUs = (RtpToMs(std::abs(diffTimeRtp), clockRate) + 1) * 1000;
        source->setJbAlarmTime(nowTimeUs, expTimeUs);
        return NOT_ENOUGH_DATA;
    }

    if (isFirstLineBroken) {
        if (isSecondLineBroken) {
        int64_t totalDiffTimeMs = RtpToMs(diffTimeRtp + jitterTimeRtp, clockRate);
            ALOGE("buffer too late... \t RTP diff from exp =%lld \t MS diff from stamp = %lld\t\t"
        String8 info;
        info.appendFormat("RTP diff from exp =%lld \t MS diff from stamp = %lld\t\t"
                    "Seq# %d \t ExpSeq# %d \t"
                    "JitterMs %d + (%d + %d * %.3f)",
                    (long long)diffTimeRtp, (long long)totalDiffTimeMs,
                    buffer->int32Data(), mNextExpectedSeqNo,
                    jitterTimeMs, tryJbTimeMs, dynamicJbTimeMs, JITTER_MULTIPLE);
        if (isSecondLineBroken) {
            ALOGE("%s", info.string());
            printNowTimeMs(startTimeMs, nowTimeMs, playedTimeMs);
            printRTPTime(rtpTime, playedTimeRtp, expiredTimeRtp, isExpired);

            mNextExpectedSeqNo = pickProperSeq(queue, firstRTPTime, playedTimeRtp, jitterTimeRtp);
        }  else {
            ALOGW("=== WARNING === buffer arrived after %d + %d = %d ms === WARNING === ",
                    jitterTimeMs, tryJbTimeMs, jitterTimeMs + tryJbTimeMs);
            ALOGW("%s", info.string());
        }
    }

    if (mNextExpectedSeqNoValid) {
        int32_t size = queue->size();
        mNextExpectedSeqNo = pickStartSeq(queue, firstRTPTime, playedTimeRtp, jitterTimeRtp);
        int32_t cntRemove = deleteUnitUnderSeq(queue, mNextExpectedSeqNo);

        if (cntRemove > 0) {
            int32_t size = queue->size();
            source->noticeAbandonBuffer(cntRemove);
            ALOGW("delete %d of %d buffers", cntRemove, size);
        }
@@ -466,7 +472,6 @@ ARTPAssembler::AssemblyStatus AHEVCAssembler::addFragmentedNALUnit(
    uint32_t rtpTimeStartAt;
    CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTimeStartAt));
    uint32_t startSeqNo = buffer->int32Data();
    bool pFrame = (nalType < 0x10);

    if (data[2] & 0x40) {
        // Huh? End bit also set on the first buffer.
@@ -476,8 +481,6 @@ ARTPAssembler::AssemblyStatus AHEVCAssembler::addFragmentedNALUnit(
        complete = true;
    } else {
        List<sp<ABuffer> >::iterator it = ++queue->begin();
        int32_t connected = 1;
        bool snapped = false;
        while (it != queue->end()) {
            ALOGV("sequence length %zu", totalCount);

@@ -488,33 +491,26 @@ ARTPAssembler::AssemblyStatus AHEVCAssembler::addFragmentedNALUnit(

            if ((uint32_t)buffer->int32Data() != expectedSeqNo) {
                ALOGV("sequence not complete, expected seqNo %u, got %u, nalType %u",
                     expectedSeqNo, (uint32_t)buffer->int32Data(), nalType);
                snapped = true;

                if (!pFrame) {
                    return WRONG_SEQUENCE_NUMBER;
                }
            }

            if (!snapped) {
                connected++;
                     expectedSeqNo, (unsigned)buffer->int32Data(), nalType);
            }

            uint32_t rtpTime;
            CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
            if (size < 3
                    || ((data[0] >> 1) & H265_NALU_MASK) != indicator
            if (size < 3) {
                ALOGV("Ignoring malformed FU buffer.");
                it = queue->erase(it);
                continue;
            }
            if (((data[0] >> 1) & H265_NALU_MASK) != indicator
                    || (data[2] & H265_NALU_MASK) != nalType
                    || (data[2] & 0x80)
                    || rtpTime != rtpTimeStartAt) {
                ALOGV("Ignoring malformed FU buffer.");

                // Delete the whole start of the FU.

                mNextExpectedSeqNo = expectedSeqNo + 1;
                deleteUnitUnderSeq(queue, mNextExpectedSeqNo);

                return MALFORMED_PACKET;
                // Assembler already have given enough time by jitter buffer
                ALOGD("Seems another frame. Incomplete frame [%d ~ %d) \t %d FUs",
                        startSeqNo, expectedSeqNo, (int)queue->distance(queue->begin(), it));
                expectedSeqNo = (uint32_t)buffer->int32Data();
                complete = true;
                break;
            }

            totalSize += size - 3;
@@ -523,13 +519,6 @@ ARTPAssembler::AssemblyStatus AHEVCAssembler::addFragmentedNALUnit(
            expectedSeqNo = (uint32_t)buffer->int32Data() + 1;

            if (data[2] & 0x40) {
                if (pFrame && !recycleUnit(startSeqNo, expectedSeqNo,
                        connected, totalCount, 0.5f)) {
                    mNextExpectedSeqNo = expectedSeqNo;
                    deleteUnitUnderSeq(queue, mNextExpectedSeqNo);

                    return MALFORMED_PACKET;
                }
                // This is the last fragment.
                complete = true;
                break;
@@ -579,6 +568,9 @@ ARTPAssembler::AssemblyStatus AHEVCAssembler::addFragmentedNALUnit(

    if (cvo >= 0) {
        unit->meta()->setInt32("cvo", cvo);
        mLastCvo = cvo;
    } else if (mLastCvo >= 0) {
        unit->meta()->setInt32("cvo", mLastCvo);
    }

    addSingleNALUnit(unit);
@@ -635,35 +627,32 @@ void AHEVCAssembler::submitAccessUnit() {
    msg->post();
}

int32_t AHEVCAssembler::pickProperSeq(const Queue *queue,
int32_t AHEVCAssembler::pickStartSeq(const Queue *queue,
        uint32_t first, int64_t play, int64_t jit) {
    // pick the first sequence number has the start bit.
    sp<ABuffer> buffer = *(queue->begin());
    int32_t nextSeqNo = buffer->int32Data();
    int32_t firstSeqNo = buffer->int32Data();

    Queue::const_iterator it = queue->begin();
    while (it != queue->end()) {
        int64_t rtpTime = findRTPTime(first, *it);
        // if pkt in time exists, that should be the next pivot
    // This only works for FU-A type & non-start sequence
    unsigned nalType = buffer->data()[0] & 0x1f;
    if (nalType != 28 || buffer->data()[2] & 0x80) {
        return firstSeqNo;
    }

    for (auto it : *queue) {
        const uint8_t *data = it->data();
        int64_t rtpTime = findRTPTime(first, it);
        if (rtpTime + jit >= play) {
            nextSeqNo = (*it)->int32Data();
            break;
        }
        it++;
        if ((data[2] & 0x80)) {
            const int32_t seqNo = it->int32Data();
            ALOGE("finding [HEAD] pkt. \t Seq# (%d ~ )[%d", firstSeqNo, seqNo);
            firstSeqNo = seqNo;
            break;
        }
    return nextSeqNo;
    }

bool AHEVCAssembler::recycleUnit(uint32_t start, uint32_t end,  uint32_t connected,
         size_t avail, float goodRatio) {
    float total = end - start;
    float valid = connected;
    float exist = avail;
    bool isRecycle = (valid / total) >= goodRatio;

    ALOGV("checking p-frame losses.. recvBufs %f valid %f diff %f recycle? %d",
            exist, valid, total, isRecycle);

    return isRecycle;
    return firstSeqNo;
}

int32_t AHEVCAssembler::deleteUnitUnderSeq(Queue *queue, uint32_t seq) {
Loading