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 include/media/stagefright/MetaData.h +1 −0 Original line number Diff line number Diff line Loading @@ -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) Loading media/libmediaplayerservice/StagefrightRecorder.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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(), °rees)) { return setParamVideoRotation(degrees); } } else if (key == "video-param-i-frames-interval") { int32_t seconds; if (safe_strtoi32(value.string(), &seconds)) { Loading Loading @@ -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()); Loading Loading @@ -1187,6 +1206,7 @@ status_t StagefrightRecorder::reset() { mMaxFileDurationUs = 0; mMaxFileSizeBytes = 0; mTrackEveryTimeDurationUs = 0; mRotationDegrees = 0; mEncoderProfiles = MediaProfiles::getInstance(); mOutputFd = -1; Loading media/libmediaplayerservice/StagefrightRecorder.h +2 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,7 @@ private: int64_t mMaxFileSizeBytes; int64_t mMaxFileDurationUs; int64_t mTrackEveryTimeDurationUs; int32_t mRotationDegrees; // Clockwise String8 mParams; int mOutputFd; Loading Loading @@ -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); Loading media/libstagefright/MPEG4Writer.cpp +62 −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 @@ -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; Loading Loading @@ -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 Loading Loading @@ -885,7 +930,8 @@ MPEG4Writer::Track::Track( mCodecSpecificData(NULL), mCodecSpecificDataSize(0), mGotAllCodecSpecificData(false), mReachedEOS(false) { mReachedEOS(false), mRotation(0) { getCodecSpecificDataFromInputFormatIfPossible(); const char *mime; Loading Loading @@ -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; Loading Loading @@ -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); 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
include/media/stagefright/MetaData.h +1 −0 Original line number Diff line number Diff line Loading @@ -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) Loading
media/libmediaplayerservice/StagefrightRecorder.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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(), °rees)) { return setParamVideoRotation(degrees); } } else if (key == "video-param-i-frames-interval") { int32_t seconds; if (safe_strtoi32(value.string(), &seconds)) { Loading Loading @@ -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()); Loading Loading @@ -1187,6 +1206,7 @@ status_t StagefrightRecorder::reset() { mMaxFileDurationUs = 0; mMaxFileSizeBytes = 0; mTrackEveryTimeDurationUs = 0; mRotationDegrees = 0; mEncoderProfiles = MediaProfiles::getInstance(); mOutputFd = -1; Loading
media/libmediaplayerservice/StagefrightRecorder.h +2 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,7 @@ private: int64_t mMaxFileSizeBytes; int64_t mMaxFileDurationUs; int64_t mTrackEveryTimeDurationUs; int32_t mRotationDegrees; // Clockwise String8 mParams; int mOutputFd; Loading Loading @@ -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); Loading
media/libstagefright/MPEG4Writer.cpp +62 −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 @@ -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; Loading Loading @@ -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 Loading Loading @@ -885,7 +930,8 @@ MPEG4Writer::Track::Track( mCodecSpecificData(NULL), mCodecSpecificDataSize(0), mGotAllCodecSpecificData(false), mReachedEOS(false) { mReachedEOS(false), mRotation(0) { getCodecSpecificDataFromInputFormatIfPossible(); const char *mime; Loading Loading @@ -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; Loading Loading @@ -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); Loading