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

Commit ae27e4fa authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "media: Support setting stopTime in MediaSource"

parents 5b4cc877 f8754cc5
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -1989,10 +1989,12 @@ status_t StagefrightRecorder::stop() {
        mCameraSourceTimeLapse = NULL;
    }

    if (mVideoEncoderSource != NULL) {
    int64_t stopTimeUs = systemTime() / 1000;
        sp<MetaData> meta = new MetaData;
        err = mVideoEncoderSource->setStopStimeUs(stopTimeUs);
    for (const auto &source : { mAudioEncoderSource, mVideoEncoderSource }) {
        if (source != nullptr && OK != source->setStopTimeUs(stopTimeUs)) {
            ALOGW("Failed to set stopTime %lld us for %s",
                    (long long)stopTimeUs, source->isVideo() ? "Video" : "Audio");
        }
    }

    if (mWriter != NULL) {
+25 −0
Original line number Diff line number Diff line
@@ -58,6 +58,8 @@ AudioSource::AudioSource(
      mOutSampleRate(outSampleRate > 0 ? outSampleRate : sampleRate),
      mTrackMaxAmplitude(false),
      mStartTimeUs(0),
      mStopSystemTimeUs(-1),
      mLastFrameTimestampUs(0),
      mMaxAmplitude(0),
      mPrevSampleTimeUs(0),
      mInitialReadTimeUs(0),
@@ -175,6 +177,7 @@ status_t AudioSource::reset() {
    }

    mStarted = false;
    mStopSystemTimeUs = -1;
    mFrameAvailableCondition.signal();

    mRecord->stop();
@@ -286,6 +289,21 @@ status_t AudioSource::read(
    return OK;
}

status_t AudioSource::setStopTimeUs(int64_t stopTimeUs) {
    Mutex::Autolock autoLock(mLock);
    ALOGV("Set stoptime: %lld us", (long long)stopTimeUs);

    if (stopTimeUs < -1) {
        ALOGE("Invalid stop time %lld us", (long long)stopTimeUs);
        return BAD_VALUE;
    } else if (stopTimeUs == -1) {
        ALOGI("reset stopTime to be -1");
    }

    mStopSystemTimeUs = stopTimeUs;
    return OK;
}

void AudioSource::signalBufferReturned(MediaBuffer *buffer) {
    ALOGV("signalBufferReturned: %p", buffer->data());
    Mutex::Autolock autoLock(mLock);
@@ -338,6 +356,12 @@ status_t AudioSource::dataCallback(const AudioRecord::Buffer& audioBuffer) {
        return OK;
    }

    if (mStopSystemTimeUs != -1 && timeUs >= mStopSystemTimeUs) {
        ALOGV("Drop Audio frame at %lld  stop time: %lld us",
                (long long)timeUs, (long long)mStopSystemTimeUs);
        return OK;
    }

    if (mNumFramesReceived == 0 && mPrevSampleTimeUs == 0) {
        mInitialReadTimeUs = timeUs;
        // Initial delay
@@ -346,6 +370,7 @@ status_t AudioSource::dataCallback(const AudioRecord::Buffer& audioBuffer) {
        }
        mPrevSampleTimeUs = mStartTimeUs;
    }
    mLastFrameTimestampUs = timeUs;

    size_t numLostBytes = 0;
    if (mNumFramesReceived > 0) {  // Ignore earlier frame lost
+23 −0
Original line number Diff line number Diff line
@@ -202,6 +202,7 @@ CameraSource::CameraSource(
      mNumFramesEncoded(0),
      mTimeBetweenFrameCaptureUs(0),
      mFirstFrameTimeUs(0),
      mStopSystemTimeUs(-1),
      mNumFramesDropped(0),
      mNumGlitches(0),
      mGlitchDurationThresholdUs(200000),
@@ -861,6 +862,7 @@ status_t CameraSource::reset() {
    {
        Mutex::Autolock autoLock(mLock);
        mStarted = false;
        mStopSystemTimeUs = -1;
        mFrameAvailableCondition.signal();

        int64_t token;
@@ -1052,12 +1054,33 @@ status_t CameraSource::read(
    return OK;
}

status_t CameraSource::setStopTimeUs(int64_t stopTimeUs) {
    Mutex::Autolock autoLock(mLock);
    ALOGV("Set stoptime: %lld us", (long long)stopTimeUs);

    if (stopTimeUs < -1) {
        ALOGE("Invalid stop time %lld us", (long long)stopTimeUs);
        return BAD_VALUE;
    } else if (stopTimeUs == -1) {
        ALOGI("reset stopTime to be -1");
    }

    mStopSystemTimeUs = stopTimeUs;
    return OK;
}

bool CameraSource::shouldSkipFrameLocked(int64_t timestampUs) {
    if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) {
        ALOGV("Drop frame at %lld/%lld us", (long long)timestampUs, (long long)mStartTimeUs);
        return true;
    }

    if (mStopSystemTimeUs != -1 && timestampUs >= mStopSystemTimeUs) {
        ALOGV("Drop Camera frame at %lld  stop time: %lld us",
                (long long)timestampUs, (long long)mStopSystemTimeUs);
        return true;
    }

    // May need to skip frame or modify timestamp. Currently implemented
    // by the subclass CameraSourceTimeLapse.
    if (skipCurrentFrame(timestampUs)) {
+5 −1
Original line number Diff line number Diff line
@@ -2123,13 +2123,17 @@ status_t MPEG4Writer::Track::stop(bool stopSource) {
    if (mDone) {
        return OK;
    }
    mDone = true;

    if (stopSource) {
        ALOGD("%s track source stopping", getTrackType());
        mSource->stop();
        ALOGD("%s track source stopped", getTrackType());
    }

    // Set mDone to be true after sucessfully stop mSource as mSource may be still outputting
    // buffers to the writer.
    mDone = true;

    void *dummy;
    pthread_join(mThread, &dummy);
    status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
+28 −8
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ struct MediaCodecSource::Puller : public AHandler {
    void stopSource();
    void pause();
    void resume();

    status_t setStopTimeUs(int64_t stopTimeUs);
    bool readBuffer(MediaBuffer **buffer);

protected:
@@ -66,6 +66,7 @@ private:
        kWhatStart = 'msta',
        kWhatStop,
        kWhatPull,
        kWhatSetStopTimeUs,
    };

    sp<MediaSource> mSource;
@@ -161,6 +162,12 @@ status_t MediaCodecSource::Puller::postSynchronouslyAndReturnError(
    return err;
}

status_t MediaCodecSource::Puller::setStopTimeUs(int64_t stopTimeUs) {
    sp<AMessage> msg = new AMessage(kWhatSetStopTimeUs, this);
    msg->setInt64("stop-time-us", stopTimeUs);
    return postSynchronouslyAndReturnError(msg);
}

status_t MediaCodecSource::Puller::start(const sp<MetaData> &meta, const sp<AMessage> &notify) {
    ALOGV("puller (%s) start", mIsAudio ? "audio" : "video");
    mLooper->start(
@@ -250,6 +257,20 @@ void MediaCodecSource::Puller::onMessageReceived(const sp<AMessage> &msg) {
            break;
        }

        case kWhatSetStopTimeUs:
        {
            sp<AReplyToken> replyID;
            CHECK(msg->senderAwaitsResponse(&replyID));
            int64_t stopTimeUs;
            CHECK(msg->findInt64("stop-time-us", &stopTimeUs));
            status_t err = mSource->setStopTimeUs(stopTimeUs);

            sp<AMessage> response = new AMessage;
            response->setInt32("err", err);
            response->postReply(replyID);
            break;
        }

        case kWhatStop:
        {
            mSource->stop();
@@ -364,11 +385,8 @@ status_t MediaCodecSource::stop() {
}


status_t MediaCodecSource::setStopStimeUs(int64_t stopTimeUs) {
    if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
        return OK;
    }
    sp<AMessage> msg = new AMessage(kWhatSetStopTimeOffset, mReflector);
status_t MediaCodecSource::setStopTimeUs(int64_t stopTimeUs) {
    sp<AMessage> msg = new AMessage(kWhatSetStopTimeUs, mReflector);
    msg->setInt64("stop-time-us", stopTimeUs);
    return postSynchronouslyAndReturnError(msg);
}
@@ -1051,7 +1069,7 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {
        response->postReply(replyID);
        break;
    }
    case kWhatSetStopTimeOffset:
    case kWhatSetStopTimeUs:
    {
        sp<AReplyToken> replyID;
        CHECK(msg->senderAwaitsResponse(&replyID));
@@ -1059,11 +1077,13 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {
        int64_t stopTimeUs;
        CHECK(msg->findInt64("stop-time-us", &stopTimeUs));

        // Propagate the timestamp offset to GraphicBufferSource.
        // Propagate the stop time to GraphicBufferSource.
        if (mFlags & FLAG_USE_SURFACE_INPUT) {
            sp<AMessage> params = new AMessage;
            params->setInt64("stop-time-us", stopTimeUs);
            err = mEncoder->setParameters(params);
        } else {
            err = mPuller->setStopTimeUs(stopTimeUs);
        }

        sp<AMessage> response = new AMessage;
Loading