diff options
author | Andreas Huber <andih@google.com> | 2012-08-09 09:15:48 -0700 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2012-08-09 13:25:48 -0700 |
commit | b9787142c5f5f8f47e7e35409f4f2ef7112ab72e (patch) | |
tree | 3966271224e78b6d8e88da104385a67900890635 | |
parent | 0d27c65ddb5c968baa6db0c26e80f5c451bc52bc (diff) | |
download | frameworks_av-b9787142c5f5f8f47e7e35409f4f2ef7112ab72e.zip frameworks_av-b9787142c5f5f8f47e7e35409f4f2ef7112ab72e.tar.gz frameworks_av-b9787142c5f5f8f47e7e35409f4f2ef7112ab72e.tar.bz2 |
Fix static sample table processing, add support for h.263 video.
Change-Id: I5628d3437b5e6f8836d78557fd07ab87e5a914e3
-rw-r--r-- | cmds/stagefright/stream.cpp | 5 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/mp4/Parser.cpp | 20 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/mp4/TrackFragment.cpp | 82 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/mp4/TrackFragment.h | 2 |
4 files changed, 53 insertions, 56 deletions
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp index 8e7861e..ac88d1f 100644 --- a/cmds/stagefright/stream.cpp +++ b/cmds/stagefright/stream.cpp @@ -349,7 +349,10 @@ int main(int argc, char **argv) { size_t len = strlen(argv[1]); if ((!usemp4 && len >= 3 && !strcasecmp(".ts", &argv[1][len - 3])) || - (usemp4 && len >= 4 && !strcasecmp(".mp4", &argv[1][len - 4]))) { + (usemp4 && len >= 4 && + (!strcasecmp(".mp4", &argv[1][len - 4]) + || !strcasecmp(".3gp", &argv[1][len- 4]) + || !strcasecmp(".3g2", &argv[1][len- 4])))) { int fd = open(argv[1], O_RDONLY); if (fd < 0) { diff --git a/media/libmediaplayerservice/nuplayer/mp4/Parser.cpp b/media/libmediaplayerservice/nuplayer/mp4/Parser.cpp index b9fe819..7938fa4 100644 --- a/media/libmediaplayerservice/nuplayer/mp4/Parser.cpp +++ b/media/libmediaplayerservice/nuplayer/mp4/Parser.cpp @@ -271,6 +271,19 @@ void Parser::onMessageReceived(const sp<AMessage> &msg) { mBuffer->setRange(0, mBuffer->size()); size_t maxBytesToRead = mBuffer->capacity() - mBuffer->size(); + + if (maxBytesToRead < needed) { + ALOGI("resizing buffer."); + + sp<ABuffer> newBuffer = + new ABuffer((mBuffer->size() + needed + 1023) & ~1023); + memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size()); + newBuffer->setRange(0, mBuffer->size()); + + mBuffer = newBuffer; + maxBytesToRead = mBuffer->capacity() - mBuffer->size(); + } + CHECK_GE(maxBytesToRead, needed); ssize_t n = mSource->readAt( @@ -1023,6 +1036,11 @@ status_t Parser::parseVisualSampleEntry( case FOURCC('m', 'p', '4', 'v'): format->setString("mime", MEDIA_MIMETYPE_VIDEO_MPEG4); break; + case FOURCC('s', '2', '6', '3'): + case FOURCC('h', '2', '6', '3'): + case FOURCC('H', '2', '6', '3'): + format->setString("mime", MEDIA_MIMETYPE_VIDEO_H263); + break; default: format->setString("mime", "application/octet-stream"); break; @@ -1062,11 +1080,13 @@ status_t Parser::parseAudioSampleEntry( case FOURCC('m', 'p', '4', 'a'): format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); break; + case FOURCC('s', 'a', 'm', 'r'): format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB); format->setInt32("channel-count", 1); format->setInt32("sample-rate", 8000); break; + case FOURCC('s', 'a', 'w', 'b'): format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB); format->setInt32("channel-count", 1); diff --git a/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.cpp b/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.cpp index 12e71db..a4c31ea 100644 --- a/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.cpp +++ b/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.cpp @@ -24,6 +24,7 @@ #include <media/stagefright/Utils.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/foundation/hexdump.h> namespace android { @@ -79,6 +80,7 @@ bool Parser::DynamicTrackFragment::complete() const { Parser::StaticTrackFragment::StaticTrackFragment() : mSampleIndex(0), mSampleCount(0), + mChunkIndex(0), mSampleToChunkIndex(-1), mSampleToChunkRemaining(0), mPrevChunkIndex(0xffffffff), @@ -149,37 +151,31 @@ void Parser::StaticTrackFragment::updateSampleInfo() { mSampleInfo.mSampleDescIndex = U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 8); - uint32_t chunkIndex = - U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex); - - CHECK_GE(chunkIndex, 1); - --chunkIndex; - - if (chunkIndex != mPrevChunkIndex) { - mPrevChunkIndex = chunkIndex; + if (mChunkIndex != mPrevChunkIndex) { + mPrevChunkIndex = mChunkIndex; if (mChunkOffsets != NULL) { uint32_t entryCount = U32_AT(mChunkOffsets->data() + 4); - if (chunkIndex >= entryCount) { + if (mChunkIndex >= entryCount) { mSampleIndex = mSampleCount; return; } mNextSampleOffset = - U32_AT(mChunkOffsets->data() + 8 + 4 * chunkIndex); + U32_AT(mChunkOffsets->data() + 8 + 4 * mChunkIndex); } else { CHECK(mChunkOffsets64 != NULL); uint32_t entryCount = U32_AT(mChunkOffsets64->data() + 4); - if (chunkIndex >= entryCount) { + if (mChunkIndex >= entryCount) { mSampleIndex = mSampleCount; return; } mNextSampleOffset = - U64_AT(mChunkOffsets64->data() + 8 + 8 * chunkIndex); + U64_AT(mChunkOffsets64->data() + 8 + 8 * mChunkIndex); } } @@ -194,14 +190,25 @@ void Parser::StaticTrackFragment::advance() { ++mSampleIndex; if (--mSampleToChunkRemaining == 0) { + ++mChunkIndex; + uint32_t entryCount = U32_AT(mSampleToChunk->data() + 4); - if ((uint32_t)(mSampleToChunkIndex + 1) == entryCount) { - mSampleIndex = mSampleCount; // EOS. - return; + // If this is the last entry in the sample to chunk table, we will + // stay on this entry. + if ((uint32_t)(mSampleToChunkIndex + 1) < entryCount) { + uint32_t nextChunkIndex = + U32_AT(mSampleToChunk->data() + 8 + 12 * (mSampleToChunkIndex + 1)); + + CHECK_GE(nextChunkIndex, 1u); + --nextChunkIndex; + + if (mChunkIndex >= nextChunkIndex) { + CHECK_EQ(mChunkIndex, nextChunkIndex); + ++mSampleToChunkIndex; + } } - ++mSampleToChunkIndex; mSampleToChunkRemaining = U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 4); } @@ -216,46 +223,13 @@ static void setU32At(uint8_t *ptr, uint32_t x) { ptr[3] = x & 0xff; } -void Parser::StaticTrackFragment::fixSampleToChunkTableIfNecessary() { - if (mSampleToChunk == NULL) { - return; - } - uint32_t entryCount = U32_AT(mSampleToChunk->data() + 4); - uint32_t totalSamples = 0; - for (uint32_t i = 0; i < entryCount; ++i) { - totalSamples += U32_AT(mSampleToChunk->data() + 8 + 12 * i + 4); - } - - if (totalSamples < mSampleCount) { - // Some samples are not accounted for in the sample-to-chunk - // data. Fabricate an extra chunk adjacent to the last one - // in the table with the same sample desription index. - - ALOGW("Faking an extra sample-to-chunk entry for %d samples.", - mSampleCount - totalSamples); - - uint32_t lastChunkIndex = - U32_AT(mSampleToChunk->data() + 8 + 12 * (entryCount - 1)); - - uint32_t lastSampleDescriptionIndex = - U32_AT(mSampleToChunk->data() + 8 + 12 * (entryCount - 1) + 8); - - uint8_t *ptr = mSampleToChunk->data() + 8 + 12 * entryCount; - - setU32At(ptr, lastChunkIndex + 1); - setU32At(ptr + 4, mSampleCount - totalSamples); - setU32At(ptr + 8, lastSampleDescriptionIndex); - setU32At(mSampleToChunk->data() + 4, entryCount + 1); - } -} - status_t Parser::StaticTrackFragment::signalCompletion() { - fixSampleToChunkTableIfNecessary(); - mSampleToChunkIndex = 0; - mSampleToChunkRemaining = (mSampleToChunk == NULL) ? 0 : - U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 4); + mSampleToChunkRemaining = + (mSampleToChunk == NULL) + ? 0 + : U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 4); updateSampleInfo(); @@ -339,7 +313,7 @@ status_t Parser::StaticTrackFragment::parseSampleToChunk( return ERROR_MALFORMED; } - parser->copyBuffer(&mSampleToChunk, offset, size, 12 /* extra */); + parser->copyBuffer(&mSampleToChunk, offset, size); return OK; } diff --git a/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.h b/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.h index e5945ac..1498aad 100644 --- a/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.h +++ b/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.h @@ -96,6 +96,7 @@ protected: private: size_t mSampleIndex; size_t mSampleCount; + uint32_t mChunkIndex; SampleInfo mSampleInfo; @@ -112,7 +113,6 @@ private: uint64_t mNextSampleOffset; void updateSampleInfo(); - void fixSampleToChunkTableIfNecessary(); DISALLOW_EVIL_CONSTRUCTORS(StaticTrackFragment); }; |