summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/MPEG4Extractor.cpp
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2009-07-28 10:03:13 -0700
committerAndreas Huber <andih@google.com>2009-07-28 11:28:14 -0700
commit0024245e134467d120b40099da16c467dc365e76 (patch)
treeb4023ffb3f2167dc3303cd048031ad7278643fd9 /media/libstagefright/MPEG4Extractor.cpp
parent9a92037bd6477533062d635b676a6c9833aab96e (diff)
downloadframeworks_av-0024245e134467d120b40099da16c467dc365e76.zip
frameworks_av-0024245e134467d120b40099da16c467dc365e76.tar.gz
frameworks_av-0024245e134467d120b40099da16c467dc365e76.tar.bz2
Squashed commit of the following:
commit 374ea382ee3a9e3ce17e4c6357fc40d02e362810 Author: Andreas Huber <andih@google.com> Date: Tue Jul 28 09:54:13 2009 -0700 PV's OMX implementation now uses (spec-compliant) microseconds instead of milliseconds in buffer timestamps. commit 8d02f8ab5d7b022ad4ad34db2a9bdeea6ce2acfe Author: Andreas Huber <andih@google.com> Date: Mon Jul 27 14:24:26 2009 -0700 Support for using an overlay for video playback on TI hardware. Appears to be currently constrained to CbYCrY 16-bit colorspace. commit d17f321cb4b15c1fea378f33a7ef5998f23dd0fc Author: Andreas Huber <andih@google.com> Date: Mon Jul 27 09:45:38 2009 -0700 Added '--audio-only' commandline option to stagefright tool. commit d8beef6be5c668c46451446d87e622933371cd75 Author: Andreas Huber <andih@google.com> Date: Fri Jul 24 13:35:00 2009 -0700 Generalize the various workarounds for OMX nodes with their own unique interpretation of the spec. commit c7dfd53eeadf8ed5a39bf2b19b014dcd62f3324d Author: Andreas Huber <andih@google.com> Date: Thu Jul 23 16:06:36 2009 -0700 Fixed erroneous TI AAC decoder behaviour wrt shutdown. The AAC decoder appears to not return out buffers on an Executing->Idle transition, implemented a workaround that does a flush on all ports followed by the Executing->Idle. Oh, and flush with OMX_ALL doesn't properly work either. Fun. commit d6377282e75060881336578f166f9c7feacf3f8f Author: Andreas Huber <andih@google.com> Date: Thu Jul 23 14:06:50 2009 -0700 Apparently the "channels" parameter in AudioTrack's constructor no longer counts channels but is a bitmask of enabled destinations, update the code accordingly. commit ff698c79e851a2e57d362e9c3a09828af4048087 Author: Andreas Huber <andih@google.com> Date: Wed Jul 22 16:54:44 2009 -0700 Fix MPEG4 decoding using TI's hardware decoder that I broke earlier... commit 2ef78bb87cd856eb7f0b3d7dd68782a8650c12bf Author: Andreas Huber <andih@google.com> Date: Wed Jul 22 15:43:18 2009 -0700 Now that the qcom decoder properly advertises its own custom colorspace, update dependent code to reflect this fact. commit bbaec96910727080fd7c8a6907c04facb9f5220f Author: Andreas Huber <andih@google.com> Date: Wed Jul 22 14:32:03 2009 -0700 Finishing up previous, incomplete change. commit 76f14a1ae816b6f434771f8d12bdad81196f351e Author: Andreas Huber <andih@google.com> Date: Wed Jul 22 14:25:17 2009 -0700 The TI video decoder now properly decoder AVC/H.264 content. commit e106130d8c100d5c94603e43864a7a93cca10252 Author: Andreas Huber <andih@google.com> Date: Wed Jul 22 08:56:04 2009 -0700 Experimental support for the TI H.264 decoder, various modifications to OMXDecoder, non-functional still. commit 241c3062dec3447db1a1ee74558cb4b9098fc404 Author: Andreas Huber <andih@google.com> Date: Tue Jul 21 12:13:09 2009 -0700 Enable TI hardware OMX decoders (except for AVC/H.264 which still has issues). This particular set of OMX nodes does not appear to properly return our buffers when sending the "disable" command on a port. Rather it reqires manually flushing that port and _then_ disabling it instead. commit 1c34506a46e32ce25f2a86f3b4250dcfc037356a Author: Andreas Huber <andih@google.com> Date: Tue Jul 21 08:51:35 2009 -0700 Make it simpler to switch between the stagefright player and PVPlayer. commit 249c6de05671d403f8dd51f095d49bf190430c9c Author: Andreas Huber <andih@google.com> Date: Mon Jul 20 14:38:15 2009 -0700 Prepare to use soon-to-be-available hardware decoders in the OMX decoder.
Diffstat (limited to 'media/libstagefright/MPEG4Extractor.cpp')
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp121
1 files changed, 71 insertions, 50 deletions
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index caaec06..4c883c6 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -73,6 +73,8 @@ private:
bool mNeedsNALFraming;
+ uint8_t *mSrcBuffer;
+
MPEG4Source(const MPEG4Source &);
MPEG4Source &operator=(const MPEG4Source &);
};
@@ -743,7 +745,8 @@ MPEG4Source::MPEG4Source(
mBuffer(NULL),
mBufferOffset(0),
mBufferSizeRemaining(0),
- mNeedsNALFraming(false) {
+ mNeedsNALFraming(false),
+ mSrcBuffer(NULL) {
const char *mime;
bool success = mFormat->findCString(kKeyMIMEType, &mime);
assert(success);
@@ -777,8 +780,13 @@ status_t MPEG4Source::start(MetaData *params) {
status_t err = mSampleTable->getMaxSampleSize(&max_size);
assert(err == OK);
- // Add padding for de-framing of AVC content just in case.
- mGroup->add_buffer(new MediaBuffer(max_size + 2));
+ // Assume that a given buffer only contains at most 10 fragments,
+ // each fragment originally prefixed with a 2 byte length will
+ // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
+ // and thus will grow by 2 bytes per fragment.
+ mGroup->add_buffer(new MediaBuffer(max_size + 10 * 2));
+
+ mSrcBuffer = new uint8_t[max_size];
mStarted = true;
@@ -793,6 +801,9 @@ status_t MPEG4Source::stop() {
mBuffer = NULL;
}
+ delete[] mSrcBuffer;
+ mSrcBuffer = NULL;
+
delete mGroup;
mGroup = NULL;
@@ -832,33 +843,31 @@ status_t MPEG4Source::read(
// fall through
}
- if (mBuffer == NULL) {
- off_t offset;
- size_t size;
- status_t err = mSampleTable->getSampleOffsetAndSize(
- mCurrentSampleIndex, &offset, &size);
+ off_t offset;
+ size_t size;
+ status_t err = mSampleTable->getSampleOffsetAndSize(
+ mCurrentSampleIndex, &offset, &size);
- if (err != OK) {
- return err;
- }
+ if (err != OK) {
+ return err;
+ }
- uint32_t dts;
- err = mSampleTable->getDecodingTime(mCurrentSampleIndex, &dts);
+ uint32_t dts;
+ err = mSampleTable->getDecodingTime(mCurrentSampleIndex, &dts);
- if (err != OK) {
- return err;
- }
-
- err = mGroup->acquire_buffer(&mBuffer);
- if (err != OK) {
- assert(mBuffer == NULL);
- return err;
- }
+ if (err != OK) {
+ return err;
+ }
- assert(mBuffer->size() + 2 >= size);
+ err = mGroup->acquire_buffer(&mBuffer);
+ if (err != OK) {
+ assert(mBuffer == NULL);
+ return err;
+ }
+ if (!mIsAVC || !mNeedsNALFraming) {
ssize_t num_bytes_read =
- mDataSource->read_at(offset, (uint8_t *)mBuffer->data() + 2, size);
+ mDataSource->read_at(offset, (uint8_t *)mBuffer->data(), size);
if (num_bytes_read < (ssize_t)size) {
mBuffer->release();
@@ -867,50 +876,62 @@ status_t MPEG4Source::read(
return err;
}
- mBuffer->set_range(2, size);
+ mBuffer->set_range(0, size);
mBuffer->meta_data()->clear();
mBuffer->meta_data()->setInt32(kKeyTimeUnits, dts);
mBuffer->meta_data()->setInt32(kKeyTimeScale, mTimescale);
-
++mCurrentSampleIndex;
- mBufferOffset = 2;
- mBufferSizeRemaining = size;
- }
-
- if (!mIsAVC) {
*out = mBuffer;
mBuffer = NULL;
return OK;
}
- uint8_t *data = (uint8_t *)mBuffer->data() + mBufferOffset;
- assert(mBufferSizeRemaining >= 2);
+ ssize_t num_bytes_read =
+ mDataSource->read_at(offset, mSrcBuffer, size);
- size_t nal_length = (data[0] << 8) | data[1];
- assert(mBufferSizeRemaining >= 2 + nal_length);
-
- if (mNeedsNALFraming) {
- // Insert marker.
- data[-2] = data[-1] = data[0] = 0;
- data[1] = 1;
+ if (num_bytes_read < (ssize_t)size) {
+ mBuffer->release();
+ mBuffer = NULL;
- mBuffer->set_range(mBufferOffset - 2, nal_length + 4);
- } else {
- mBuffer->set_range(mBufferOffset + 2, nal_length);
+ return err;
}
- mBufferOffset += nal_length + 2;
- mBufferSizeRemaining -= nal_length + 2;
+ uint8_t *dstData = (uint8_t *)mBuffer->data();
+ size_t srcOffset = 0;
+ size_t dstOffset = 0;
+ while (srcOffset < size) {
+ assert(srcOffset + 1 < size);
+ size_t nalLength =
+ (mSrcBuffer[srcOffset] << 8) | mSrcBuffer[srcOffset + 1];
+ assert(srcOffset + 1 + nalLength < size);
+ srcOffset += 2;
+
+ if (nalLength == 0) {
+ continue;
+ }
- if (mBufferSizeRemaining > 0) {
- *out = mBuffer->clone();
- } else {
- *out = mBuffer;
- mBuffer = NULL;
+ assert(dstOffset + 4 <= mBuffer->size());
+
+ dstData[dstOffset++] = 0;
+ dstData[dstOffset++] = 0;
+ dstData[dstOffset++] = 0;
+ dstData[dstOffset++] = 1;
+ memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
+ srcOffset += nalLength;
+ dstOffset += nalLength;
}
+ mBuffer->set_range(0, dstOffset);
+ mBuffer->meta_data()->clear();
+ mBuffer->meta_data()->setInt32(kKeyTimeUnits, dts);
+ mBuffer->meta_data()->setInt32(kKeyTimeScale, mTimescale);
+ ++mCurrentSampleIndex;
+
+ *out = mBuffer;
+ mBuffer = NULL;
+
return OK;
}