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

Commit 3300e966 authored by James Dong's avatar James Dong
Browse files

Support audio and video track interleaving in the recorded mp4 file

Change-Id: Ifa27eb23ee265f84fe06773b29b0eb2b0b075b60
parent 51867f23
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -62,8 +62,9 @@ private:
    int mWidth, mHeight;
    int64_t mFirstFrameTimeUs;
    int64_t mLastFrameTimestampUs;
    int32_t mNumFrames;
    int32_t mNumFramesReleased;
    int32_t mNumFramesReceived;
    int32_t mNumFramesEncoded;
    int32_t mNumFramesDropped;
    bool mStarted;

    CameraSource(const sp<Camera> &camera);
+9 −2
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ public:
    void writeFourcc(const char *fourcc);
    void write(const void *data, size_t size);
    void endBox();
    uint32_t interleaveDuration() const { return mInterleaveDurationUs; }
    status_t setInterleaveDuration(uint32_t duration);

protected:
    virtual ~MPEG4Writer();
@@ -59,14 +61,19 @@ private:
    FILE *mFile;
    off_t mOffset;
    off_t mMdatOffset;
    uint32_t mInterleaveDurationUs;
    Mutex mLock;

    List<Track *> mTracks;

    List<off_t> mBoxes;

    off_t addSample(MediaBuffer *buffer);
    off_t addLengthPrefixedSample(MediaBuffer *buffer);
    void lock();
    void unlock();

    // Acquire lock before calling these methods
    off_t addSample_l(MediaBuffer *buffer);
    off_t addLengthPrefixedSample_l(MediaBuffer *buffer);

    MPEG4Writer(const MPEG4Writer &);
    MPEG4Writer &operator=(const MPEG4Writer &);
+16 −4
Original line number Diff line number Diff line
@@ -213,25 +213,31 @@ status_t StagefrightRecorder::setParamVideoEncodingBitRate(int32_t bitRate) {
    return OK;
}

status_t StagefrightRecorder::setMaxDurationOrFileSize(int32_t limit, bool limit_is_duration) {
    LOGV("setMaxDurationOrFileSize: limit (%d) for %s",
status_t StagefrightRecorder::setParamMaxDurationOrFileSize(int32_t limit,
        bool limit_is_duration) {
    LOGV("setParamMaxDurationOrFileSize: limit (%d) for %s",
            limit, limit_is_duration?"duration":"size");
    return OK;
}

status_t StagefrightRecorder::setParamInterleaveDuration(int32_t durationUs) {
    LOGV("setParamInterleaveDuration: %d", durationUs);
    mInterleaveDurationUs = durationUs;
    return OK;
}
status_t StagefrightRecorder::setParameter(
        const String8 &key, const String8 &value) {
    LOGV("setParameter: key (%s) => value (%s)", key.string(), value.string());
    if (key == "max-duration") {
        int32_t max_duration_ms;
        if (safe_strtoi64(value.string(), &max_duration_ms)) {
            return setMaxDurationOrFileSize(
            return setParamMaxDurationOrFileSize(
                    max_duration_ms, true /* limit_is_duration */);
        }
    } else if (key == "max-filesize") {
        int32_t max_filesize_bytes;
        if (safe_strtoi64(value.string(), &max_filesize_bytes)) {
            return setMaxDurationOrFileSize(
            return setParamMaxDurationOrFileSize(
                    max_filesize_bytes, false /* limit is filesize */);
        }
    } else if (key == "audio-param-sampling-rate") {
@@ -254,6 +260,11 @@ status_t StagefrightRecorder::setParameter(
        if (safe_strtoi64(value.string(), &video_bitrate)) {
            return setParamVideoEncodingBitRate(video_bitrate);
        }
    } else if (key == "param-interleave-duration-us") {
        int32_t durationUs;
        if (safe_strtoi64(value.string(), &durationUs)) {
            return setParamInterleaveDuration(durationUs);
        }
    } else {
        LOGE("setParameter: failed to find key %s", key.string());
        return BAD_VALUE;
@@ -480,6 +491,7 @@ status_t StagefrightRecorder::startMPEG4Recording() {
        mWriter->addSource(encoder);
    }

    ((MPEG4Writer *)mWriter.get())->setInterleaveDuration(mInterleaveDurationUs);
    mWriter->start();
    return OK;
}
+3 −1
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ private:
    int32_t mAudioBitRate;
    int32_t mAudioChannels;
    int32_t mSampleRate;
    int32_t mInterleaveDurationUs;

    String8 mParams;
    int mOutputFd;
@@ -87,7 +88,8 @@ private:
    status_t setParamAudioEncodingBitRate(int32_t bitRate);
    status_t setParamAudioNumberOfChannels(int32_t channles);
    status_t setParamAudioSamplingRate(int32_t sampleRate);
    status_t setMaxDurationOrFileSize(int32_t limit, bool limit_is_duration);
    status_t setParamInterleaveDuration(int32_t durationUs);
    status_t setParamMaxDurationOrFileSize(int32_t limit, bool limit_is_duration);

    StagefrightRecorder(const StagefrightRecorder &);
    StagefrightRecorder &operator=(const StagefrightRecorder &);
+13 −10
Original line number Diff line number Diff line
@@ -130,8 +130,9 @@ CameraSource::CameraSource(const sp<Camera> &camera)
      mHeight(0),
      mFirstFrameTimeUs(0),
      mLastFrameTimestampUs(0),
      mNumFrames(0),
      mNumFramesReleased(0),
      mNumFramesReceived(0),
      mNumFramesEncoded(0),
      mNumFramesDropped(0),
      mStarted(false) {
    String8 s = mCamera->getParameters();
    printf("params: \"%s\"\n", s.string());
@@ -178,9 +179,11 @@ status_t CameraSource::stop() {
    mCamera->stopRecording();

    releaseQueuedFrames();
    LOGI("Frames received/released: %d/%d, timestamp (us) last/first: %lld/%lld",
            mNumFrames, mNumFramesReleased,
    LOGI("Frames received/encoded/dropped: %d/%d/%d, timestamp (us) last/first: %lld/%lld",
            mNumFramesReceived, mNumFramesEncoded, mNumFramesDropped,
            mLastFrameTimestampUs, mFirstFrameTimeUs);

    CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped);
    return OK;
}

@@ -190,7 +193,7 @@ void CameraSource::releaseQueuedFrames() {
        it = mFrames.begin();
        mCamera->releaseRecordingFrame(*it);
        mFrames.erase(it);
        ++mNumFramesReleased;
        ++mNumFramesDropped;
    }
}

@@ -231,7 +234,7 @@ status_t CameraSource::read(

        frameTime = *mFrameTimes.begin();
        mFrameTimes.erase(mFrameTimes.begin());
        ++mNumFramesReleased;
        ++mNumFramesEncoded;
    }

    *buffer = new MediaBuffer(frame->size());
@@ -252,15 +255,15 @@ void CameraSource::dataCallbackTimestamp(int64_t timestampUs,
    Mutex::Autolock autoLock(mLock);
    if (!mStarted) {
        mCamera->releaseRecordingFrame(data);
        ++mNumFrames;
        ++mNumFramesReleased;
        ++mNumFramesReceived;
        ++mNumFramesDropped;
        return;
    }

    if (mNumFrames == 0) {
    if (mNumFramesReceived == 0) {
        mFirstFrameTimeUs = timestampUs;
    }
    ++mNumFrames;
    ++mNumFramesReceived;

    mFrames.push_back(data);
    mFrameTimes.push_back(timestampUs - mFirstFrameTimeUs);
Loading