Loading include/media/stagefright/MPEG4Writer.h +1 −0 Original line number Diff line number Diff line Loading @@ -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 &); Loading media/libmediaplayerservice/StagefrightRecorder.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -345,6 +345,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) { Loading Loading @@ -599,6 +610,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(), °rees)) { return setParamVideoRotation(degrees); } } else if (key == "video-param-i-frames-interval") { int32_t seconds; if (safe_strtoi32(value.string(), &seconds)) { Loading Loading @@ -1255,6 +1271,9 @@ void StagefrightRecorder::setupMPEG4MetaData(int64_t startTimeUs, int32_t totalB if (mTrackEveryTimeDurationUs > 0) { (*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs); } if (mRotationDegrees != 0) { (*meta)->setInt32(kKeyRotation, mRotationDegrees); } } status_t StagefrightRecorder::startMPEG4Recording() { Loading media/libmediaplayerservice/StagefrightRecorder.h +2 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,7 @@ private: int64_t mMaxFileSizeBytes; int64_t mMaxFileDurationUs; int64_t mTrackEveryTimeDurationUs; int32_t mRotationDegrees; // Clockwise bool mCaptureTimeLapse; int64_t mTimeBetweenTimeLapseFrameCaptureUs; Loading Loading @@ -146,6 +147,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); Loading media/libstagefright/MPEG4Writer.cpp +63 −19 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -520,6 +521,59 @@ void MPEG4Writer::stopWriterThread() { LOGD("Writer thread stopped"); } /* * 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; Loading Loading @@ -585,15 +639,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); // matrix writeInt32(0); // predefined writeInt32(0); // predefined writeInt32(0); // predefined Loading Loading @@ -886,7 +932,8 @@ MPEG4Writer::Track::Track( mCodecSpecificData(NULL), mCodecSpecificDataSize(0), mGotAllCodecSpecificData(false), mReachedEOS(false) { mReachedEOS(false), mRotation(0) { getCodecSpecificDataFromInputFormatIfPossible(); const char *mime; Loading Loading @@ -1179,6 +1226,11 @@ status_t MPEG4Writer::Track::start(MetaData *params) { startTimeUs = 0; } int32_t rotationDegrees; if (!mIsAudio && params && params->findInt32(kKeyRotation, &rotationDegrees)) { mRotation = rotationDegrees; } mIsRealTimeRecording = true; { int32_t isNotRealTime; Loading Loading @@ -2075,15 +2127,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); // matrix if (mIsAudio) { mOwner->writeInt32(0); Loading Loading
include/media/stagefright/MPEG4Writer.h +1 −0 Original line number Diff line number Diff line Loading @@ -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 &); Loading
media/libmediaplayerservice/StagefrightRecorder.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -345,6 +345,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) { Loading Loading @@ -599,6 +610,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(), °rees)) { return setParamVideoRotation(degrees); } } else if (key == "video-param-i-frames-interval") { int32_t seconds; if (safe_strtoi32(value.string(), &seconds)) { Loading Loading @@ -1255,6 +1271,9 @@ void StagefrightRecorder::setupMPEG4MetaData(int64_t startTimeUs, int32_t totalB if (mTrackEveryTimeDurationUs > 0) { (*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs); } if (mRotationDegrees != 0) { (*meta)->setInt32(kKeyRotation, mRotationDegrees); } } status_t StagefrightRecorder::startMPEG4Recording() { Loading
media/libmediaplayerservice/StagefrightRecorder.h +2 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,7 @@ private: int64_t mMaxFileSizeBytes; int64_t mMaxFileDurationUs; int64_t mTrackEveryTimeDurationUs; int32_t mRotationDegrees; // Clockwise bool mCaptureTimeLapse; int64_t mTimeBetweenTimeLapseFrameCaptureUs; Loading Loading @@ -146,6 +147,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); Loading
media/libstagefright/MPEG4Writer.cpp +63 −19 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -520,6 +521,59 @@ void MPEG4Writer::stopWriterThread() { LOGD("Writer thread stopped"); } /* * 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; Loading Loading @@ -585,15 +639,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); // matrix writeInt32(0); // predefined writeInt32(0); // predefined writeInt32(0); // predefined Loading Loading @@ -886,7 +932,8 @@ MPEG4Writer::Track::Track( mCodecSpecificData(NULL), mCodecSpecificDataSize(0), mGotAllCodecSpecificData(false), mReachedEOS(false) { mReachedEOS(false), mRotation(0) { getCodecSpecificDataFromInputFormatIfPossible(); const char *mime; Loading Loading @@ -1179,6 +1226,11 @@ status_t MPEG4Writer::Track::start(MetaData *params) { startTimeUs = 0; } int32_t rotationDegrees; if (!mIsAudio && params && params->findInt32(kKeyRotation, &rotationDegrees)) { mRotation = rotationDegrees; } mIsRealTimeRecording = true; { int32_t isNotRealTime; Loading Loading @@ -2075,15 +2127,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); // matrix if (mIsAudio) { mOwner->writeInt32(0); Loading