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

Commit 73c3e636 authored by Wonsik Kim's avatar Wonsik Kim
Browse files

MediaRecorder: Handle 24-hour timelapse duration

Handle FPS in double / 64-bit integer and allow room for error.

Bug: 34870132
Test: cts-tradefed run cts-dev --module CtsMediaTestCases --test android.media.cts.MediaRecorderTest
Change-Id: I371d22d9ae70e2d77b08bd6c501e8b34a71592d1
parent 565a0ed7
Loading
Loading
Loading
Loading
+20 −10
Original line number Diff line number Diff line
@@ -397,13 +397,13 @@ status_t StagefrightRecorder::setNextOutputFile(int fd) {

// Attempt to parse an float literal optionally surrounded by whitespace,
// returns true on success, false otherwise.
static bool safe_strtof(const char *s, float *val) {
static bool safe_strtod(const char *s, double *val) {
    char *end;

    // It is lame, but according to man page, we have to set errno to 0
    // before calling strtof().
    // before calling strtod().
    errno = 0;
    *val = strtof(s, &end);
    *val = strtod(s, &end);

    if (end == s || errno == ERANGE) {
        return false;
@@ -706,13 +706,23 @@ status_t StagefrightRecorder::setParamCaptureFpsEnable(int32_t captureFpsEnable)
    return OK;
}

status_t StagefrightRecorder::setParamCaptureFps(float fps) {
status_t StagefrightRecorder::setParamCaptureFps(double fps) {
    ALOGV("setParamCaptureFps: %.2f", fps);

    int64_t timeUs = (int64_t) (1000000.0 / fps + 0.5f);
    constexpr int64_t k1E12 = 1000000000000ll;
    int64_t fpsx1e12 = k1E12 * fps;
    if (fpsx1e12 == 0) {
        ALOGE("FPS is zero or too small");
        return BAD_VALUE;
    }

    // This does not overflow since 10^6 * 10^12 < 2^63
    int64_t timeUs = 1000000ll * k1E12 / fpsx1e12;

    // Not allowing time more than a day
    if (timeUs <= 0 || timeUs > 86400*1E6) {
    // Not allowing time more than a day and a millisecond for error margin.
    // Note: 1e12 / 86400 = 11574074.(074) and 1e18 / 11574074 = 86400000553;
    //       therefore 1 ms of margin should be sufficient.
    if (timeUs <= 0 || timeUs > 86400001000ll) {
        ALOGE("Time between frame capture (%lld) is out of range [0, 1 Day]", (long long)timeUs);
        return BAD_VALUE;
    }
@@ -846,8 +856,8 @@ status_t StagefrightRecorder::setParameter(
            return setParamCaptureFpsEnable(captureFpsEnable);
        }
    } else if (key == "time-lapse-fps") {
        float fps;
        if (safe_strtof(value.string(), &fps)) {
        double fps;
        if (safe_strtod(value.string(), &fps)) {
            return setParamCaptureFps(fps);
        }
    } else {
@@ -2073,7 +2083,7 @@ status_t StagefrightRecorder::reset() {
    mMaxFileSizeBytes = 0;
    mTrackEveryTimeDurationUs = 0;
    mCaptureFpsEnable = false;
    mCaptureFps = 0.0f;
    mCaptureFps = 0.0;
    mTimeBetweenCaptureUs = -1;
    mCameraSourceTimeLapse = NULL;
    mMetaDataStoredInVideoBuffers = kMetadataBufferTypeInvalid;
+2 −2
Original line number Diff line number Diff line
@@ -122,7 +122,7 @@ private:
    int32_t mTotalBitRate;

    bool mCaptureFpsEnable;
    float mCaptureFps;
    double mCaptureFps;
    int64_t mTimeBetweenCaptureUs;
    sp<CameraSourceTimeLapse> mCameraSourceTimeLapse;

@@ -172,7 +172,7 @@ private:
    status_t setParamAudioSamplingRate(int32_t sampleRate);
    status_t setParamAudioTimeScale(int32_t timeScale);
    status_t setParamCaptureFpsEnable(int32_t timeLapseEnable);
    status_t setParamCaptureFps(float fps);
    status_t setParamCaptureFps(double fps);
    status_t setParamVideoEncodingBitRate(int32_t bitRate);
    status_t setParamVideoIFramesInterval(int32_t seconds);
    status_t setParamVideoEncoderProfile(int32_t profile);