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

Commit 115d98ab authored by Rachad Alao's avatar Rachad Alao Committed by Android (Google) Code Review
Browse files

Merge "media: Move video buffer timestamp adjustment from CodecSource to...

Merge "media: Move video buffer timestamp adjustment from CodecSource to GraphicBufferSource." into nyc-dr1-dev
parents 9ede6cef fcf7cf78
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -192,6 +192,7 @@ public:
        INTERNAL_OPTION_START_TIME, // data is an int64_t
        INTERNAL_OPTION_TIME_LAPSE, // data is an int64_t[2]
        INTERNAL_OPTION_COLOR_ASPECTS, // data is ColorAspects
        INTERNAL_OPTION_TIME_OFFSET, // data is an int64_t
    };
    virtual status_t setInternalOption(
            node_id node,
+1 −1
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ struct MediaCodecSource : public MediaSource,

    bool isVideo() const { return mIsVideo; }
    sp<IGraphicBufferProducer> getGraphicBufferProducer();
    void setInputBufferTimeOffset(int64_t timeOffsetUs);
    status_t setInputBufferTimeOffset(int64_t timeOffsetUs);
    int64_t getFirstSampleSystemTimeUs();

    // MediaSource
+17 −0
Original line number Diff line number Diff line
@@ -7473,6 +7473,23 @@ status_t ACodec::setParameters(const sp<AMessage> &params) {
        }
    }

    int64_t timeOffsetUs;
    if (params->findInt64("time-offset-us", &timeOffsetUs)) {
        status_t err = mOMX->setInternalOption(
            mNode,
            kPortIndexInput,
            IOMX::INTERNAL_OPTION_TIME_OFFSET,
            &timeOffsetUs,
            sizeof(timeOffsetUs));

        if (err != OK) {
            ALOGE("[%s] Unable to set input buffer time offset (err %d)",
                mComponentName.c_str(),
                err);
            return err;
        }
    }

    int64_t skipFramesBeforeUs;
    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
        status_t err =
+12 −6
Original line number Diff line number Diff line
@@ -336,10 +336,10 @@ sp<MediaCodecSource> MediaCodecSource::Create(
    return NULL;
}

void MediaCodecSource::setInputBufferTimeOffset(int64_t timeOffsetUs) {
status_t MediaCodecSource::setInputBufferTimeOffset(int64_t timeOffsetUs) {
    sp<AMessage> msg = new AMessage(kWhatSetInputBufferTimeOffset, mReflector);
    msg->setInt64("time-offset-us", timeOffsetUs);
    postSynchronouslyAndReturnError(msg);
    return postSynchronouslyAndReturnError(msg);
}

int64_t MediaCodecSource::getFirstSampleSystemTimeUs() {
@@ -874,9 +874,7 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {
                                break;
                            }
                        }
                        // Time offset is not applied at
                        // feedEncoderInputBuffer() in surface input case.
                        timeUs += mInputBufferTimeOffsetUs;
                        // Timestamp offset is already adjusted in GraphicBufferSource.
                        // GraphicBufferSource is supposed to discard samples
                        // queued before start, and offset timeUs by start time
                        CHECK_GE(timeUs, 0ll);
@@ -1015,10 +1013,18 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {
    {
        sp<AReplyToken> replyID;
        CHECK(msg->senderAwaitsResponse(&replyID));

        status_t err = OK;
        CHECK(msg->findInt64("time-offset-us", &mInputBufferTimeOffsetUs));

        // Propagate the timestamp offset to GraphicBufferSource.
        if (mIsVideo) {
            sp<AMessage> params = new AMessage;
            params->setInt64("time-offset-us", mInputBufferTimeOffsetUs);
            err = mEncoder->setParameters(params);
        }

        sp<AMessage> response = new AMessage;
        response->setInt32("err", err);
        response->postReply(replyID);
        break;
    }
+40 −23
Original line number Diff line number Diff line
@@ -145,7 +145,8 @@ GraphicBufferSource::GraphicBufferSource(
    mTimePerCaptureUs(-1ll),
    mTimePerFrameUs(-1ll),
    mPrevCaptureUs(-1ll),
    mPrevFrameUs(-1ll) {
    mPrevFrameUs(-1ll),
    mInputBufferTimeOffsetUs(0ll) {

    ALOGV("GraphicBufferSource w=%u h=%u c=%u",
            bufferWidth, bufferHeight, bufferCount);
@@ -774,6 +775,7 @@ status_t GraphicBufferSource::signalEndOfInputStream() {

int64_t GraphicBufferSource::getTimestamp(const BufferItem &item) {
    int64_t timeUs = item.mTimestamp / 1000;
    timeUs += mInputBufferTimeOffsetUs;

    if (mTimePerCaptureUs > 0ll
            && (mTimePerCaptureUs > 2 * mTimePerFrameUs
@@ -802,7 +804,16 @@ int64_t GraphicBufferSource::getTimestamp(const BufferItem &item) {
                static_cast<long long>(mPrevFrameUs));

        return mPrevFrameUs;
    } else if (mMaxTimestampGapUs > 0ll) {
    } else {
        int64_t originalTimeUs = timeUs;
        if (originalTimeUs <= mPrevOriginalTimeUs) {
                // Drop the frame if it's going backward in time. Bad timestamp
                // could disrupt encoder's rate control completely.
            ALOGW("Dropping frame that's going backward in time");
            return -1;
        }

        if (mMaxTimestampGapUs > 0ll) {
            //TODO: Fix the case when mMaxTimestampGapUs and mTimePerCaptureUs are both set.

            /* Cap timestamp gap between adjacent frames to specified max
@@ -812,26 +823,20 @@ int64_t GraphicBufferSource::getTimestamp(const BufferItem &item) {
             * where encoder's rate control logic produces huge frames after a
             * long period of suspension.
             */

        int64_t originalTimeUs = timeUs;
            if (mPrevOriginalTimeUs >= 0ll) {
            if (originalTimeUs < mPrevOriginalTimeUs) {
                // Drop the frame if it's going backward in time. Bad timestamp
                // could disrupt encoder's rate control completely.
                ALOGW("Dropping frame that's going backward in time");
                return -1;
            }
                int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs;
                timeUs = (timestampGapUs < mMaxTimestampGapUs ?
                    timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs;
        }
        mPrevOriginalTimeUs = originalTimeUs;
        mPrevModifiedTimeUs = timeUs;
                mOriginalTimeUs.add(timeUs, originalTimeUs);
                ALOGV("IN  timestamp: %lld -> %lld",
                    static_cast<long long>(originalTimeUs),
                    static_cast<long long>(timeUs));
            }
        }

        mPrevOriginalTimeUs = originalTimeUs;
        mPrevModifiedTimeUs = timeUs;
    }

    return timeUs;
}
@@ -1048,6 +1053,18 @@ status_t GraphicBufferSource::setMaxTimestampGapUs(int64_t maxGapUs) {
    return OK;
}

status_t GraphicBufferSource::setInputBufferTimeOffset(int64_t timeOffsetUs) {
    Mutex::Autolock autoLock(mMutex);

    // timeOffsetUs must be negative for adjustment.
    if (timeOffsetUs >= 0ll) {
        return INVALID_OPERATION;
    }

    mInputBufferTimeOffsetUs = timeOffsetUs;
    return OK;
}

status_t GraphicBufferSource::setMaxFps(float maxFps) {
    Mutex::Autolock autoLock(mMutex);

Loading