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

Commit 4974d5ea authored by James Dong's avatar James Dong Committed by Android Git Automerger
Browse files

am 1653e261: Merge "Rotation support" into gingerbread

* commit '1653e261e84922facfe27d3d8acc455ed2b6b6da':
  Rotation support
parents 6d807958 aca1fe35
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -154,6 +154,7 @@ private:
    bool exceedsFileDurationLimit();
    bool isFileStreamable() const;
    void trackProgressStatus(const Track* track, int64_t timeUs, status_t err = OK);
    void writeCompositionMatrix(int32_t degrees);

    MPEG4Writer(const MPEG4Writer &);
    MPEG4Writer &operator=(const MPEG4Writer &);
+1 −0
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ enum {
    // Track authoring progress status
    // kKeyTrackTimeStatus is used to track progress in elapsed time
    kKeyTrackTimeStatus   = 'tktm',  // int64_t
    kKeyRotationDegree    = 'rdge',  // int32_t (clockwise, in degree)

    kKeyNotRealTime       = 'ntrt',  // bool (int32_t)

+20 −0
Original line number Diff line number Diff line
@@ -340,6 +340,17 @@ status_t StagefrightRecorder::setParamVideoEncodingBitRate(int32_t bitRate) {
    return OK;
}

// Always rotate clockwise, and only support 0, 90, 180 and 270 for now.
status_t StagefrightRecorder::setParamVideoRotation(int32_t degrees) {
    LOGV("setParamVideoRotation: %d", degrees);
    if (degrees < 0 || degrees % 90 != 0) {
        LOGE("Unsupported video rotation angle: %d", degrees);
        return BAD_VALUE;
    }
    mRotationDegrees = degrees % 360;
    return OK;
}

status_t StagefrightRecorder::setParamMaxFileDurationUs(int64_t timeUs) {
    LOGV("setParamMaxFileDurationUs: %lld us", timeUs);
    if (timeUs <= 0) {
@@ -532,6 +543,11 @@ status_t StagefrightRecorder::setParameter(
        if (safe_strtoi32(value.string(), &video_bitrate)) {
            return setParamVideoEncodingBitRate(video_bitrate);
        }
    } else if (key == "video-param-rotation-angle-degrees") {
        int32_t degrees;
        if (safe_strtoi32(value.string(), &degrees)) {
            return setParamVideoRotation(degrees);
        }
    } else if (key == "video-param-i-frames-interval") {
        int32_t seconds;
        if (safe_strtoi32(value.string(), &seconds)) {
@@ -1105,6 +1121,9 @@ status_t StagefrightRecorder::startMPEG4Recording() {
    if (mTrackEveryTimeDurationUs > 0) {
        meta->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs);
    }
    if (mRotationDegrees != 0) {
        meta->setInt32(kKeyRotationDegree, mRotationDegrees);
    }
    writer->setListener(mListener);
    mWriter = writer;
    return mWriter->start(meta.get());
@@ -1187,6 +1206,7 @@ status_t StagefrightRecorder::reset() {
    mMaxFileDurationUs = 0;
    mMaxFileSizeBytes = 0;
    mTrackEveryTimeDurationUs = 0;
    mRotationDegrees = 0;
    mEncoderProfiles = MediaProfiles::getInstance();

    mOutputFd = -1;
+2 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ private:
    int64_t mMaxFileSizeBytes;
    int64_t mMaxFileDurationUs;
    int64_t mTrackEveryTimeDurationUs;
    int32_t mRotationDegrees;  // Clockwise

    String8 mParams;
    int mOutputFd;
@@ -120,6 +121,7 @@ private:
    status_t setParamVideoEncoderLevel(int32_t level);
    status_t setParamVideoCameraId(int32_t cameraId);
    status_t setParamVideoTimeScale(int32_t timeScale);
    status_t setParamVideoRotation(int32_t degrees);
    status_t setParamTrackTimeStatus(int64_t timeDurationUs);
    status_t setParamInterleaveDuration(int32_t durationUs);
    status_t setParam64BitFileOffset(bool use64BitFileOffset);
+62 −19
Original line number Diff line number Diff line
@@ -202,6 +202,7 @@ private:

    // Simple validation on the codec specific data
    status_t checkCodecSpecificData() const;
    int32_t mRotation;

    void updateTrackSizeEstimate();
    void addOneStscTableEntry(size_t chunkId, size_t sampleId);
@@ -519,6 +520,58 @@ void MPEG4Writer::stopWriterThread() {
    pthread_join(mThread, &dummy);
}

/*
 * MP4 file standard defines a composition matrix:
 * | a  b  u |
 * | c  d  v |
 * | x  y  w |
 *
 * the element in the matrix is stored in the following
 * order: {a, b, u, c, d, v, x, y, w},
 * where a, b, c, d, x, and y is in 16.16 format, while
 * u, v and w is in 2.30 format.
 */
void MPEG4Writer::writeCompositionMatrix(int degrees) {
    LOGV("writeCompositionMatrix");
    uint32_t a = 0x00010000;
    uint32_t b = 0;
    uint32_t c = 0;
    uint32_t d = 0x00010000;
    switch (degrees) {
        case 0:
            break;
        case 90:
            a = 0;
            b = 0x00010000;
            c = 0xFFFF0000;
            d = 0;
            break;
        case 180:
            a = 0xFFFF0000;
            d = 0xFFFF0000;
            break;
        case 270:
            a = 0;
            b = 0xFFFF0000;
            c = 0x00010000;
            d = 0;
            break;
        default:
            CHECK(!"Should never reach this unknown rotation");
            break;
    }

    writeInt32(a);           // a
    writeInt32(b);           // b
    writeInt32(0);           // u
    writeInt32(c);           // c
    writeInt32(d);           // d
    writeInt32(0);           // v
    writeInt32(0);           // x
    writeInt32(0);           // y
    writeInt32(0x40000000);  // w
}

status_t MPEG4Writer::stop() {
    if (mFile == NULL) {
        return OK;
@@ -584,15 +637,7 @@ status_t MPEG4Writer::stop() {
        writeInt16(0);             // reserved
        writeInt32(0);             // reserved
        writeInt32(0);             // reserved
        writeInt32(0x10000);       // matrix
        writeInt32(0);
        writeInt32(0);
        writeInt32(0);
        writeInt32(0x10000);
        writeInt32(0);
        writeInt32(0);
        writeInt32(0);
        writeInt32(0x40000000);
        writeCompositionMatrix(0);
        writeInt32(0);             // predefined
        writeInt32(0);             // predefined
        writeInt32(0);             // predefined
@@ -885,7 +930,8 @@ MPEG4Writer::Track::Track(
      mCodecSpecificData(NULL),
      mCodecSpecificDataSize(0),
      mGotAllCodecSpecificData(false),
      mReachedEOS(false) {
      mReachedEOS(false),
      mRotation(0) {
    getCodecSpecificDataFromInputFormatIfPossible();

    const char *mime;
@@ -1178,6 +1224,11 @@ status_t MPEG4Writer::Track::start(MetaData *params) {
        startTimeUs = 0;
    }

    int32_t rotationDegrees;
    if (!mIsAudio && params && params->findInt32(kKeyRotationDegree, &rotationDegrees)) {
        mRotation = rotationDegrees;
    }

    mIsRealTimeRecording = true;
    {
        int32_t isNotRealTime;
@@ -2071,15 +2122,7 @@ void MPEG4Writer::Track::writeTrackHeader(
        mOwner->writeInt16(mIsAudio ? 0x100 : 0);  // volume
        mOwner->writeInt16(0);             // reserved

        mOwner->writeInt32(0x10000);       // matrix
        mOwner->writeInt32(0);
        mOwner->writeInt32(0);
        mOwner->writeInt32(0);
        mOwner->writeInt32(0x10000);
        mOwner->writeInt32(0);
        mOwner->writeInt32(0);
        mOwner->writeInt32(0);
        mOwner->writeInt32(0x40000000);
        mOwner->writeCompositionMatrix(mRotation);

        if (mIsAudio) {
            mOwner->writeInt32(0);