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
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index ed2a817..acc3b06 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -100,6 +100,9 @@
kSupportsMultipleFramesPerInputBuffer = 1024,
kRequiresLargerEncoderOutputBuffer = 2048,
kOutputBuffersAreUnreadable = 4096,
+#if defined(OMAP_ENHANCEMENT)
+ kAvoidMemcopyInputRecordingFrames = 0x20000000,
+#endif
};
struct CodecNameAndQuirks {
@@ -347,6 +350,9 @@
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 92ea39f..e1f088d 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -105,7 +105,11 @@
}
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 a0f17b5..74321ba 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -2142,6 +2142,83 @@
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
@@ -2200,7 +2277,9 @@
}
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 21bf608..79cc0a5 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -271,6 +271,16 @@
index, "output-buffers-are-unreadable")) {
quirks |= kOutputBuffersAreUnreadable;
}
+#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;
}
@@ -699,6 +709,22 @@
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;
@@ -2218,6 +2244,14 @@
// 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;
}
@@ -3190,6 +3224,23 @@
}
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;
@@ -3246,6 +3297,10 @@
#endif // USE_SAMSUNG_COLORFORMAT
}
+#ifdef OMAP_ENHANCEMENT
+ }
+#endif
+
int64_t lastBufferTimeUs;
CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs));
CHECK(lastBufferTimeUs >= 0);
@@ -3331,6 +3386,14 @@
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;
@@ -4675,6 +4738,15 @@
////////////////////////////////////////////////////////////////////////////////
+#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,