Loading include/media/stagefright/foundation/ALookup.h +6 −6 Original line number Diff line number Diff line Loading @@ -27,14 +27,14 @@ template<typename T, typename U> struct ALookup { ALookup(std::initializer_list<std::pair<T, U>> list); bool lookup(const T& from, U *to); bool rlookup(const U& from, T *to); bool lookup(const T& from, U *to) const; bool rlookup(const U& from, T *to) const; template<typename V, typename = typename std::enable_if<!std::is_same<T, V>::value>::type> inline bool map(const T& from, V *to) { return lookup(from, to); } inline bool map(const T& from, V *to) const { return lookup(from, to); } template<typename V, typename = typename std::enable_if<!std::is_same<T, V>::value>::type> inline bool map(const V& from, T *to) { return rlookup(from, to); } inline bool map(const V& from, T *to) const { return rlookup(from, to); } private: std::vector<std::pair<T, U>> mTable; Loading @@ -46,7 +46,7 @@ ALookup<T, U>::ALookup(std::initializer_list<std::pair<T, U>> list) } template<typename T, typename U> bool ALookup<T, U>::lookup(const T& from, U *to) { bool ALookup<T, U>::lookup(const T& from, U *to) const { for (auto elem : mTable) { if (elem.first == from) { *to = elem.second; Loading @@ -57,7 +57,7 @@ bool ALookup<T, U>::lookup(const T& from, U *to) { } template<typename T, typename U> bool ALookup<T, U>::rlookup(const U& from, T *to) { bool ALookup<T, U>::rlookup(const U& from, T *to) const { for (auto elem : mTable) { if (elem.second == from) { *to = elem.first; Loading include/media/stagefright/foundation/ColorUtils.h +9 −0 Original line number Diff line number Diff line Loading @@ -129,6 +129,15 @@ struct ColorUtils { static status_t convertCodecColorAspectsToPlatformAspects( const ColorAspects &aspects, int32_t *range, int32_t *standard, int32_t *transfer); // converts Other values to Unspecified static void convertCodecColorAspectsToIsoAspects( const ColorAspects &aspects, int32_t *primaries, int32_t *transfer, int32_t *coeffs, bool *fullRange); // converts unsupported values to Other static void convertIsoColorAspectsToCodecAspects( int32_t primaries, int32_t transfer, int32_t coeffs, bool fullRange, ColorAspects &aspects); // updates Unspecified color aspects to their defaults based on the video size static void setDefaultCodecColorAspectsIfNeeded( ColorAspects &aspects, int32_t width, int32_t height); Loading media/libstagefright/MPEG4Extractor.cpp +59 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/foundation/AUtils.h> #include <media/stagefright/foundation/ColorUtils.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaBufferGroup.h> #include <media/stagefright/MediaDefs.h> Loading Loading @@ -2083,6 +2084,21 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { break; } case FOURCC('c', 'o', 'l', 'r'): { *offset += chunk_size; // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd') // ignore otherwise if (depth >= 2 && mPath[depth - 2] == FOURCC('s', 't', 's', 'd')) { status_t err = parseColorInfo(data_offset, chunk_data_size); if (err != OK) { return err; } } break; } case FOURCC('t', 'i', 't', 'l'): case FOURCC('p', 'e', 'r', 'f'): case FOURCC('a', 'u', 't', 'h'): Loading Loading @@ -2663,6 +2679,49 @@ status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { return OK; } status_t MPEG4Extractor::parseColorInfo(off64_t offset, size_t size) { if (size < 4 || size == SIZE_MAX || mLastTrack == NULL) { return ERROR_MALFORMED; } uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; if (buffer == NULL) { return ERROR_MALFORMED; } if (mDataSource->readAt(offset, buffer, size) != (ssize_t)size) { delete[] buffer; buffer = NULL; return ERROR_IO; } int32_t type = U32_AT(&buffer[0]); if ((type == FOURCC('n', 'c', 'l', 'x') && size >= 11) || (type == FOURCC('n', 'c', 'l', 'c' && size >= 10))) { int32_t primaries = U16_AT(&buffer[4]); int32_t transfer = U16_AT(&buffer[6]); int32_t coeffs = U16_AT(&buffer[8]); bool fullRange = (type == FOURCC('n', 'c', 'l', 'x')) && (buffer[10] & 128); ColorAspects aspects; ColorUtils::convertIsoColorAspectsToCodecAspects( primaries, transfer, coeffs, fullRange, aspects); // only store the first color specification if (!mLastTrack->meta->hasData(kKeyColorPrimaries)) { mLastTrack->meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries); mLastTrack->meta->setInt32(kKeyTransferFunction, aspects.mTransfer); mLastTrack->meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs); mLastTrack->meta->setInt32(kKeyColorRange, aspects.mRange); } } delete[] buffer; buffer = NULL; return OK; } status_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) { if (size < 4 || size == SIZE_MAX) { return ERROR_MALFORMED; Loading media/libstagefright/MPEG4Writer.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/foundation/ColorUtils.h> #include <media/stagefright/MPEG4Writer.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MetaData.h> Loading Loading @@ -371,6 +372,7 @@ private: void writeVmhdBox(); void writeHdlrBox(); void writeTkhdBox(uint32_t now); void writeColrBox(); void writeMp4aEsdsBox(); void writeMp4vEsdsBox(); void writeAudioFourCCBox(); Loading Loading @@ -2353,6 +2355,7 @@ status_t MPEG4Writer::Track::threadEntry() { if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecConfig) && isCodecConfig) { CHECK(!mGotAllCodecSpecificData); mMeta = mSource->getFormat(); // get output format after format change if (mIsAvc) { status_t err = makeAVCCodecSpecificData( Loading Loading @@ -2960,9 +2963,32 @@ void MPEG4Writer::Track::writeVideoFourCCBox() { } writePaspBox(); writeColrBox(); mOwner->endBox(); // mp4v, s263 or avc1 } void MPEG4Writer::Track::writeColrBox() { ColorAspects aspects; memset(&aspects, 0, sizeof(aspects)); // TRICKY: using | instead of || because we want to execute all findInt32-s if (mMeta->findInt32(kKeyColorPrimaries, (int32_t*)&aspects.mPrimaries) | mMeta->findInt32(kKeyTransferFunction, (int32_t*)&aspects.mTransfer) | mMeta->findInt32(kKeyColorMatrix, (int32_t*)&aspects.mMatrixCoeffs) | mMeta->findInt32(kKeyColorRange, (int32_t*)&aspects.mRange)) { int32_t primaries, transfer, coeffs; bool fullRange; ColorUtils::convertCodecColorAspectsToIsoAspects( aspects, &primaries, &transfer, &coeffs, &fullRange); mOwner->beginBox("colr"); mOwner->writeFourcc("nclx"); mOwner->writeInt16(primaries); mOwner->writeInt16(transfer); mOwner->writeInt16(coeffs); mOwner->writeInt8(fullRange ? 128 : 0); mOwner->endBox(); // colr } } void MPEG4Writer::Track::writeAudioFourCCBox() { const char *mime; bool success = mMeta->findCString(kKeyMIMEType, &mime); Loading media/libstagefright/MediaCodecSource.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -781,6 +781,13 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) { mAvailEncoderInputIndices.push_back(index); feedEncoderInputBuffers(); } else if (cbID == MediaCodec::CB_OUTPUT_FORMAT_CHANGED) { status_t err = mEncoder->getOutputFormat(&mOutputFormat); if (err != OK) { signalEOS(err); break; } convertMessageToMetaData(mOutputFormat, mMeta); } else if (cbID == MediaCodec::CB_OUTPUT_AVAILABLE) { int32_t index; size_t offset; Loading Loading
include/media/stagefright/foundation/ALookup.h +6 −6 Original line number Diff line number Diff line Loading @@ -27,14 +27,14 @@ template<typename T, typename U> struct ALookup { ALookup(std::initializer_list<std::pair<T, U>> list); bool lookup(const T& from, U *to); bool rlookup(const U& from, T *to); bool lookup(const T& from, U *to) const; bool rlookup(const U& from, T *to) const; template<typename V, typename = typename std::enable_if<!std::is_same<T, V>::value>::type> inline bool map(const T& from, V *to) { return lookup(from, to); } inline bool map(const T& from, V *to) const { return lookup(from, to); } template<typename V, typename = typename std::enable_if<!std::is_same<T, V>::value>::type> inline bool map(const V& from, T *to) { return rlookup(from, to); } inline bool map(const V& from, T *to) const { return rlookup(from, to); } private: std::vector<std::pair<T, U>> mTable; Loading @@ -46,7 +46,7 @@ ALookup<T, U>::ALookup(std::initializer_list<std::pair<T, U>> list) } template<typename T, typename U> bool ALookup<T, U>::lookup(const T& from, U *to) { bool ALookup<T, U>::lookup(const T& from, U *to) const { for (auto elem : mTable) { if (elem.first == from) { *to = elem.second; Loading @@ -57,7 +57,7 @@ bool ALookup<T, U>::lookup(const T& from, U *to) { } template<typename T, typename U> bool ALookup<T, U>::rlookup(const U& from, T *to) { bool ALookup<T, U>::rlookup(const U& from, T *to) const { for (auto elem : mTable) { if (elem.second == from) { *to = elem.first; Loading
include/media/stagefright/foundation/ColorUtils.h +9 −0 Original line number Diff line number Diff line Loading @@ -129,6 +129,15 @@ struct ColorUtils { static status_t convertCodecColorAspectsToPlatformAspects( const ColorAspects &aspects, int32_t *range, int32_t *standard, int32_t *transfer); // converts Other values to Unspecified static void convertCodecColorAspectsToIsoAspects( const ColorAspects &aspects, int32_t *primaries, int32_t *transfer, int32_t *coeffs, bool *fullRange); // converts unsupported values to Other static void convertIsoColorAspectsToCodecAspects( int32_t primaries, int32_t transfer, int32_t coeffs, bool fullRange, ColorAspects &aspects); // updates Unspecified color aspects to their defaults based on the video size static void setDefaultCodecColorAspectsIfNeeded( ColorAspects &aspects, int32_t width, int32_t height); Loading
media/libstagefright/MPEG4Extractor.cpp +59 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/foundation/AUtils.h> #include <media/stagefright/foundation/ColorUtils.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaBufferGroup.h> #include <media/stagefright/MediaDefs.h> Loading Loading @@ -2083,6 +2084,21 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { break; } case FOURCC('c', 'o', 'l', 'r'): { *offset += chunk_size; // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd') // ignore otherwise if (depth >= 2 && mPath[depth - 2] == FOURCC('s', 't', 's', 'd')) { status_t err = parseColorInfo(data_offset, chunk_data_size); if (err != OK) { return err; } } break; } case FOURCC('t', 'i', 't', 'l'): case FOURCC('p', 'e', 'r', 'f'): case FOURCC('a', 'u', 't', 'h'): Loading Loading @@ -2663,6 +2679,49 @@ status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { return OK; } status_t MPEG4Extractor::parseColorInfo(off64_t offset, size_t size) { if (size < 4 || size == SIZE_MAX || mLastTrack == NULL) { return ERROR_MALFORMED; } uint8_t *buffer = new (std::nothrow) uint8_t[size + 1]; if (buffer == NULL) { return ERROR_MALFORMED; } if (mDataSource->readAt(offset, buffer, size) != (ssize_t)size) { delete[] buffer; buffer = NULL; return ERROR_IO; } int32_t type = U32_AT(&buffer[0]); if ((type == FOURCC('n', 'c', 'l', 'x') && size >= 11) || (type == FOURCC('n', 'c', 'l', 'c' && size >= 10))) { int32_t primaries = U16_AT(&buffer[4]); int32_t transfer = U16_AT(&buffer[6]); int32_t coeffs = U16_AT(&buffer[8]); bool fullRange = (type == FOURCC('n', 'c', 'l', 'x')) && (buffer[10] & 128); ColorAspects aspects; ColorUtils::convertIsoColorAspectsToCodecAspects( primaries, transfer, coeffs, fullRange, aspects); // only store the first color specification if (!mLastTrack->meta->hasData(kKeyColorPrimaries)) { mLastTrack->meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries); mLastTrack->meta->setInt32(kKeyTransferFunction, aspects.mTransfer); mLastTrack->meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs); mLastTrack->meta->setInt32(kKeyColorRange, aspects.mRange); } } delete[] buffer; buffer = NULL; return OK; } status_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) { if (size < 4 || size == SIZE_MAX) { return ERROR_MALFORMED; Loading
media/libstagefright/MPEG4Writer.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/foundation/ColorUtils.h> #include <media/stagefright/MPEG4Writer.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MetaData.h> Loading Loading @@ -371,6 +372,7 @@ private: void writeVmhdBox(); void writeHdlrBox(); void writeTkhdBox(uint32_t now); void writeColrBox(); void writeMp4aEsdsBox(); void writeMp4vEsdsBox(); void writeAudioFourCCBox(); Loading Loading @@ -2353,6 +2355,7 @@ status_t MPEG4Writer::Track::threadEntry() { if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecConfig) && isCodecConfig) { CHECK(!mGotAllCodecSpecificData); mMeta = mSource->getFormat(); // get output format after format change if (mIsAvc) { status_t err = makeAVCCodecSpecificData( Loading Loading @@ -2960,9 +2963,32 @@ void MPEG4Writer::Track::writeVideoFourCCBox() { } writePaspBox(); writeColrBox(); mOwner->endBox(); // mp4v, s263 or avc1 } void MPEG4Writer::Track::writeColrBox() { ColorAspects aspects; memset(&aspects, 0, sizeof(aspects)); // TRICKY: using | instead of || because we want to execute all findInt32-s if (mMeta->findInt32(kKeyColorPrimaries, (int32_t*)&aspects.mPrimaries) | mMeta->findInt32(kKeyTransferFunction, (int32_t*)&aspects.mTransfer) | mMeta->findInt32(kKeyColorMatrix, (int32_t*)&aspects.mMatrixCoeffs) | mMeta->findInt32(kKeyColorRange, (int32_t*)&aspects.mRange)) { int32_t primaries, transfer, coeffs; bool fullRange; ColorUtils::convertCodecColorAspectsToIsoAspects( aspects, &primaries, &transfer, &coeffs, &fullRange); mOwner->beginBox("colr"); mOwner->writeFourcc("nclx"); mOwner->writeInt16(primaries); mOwner->writeInt16(transfer); mOwner->writeInt16(coeffs); mOwner->writeInt8(fullRange ? 128 : 0); mOwner->endBox(); // colr } } void MPEG4Writer::Track::writeAudioFourCCBox() { const char *mime; bool success = mMeta->findCString(kKeyMIMEType, &mime); Loading
media/libstagefright/MediaCodecSource.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -781,6 +781,13 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) { mAvailEncoderInputIndices.push_back(index); feedEncoderInputBuffers(); } else if (cbID == MediaCodec::CB_OUTPUT_FORMAT_CHANGED) { status_t err = mEncoder->getOutputFormat(&mOutputFormat); if (err != OK) { signalEOS(err); break; } convertMessageToMetaData(mOutputFormat, mMeta); } else if (cbID == MediaCodec::CB_OUTPUT_AVAILABLE) { int32_t index; size_t offset; Loading