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

Commit d01371bf authored by Nipun Kwatra's avatar Nipun Kwatra
Browse files

Allowing setting of time lapse parameters through MediaRecorder.java

added setTimeLapseParameters() to MediaRecorder.java and SetParameter support
in StagefrightRecorder to allow enabling time lapse and setting the corresponding
parameters.

Change-Id: I509040aa71f8d3fc37337b0894a81d9c0fd7a40a
parent 9c9d0684
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -33,11 +33,13 @@ class CameraSourceTimeLapse : public CameraSource {
public:
    static CameraSourceTimeLapse *Create(bool useStillCameraForTimeLapse,
        int64_t timeBetweenTimeLapseFrameCaptureUs,
        int32_t width, int32_t height,
        int32_t videoFrameRate);

    static CameraSourceTimeLapse *CreateFromCamera(const sp<Camera> &camera,
        bool useStillCameraForTimeLapse,
        int64_t timeBetweenTimeLapseFrameCaptureUs,
        int32_t width, int32_t height,
        int32_t videoFrameRate);

    virtual ~CameraSourceTimeLapse();
@@ -70,6 +72,7 @@ private:
    CameraSourceTimeLapse(const sp<Camera> &camera,
        bool useStillCameraForTimeLapse,
        int64_t timeBetweenTimeLapseFrameCaptureUs,
        int32_t width, int32_t height,
        int32_t videoFrameRate);

    // For still camera case starts a thread which calls camera's takePicture()
+26 −0
Original line number Diff line number Diff line
@@ -278,6 +278,23 @@ public class MediaRecorder
        setAudioEncoder(profile.audioCodec);
    }

    /**
     * Enables/Disables time lapse capture and sets its parameters. This method should
     * be called after setProfile().
     *
     * @param enableTimeLapse Pass true to enable time lapse capture, false to disable it.
     * @param timeBetweenTimeLapseFrameCaptureMs time between two captures of time lapse frames.
     * @param encoderLevel the video encoder level.
     */
    public void setTimeLapseParameters(boolean enableTimeLapse,
            int timeBetweenTimeLapseFrameCaptureMs, int encoderLevel) {
        setParameter(String.format("time-lapse-enable=%d",
                    (enableTimeLapse) ? 1 : 0));
        setParameter(String.format("time-between-time-lapse-frame-capture=%d",
                    timeBetweenTimeLapseFrameCaptureMs));
        setVideoEncoderLevel(encoderLevel);
    }

    /**
     * Sets the format of the output file produced during recording. Call this
     * after setAudioSource()/setVideoSource() but before prepare().
@@ -444,6 +461,15 @@ public class MediaRecorder
        setParameter(String.format("video-param-encoding-bitrate=%d", bitRate));
    }

    /**
     * Sets the level of the encoder. Call this before prepare().
     *
     * @param encoderLevel the video encoder level.
     */
    public void setVideoEncoderLevel(int encoderLevel) {
        setParameter(String.format("video-param-encoder-level=%d", encoderLevel));
    }

    /**
     * Pass in the file descriptor of the file to be written. Call this after
     * setOutputFormat() but before prepare().
+59 −8
Original line number Diff line number Diff line
@@ -473,6 +473,32 @@ status_t StagefrightRecorder::setParamAudioTimeScale(int32_t timeScale) {
    return OK;
}

status_t StagefrightRecorder::setParamTimeLapseEnable(int32_t timeLapseEnable) {
    LOGV("setParamTimeLapseEnable: %d", timeLapseEnable);

    if(timeLapseEnable == 0) {
        mCaptureTimeLapse = false;
    } else if (timeLapseEnable == 1) {
        mCaptureTimeLapse = true;
    } else {
        return BAD_VALUE;
    }
    return OK;
}

status_t StagefrightRecorder::setParamTimeBetweenTimeLapseFrameCapture(int64_t timeUs) {
    LOGV("setParamTimeBetweenTimeLapseFrameCapture: %lld us", timeUs);

    // Not allowing time more than a day
    if (timeUs <= 0 || timeUs > 86400*1E6) {
        LOGE("Time between time lapse frame capture (%lld) is out of range [0, 1 Day]", timeUs);
        return BAD_VALUE;
    }

    mTimeBetweenTimeLapseFrameCaptureUs = timeUs;
    return OK;
}

status_t StagefrightRecorder::setParameter(
        const String8 &key, const String8 &value) {
    LOGV("setParameter: key (%s) => value (%s)", key.string(), value.string());
@@ -556,6 +582,17 @@ status_t StagefrightRecorder::setParameter(
        if (safe_strtoi32(value.string(), &timeScale)) {
            return setParamVideoTimeScale(timeScale);
        }
    } else if (key == "time-lapse-enable") {
        int32_t timeLapseEnable;
        if (safe_strtoi32(value.string(), &timeLapseEnable)) {
            return setParamTimeLapseEnable(timeLapseEnable);
        }
    } else if (key == "time-between-time-lapse-frame-capture") {
        int64_t timeBetweenTimeLapseFrameCaptureMs;
        if (safe_strtoi64(value.string(), &timeBetweenTimeLapseFrameCaptureMs)) {
            return setParamTimeBetweenTimeLapseFrameCapture(
                    1000LL * timeBetweenTimeLapseFrameCaptureMs);
        }
    } else {
        LOGE("setParameter: failed to find key %s", key.string());
    }
@@ -813,10 +850,14 @@ void StagefrightRecorder::clipVideoFrameWidth() {
}

status_t StagefrightRecorder::setupCameraSource() {
    if(!mCaptureTimeLapse) {
        // Dont clip for time lapse capture as encoder will have enough
        // time to encode because of slow capture rate of time lapse.
        clipVideoBitRate();
        clipVideoFrameRate();
        clipVideoFrameWidth();
        clipVideoFrameHeight();
    }

    int64_t token = IPCThreadState::self()->clearCallingIdentity();
    if (mCamera == 0) {
@@ -831,7 +872,13 @@ status_t StagefrightRecorder::setupCameraSource() {

    // Set the actual video recording frame size
    CameraParameters params(mCamera->getParameters());

    // dont change the preview size for time lapse as mVideoWidth, mVideoHeight
    // may correspond to HD resolution not supported by video camera.
    if (!mCaptureTimeLapse) {
        params.setPreviewSize(mVideoWidth, mVideoHeight);
    }

    params.setPreviewFrameRate(mFrameRate);
    String8 s = params.flatten();
    CHECK_EQ(OK, mCamera->setParameters(s));
@@ -840,8 +887,9 @@ status_t StagefrightRecorder::setupCameraSource() {
    // Check on video frame size
    int frameWidth = 0, frameHeight = 0;
    newCameraParams.getPreviewSize(&frameWidth, &frameHeight);
    if (frameWidth  < 0 || frameWidth  != mVideoWidth ||
        frameHeight < 0 || frameHeight != mVideoHeight) {
    if (!mCaptureTimeLapse &&
        (frameWidth  < 0 || frameWidth  != mVideoWidth ||
        frameHeight < 0 || frameHeight != mVideoHeight)) {
        LOGE("Failed to set the video frame size to %dx%d",
                mVideoWidth, mVideoHeight);
        IPCThreadState::self()->restoreCallingIdentity(token);
@@ -882,7 +930,8 @@ status_t StagefrightRecorder::setupVideoEncoder(const sp<MediaWriter>& writer) {
    if (err != OK) return err;

    sp<CameraSource> cameraSource = (mCaptureTimeLapse) ?
        CameraSourceTimeLapse::CreateFromCamera(mCamera, true, 3E6, mFrameRate):
        CameraSourceTimeLapse::CreateFromCamera(mCamera, true,
                mTimeBetweenTimeLapseFrameCaptureUs, mVideoWidth, mVideoHeight, mFrameRate):
        CameraSource::CreateFromCamera(mCamera);
    CHECK(cameraSource != NULL);

@@ -934,6 +983,7 @@ status_t StagefrightRecorder::setupVideoEncoder(const sp<MediaWriter>& writer) {
    OMXClient client;
    CHECK_EQ(client.connect(), OK);

    // Use software codec for time lapse
    uint32_t encoder_flags = (mCaptureTimeLapse) ? OMXCodec::kPreferSoftwareCodecs : 0;
    sp<MediaSource> encoder = OMXCodec::Create(
            client.interface(), enc_meta,
@@ -1081,6 +1131,7 @@ status_t StagefrightRecorder::reset() {
    mMaxFileSizeBytes = 0;
    mTrackEveryTimeDurationUs = 0;
    mCaptureTimeLapse = false;
    mTimeBetweenTimeLapseFrameCaptureUs = -1;
    mEncoderProfiles = MediaProfiles::getInstance();

    mOutputFd = -1;
+3 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ private:
    int64_t mTrackEveryTimeDurationUs;

    bool mCaptureTimeLapse;
    int64_t mTimeBetweenTimeLapseFrameCaptureUs;

    String8 mParams;
    int mOutputFd;
@@ -114,6 +115,8 @@ private:
    status_t setParamAudioNumberOfChannels(int32_t channles);
    status_t setParamAudioSamplingRate(int32_t sampleRate);
    status_t setParamAudioTimeScale(int32_t timeScale);
    status_t setParamTimeLapseEnable(int32_t timeLapseEnable);
    status_t setParamTimeBetweenTimeLapseFrameCapture(int64_t timeUs);
    status_t setParamVideoEncodingBitRate(int32_t bitRate);
    status_t setParamVideoIFramesInterval(int32_t seconds);
    status_t setParamVideoEncoderProfile(int32_t profile);
+5 −7
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ namespace android {
// static
CameraSourceTimeLapse *CameraSourceTimeLapse::Create(bool useStillCameraForTimeLapse,
        int64_t timeBetweenTimeLapseFrameCaptureUs,
        int32_t width, int32_t height,
        int32_t videoFrameRate) {
    sp<Camera> camera = Camera::connect(0);

@@ -41,25 +42,27 @@ CameraSourceTimeLapse *CameraSourceTimeLapse::Create(bool useStillCameraForTimeL
    }

    return new CameraSourceTimeLapse(camera, useStillCameraForTimeLapse,
            timeBetweenTimeLapseFrameCaptureUs, videoFrameRate);
            timeBetweenTimeLapseFrameCaptureUs, width, height, videoFrameRate);
}

// static
CameraSourceTimeLapse *CameraSourceTimeLapse::CreateFromCamera(const sp<Camera> &camera,
        bool useStillCameraForTimeLapse,
        int64_t timeBetweenTimeLapseFrameCaptureUs,
        int32_t width, int32_t height,
        int32_t videoFrameRate) {
    if (camera.get() == NULL) {
        return NULL;
    }

    return new CameraSourceTimeLapse(camera, useStillCameraForTimeLapse,
            timeBetweenTimeLapseFrameCaptureUs, videoFrameRate);
            timeBetweenTimeLapseFrameCaptureUs, width, height, videoFrameRate);
}

CameraSourceTimeLapse::CameraSourceTimeLapse(const sp<Camera> &camera,
        bool useStillCameraForTimeLapse,
        int64_t timeBetweenTimeLapseFrameCaptureUs,
        int32_t width, int32_t height,
        int32_t videoFrameRate)
    : CameraSource(camera),
      mUseStillCameraForTimeLapse(useStillCameraForTimeLapse),
@@ -70,11 +73,6 @@ CameraSourceTimeLapse::CameraSourceTimeLapse(const sp<Camera> &camera,

    LOGV("starting time lapse mode");
    if(mUseStillCameraForTimeLapse) {
        // Currently hardcoded the picture size. Will need to choose
        // automatically or pass in from the app.
        int32_t width, height;
        width = 1024;
        height = 768;
        mMeta->setInt32(kKeyWidth, width);
        mMeta->setInt32(kKeyHeight, height);
    }