summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2012-08-09 09:15:48 -0700
committerAndreas Huber <andih@google.com>2012-08-09 13:25:48 -0700
commitb9787142c5f5f8f47e7e35409f4f2ef7112ab72e (patch)
tree3966271224e78b6d8e88da104385a67900890635
parent0d27c65ddb5c968baa6db0c26e80f5c451bc52bc (diff)
downloadframeworks_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.cpp5
-rw-r--r--media/libmediaplayerservice/nuplayer/mp4/Parser.cpp20
-rw-r--r--media/libmediaplayerservice/nuplayer/mp4/TrackFragment.cpp82
-rw-r--r--media/libmediaplayerservice/nuplayer/mp4/TrackFragment.h2
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);
};