diff options
author | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2012-09-23 03:36:03 +0100 |
---|---|---|
committer | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2013-01-03 15:25:10 +0000 |
commit | d54fa82a944f1977fd7ba05e4a875e0d58437ec4 (patch) | |
tree | 04f0a45e63004b57035f96ba0de4a361eb5b5f18 | |
parent | 2fa0f79025df3193bc4353a82206baf4bd3e6e9f (diff) | |
download | frameworks_av-d54fa82a944f1977fd7ba05e4a875e0d58437ec4.zip frameworks_av-d54fa82a944f1977fd7ba05e4a875e0d58437ec4.tar.gz frameworks_av-d54fa82a944f1977fd7ba05e4a875e0d58437ec4.tar.bz2 |
stagefright: OMXCodec: Re-enable OMX.TI.Video.encoder's quirks
These have been around since early stagefright, and were dropped for
JB. Unfortunately, they're still necessary with for this encoder to
work.
Change-Id: I8a251bf195a24b166db7464a90a822d6e69b644d
libstagefright: Add support for the 720P OMAP3 encoders
Bring back some more OMAP code that was removed by Google in JB,
and a couple of omapzoom patches.
This may stop being necessary if TI publishes JB-specific OMAP3
code, but as long as we're using the ICS domx, these need to
be here
Change-Id: Ia29f8c9f9ed769ba07b09c07260486f6502841d6
libstagefright: Unbreak OMAP4 encoders
The "manual" construction of the h264 codec data is only needed
on OMAP3. Execution of this code on OMAP4 breaks the mpeg4 header
generation
Change-Id: I3ae52f2e685e2d9097796685c98dffa93cfa6430
-rw-r--r-- | include/media/stagefright/OMXCodec.h | 6 | ||||
-rwxr-xr-x | media/libstagefright/CameraSource.cpp | 4 | ||||
-rwxr-xr-x | media/libstagefright/MPEG4Writer.cpp | 79 | ||||
-rw-r--r-- | media/libstagefright/OMXCodec.cpp | 72 |
4 files changed, 161 insertions, 0 deletions
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index aad8844..bdd35a4 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -108,6 +108,9 @@ struct OMXCodec : public MediaSource, kRequiresGlobalFlush = 0x20000000, // 2^29 kRequiresWMAProComponent = 0x40000000, //2^30 #endif +#if defined(OMAP_ENHANCEMENT) + kAvoidMemcopyInputRecordingFrames = 0x20000000, +#endif }; struct CodecNameAndQuirks { @@ -368,6 +371,9 @@ private: void dumpPortStatus(OMX_U32 portIndex); status_t configureCodec(const sp<MetaData> &meta); +#if defined(OMAP_ENHANCEMENT) + void restorePatchedDataPointer(BufferInfo *info); +#endif status_t applyRotation(); status_t waitForBufferFilled_l(); diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp index 29a2369..602a51f 100755 --- a/media/libstagefright/CameraSource.cpp +++ b/media/libstagefright/CameraSource.cpp @@ -105,7 +105,11 @@ static int32_t getColorFormat(const char* colorFormat) { } if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422I)) { +#if defined(TARGET_OMAP3) && defined(OMAP_ENHANCEMENT) + return OMX_COLOR_FormatCbYCrY; +#else return OMX_COLOR_FormatYCbYCr; +#endif } if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_RGB565)) { diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index 8b52e15..2b76660 100755 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -2040,6 +2040,83 @@ status_t MPEG4Writer::Track::threadEntry() { mGotAllCodecSpecificData = true; continue; } +#if defined(OMAP_ENHANCEMENT) && defined(TARGET_OMAP3) + else if (mIsAvc && count < 3) { + size_t size = buffer->range_length(); + + switch (count) { + case 1: + { + CHECK_EQ(mCodecSpecificData, (void *)NULL); + mCodecSpecificData = malloc(size + 8); + uint8_t *header = (uint8_t *)mCodecSpecificData; + header[0] = 1; + header[1] = 0x42; // profile + header[2] = 0x80; + header[3] = 0x1e; // level + header[4] = 0xfc | 3; + header[5] = 0xe0 | 1; + header[6] = size >> 8; + header[7] = size & 0xff; + memcpy(&header[8], + (const uint8_t *)buffer->data() + buffer->range_offset(), + size); + + mCodecSpecificDataSize = size + 8; + break; + } + + case 2: + { + size_t offset = mCodecSpecificDataSize; + mCodecSpecificDataSize += size + 3; + mCodecSpecificData = realloc(mCodecSpecificData, mCodecSpecificDataSize); + uint8_t *header = (uint8_t *)mCodecSpecificData; + header[offset] = 1; + header[offset + 1] = size >> 8; + header[offset + 2] = size & 0xff; + memcpy(&header[offset + 3], + (const uint8_t *)buffer->data() + buffer->range_offset(), + size); + break; + } + } + + buffer->release(); + buffer = NULL; + + continue; + + } else if (mCodecSpecificData == NULL && mIsMPEG4) { + const uint8_t *data = + (const uint8_t *)buffer->data() + buffer->range_offset(); + + const size_t size = buffer->range_length(); + + size_t offset = 0; + while (offset + 3 < size) { + if (data[offset] == 0x00 && data[offset + 1] == 0x00 + && data[offset + 2] == 0x01 && data[offset + 3] == 0xb6) { + break; + } + + ++offset; + } + + // CHECK(offset + 3 < size); + if (offset + 3 >= size) { + // XXX assume the entire first chunk of data is the codec specific + // data. + offset = size; + } + + mCodecSpecificDataSize = offset; + mCodecSpecificData = malloc(offset); + memcpy(mCodecSpecificData, data, offset); + + buffer->set_range(buffer->range_offset() + offset, size - offset); + } +#endif // Make a deep copy of the MediaBuffer and Metadata and release // the original as soon as we can @@ -2098,7 +2175,9 @@ status_t MPEG4Writer::Track::threadEntry() { } timestampUs -= previousPausedDurationUs; +#ifndef OMAP_ENHANCEMENT CHECK_GE(timestampUs, 0ll); +#endif if (!mIsAudio) { /* * Composition time: timestampUs diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 1992533..1135143 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -301,6 +301,16 @@ uint32_t OMXCodec::getComponentQuirks( quirks |= QCOMXCodec::getQCComponentQuirks(list,index); #endif +#ifdef OMAP_ENHANCEMENT + if (list->codecHasQuirk( + index, "avoid-memcopy-input-recording-frames")) { + quirks |= kAvoidMemcopyInputRecordingFrames; + } + if (list->codecHasQuirk( + index, "input-buffer-sizes-are-bogus")) { + quirks |= kInputBufferSizesAreBogus; + } +#endif return quirks; } @@ -822,6 +832,22 @@ status_t OMXCodec::setVideoPortFormatType( index, format.eCompressionFormat, format.eColorFormat); #endif + if (!strcmp("OMX.TI.Video.encoder", mComponentName) || + !strcmp("OMX.TI.720P.Encoder", mComponentName)) { + if (portIndex == kPortIndexInput + && colorFormat == format.eColorFormat) { + // eCompressionFormat does not seem right. + found = true; + break; + } + if (portIndex == kPortIndexOutput + && compressionFormat == format.eCompressionFormat) { + // eColorFormat does not seem right. + found = true; + break; + } + } + if (format.eCompressionFormat == compressionFormat && format.eColorFormat == colorFormat) { found = true; @@ -2369,6 +2395,14 @@ void OMXCodec::on_message(const omx_message &msg) { // Buffer could not be released until empty buffer done is called. if (info->mMediaBuffer != NULL) { +#ifdef OMAP_ENHANCEMENT + if (mIsEncoder && + (mQuirks & kAvoidMemcopyInputRecordingFrames)) { + // If zero-copy mode is enabled this will send the + // input buffer back to the upstream source. + restorePatchedDataPointer(info); + } +#endif info->mMediaBuffer->release(); info->mMediaBuffer = NULL; } @@ -3372,6 +3406,23 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) { } bool releaseBuffer = true; +#ifdef OMAP_ENHANCEMENT + if (mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames)) { + CHECK(mOMXLivesLocally && offset == 0); + + OMX_BUFFERHEADERTYPE *header = + (OMX_BUFFERHEADERTYPE *)info->mBuffer; + + CHECK(header->pBuffer == info->mData); + + header->pBuffer = + (OMX_U8 *)srcBuffer->data() + srcBuffer->range_offset(); + + releaseBuffer = false; + info->mMediaBuffer = srcBuffer; + } else { +#endif + if (mFlags & kStoreMetaDataInVideoBuffers) { releaseBuffer = false; info->mMediaBuffer = srcBuffer; @@ -3428,6 +3479,10 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) { #endif // USE_SAMSUNG_COLORFORMAT } +#ifdef OMAP_ENHANCEMENT + } +#endif + int64_t lastBufferTimeUs; CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs)); CHECK(lastBufferTimeUs >= 0); @@ -3527,6 +3582,14 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) { return false; } + // This component does not ever signal the EOS flag on output buffers, + // Thanks for nothing. + if (mSignalledEOS && (!strcmp(mComponentName, "OMX.TI.Video.encoder") || + !strcmp(mComponentName, "OMX.TI.720P.Encoder"))) { + mNoMoreOutputData = true; + mBufferFilled.signal(); + } + info->mStatus = OWNED_BY_COMPONENT; return true; @@ -5128,6 +5191,15 @@ status_t OMXCodec::pause() { //////////////////////////////////////////////////////////////////////////////// +#ifdef OMAP_ENHANCEMENT +void OMXCodec::restorePatchedDataPointer(BufferInfo *info) { + CHECK(mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames)); + CHECK(mOMXLivesLocally); + + OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)info->mBuffer; + header->pBuffer = (OMX_U8 *)info->mData; +} +#endif status_t QueryCodecs( const sp<IOMX> &omx, const char *mime, bool queryDecoders, bool hwCodecOnly, |