summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRicardo Cerqueira <cyanogenmod@cerqueira.org>2012-09-23 03:36:03 +0100
committerRicardo Cerqueira <cyanogenmod@cerqueira.org>2013-01-03 15:25:10 +0000
commitd54fa82a944f1977fd7ba05e4a875e0d58437ec4 (patch)
tree04f0a45e63004b57035f96ba0de4a361eb5b5f18
parent2fa0f79025df3193bc4353a82206baf4bd3e6e9f (diff)
downloadframeworks_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.h6
-rwxr-xr-xmedia/libstagefright/CameraSource.cpp4
-rwxr-xr-xmedia/libstagefright/MPEG4Writer.cpp79
-rw-r--r--media/libstagefright/OMXCodec.cpp72
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,