diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 8687fab..1247588 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -104,7 +104,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
 	libstagefright liblog libutils libbinder libgui \
-        libstagefright_foundation libmedia libmedia_native
+        libstagefright_foundation libmedia libmedia_native libcutils
 
 LOCAL_C_INCLUDES:= \
 	frameworks/av/media/libstagefright \
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
index a9f0ab2..8e7861e 100644
--- a/cmds/stagefright/stream.cpp
+++ b/cmds/stagefright/stream.cpp
@@ -19,6 +19,7 @@
 #include "utils/Log.h"
 
 #include <binder/ProcessState.h>
+#include <cutils/properties.h> // for property_get
 
 #include <media/IStreamSource.h>
 #include <media/mediaplayer.h>
@@ -342,8 +343,13 @@
 
     sp<IStreamSource> source;
 
+    char prop[PROPERTY_VALUE_MAX];
+    bool usemp4 = property_get("media.stagefright.use-mp4source", prop, NULL) &&
+            (!strcmp(prop, "1") || !strcasecmp(prop, "true"));
+
     size_t len = strlen(argv[1]);
-    if (len >= 3 && !strcasecmp(".ts", &argv[1][len - 3])) {
+    if ((!usemp4 && len >= 3 && !strcasecmp(".ts", &argv[1][len - 3])) ||
+        (usemp4 && len >= 4 && !strcasecmp(".mp4", &argv[1][len - 4]))) {
         int fd = open(argv[1], O_RDONLY);
 
         if (fd < 0) {
diff --git a/include/media/stagefright/foundation/hexdump.h b/include/media/stagefright/foundation/hexdump.h
index f6083a9..8360c5a 100644
--- a/include/media/stagefright/foundation/hexdump.h
+++ b/include/media/stagefright/foundation/hexdump.h
@@ -22,7 +22,11 @@
 
 namespace android {
 
-void hexdump(const void *_data, size_t size);
+struct AString;
+
+void hexdump(
+        const void *_data, size_t size,
+        size_t indent = 0, AString *appendTo = NULL);
 
 }  // namespace android
 
diff --git a/media/libmediaplayerservice/nuplayer/Android.mk b/media/libmediaplayerservice/nuplayer/Android.mk
index f97ba57..f469054 100644
--- a/media/libmediaplayerservice/nuplayer/Android.mk
+++ b/media/libmediaplayerservice/nuplayer/Android.mk
@@ -11,6 +11,9 @@
         NuPlayerStreamListener.cpp      \
         RTSPSource.cpp                  \
         StreamingSource.cpp             \
+        mp4/MP4Source.cpp               \
+        mp4/Parser.cpp                  \
+        mp4/TrackFragment.cpp           \
 
 LOCAL_C_INCLUDES := \
 	$(TOP)/frameworks/av/media/libstagefright/httplive            \
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 99569c9..f0c3240 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -128,7 +128,7 @@
     return OK;
 }
 
-sp<MetaData> NuPlayer::GenericSource::getFormat(bool audio) {
+sp<MetaData> NuPlayer::GenericSource::getFormatMeta(bool audio) {
     sp<MediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource;
 
     if (source == NULL) {
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index aaa5876..e50b855 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -43,7 +43,6 @@
 
     virtual status_t feedMoreTSData();
 
-    virtual sp<MetaData> getFormat(bool audio);
     virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
 
     virtual status_t getDuration(int64_t *durationUs);
@@ -53,6 +52,8 @@
 protected:
     virtual ~GenericSource();
 
+    virtual sp<MetaData> getFormatMeta(bool audio);
+
 private:
     struct Track {
         sp<MediaSource> mSource;
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
index 22b8847..1e98f35 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
@@ -81,7 +81,7 @@
     mTSParser = new ATSParser;
 }
 
-sp<MetaData> NuPlayer::HTTPLiveSource::getFormat(bool audio) {
+sp<MetaData> NuPlayer::HTTPLiveSource::getFormatMeta(bool audio) {
     ATSParser::SourceType type =
         audio ? ATSParser::AUDIO : ATSParser::VIDEO;
 
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
index f22af5b..9950a9e 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
@@ -37,7 +37,6 @@
 
     virtual status_t feedMoreTSData();
 
-    virtual sp<MetaData> getFormat(bool audio);
     virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
 
     virtual status_t getDuration(int64_t *durationUs);
@@ -47,6 +46,8 @@
 protected:
     virtual ~HTTPLiveSource();
 
+    virtual sp<MetaData> getFormatMeta(bool audio);
+
 private:
     enum Flags {
         // Don't log any URLs.
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index daf60f6..a02732b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -28,9 +28,11 @@
 #include "RTSPSource.h"
 #include "StreamingSource.h"
 #include "GenericSource.h"
+#include "mp4/MP4Source.h"
 
 #include "ATSParser.h"
 
+#include <cutils/properties.h> // for property_get
 #include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -43,6 +45,9 @@
 
 #include "avc_utils.h"
 
+#include "ESDS.h"
+#include <media/stagefright/Utils.h>
+
 namespace android {
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -81,7 +86,14 @@
 void NuPlayer::setDataSource(const sp<IStreamSource> &source) {
     sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
 
-    msg->setObject("source", new StreamingSource(source));
+    char prop[PROPERTY_VALUE_MAX];
+    if (property_get("media.stagefright.use-mp4source", prop, NULL)
+            && (!strcmp(prop, "1") || !strcasecmp(prop, "true"))) {
+        msg->setObject("source", new MP4Source(source));
+    } else {
+        msg->setObject("source", new StreamingSource(source));
+    }
+
     msg->post();
 }
 
@@ -679,16 +691,16 @@
         return OK;
     }
 
-    sp<MetaData> meta = mSource->getFormat(audio);
+    sp<AMessage> format = mSource->getFormat(audio);
 
-    if (meta == NULL) {
+    if (format == NULL) {
         return -EWOULDBLOCK;
     }
 
     if (!audio) {
-        const char *mime;
-        CHECK(meta->findCString(kKeyMIMEType, &mime));
-        mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime);
+        AString mime;
+        CHECK(format->findString("mime", &mime));
+        mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
     }
 
     sp<AMessage> notify =
@@ -699,7 +711,7 @@
                        new Decoder(notify, mNativeWindow);
     looper()->registerHandler(*decoder);
 
-    (*decoder)->configure(meta);
+    (*decoder)->configure(format);
 
     int64_t durationUs;
     if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
@@ -930,4 +942,19 @@
     }
 }
 
+sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
+    sp<MetaData> meta = getFormatMeta(audio);
+
+    if (meta == NULL) {
+        return NULL;
+    }
+
+    sp<AMessage> msg = new AMessage;
+
+    if(convertMetaDataToMessage(meta, &msg) == OK) {
+        return msg;
+    }
+    return NULL;
+}
+
 }  // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 25766e0..996806e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -60,14 +60,16 @@
 
     virtual void onMessageReceived(const sp<AMessage> &msg);
 
+public:
+    struct NuPlayerStreamListener;
+    struct Source;
+
 private:
     struct Decoder;
     struct GenericSource;
     struct HTTPLiveSource;
-    struct NuPlayerStreamListener;
     struct Renderer;
     struct RTSPSource;
-    struct Source;
     struct StreamingSource;
 
     enum {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 0e53662..22f699e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -20,15 +20,11 @@
 
 #include "NuPlayerDecoder.h"
 
-#include "ESDS.h"
-
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/ACodec.h>
 #include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/Utils.h>
 
 namespace android {
 
@@ -42,16 +38,24 @@
 NuPlayer::Decoder::~Decoder() {
 }
 
-void NuPlayer::Decoder::configure(const sp<MetaData> &meta) {
+void NuPlayer::Decoder::configure(const sp<AMessage> &format) {
     CHECK(mCodec == NULL);
 
-    const char *mime;
-    CHECK(meta->findCString(kKeyMIMEType, &mime));
+    AString mime;
+    CHECK(format->findString("mime", &mime));
 
     sp<AMessage> notifyMsg =
         new AMessage(kWhatCodecNotify, id());
 
-    sp<AMessage> format = makeFormat(meta);
+    mCSDIndex = 0;
+    for (size_t i = 0;; ++i) {
+        sp<ABuffer> csd;
+        if (!format->findBuffer(StringPrintf("csd-%d", i).c_str(), &csd)) {
+            break;
+        }
+
+        mCSD.push(csd);
+    }
 
     if (mNativeWindow != NULL) {
         format->setObject("native-window", mNativeWindow);
@@ -61,7 +65,7 @@
     // quickly, violating the OpenMAX specs, until that is remedied
     // we need to invest in an extra looper to free the main event
     // queue.
-    bool needDedicatedLooper = !strncasecmp(mime, "video/", 6);
+    bool needDedicatedLooper = !strncasecmp(mime.c_str(), "video/", 6);
 
     mCodec = new ACodec;
 
@@ -100,25 +104,6 @@
     }
 }
 
-sp<AMessage> NuPlayer::Decoder::makeFormat(const sp<MetaData> &meta) {
-    CHECK(mCSD.isEmpty());
-
-    sp<AMessage> msg;
-    CHECK_EQ(convertMetaDataToMessage(meta, &msg), (status_t)OK);
-
-    mCSDIndex = 0;
-    for (size_t i = 0;; ++i) {
-        sp<ABuffer> csd;
-        if (!msg->findBuffer(StringPrintf("csd-%d", i).c_str(), &csd)) {
-            break;
-        }
-
-        mCSD.push(csd);
-    }
-
-    return msg;
-}
-
 void NuPlayer::Decoder::onFillThisBuffer(const sp<AMessage> &msg) {
     sp<AMessage> reply;
     CHECK(msg->findMessage("reply", &reply));
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
index 3ab1fcf..a876148 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
@@ -30,7 +30,7 @@
     Decoder(const sp<AMessage> &notify,
             const sp<NativeWindowWrapper> &nativeWindow = NULL);
 
-    void configure(const sp<MetaData> &meta);
+    void configure(const sp<AMessage> &format);
 
     void signalFlush();
     void signalResume();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index 531b29f..66aeff3 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -34,7 +34,7 @@
     // an error or ERROR_END_OF_STREAM if not.
     virtual status_t feedMoreTSData() = 0;
 
-    virtual sp<MetaData> getFormat(bool audio) = 0;
+    virtual sp<AMessage> getFormat(bool audio);
 
     virtual status_t dequeueAccessUnit(
             bool audio, sp<ABuffer> *accessUnit) = 0;
@@ -54,6 +54,8 @@
 protected:
     virtual ~Source() {}
 
+    virtual sp<MetaData> getFormatMeta(bool audio) { return NULL; }
+
 private:
     DISALLOW_EVIL_CONSTRUCTORS(Source);
 };
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index c910488..4a704e3 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -95,7 +95,7 @@
     return mFinalResult;
 }
 
-sp<MetaData> NuPlayer::RTSPSource::getFormat(bool audio) {
+sp<MetaData> NuPlayer::RTSPSource::getFormatMeta(bool audio) {
     sp<AnotherPacketSource> source = getSource(audio);
 
     if (source == NULL) {
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h
index e11e304..c8409e5 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.h
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h
@@ -40,7 +40,6 @@
 
     virtual status_t feedMoreTSData();
 
-    virtual sp<MetaData> getFormat(bool audio);
     virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
 
     virtual status_t getDuration(int64_t *durationUs);
@@ -52,6 +51,8 @@
 protected:
     virtual ~RTSPSource();
 
+    virtual sp<MetaData> getFormatMeta(bool audio);
+
 private:
     enum {
         kWhatNotify          = 'noti',
diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
index 7c9bc5e..b696aa4 100644
--- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
@@ -107,7 +107,7 @@
     return OK;
 }
 
-sp<MetaData> NuPlayer::StreamingSource::getFormat(bool audio) {
+sp<MetaData> NuPlayer::StreamingSource::getFormatMeta(bool audio) {
     ATSParser::SourceType type =
         audio ? ATSParser::AUDIO : ATSParser::VIDEO;
 
diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.h b/media/libmediaplayerservice/nuplayer/StreamingSource.h
index ca00ef9..3971e2a 100644
--- a/media/libmediaplayerservice/nuplayer/StreamingSource.h
+++ b/media/libmediaplayerservice/nuplayer/StreamingSource.h
@@ -33,12 +33,13 @@
 
     virtual status_t feedMoreTSData();
 
-    virtual sp<MetaData> getFormat(bool audio);
     virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
 
 protected:
     virtual ~StreamingSource();
 
+    virtual sp<MetaData> getFormatMeta(bool audio);
+
 private:
     sp<IStreamSource> mSource;
     status_t mFinalResult;
diff --git a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp
new file mode 100644
index 0000000..25c91e9
--- /dev/null
+++ b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MP4Source.h"
+
+#include "Parser.h"
+#include "../NuPlayerStreamListener.h"
+
+#include <media/IStreamSource.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MetaData.h>
+
+namespace android {
+
+struct StreamSource : public Parser::Source {
+    StreamSource(const sp<IStreamSource> &source)
+        : mListener(new NuPlayer::NuPlayerStreamListener(source, 0)),
+          mPosition(0) {
+        mListener->start();
+    }
+
+    virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
+        if (offset < mPosition) {
+            return -EPIPE;
+        }
+
+        while (offset > mPosition) {
+            char buffer[1024];
+            off64_t skipBytes = offset - mPosition;
+            if (skipBytes > sizeof(buffer)) {
+                skipBytes = sizeof(buffer);
+            }
+
+            sp<AMessage> extra;
+            ssize_t n;
+            for (;;) {
+                n = mListener->read(buffer, skipBytes, &extra);
+
+                if (n == -EWOULDBLOCK) {
+                    usleep(10000);
+                    continue;
+                }
+
+                break;
+            }
+
+            ALOGV("skipped %ld bytes at offset %lld", n, mPosition);
+
+            if (n < 0) {
+                return n;
+            }
+
+            mPosition += n;
+        }
+
+        sp<AMessage> extra;
+        size_t total = 0;
+        while (total < size) {
+            ssize_t n = mListener->read(
+                    (uint8_t *)data + total, size - total, &extra);
+
+            if (n == -EWOULDBLOCK) {
+                usleep(10000);
+                continue;
+            } else if (n == 0) {
+                break;
+            } else if (n < 0) {
+                mPosition += total;
+                return n;
+            }
+
+            total += n;
+        }
+
+        ALOGV("read %ld bytes at offset %lld", n, mPosition);
+
+        mPosition += total;
+
+        return total;
+    }
+
+private:
+    sp<NuPlayer::NuPlayerStreamListener> mListener;
+    off64_t mPosition;
+
+    DISALLOW_EVIL_CONSTRUCTORS(StreamSource);
+};
+
+MP4Source::MP4Source(const sp<IStreamSource> &source)
+    : mSource(source),
+      mLooper(new ALooper),
+      mParser(new Parser),
+      mEOS(false) {
+    mLooper->registerHandler(mParser);
+}
+
+MP4Source::~MP4Source() {
+}
+
+void MP4Source::start() {
+    mLooper->start(false /* runOnCallingThread */);
+    mParser->start(new StreamSource(mSource));
+}
+
+status_t MP4Source::feedMoreTSData() {
+    return mEOS ? ERROR_END_OF_STREAM : (status_t)OK;
+}
+
+sp<AMessage> MP4Source::getFormat(bool audio) {
+    return mParser->getFormat(audio);
+}
+
+status_t MP4Source::dequeueAccessUnit(
+        bool audio, sp<ABuffer> *accessUnit) {
+    return mParser->dequeueAccessUnit(audio, accessUnit);
+}
+
+}  // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.h b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.h
new file mode 100644
index 0000000..57430aa
--- /dev/null
+++ b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MP4_SOURCE_H
+#define MP4_SOURCE_H
+
+#include "NuPlayerSource.h"
+
+namespace android {
+
+struct Parser;
+
+struct MP4Source : public NuPlayer::Source {
+    MP4Source(const sp<IStreamSource> &source);
+
+    virtual void start();
+
+    virtual status_t feedMoreTSData();
+
+    virtual sp<AMessage> getFormat(bool audio);
+
+    virtual status_t dequeueAccessUnit(
+            bool audio, sp<ABuffer> *accessUnit);
+
+protected:
+    virtual ~MP4Source();
+
+private:
+    sp<IStreamSource> mSource;
+    sp<ALooper> mLooper;
+    sp<Parser> mParser;
+    bool mEOS;
+
+    DISALLOW_EVIL_CONSTRUCTORS(MP4Source);
+};
+
+}  // namespace android
+
+#endif // MP4_SOURCE_H
diff --git a/media/libmediaplayerservice/nuplayer/mp4/Parser.cpp b/media/libmediaplayerservice/nuplayer/mp4/Parser.cpp
new file mode 100644
index 0000000..b9fe819
--- /dev/null
+++ b/media/libmediaplayerservice/nuplayer/mp4/Parser.cpp
@@ -0,0 +1,1643 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Parser"
+#include <utils/Log.h>
+
+#include "Parser.h"
+#include "TrackFragment.h"
+
+#include "ESDS.h"
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/Utils.h>
+
+#include "../NuPlayerStreamListener.h"
+
+namespace android {
+
+static const char *Fourcc2String(uint32_t fourcc) {
+    static char buffer[5];
+    buffer[4] = '\0';
+    buffer[0] = fourcc >> 24;
+    buffer[1] = (fourcc >> 16) & 0xff;
+    buffer[2] = (fourcc >> 8) & 0xff;
+    buffer[3] = fourcc & 0xff;
+
+    return buffer;
+}
+
+static const char *IndentString(size_t n) {
+    static const char kSpace[] = "                              ";
+    return kSpace + sizeof(kSpace) - 2 * n - 1;
+}
+
+// static
+const Parser::DispatchEntry Parser::kDispatchTable[] = {
+    { FOURCC('m', 'o', 'o', 'v'), 0, NULL },
+    { FOURCC('t', 'r', 'a', 'k'), FOURCC('m', 'o', 'o', 'v'), NULL },
+    { FOURCC('u', 'd', 't', 'a'), FOURCC('t', 'r', 'a', 'k'), NULL },
+    { FOURCC('u', 'd', 't', 'a'), FOURCC('m', 'o', 'o', 'v'), NULL },
+    { FOURCC('m', 'e', 't', 'a'), FOURCC('u', 'd', 't', 'a'), NULL },
+    { FOURCC('i', 'l', 's', 't'), FOURCC('m', 'e', 't', 'a'), NULL },
+
+    { FOURCC('t', 'k', 'h', 'd'), FOURCC('t', 'r', 'a', 'k'),
+        &Parser::parseTrackHeader
+    },
+
+    { FOURCC('m', 'v', 'e', 'x'), FOURCC('m', 'o', 'o', 'v'), NULL },
+
+    { FOURCC('t', 'r', 'e', 'x'), FOURCC('m', 'v', 'e', 'x'),
+        &Parser::parseTrackExtends
+    },
+
+    { FOURCC('e', 'd', 't', 's'), FOURCC('t', 'r', 'a', 'k'), NULL },
+    { FOURCC('m', 'd', 'i', 'a'), FOURCC('t', 'r', 'a', 'k'), NULL },
+
+    { FOURCC('m', 'd', 'h', 'd'), FOURCC('m', 'd', 'i', 'a'),
+        &Parser::parseMediaHeader
+    },
+
+    { FOURCC('h', 'd', 'l', 'r'), FOURCC('m', 'd', 'i', 'a'),
+        &Parser::parseMediaHandler
+    },
+
+    { FOURCC('m', 'i', 'n', 'f'), FOURCC('m', 'd', 'i', 'a'), NULL },
+    { FOURCC('d', 'i', 'n', 'f'), FOURCC('m', 'i', 'n', 'f'), NULL },
+    { FOURCC('s', 't', 'b', 'l'), FOURCC('m', 'i', 'n', 'f'), NULL },
+    { FOURCC('s', 't', 's', 'd'), FOURCC('s', 't', 'b', 'l'), NULL },
+
+    { FOURCC('s', 't', 's', 'z'), FOURCC('s', 't', 'b', 'l'),
+        &Parser::parseSampleSizes },
+
+    { FOURCC('s', 't', 'z', '2'), FOURCC('s', 't', 'b', 'l'),
+        &Parser::parseCompactSampleSizes },
+
+    { FOURCC('s', 't', 's', 'c'), FOURCC('s', 't', 'b', 'l'),
+        &Parser::parseSampleToChunk },
+
+    { FOURCC('s', 't', 'c', 'o'), FOURCC('s', 't', 'b', 'l'),
+        &Parser::parseChunkOffsets },
+
+    { FOURCC('c', 'o', '6', '4'), FOURCC('s', 't', 'b', 'l'),
+        &Parser::parseChunkOffsets64 },
+
+    { FOURCC('a', 'v', 'c', 'C'), FOURCC('a', 'v', 'c', '1'),
+        &Parser::parseAVCCodecSpecificData },
+
+    { FOURCC('e', 's', 'd', 's'), FOURCC('m', 'p', '4', 'a'),
+        &Parser::parseESDSCodecSpecificData },
+
+    { FOURCC('e', 's', 'd', 's'), FOURCC('m', 'p', '4', 'v'),
+        &Parser::parseESDSCodecSpecificData },
+
+    { FOURCC('m', 'd', 'a', 't'), 0, &Parser::parseMediaData },
+
+    { FOURCC('m', 'o', 'o', 'f'), 0, NULL },
+    { FOURCC('t', 'r', 'a', 'f'), FOURCC('m', 'o', 'o', 'f'), NULL },
+
+    { FOURCC('t', 'f', 'h', 'd'), FOURCC('t', 'r', 'a', 'f'),
+        &Parser::parseTrackFragmentHeader
+    },
+    { FOURCC('t', 'r', 'u', 'n'), FOURCC('t', 'r', 'a', 'f'),
+        &Parser::parseTrackFragmentRun
+    },
+
+    { FOURCC('m', 'f', 'r', 'a'), 0, NULL },
+};
+
+struct FileSource : public Parser::Source {
+    FileSource(const char *filename)
+        : mFile(fopen(filename, "rb")) {
+            CHECK(mFile != NULL);
+        }
+
+    virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
+        fseek(mFile, offset, SEEK_SET);
+        return fread(data, 1, size, mFile);
+    }
+
+    private:
+    FILE *mFile;
+
+    DISALLOW_EVIL_CONSTRUCTORS(FileSource);
+};
+
+Parser::Parser()
+    : mBufferPos(0),
+      mSuspended(false) {
+}
+
+Parser::~Parser() {
+}
+
+void Parser::start(const char *filename) {
+    sp<AMessage> msg = new AMessage(kWhatStart, id());
+    msg->setObject("source", new FileSource(filename));
+    msg->post();
+}
+
+void Parser::start(const sp<Source> &source) {
+    sp<AMessage> msg = new AMessage(kWhatStart, id());
+    msg->setObject("source", source);
+    msg->post();
+}
+
+sp<AMessage> Parser::getFormat(bool audio) {
+    sp<AMessage> msg = new AMessage(kWhatGetFormat, id());
+    msg->setInt32("audio", audio);
+
+    sp<AMessage> response;
+    status_t err = msg->postAndAwaitResponse(&response);
+
+    if (err != OK) {
+        return NULL;
+    }
+
+    if (response->findInt32("err", &err) && err != OK) {
+        return NULL;
+    }
+
+    sp<AMessage> format;
+    CHECK(response->findMessage("format", &format));
+
+    ALOGV("returning format %s", format->debugString().c_str());
+    return format;
+}
+
+status_t Parser::dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit) {
+    sp<AMessage> msg = new AMessage(kWhatDequeueAccessUnit, id());
+    msg->setInt32("audio", audio);
+
+    sp<AMessage> response;
+    status_t err = msg->postAndAwaitResponse(&response);
+
+    if (err != OK) {
+        return err;
+    }
+
+    if (response->findInt32("err", &err) && err != OK) {
+        return err;
+    }
+
+    CHECK(response->findBuffer("accessUnit", accessUnit));
+
+    return OK;
+}
+
+ssize_t Parser::findTrack(bool wantAudio) const {
+    for (size_t i = 0; i < mTracks.size(); ++i) {
+        const TrackInfo *info = &mTracks.valueAt(i);
+
+        bool isAudio =
+            info->mMediaHandlerType == FOURCC('s', 'o', 'u', 'n');
+
+        bool isVideo =
+            info->mMediaHandlerType == FOURCC('v', 'i', 'd', 'e');
+
+        if ((wantAudio && isAudio) || (!wantAudio && !isAudio)) {
+            if (info->mSampleDescs.empty()) {
+                break;
+            }
+
+            return i;
+        }
+    }
+
+    return -EWOULDBLOCK;
+}
+
+void Parser::onMessageReceived(const sp<AMessage> &msg) {
+    switch (msg->what()) {
+        case kWhatStart:
+        {
+            sp<RefBase> obj;
+            CHECK(msg->findObject("source", &obj));
+
+            mSource = static_cast<Source *>(obj.get());
+
+            mBuffer = new ABuffer(512 * 1024);
+            mBuffer->setRange(0, 0);
+
+            enter(0, 0);
+
+            (new AMessage(kWhatProceed, id()))->post();
+            break;
+        }
+
+        case kWhatProceed:
+        {
+            CHECK(!mSuspended);
+
+            status_t err = onProceed();
+
+            if (err == OK) {
+                if (!mSuspended) {
+                    msg->post();
+                }
+            } else if (err != -EAGAIN) {
+                ALOGE("onProceed returned error %d", err);
+            }
+
+            break;
+        }
+
+        case kWhatReadMore:
+        {
+            size_t needed;
+            CHECK(msg->findSize("needed", &needed));
+
+            memmove(mBuffer->base(), mBuffer->data(), mBuffer->size());
+            mBufferPos += mBuffer->offset();
+            mBuffer->setRange(0, mBuffer->size());
+
+            size_t maxBytesToRead = mBuffer->capacity() - mBuffer->size();
+            CHECK_GE(maxBytesToRead, needed);
+
+            ssize_t n = mSource->readAt(
+                    mBufferPos + mBuffer->size(),
+                    mBuffer->data() + mBuffer->size(), needed);
+
+            if (n < (ssize_t)needed) {
+                ALOGI("%s", "Reached EOF");
+            } else {
+                mBuffer->setRange(0, mBuffer->size() + n);
+                (new AMessage(kWhatProceed, id()))->post();
+            }
+
+            break;
+        }
+
+        case kWhatGetFormat:
+        {
+            int32_t wantAudio;
+            CHECK(msg->findInt32("audio", &wantAudio));
+
+            status_t err = -EWOULDBLOCK;
+            sp<AMessage> response = new AMessage;
+
+            ssize_t trackIndex = findTrack(wantAudio);
+
+            if (trackIndex < 0) {
+                err = trackIndex;
+            } else {
+                TrackInfo *info = &mTracks.editValueAt(trackIndex);
+
+                response->setMessage(
+                        "format", info->mSampleDescs.itemAt(0).mFormat);
+
+                err = OK;
+            }
+
+            response->setInt32("err", err);
+
+            uint32_t replyID;
+            CHECK(msg->senderAwaitsResponse(&replyID));
+
+            response->postReply(replyID);
+            break;
+        }
+
+        case kWhatDequeueAccessUnit:
+        {
+            int32_t wantAudio;
+            CHECK(msg->findInt32("audio", &wantAudio));
+
+            status_t err = -EWOULDBLOCK;
+            sp<AMessage> response = new AMessage;
+
+            ssize_t trackIndex = findTrack(wantAudio);
+
+            if (trackIndex < 0) {
+                err = trackIndex;
+            } else {
+                sp<ABuffer> accessUnit;
+                err = onDequeueAccessUnit(trackIndex, &accessUnit);
+
+                if (err == OK) {
+                    response->setBuffer("accessUnit", accessUnit);
+                }
+            }
+
+            response->setInt32("err", err);
+
+            uint32_t replyID;
+            CHECK(msg->senderAwaitsResponse(&replyID));
+
+            response->postReply(replyID);
+            break;
+        }
+
+        default:
+            TRESPASS();
+    }
+}
+
+status_t Parser::onProceed() {
+    status_t err;
+
+    if ((err = need(8)) != OK) {
+        return err;
+    }
+
+    uint64_t size = readU32(0);
+    uint32_t type = readU32(4);
+
+    size_t offset = 8;
+
+    if (size == 1) {
+        if ((err = need(16)) != OK) {
+            return err;
+        }
+
+        size = readU64(offset);
+        offset += 8;
+    }
+
+    uint8_t userType[16];
+
+    if (type == FOURCC('u', 'u', 'i', 'd')) {
+        if ((err = need(offset + 16)) != OK) {
+            return err;
+        }
+
+        memcpy(userType, mBuffer->data() + offset, 16);
+        offset += 16;
+    }
+
+    CHECK(!mStack.isEmpty());
+    uint32_t ptype = mStack.itemAt(mStack.size() - 1).mType;
+
+    static const size_t kNumDispatchers =
+        sizeof(kDispatchTable) / sizeof(kDispatchTable[0]);
+
+    size_t i;
+    for (i = 0; i < kNumDispatchers; ++i) {
+        if (kDispatchTable[i].mType == type
+                && kDispatchTable[i].mParentType == ptype) {
+            break;
+        }
+    }
+
+    // SampleEntry boxes are container boxes that start with a variable
+    // amount of data depending on the media handler type.
+    // We don't look inside 'hint' type SampleEntry boxes.
+
+    bool isSampleEntryBox =
+        (ptype == FOURCC('s', 't', 's', 'd'))
+        && editTrack(mCurrentTrackID)->mMediaHandlerType
+        != FOURCC('h', 'i', 'n', 't');
+
+    if ((i < kNumDispatchers && kDispatchTable[i].mHandler == 0)
+            || isSampleEntryBox || ptype == FOURCC('i', 'l', 's', 't')) {
+        // This is a container box.
+        if (type == FOURCC('m', 'e', 't', 'a')) {
+            if ((err = need(offset + 4)) < OK) {
+                return err;
+            }
+
+            if (readU32(offset) != 0) {
+                return -EINVAL;
+            }
+
+            offset += 4;
+        } else if (type == FOURCC('s', 't', 's', 'd')) {
+            if ((err = need(offset + 8)) < OK) {
+                return err;
+            }
+
+            if (readU32(offset) != 0) {
+                return -EINVAL;
+            }
+
+            if (readU32(offset + 4) == 0) {
+                // We need at least some entries.
+                return -EINVAL;
+            }
+
+            offset += 8;
+        } else if (isSampleEntryBox) {
+            size_t headerSize;
+
+            switch (editTrack(mCurrentTrackID)->mMediaHandlerType) {
+                case FOURCC('v', 'i', 'd', 'e'):
+                {
+                    // 8 bytes SampleEntry + 70 bytes VisualSampleEntry
+                    headerSize = 78;
+                    break;
+                }
+
+                case FOURCC('s', 'o', 'u', 'n'):
+                {
+                    // 8 bytes SampleEntry + 20 bytes AudioSampleEntry
+                    headerSize = 28;
+                    break;
+                }
+
+                case FOURCC('m', 'e', 't', 'a'):
+                {
+                    headerSize = 8;  // 8 bytes SampleEntry
+                    break;
+                }
+
+                default:
+                    TRESPASS();
+            }
+
+            if (offset + headerSize > size) {
+                return -EINVAL;
+            }
+
+            if ((err = need(offset + headerSize)) != OK) {
+                return err;
+            }
+
+            switch (editTrack(mCurrentTrackID)->mMediaHandlerType) {
+                case FOURCC('v', 'i', 'd', 'e'):
+                {
+                    err = parseVisualSampleEntry(
+                            type, offset, offset + headerSize);
+                    break;
+                }
+
+                case FOURCC('s', 'o', 'u', 'n'):
+                {
+                    err = parseAudioSampleEntry(
+                            type, offset, offset + headerSize);
+                    break;
+                }
+
+                case FOURCC('m', 'e', 't', 'a'):
+                {
+                    err = OK;
+                    break;
+                }
+
+                default:
+                    TRESPASS();
+            }
+
+            if (err != OK) {
+                return err;
+            }
+
+            offset += headerSize;
+        }
+
+        skip(offset);
+
+        ALOGV("%sentering box of type '%s'",
+                IndentString(mStack.size()), Fourcc2String(type));
+
+        enter(type, size - offset);
+    } else {
+        if (!fitsContainer(size)) {
+            return -EINVAL;
+        }
+
+        if (i < kNumDispatchers && kDispatchTable[i].mHandler != 0) {
+            // We have a handler for this box type.
+
+            if ((err = need(size)) != OK) {
+                return err;
+            }
+
+            ALOGV("%sparsing box of type '%s'",
+                    IndentString(mStack.size()), Fourcc2String(type));
+
+            if ((err = (this->*kDispatchTable[i].mHandler)(
+                            type, offset, size)) != OK) {
+                return err;
+            }
+        } else {
+            // Unknown box type
+
+            ALOGV("%sskipping box of type '%s', size %llu",
+                    IndentString(mStack.size()),
+                    Fourcc2String(type), size);
+
+        }
+
+        skip(size);
+    }
+
+    return OK;
+}
+
+// static
+int Parser::CompareSampleLocation(
+        const SampleInfo &sample, const MediaDataInfo &mdatInfo) {
+    if (sample.mOffset + sample.mSize < mdatInfo.mOffset) {
+        return -1;
+    }
+
+    if (sample.mOffset >= mdatInfo.mOffset + mdatInfo.mBuffer->size()) {
+        return 1;
+    }
+
+    // Otherwise make sure the sample is completely contained within this
+    // media data block.
+
+    CHECK_GE(sample.mOffset, mdatInfo.mOffset);
+
+    CHECK_LE(sample.mOffset + sample.mSize,
+             mdatInfo.mOffset + mdatInfo.mBuffer->size());
+
+    return 0;
+}
+
+void Parser::resumeIfNecessary() {
+    if (!mSuspended) {
+        return;
+    }
+
+    ALOGI("resuming.");
+
+    mSuspended = false;
+    (new AMessage(kWhatProceed, id()))->post();
+}
+
+status_t Parser::getSample(
+        TrackInfo *info, sp<TrackFragment> *fragment, SampleInfo *sampleInfo) {
+    for (;;) {
+        if (info->mFragments.empty()) {
+            resumeIfNecessary();
+            return -EWOULDBLOCK;
+        }
+
+        *fragment = *info->mFragments.begin();
+
+        status_t err = (*fragment)->getSample(sampleInfo);
+
+        if (err == OK) {
+            return OK;
+        } else if (err != ERROR_END_OF_STREAM) {
+            return err;
+        }
+
+        // Really, end of this fragment...
+
+        info->mFragments.erase(info->mFragments.begin());
+    }
+}
+
+status_t Parser::onDequeueAccessUnit(
+        size_t trackIndex, sp<ABuffer> *accessUnit) {
+    TrackInfo *info = &mTracks.editValueAt(trackIndex);
+
+    sp<TrackFragment> fragment;
+    SampleInfo sampleInfo;
+    status_t err = getSample(info, &fragment, &sampleInfo);
+
+    if (err == -EWOULDBLOCK) {
+        resumeIfNecessary();
+        return err;
+    } else if (err != OK) {
+        return err;
+    }
+
+    err = -EWOULDBLOCK;
+
+    bool checkDroppable = false;
+
+    for (size_t i = 0; i < mMediaData.size(); ++i) {
+        const MediaDataInfo &mdatInfo = mMediaData.itemAt(i);
+
+        int cmp = CompareSampleLocation(sampleInfo, mdatInfo);
+
+        if (cmp < 0) {
+            return -EPIPE;
+        } else if (cmp == 0) {
+            if (i > 0) {
+                checkDroppable = true;
+            }
+
+            err = makeAccessUnit(info, sampleInfo, mdatInfo, accessUnit);
+            break;
+        }
+    }
+
+    if (err != OK) {
+        return err;
+    }
+
+    fragment->advance();
+
+    if (!mMediaData.empty() && checkDroppable) {
+        size_t numDroppable = 0;
+        bool done = false;
+
+        for (size_t i = 0; !done && i < mMediaData.size(); ++i) {
+            const MediaDataInfo &mdatInfo = mMediaData.itemAt(i);
+
+            for (size_t j = 0; j < mTracks.size(); ++j) {
+                TrackInfo *info = &mTracks.editValueAt(j);
+
+                sp<TrackFragment> fragment;
+                SampleInfo sampleInfo;
+                err = getSample(info, &fragment, &sampleInfo);
+
+                if (err != OK) {
+                    done = true;
+                    break;
+                }
+
+                int cmp = CompareSampleLocation(sampleInfo, mdatInfo);
+
+                if (cmp <= 0) {
+                    done = true;
+                    break;
+                }
+            }
+
+            if (!done) {
+                ++numDroppable;
+            }
+        }
+
+        if (numDroppable > 0) {
+            mMediaData.removeItemsAt(0, numDroppable);
+
+            if (mMediaData.size() < 5) {
+                resumeIfNecessary();
+            }
+        }
+    }
+
+    return err;
+}
+
+static size_t parseNALSize(size_t nalLengthSize, const uint8_t *data) {
+    switch (nalLengthSize) {
+        case 1:
+            return *data;
+        case 2:
+            return U16_AT(data);
+        case 3:
+            return ((size_t)data[0] << 16) | U16_AT(&data[1]);
+        case 4:
+            return U32_AT(data);
+    }
+
+    // This cannot happen, mNALLengthSize springs to life by adding 1 to
+    // a 2-bit integer.
+    TRESPASS();
+
+    return 0;
+}
+
+status_t Parser::makeAccessUnit(
+        TrackInfo *info,
+        const SampleInfo &sample,
+        const MediaDataInfo &mdatInfo,
+        sp<ABuffer> *accessUnit) {
+    if (sample.mSampleDescIndex < 1
+            || sample.mSampleDescIndex > info->mSampleDescs.size()) {
+        return ERROR_MALFORMED;
+    }
+
+    int64_t presentationTimeUs =
+        1000000ll * sample.mPresentationTime / info->mMediaTimeScale;
+
+    const SampleDescription &sampleDesc =
+        info->mSampleDescs.itemAt(sample.mSampleDescIndex - 1);
+
+    size_t nalLengthSize;
+    if (!sampleDesc.mFormat->findSize("nal-length-size", &nalLengthSize)) {
+        *accessUnit = new ABuffer(sample.mSize);
+
+        memcpy((*accessUnit)->data(),
+               mdatInfo.mBuffer->data() + (sample.mOffset - mdatInfo.mOffset),
+               sample.mSize);
+
+        (*accessUnit)->meta()->setInt64("timeUs", presentationTimeUs);
+        return OK;
+    }
+
+    const uint8_t *srcPtr =
+        mdatInfo.mBuffer->data() + (sample.mOffset - mdatInfo.mOffset);
+
+    for (int i = 0; i < 2 ; ++i) {
+        size_t srcOffset = 0;
+        size_t dstOffset = 0;
+
+        while (srcOffset < sample.mSize) {
+            if (srcOffset + nalLengthSize > sample.mSize) {
+                return ERROR_MALFORMED;
+            }
+
+            size_t nalSize = parseNALSize(nalLengthSize, &srcPtr[srcOffset]);
+            srcOffset += nalLengthSize;
+
+            if (srcOffset + nalSize > sample.mSize) {
+                return ERROR_MALFORMED;
+            }
+
+            if (i == 1) {
+                memcpy((*accessUnit)->data() + dstOffset,
+                       "\x00\x00\x00\x01",
+                       4);
+
+                memcpy((*accessUnit)->data() + dstOffset + 4,
+                       srcPtr + srcOffset,
+                       nalSize);
+            }
+
+            srcOffset += nalSize;
+            dstOffset += nalSize + 4;
+        }
+
+        if (i == 0) {
+            (*accessUnit) = new ABuffer(dstOffset);
+            (*accessUnit)->meta()->setInt64(
+                    "timeUs", presentationTimeUs);
+        }
+    }
+
+    return OK;
+}
+
+status_t Parser::need(size_t size) {
+    if (!fitsContainer(size)) {
+        return -EINVAL;
+    }
+
+    if (size <= mBuffer->size()) {
+        return OK;
+    }
+
+    sp<AMessage> msg = new AMessage(kWhatReadMore, id());
+    msg->setSize("needed", size - mBuffer->size());
+    msg->post();
+
+    // ALOGV("need(%d) returning -EAGAIN, only have %d", size, mBuffer->size());
+
+    return -EAGAIN;
+}
+
+void Parser::enter(uint32_t type, uint64_t size) {
+    Container container;
+    container.mType = type;
+    container.mExtendsToEOF = (size == 0);
+    container.mBytesRemaining = size;
+
+    mStack.push(container);
+}
+
+bool Parser::fitsContainer(uint64_t size) const {
+    CHECK(!mStack.isEmpty());
+    const Container &container = mStack.itemAt(mStack.size() - 1);
+
+    return container.mExtendsToEOF || size <= container.mBytesRemaining;
+}
+
+uint16_t Parser::readU16(size_t offset) {
+    CHECK_LE(offset + 2, mBuffer->size());
+
+    const uint8_t *ptr = mBuffer->data() + offset;
+    return (ptr[0] << 8) | ptr[1];
+}
+
+uint32_t Parser::readU32(size_t offset) {
+    CHECK_LE(offset + 4, mBuffer->size());
+
+    const uint8_t *ptr = mBuffer->data() + offset;
+    return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];
+}
+
+uint64_t Parser::readU64(size_t offset) {
+    return (((uint64_t)readU32(offset)) << 32) | readU32(offset + 4);
+}
+
+void Parser::skip(off_t distance) {
+    CHECK(!mStack.isEmpty());
+    for (size_t i = mStack.size(); i-- > 0;) {
+        Container *container = &mStack.editItemAt(i);
+        if (!container->mExtendsToEOF) {
+            CHECK_LE(distance, (off_t)container->mBytesRemaining);
+
+            container->mBytesRemaining -= distance;
+
+            if (container->mBytesRemaining == 0) {
+                ALOGV("%sleaving box of type '%s'",
+                        IndentString(mStack.size() - 1),
+                        Fourcc2String(container->mType));
+
+#if 0
+                if (container->mType == FOURCC('s', 't', 's', 'd')) {
+                    TrackInfo *trackInfo = editTrack(mCurrentTrackID);
+                    for (size_t i = 0;
+                            i < trackInfo->mSampleDescs.size(); ++i) {
+                        ALOGI("format #%d: %s",
+                              i,
+                              trackInfo->mSampleDescs.itemAt(i)
+                                .mFormat->debugString().c_str());
+                    }
+                }
+#endif
+
+                if (container->mType == FOURCC('s', 't', 'b', 'l')) {
+                    TrackInfo *trackInfo = editTrack(mCurrentTrackID);
+
+                    trackInfo->mStaticFragment->signalCompletion();
+
+                    CHECK(trackInfo->mFragments.empty());
+                    trackInfo->mFragments.push_back(trackInfo->mStaticFragment);
+                    trackInfo->mStaticFragment.clear();
+                } else if (container->mType == FOURCC('t', 'r', 'a', 'f')) {
+                    TrackInfo *trackInfo =
+                        editTrack(mTrackFragmentHeaderInfo.mTrackID);
+
+                    const sp<TrackFragment> &fragment =
+                        *--trackInfo->mFragments.end();
+
+                    static_cast<DynamicTrackFragment *>(
+                            fragment.get())->signalCompletion();
+                }
+
+                container = NULL;
+                mStack.removeItemsAt(i);
+            }
+        }
+    }
+
+    if (distance < (off_t)mBuffer->size()) {
+        mBuffer->setRange(mBuffer->offset() + distance, mBuffer->size() - distance);
+        mBufferPos += distance;
+        return;
+    }
+
+    mBuffer->setRange(0, 0);
+    mBufferPos += distance;
+}
+
+status_t Parser::parseTrackHeader(
+        uint32_t type, size_t offset, uint64_t size) {
+    if (offset + 4 > size) {
+        return -EINVAL;
+    }
+
+    uint32_t flags = readU32(offset);
+
+    uint32_t version = flags >> 24;
+    flags &= 0xffffff;
+
+    uint32_t trackID;
+    uint64_t duration;
+
+    if (version == 1) {
+        if (offset + 36 > size) {
+            return -EINVAL;
+        }
+
+        trackID = readU32(offset + 20);
+        duration = readU64(offset + 28);
+
+        offset += 36;
+    } else if (version == 0) {
+        if (offset + 24 > size) {
+            return -EINVAL;
+        }
+
+        trackID = readU32(offset + 12);
+        duration = readU32(offset + 20);
+
+        offset += 24;
+    } else {
+        return -EINVAL;
+    }
+
+    TrackInfo *info = editTrack(trackID, true /* createIfNecessary */);
+    info->mFlags = flags;
+    info->mDuration = duration;
+
+    info->mStaticFragment = new StaticTrackFragment;
+
+    mCurrentTrackID = trackID;
+
+    return OK;
+}
+
+status_t Parser::parseMediaHeader(
+        uint32_t type, size_t offset, uint64_t size) {
+    if (offset + 4 > size) {
+        return -EINVAL;
+    }
+
+    uint32_t versionAndFlags = readU32(offset);
+
+    if (versionAndFlags & 0xffffff) {
+        return ERROR_MALFORMED;
+    }
+
+    uint32_t version = versionAndFlags >> 24;
+
+    TrackInfo *info = editTrack(mCurrentTrackID);
+
+    if (version == 1) {
+        if (offset + 4 + 32 > size) {
+            return -EINVAL;
+        }
+        info->mMediaTimeScale = U32_AT(mBuffer->data() + offset + 20);
+    } else if (version == 0) {
+        if (offset + 4 + 20 > size) {
+            return -EINVAL;
+        }
+        info->mMediaTimeScale = U32_AT(mBuffer->data() + offset + 12);
+    } else {
+        return ERROR_MALFORMED;
+    }
+
+    return OK;
+}
+
+status_t Parser::parseMediaHandler(
+        uint32_t type, size_t offset, uint64_t size) {
+    if (offset + 12 > size) {
+        return -EINVAL;
+    }
+
+    if (readU32(offset) != 0) {
+        return -EINVAL;
+    }
+
+    uint32_t handlerType = readU32(offset + 8);
+
+    switch (handlerType) {
+        case FOURCC('v', 'i', 'd', 'e'):
+        case FOURCC('s', 'o', 'u', 'n'):
+        case FOURCC('h', 'i', 'n', 't'):
+        case FOURCC('m', 'e', 't', 'a'):
+            break;
+
+        default:
+            return -EINVAL;
+    }
+
+    editTrack(mCurrentTrackID)->mMediaHandlerType = handlerType;
+
+    return OK;
+}
+
+status_t Parser::parseVisualSampleEntry(
+        uint32_t type, size_t offset, uint64_t size) {
+    if (offset + 78 > size) {
+        return -EINVAL;
+    }
+
+    TrackInfo *trackInfo = editTrack(mCurrentTrackID);
+
+    trackInfo->mSampleDescs.push();
+    SampleDescription *sampleDesc =
+        &trackInfo->mSampleDescs.editItemAt(
+                trackInfo->mSampleDescs.size() - 1);
+
+    sampleDesc->mType = type;
+    sampleDesc->mDataRefIndex = readU16(offset + 6);
+
+    sp<AMessage> format = new AMessage;
+
+    switch (type) {
+        case FOURCC('a', 'v', 'c', '1'):
+            format->setString("mime", MEDIA_MIMETYPE_VIDEO_AVC);
+            break;
+        case FOURCC('m', 'p', '4', 'v'):
+            format->setString("mime", MEDIA_MIMETYPE_VIDEO_MPEG4);
+            break;
+        default:
+            format->setString("mime", "application/octet-stream");
+            break;
+    }
+
+    format->setInt32("width", readU16(offset + 8 + 16));
+    format->setInt32("height", readU16(offset + 8 + 18));
+
+    sampleDesc->mFormat = format;
+
+    return OK;
+}
+
+status_t Parser::parseAudioSampleEntry(
+        uint32_t type, size_t offset, uint64_t size) {
+    if (offset + 28 > size) {
+        return -EINVAL;
+    }
+
+    TrackInfo *trackInfo = editTrack(mCurrentTrackID);
+
+    trackInfo->mSampleDescs.push();
+    SampleDescription *sampleDesc =
+        &trackInfo->mSampleDescs.editItemAt(
+                trackInfo->mSampleDescs.size() - 1);
+
+    sampleDesc->mType = type;
+    sampleDesc->mDataRefIndex = readU16(offset + 6);
+
+    sp<AMessage> format = new AMessage;
+
+    format->setInt32("channel-count", readU16(offset + 8 + 8));
+    format->setInt32("sample-size", readU16(offset + 8 + 10));
+    format->setInt32("sample-rate", readU32(offset + 8 + 16) / 65536.0f);
+
+    switch (type) {
+        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);
+            format->setInt32("sample-rate", 16000);
+            break;
+        default:
+            format->setString("mime", "application/octet-stream");
+            break;
+    }
+
+    sampleDesc->mFormat = format;
+
+    return OK;
+}
+
+static void addCodecSpecificData(
+        const sp<AMessage> &format, int32_t index,
+        const void *data, size_t size,
+        bool insertStartCode = false) {
+    sp<ABuffer> csd = new ABuffer(insertStartCode ? size + 4 : size);
+
+    memcpy(csd->data() + (insertStartCode ? 4 : 0), data, size);
+
+    if (insertStartCode) {
+        memcpy(csd->data(), "\x00\x00\x00\x01", 4);
+    }
+
+    csd->meta()->setInt32("csd", true);
+    csd->meta()->setInt64("timeUs", 0ll);
+
+    format->setBuffer(StringPrintf("csd-%d", index).c_str(), csd);
+}
+
+status_t Parser::parseSampleSizes(
+        uint32_t type, size_t offset, uint64_t size) {
+    return editTrack(mCurrentTrackID)->mStaticFragment->parseSampleSizes(
+            this, type, offset, size);
+}
+
+status_t Parser::parseCompactSampleSizes(
+        uint32_t type, size_t offset, uint64_t size) {
+    return editTrack(mCurrentTrackID)->mStaticFragment->parseCompactSampleSizes(
+            this, type, offset, size);
+}
+
+status_t Parser::parseSampleToChunk(
+        uint32_t type, size_t offset, uint64_t size) {
+    return editTrack(mCurrentTrackID)->mStaticFragment->parseSampleToChunk(
+            this, type, offset, size);
+}
+
+status_t Parser::parseChunkOffsets(
+        uint32_t type, size_t offset, uint64_t size) {
+    return editTrack(mCurrentTrackID)->mStaticFragment->parseChunkOffsets(
+            this, type, offset, size);
+}
+
+status_t Parser::parseChunkOffsets64(
+        uint32_t type, size_t offset, uint64_t size) {
+    return editTrack(mCurrentTrackID)->mStaticFragment->parseChunkOffsets64(
+            this, type, offset, size);
+}
+
+status_t Parser::parseAVCCodecSpecificData(
+        uint32_t type, size_t offset, uint64_t size) {
+    TrackInfo *trackInfo = editTrack(mCurrentTrackID);
+
+    SampleDescription *sampleDesc =
+        &trackInfo->mSampleDescs.editItemAt(
+                trackInfo->mSampleDescs.size() - 1);
+
+    if (sampleDesc->mType != FOURCC('a', 'v', 'c', '1')) {
+        return -EINVAL;
+    }
+
+    const uint8_t *ptr = mBuffer->data() + offset;
+
+    size -= offset;
+    offset = 0;
+
+    if (size < 7 || ptr[0] != 0x01) {
+        return ERROR_MALFORMED;
+    }
+
+    sampleDesc->mFormat->setSize("nal-length-size", 1 + (ptr[4] & 3));
+
+    size_t numSPS = ptr[5] & 31;
+
+    ptr += 6;
+    size -= 6;
+
+    for (size_t i = 0; i < numSPS; ++i) {
+        if (size < 2) {
+            return ERROR_MALFORMED;
+        }
+
+        size_t length = U16_AT(ptr);
+
+        ptr += 2;
+        size -= 2;
+
+        if (size < length) {
+            return ERROR_MALFORMED;
+        }
+
+        addCodecSpecificData(
+                sampleDesc->mFormat, i, ptr, length,
+                true /* insertStartCode */);
+
+        ptr += length;
+        size -= length;
+    }
+
+    if (size < 1) {
+        return ERROR_MALFORMED;
+    }
+
+    size_t numPPS = *ptr;
+    ++ptr;
+    --size;
+
+    for (size_t i = 0; i < numPPS; ++i) {
+        if (size < 2) {
+            return ERROR_MALFORMED;
+        }
+
+        size_t length = U16_AT(ptr);
+
+        ptr += 2;
+        size -= 2;
+
+        if (size < length) {
+            return ERROR_MALFORMED;
+        }
+
+        addCodecSpecificData(
+                sampleDesc->mFormat, numSPS + i, ptr, length,
+                true /* insertStartCode */);
+
+        ptr += length;
+        size -= length;
+    }
+
+    return OK;
+}
+
+status_t Parser::parseESDSCodecSpecificData(
+        uint32_t type, size_t offset, uint64_t size) {
+    TrackInfo *trackInfo = editTrack(mCurrentTrackID);
+
+    SampleDescription *sampleDesc =
+        &trackInfo->mSampleDescs.editItemAt(
+                trackInfo->mSampleDescs.size() - 1);
+
+    if (sampleDesc->mType != FOURCC('m', 'p', '4', 'a')
+            && sampleDesc->mType != FOURCC('m', 'p', '4', 'v')) {
+        return -EINVAL;
+    }
+
+    const uint8_t *ptr = mBuffer->data() + offset;
+
+    size -= offset;
+    offset = 0;
+
+    if (size < 4) {
+        return -EINVAL;
+    }
+
+    if (U32_AT(ptr) != 0) {
+        return -EINVAL;
+    }
+
+    ptr += 4;
+    size -=4;
+
+    ESDS esds(ptr, size);
+
+    uint8_t objectTypeIndication;
+    if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) {
+        return ERROR_MALFORMED;
+    }
+
+    const uint8_t *csd;
+    size_t csd_size;
+    if (esds.getCodecSpecificInfo(
+                (const void **)&csd, &csd_size) != OK) {
+        return ERROR_MALFORMED;
+    }
+
+    addCodecSpecificData(sampleDesc->mFormat, 0, csd, csd_size);
+
+    if (sampleDesc->mType != FOURCC('m', 'p', '4', 'a')) {
+        return OK;
+    }
+
+    if (csd_size == 0) {
+        // There's no further information, i.e. no codec specific data
+        // Let's assume that the information provided in the mpeg4 headers
+        // is accurate and hope for the best.
+
+        return OK;
+    }
+
+    if (csd_size < 2) {
+        return ERROR_MALFORMED;
+    }
+
+    uint32_t objectType = csd[0] >> 3;
+
+    if (objectType == 31) {
+        return ERROR_UNSUPPORTED;
+    }
+
+    uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7);
+    int32_t sampleRate = 0;
+    int32_t numChannels = 0;
+    if (freqIndex == 15) {
+        if (csd_size < 5) {
+            return ERROR_MALFORMED;
+        }
+
+        sampleRate = (csd[1] & 0x7f) << 17
+                        | csd[2] << 9
+                        | csd[3] << 1
+                        | (csd[4] >> 7);
+
+        numChannels = (csd[4] >> 3) & 15;
+    } else {
+        static uint32_t kSamplingRate[] = {
+            96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
+            16000, 12000, 11025, 8000, 7350
+        };
+
+        if (freqIndex == 13 || freqIndex == 14) {
+            return ERROR_MALFORMED;
+        }
+
+        sampleRate = kSamplingRate[freqIndex];
+        numChannels = (csd[1] >> 3) & 15;
+    }
+
+    if (numChannels == 0) {
+        return ERROR_UNSUPPORTED;
+    }
+
+    sampleDesc->mFormat->setInt32("sample-rate", sampleRate);
+    sampleDesc->mFormat->setInt32("channel-count", numChannels);
+
+    return OK;
+}
+
+status_t Parser::parseMediaData(
+        uint32_t type, size_t offset, uint64_t size) {
+    ALOGV("skipping 'mdat' chunk at offsets 0x%08lx-0x%08llx.",
+          mBufferPos + offset, mBufferPos + size);
+
+    sp<ABuffer> buffer = new ABuffer(size - offset);
+    memcpy(buffer->data(), mBuffer->data() + offset, size - offset);
+
+    mMediaData.push();
+    MediaDataInfo *info = &mMediaData.editItemAt(mMediaData.size() - 1);
+    info->mBuffer = buffer;
+    info->mOffset = mBufferPos + offset;
+
+    if (mMediaData.size() > 10) {
+        ALOGI("suspending for now.");
+        mSuspended = true;
+    }
+
+    return OK;
+}
+
+status_t Parser::parseTrackExtends(
+        uint32_t type, size_t offset, uint64_t size) {
+    if (offset + 24 > size) {
+        return -EINVAL;
+    }
+
+    if (readU32(offset) != 0) {
+        return -EINVAL;
+    }
+
+    uint32_t trackID = readU32(offset + 4);
+
+    TrackInfo *info = editTrack(trackID, true /* createIfNecessary */);
+    info->mDefaultSampleDescriptionIndex = readU32(offset + 8);
+    info->mDefaultSampleDuration = readU32(offset + 12);
+    info->mDefaultSampleSize = readU32(offset + 16);
+    info->mDefaultSampleFlags = readU32(offset + 20);
+
+    return OK;
+}
+
+Parser::TrackInfo *Parser::editTrack(
+        uint32_t trackID, bool createIfNecessary) {
+    ssize_t i = mTracks.indexOfKey(trackID);
+
+    if (i >= 0) {
+        return &mTracks.editValueAt(i);
+    }
+
+    if (!createIfNecessary) {
+        return NULL;
+    }
+
+    TrackInfo info;
+    info.mTrackID = trackID;
+    info.mFlags = 0;
+    info.mDuration = 0xffffffff;
+    info.mMediaTimeScale = 0;
+    info.mMediaHandlerType = 0;
+    info.mDefaultSampleDescriptionIndex = 0;
+    info.mDefaultSampleDuration = 0;
+    info.mDefaultSampleSize = 0;
+    info.mDefaultSampleFlags = 0;
+
+    info.mDecodingTime = 0;
+
+    mTracks.add(trackID, info);
+    return &mTracks.editValueAt(mTracks.indexOfKey(trackID));
+}
+
+status_t Parser::parseTrackFragmentHeader(
+        uint32_t type, size_t offset, uint64_t size) {
+    if (offset + 8 > size) {
+        return -EINVAL;
+    }
+
+    uint32_t flags = readU32(offset);
+
+    if (flags & 0xff000000) {
+        return -EINVAL;
+    }
+
+    mTrackFragmentHeaderInfo.mFlags = flags;
+
+    mTrackFragmentHeaderInfo.mTrackID = readU32(offset + 4);
+    offset += 8;
+
+    if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) {
+        if (offset + 8 > size) {
+            return -EINVAL;
+        }
+
+        mTrackFragmentHeaderInfo.mBaseDataOffset = readU64(offset);
+        offset += 8;
+    }
+
+    if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) {
+        if (offset + 4 > size) {
+            return -EINVAL;
+        }
+
+        mTrackFragmentHeaderInfo.mSampleDescriptionIndex = readU32(offset);
+        offset += 4;
+    }
+
+    if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
+        if (offset + 4 > size) {
+            return -EINVAL;
+        }
+
+        mTrackFragmentHeaderInfo.mDefaultSampleDuration = readU32(offset);
+        offset += 4;
+    }
+
+    if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
+        if (offset + 4 > size) {
+            return -EINVAL;
+        }
+
+        mTrackFragmentHeaderInfo.mDefaultSampleSize = readU32(offset);
+        offset += 4;
+    }
+
+    if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
+        if (offset + 4 > size) {
+            return -EINVAL;
+        }
+
+        mTrackFragmentHeaderInfo.mDefaultSampleFlags = readU32(offset);
+        offset += 4;
+    }
+
+    if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) {
+        CHECK(!mStack.isEmpty());
+
+        // This should point to the start of the data inside the 'mdat' box
+        // following the current 'moof' box.
+
+        mTrackFragmentHeaderInfo.mBaseDataOffset =
+            mBufferPos + mStack.itemAt(mStack.size() - 1).mBytesRemaining + 8;
+    }
+
+    mTrackFragmentHeaderInfo.mDataOffset =
+        mTrackFragmentHeaderInfo.mBaseDataOffset;
+
+    TrackInfo *trackInfo = editTrack(mTrackFragmentHeaderInfo.mTrackID);
+
+    if (trackInfo->mFragments.empty()
+            || (*trackInfo->mFragments.begin())->complete()) {
+        trackInfo->mFragments.push_back(new DynamicTrackFragment);
+    }
+
+    return OK;
+}
+
+status_t Parser::parseTrackFragmentRun(
+        uint32_t type, size_t offset, uint64_t size) {
+    if (offset + 8 > size) {
+        return -EINVAL;
+    }
+
+    enum {
+        kDataOffsetPresent                  = 0x01,
+        kFirstSampleFlagsPresent            = 0x04,
+        kSampleDurationPresent              = 0x100,
+        kSampleSizePresent                  = 0x200,
+        kSampleFlagsPresent                 = 0x400,
+        kSampleCompositionTimeOffsetPresent = 0x800,
+    };
+
+    uint32_t flags = readU32(offset);
+
+    if (flags & 0xff000000) {
+        return -EINVAL;
+    }
+
+    if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) {
+        // These two shall not be used together.
+        return -EINVAL;
+    }
+
+    uint32_t sampleCount = readU32(offset + 4);
+    offset += 8;
+
+    uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset;
+
+    uint32_t firstSampleFlags = 0;
+
+    if (flags & kDataOffsetPresent) {
+        if (offset + 4 > size) {
+            return -EINVAL;
+        }
+
+        int32_t dataOffsetDelta = (int32_t)readU32(offset);
+
+        dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta;
+
+        offset += 4;
+    }
+
+    if (flags & kFirstSampleFlagsPresent) {
+        if (offset + 4 > size) {
+            return -EINVAL;
+        }
+
+        firstSampleFlags = readU32(offset);
+        offset += 4;
+    }
+
+    TrackInfo *info = editTrack(mTrackFragmentHeaderInfo.mTrackID);
+
+    if (info == NULL) {
+        return -EINVAL;
+    }
+
+    uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0,
+             sampleCtsOffset = 0;
+
+    size_t bytesPerSample = 0;
+    if (flags & kSampleDurationPresent) {
+        bytesPerSample += 4;
+    } else if (mTrackFragmentHeaderInfo.mFlags
+            & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
+        sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration;
+    } else {
+        sampleDuration = info->mDefaultSampleDuration;
+    }
+
+    if (flags & kSampleSizePresent) {
+        bytesPerSample += 4;
+    } else if (mTrackFragmentHeaderInfo.mFlags
+            & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
+        sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
+    } else {
+        sampleSize = info->mDefaultSampleSize;
+    }
+
+    if (flags & kSampleFlagsPresent) {
+        bytesPerSample += 4;
+    } else if (mTrackFragmentHeaderInfo.mFlags
+            & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
+        sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
+    } else {
+        sampleFlags = info->mDefaultSampleFlags;
+    }
+
+    if (flags & kSampleCompositionTimeOffsetPresent) {
+        bytesPerSample += 4;
+    } else {
+        sampleCtsOffset = 0;
+    }
+
+    if (offset + sampleCount * bytesPerSample > size) {
+        return -EINVAL;
+    }
+
+    uint32_t sampleDescIndex =
+        (mTrackFragmentHeaderInfo.mFlags
+            & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent)
+            ? mTrackFragmentHeaderInfo.mSampleDescriptionIndex
+            : info->mDefaultSampleDescriptionIndex;
+
+    for (uint32_t i = 0; i < sampleCount; ++i) {
+        if (flags & kSampleDurationPresent) {
+            sampleDuration = readU32(offset);
+            offset += 4;
+        }
+
+        if (flags & kSampleSizePresent) {
+            sampleSize = readU32(offset);
+            offset += 4;
+        }
+
+        if (flags & kSampleFlagsPresent) {
+            sampleFlags = readU32(offset);
+            offset += 4;
+        }
+
+        if (flags & kSampleCompositionTimeOffsetPresent) {
+            sampleCtsOffset = readU32(offset);
+            offset += 4;
+        }
+
+        ALOGV("adding sample at offset 0x%08llx, size %u, duration %u, "
+              "sampleDescIndex=%u, flags 0x%08x",
+                dataOffset, sampleSize, sampleDuration,
+                sampleDescIndex,
+                (flags & kFirstSampleFlagsPresent) && i == 0
+                    ? firstSampleFlags : sampleFlags);
+
+        const sp<TrackFragment> &fragment = *--info->mFragments.end();
+
+        uint32_t decodingTime = info->mDecodingTime;
+        info->mDecodingTime += sampleDuration;
+        uint32_t presentationTime = decodingTime + sampleCtsOffset;
+
+        static_cast<DynamicTrackFragment *>(
+                fragment.get())->addSample(
+                    dataOffset,
+                    sampleSize,
+                    presentationTime,
+                    sampleDescIndex,
+                    ((flags & kFirstSampleFlagsPresent) && i == 0)
+                        ? firstSampleFlags : sampleFlags);
+
+        dataOffset += sampleSize;
+    }
+
+    mTrackFragmentHeaderInfo.mDataOffset = dataOffset;
+
+    return OK;
+}
+
+void Parser::copyBuffer(
+        sp<ABuffer> *dst, size_t offset, uint64_t size, size_t extra) const {
+    sp<ABuffer> buf = new ABuffer(size + extra);
+    memcpy(buf->data(), mBuffer->data() + offset, size);
+
+    *dst = buf;
+}
+
+}  // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/mp4/Parser.h b/media/libmediaplayerservice/nuplayer/mp4/Parser.h
new file mode 100644
index 0000000..50c96bb
--- /dev/null
+++ b/media/libmediaplayerservice/nuplayer/mp4/Parser.h
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PARSER_H_
+
+#define PARSER_H_
+
+#include <media/stagefright/foundation/AHandler.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+struct ABuffer;
+
+struct Parser : public AHandler {
+    struct Source : public RefBase {
+        Source() {}
+
+        virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;
+
+        protected:
+        virtual ~Source() {}
+
+        private:
+        DISALLOW_EVIL_CONSTRUCTORS(Source);
+    };
+
+    Parser();
+
+    void start(const char *filename);
+    void start(const sp<Source> &source);
+
+    sp<AMessage> getFormat(bool audio);
+    status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
+
+    virtual void onMessageReceived(const sp<AMessage> &msg);
+
+protected:
+    virtual ~Parser();
+
+private:
+    enum {
+        kWhatStart,
+        kWhatProceed,
+        kWhatReadMore,
+        kWhatGetFormat,
+        kWhatDequeueAccessUnit,
+    };
+
+    struct TrackFragment;
+    struct DynamicTrackFragment;
+    struct StaticTrackFragment;
+
+    struct DispatchEntry {
+        uint32_t mType;
+        uint32_t mParentType;
+        status_t (Parser::*mHandler)(uint32_t, size_t, uint64_t);
+    };
+
+    struct Container {
+        uint64_t mBytesRemaining;
+        uint32_t mType;
+        bool mExtendsToEOF;
+    };
+
+    struct SampleDescription {
+        uint32_t mType;
+        uint16_t mDataRefIndex;
+
+        sp<AMessage> mFormat;
+    };
+
+    struct SampleInfo {
+        off64_t mOffset;
+        size_t mSize;
+        uint32_t mPresentationTime;
+        size_t mSampleDescIndex;
+        uint32_t mFlags;
+    };
+
+    struct MediaDataInfo {
+        sp<ABuffer> mBuffer;
+        off64_t mOffset;
+    };
+
+    struct TrackInfo {
+        enum Flags {
+            kTrackEnabled     = 0x01,
+            kTrackInMovie     = 0x02,
+            kTrackInPreview   = 0x04,
+        };
+
+        uint32_t mTrackID;
+        uint32_t mFlags;
+        uint32_t mDuration;  // This is the duration in terms of movie timescale!
+
+        uint32_t mMediaTimeScale;
+
+        uint32_t mMediaHandlerType;
+        Vector<SampleDescription> mSampleDescs;
+
+        // from track extends:
+        uint32_t mDefaultSampleDescriptionIndex;
+        uint32_t mDefaultSampleDuration;
+        uint32_t mDefaultSampleSize;
+        uint32_t mDefaultSampleFlags;
+
+        uint32_t mDecodingTime;
+
+        sp<StaticTrackFragment> mStaticFragment;
+        List<sp<TrackFragment> > mFragments;
+    };
+
+    struct TrackFragmentHeaderInfo {
+        enum Flags {
+            kBaseDataOffsetPresent         = 0x01,
+            kSampleDescriptionIndexPresent = 0x02,
+            kDefaultSampleDurationPresent  = 0x08,
+            kDefaultSampleSizePresent      = 0x10,
+            kDefaultSampleFlagsPresent     = 0x20,
+            kDurationIsEmpty               = 0x10000,
+        };
+
+        uint32_t mTrackID;
+        uint32_t mFlags;
+        uint64_t mBaseDataOffset;
+        uint32_t mSampleDescriptionIndex;
+        uint32_t mDefaultSampleDuration;
+        uint32_t mDefaultSampleSize;
+        uint32_t mDefaultSampleFlags;
+
+        uint64_t mDataOffset;
+    };
+
+    static const DispatchEntry kDispatchTable[];
+
+    sp<Source> mSource;
+    off_t mBufferPos;
+    bool mSuspended;
+    sp<ABuffer> mBuffer;
+    Vector<Container> mStack;
+    KeyedVector<uint32_t, TrackInfo> mTracks;  // TrackInfo by trackID
+    Vector<MediaDataInfo> mMediaData;
+
+    uint32_t mCurrentTrackID;
+
+    TrackFragmentHeaderInfo mTrackFragmentHeaderInfo;
+
+    status_t onProceed();
+    status_t onDequeueAccessUnit(size_t trackIndex, sp<ABuffer> *accessUnit);
+
+    void enter(uint32_t type, uint64_t size);
+
+    uint16_t readU16(size_t offset);
+    uint32_t readU32(size_t offset);
+    uint64_t readU64(size_t offset);
+    void skip(off_t distance);
+    status_t need(size_t size);
+    bool fitsContainer(uint64_t size) const;
+
+    status_t parseTrackHeader(
+            uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseMediaHeader(
+            uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseMediaHandler(
+            uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseTrackExtends(
+            uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseTrackFragmentHeader(
+            uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseTrackFragmentRun(
+            uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseVisualSampleEntry(
+            uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseAudioSampleEntry(
+            uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseSampleSizes(
+            uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseCompactSampleSizes(
+            uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseSampleToChunk(
+            uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseChunkOffsets(
+            uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseChunkOffsets64(
+            uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseAVCCodecSpecificData(
+            uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseESDSCodecSpecificData(
+            uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseMediaData(
+            uint32_t type, size_t offset, uint64_t size);
+
+    TrackInfo *editTrack(uint32_t trackID, bool createIfNecessary = false);
+
+    ssize_t findTrack(bool wantAudio) const;
+
+    status_t makeAccessUnit(
+            TrackInfo *info,
+            const SampleInfo &sample,
+            const MediaDataInfo &mdatInfo,
+            sp<ABuffer> *accessUnit);
+
+    status_t getSample(
+            TrackInfo *info,
+            sp<TrackFragment> *fragment,
+            SampleInfo *sampleInfo);
+
+    static int CompareSampleLocation(
+        const SampleInfo &sample, const MediaDataInfo &mdatInfo);
+
+    void resumeIfNecessary();
+
+    void copyBuffer(
+            sp<ABuffer> *dst,
+            size_t offset, uint64_t size, size_t extra = 0) const;
+
+    DISALLOW_EVIL_CONSTRUCTORS(Parser);
+};
+
+}  // namespace android
+
+#endif  // PARSER_H_
+
diff --git a/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.cpp b/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.cpp
new file mode 100644
index 0000000..e2df468
--- /dev/null
+++ b/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.cpp
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "TrackFragment"
+#include <utils/Log.h>
+
+#include "TrackFragment.h"
+
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/Utils.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+
+namespace android {
+
+Parser::DynamicTrackFragment::DynamicTrackFragment()
+    : mComplete(false),
+      mSampleIndex(0) {
+}
+
+Parser::DynamicTrackFragment::~DynamicTrackFragment() {
+}
+
+status_t Parser::DynamicTrackFragment::getSample(SampleInfo *info) {
+    if (mSampleIndex >= mSamples.size()) {
+        return mComplete ? ERROR_END_OF_STREAM : -EWOULDBLOCK;
+    }
+
+    *info = mSamples.itemAt(mSampleIndex);
+
+    return OK;
+}
+
+void Parser::DynamicTrackFragment::advance() {
+    ++mSampleIndex;
+}
+
+void Parser::DynamicTrackFragment::addSample(
+        off64_t dataOffset, size_t sampleSize,
+        uint32_t presentationTime,
+        size_t sampleDescIndex,
+        uint32_t flags) {
+    mSamples.push();
+    SampleInfo *sampleInfo = &mSamples.editItemAt(mSamples.size() - 1);
+
+    sampleInfo->mOffset = dataOffset;
+    sampleInfo->mSize = sampleSize;
+    sampleInfo->mPresentationTime = presentationTime;
+    sampleInfo->mSampleDescIndex = sampleDescIndex;
+    sampleInfo->mFlags = flags;
+}
+
+status_t Parser::DynamicTrackFragment::signalCompletion() {
+    mComplete = true;
+
+    return OK;
+}
+
+bool Parser::DynamicTrackFragment::complete() const {
+    return mComplete;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+Parser::StaticTrackFragment::StaticTrackFragment()
+    : mSampleIndex(0),
+      mSampleCount(0),
+      mSampleToChunkIndex(-1),
+      mSampleToChunkRemaining(0),
+      mPrevChunkIndex(0xffffffff),
+      mNextSampleOffset(0) {
+}
+
+Parser::StaticTrackFragment::~StaticTrackFragment() {
+}
+
+status_t Parser::StaticTrackFragment::getSample(SampleInfo *info) {
+    if (mSampleIndex >= mSampleCount) {
+        return ERROR_END_OF_STREAM;
+    }
+
+    *info = mSampleInfo;
+
+    ALOGV("returning sample %d at [0x%08llx, 0x%08llx)",
+          mSampleIndex,
+          info->mOffset, info->mOffset + info->mSize);
+
+    return OK;
+}
+
+void Parser::StaticTrackFragment::updateSampleInfo() {
+    if (mSampleIndex >= mSampleCount) {
+        return;
+    }
+
+    if (mSampleSizes != NULL) {
+        uint32_t defaultSampleSize = U32_AT(mSampleSizes->data() + 4);
+        if (defaultSampleSize > 0) {
+            mSampleInfo.mSize = defaultSampleSize;
+        } else {
+            mSampleInfo.mSize= U32_AT(mSampleSizes->data() + 12 + 4 * mSampleIndex);
+        }
+    } else {
+        CHECK(mCompactSampleSizes != NULL);
+
+        uint32_t fieldSize = U32_AT(mCompactSampleSizes->data() + 4);
+
+        switch (fieldSize) {
+            case 4:
+            {
+                unsigned byte = mCompactSampleSizes->data()[12 + mSampleIndex / 2];
+                mSampleInfo.mSize = (mSampleIndex & 1) ? byte & 0x0f : byte >> 4;
+                break;
+            }
+
+            case 8:
+            {
+                mSampleInfo.mSize = mCompactSampleSizes->data()[12 + mSampleIndex];
+                break;
+            }
+
+            default:
+            {
+                CHECK_EQ(fieldSize, 16);
+                mSampleInfo.mSize =
+                    U16_AT(mCompactSampleSizes->data() + 12 + mSampleIndex * 2);
+                break;
+            }
+        }
+    }
+
+    CHECK_GT(mSampleToChunkRemaining, 0);
+
+    // The sample desc index is 1-based... XXX
+    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 (mChunkOffsets != NULL) {
+            uint32_t entryCount = U32_AT(mChunkOffsets->data() + 4);
+
+            if (chunkIndex >= entryCount) {
+                mSampleIndex = mSampleCount;
+                return;
+            }
+
+            mNextSampleOffset =
+                U32_AT(mChunkOffsets->data() + 8 + 4 * chunkIndex);
+        } else {
+            CHECK(mChunkOffsets64 != NULL);
+
+            uint32_t entryCount = U32_AT(mChunkOffsets64->data() + 4);
+
+            if (chunkIndex >= entryCount) {
+                mSampleIndex = mSampleCount;
+                return;
+            }
+
+            mNextSampleOffset =
+                U64_AT(mChunkOffsets64->data() + 8 + 8 * chunkIndex);
+        }
+    }
+
+    mSampleInfo.mOffset = mNextSampleOffset;
+
+    mSampleInfo.mPresentationTime = 0;
+    mSampleInfo.mFlags = 0;
+}
+
+void Parser::StaticTrackFragment::advance() {
+    mNextSampleOffset += mSampleInfo.mSize;
+
+    ++mSampleIndex;
+    if (--mSampleToChunkRemaining == 0) {
+        uint32_t entryCount = U32_AT(mSampleToChunk->data() + 4);
+
+        if ((uint32_t)(mSampleToChunkIndex + 1) == entryCount) {
+            mSampleIndex = mSampleCount;  // EOS.
+            return;
+        }
+
+        ++mSampleToChunkIndex;
+        mSampleToChunkRemaining =
+            U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 4);
+    }
+
+    updateSampleInfo();
+}
+
+static void setU32At(uint8_t *ptr, uint32_t x) {
+    ptr[0] = x >> 24;
+    ptr[1] = (x >> 16) & 0xff;
+    ptr[2] = (x >> 8) & 0xff;
+    ptr[3] = x & 0xff;
+}
+
+void Parser::StaticTrackFragment::fixSampleToChunkTableIfNecessary() {
+    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 =
+        U32_AT(mSampleToChunk->data() + 8 + 12 * mSampleToChunkIndex + 4);
+
+    updateSampleInfo();
+
+    return OK;
+}
+
+bool Parser::StaticTrackFragment::complete() const {
+    return true;
+}
+
+status_t Parser::StaticTrackFragment::parseSampleSizes(
+        Parser *parser, uint32_t type, size_t offset, uint64_t size) {
+    if (offset + 12 > size) {
+        return ERROR_MALFORMED;
+    }
+
+    if (parser->readU32(offset) != 0) {
+        return ERROR_MALFORMED;
+    }
+
+    uint32_t sampleSize = parser->readU32(offset + 4);
+    uint32_t sampleCount = parser->readU32(offset + 8);
+
+    if (sampleSize == 0 && offset + 12 + sampleCount * 4 != size) {
+        return ERROR_MALFORMED;
+    }
+
+    parser->copyBuffer(&mSampleSizes, offset, size);
+
+    mSampleCount = sampleCount;
+
+    return OK;
+}
+
+status_t Parser::StaticTrackFragment::parseCompactSampleSizes(
+        Parser *parser, uint32_t type, size_t offset, uint64_t size) {
+    if (offset + 12 > size) {
+        return ERROR_MALFORMED;
+    }
+
+    if (parser->readU32(offset) != 0) {
+        return ERROR_MALFORMED;
+    }
+
+    uint32_t fieldSize = parser->readU32(offset + 4);
+
+    if (fieldSize != 4 && fieldSize != 8 && fieldSize != 16) {
+        return ERROR_MALFORMED;
+    }
+
+    uint32_t sampleCount = parser->readU32(offset + 8);
+
+    if (offset + 12 + (sampleCount * fieldSize + 4) / 8 != size) {
+        return ERROR_MALFORMED;
+    }
+
+    parser->copyBuffer(&mCompactSampleSizes, offset, size);
+
+    mSampleCount = sampleCount;
+
+    return OK;
+}
+
+status_t Parser::StaticTrackFragment::parseSampleToChunk(
+        Parser *parser, uint32_t type, size_t offset, uint64_t size) {
+    if (offset + 8 > size) {
+        return ERROR_MALFORMED;
+    }
+
+    if (parser->readU32(offset) != 0) {
+        return ERROR_MALFORMED;
+    }
+
+    uint32_t entryCount = parser->readU32(offset + 4);
+
+    if (entryCount == 0 || offset + 8 + entryCount * 12 != size) {
+        return ERROR_MALFORMED;
+    }
+
+    parser->copyBuffer(&mSampleToChunk, offset, size, 12 /* extra */);
+
+    return OK;
+}
+
+status_t Parser::StaticTrackFragment::parseChunkOffsets(
+        Parser *parser, uint32_t type, size_t offset, uint64_t size) {
+    if (offset + 8 > size) {
+        return ERROR_MALFORMED;
+    }
+
+    if (parser->readU32(offset) != 0) {
+        return ERROR_MALFORMED;
+    }
+
+    uint32_t entryCount = parser->readU32(offset + 4);
+
+    if (offset + 8 + entryCount * 4 != size) {
+        return ERROR_MALFORMED;
+    }
+
+    parser->copyBuffer(&mChunkOffsets, offset, size);
+
+    return OK;
+}
+
+status_t Parser::StaticTrackFragment::parseChunkOffsets64(
+        Parser *parser, uint32_t type, size_t offset, uint64_t size) {
+    if (offset + 8 > size) {
+        return ERROR_MALFORMED;
+    }
+
+    if (parser->readU32(offset) != 0) {
+        return ERROR_MALFORMED;
+    }
+
+    uint32_t entryCount = parser->readU32(offset + 4);
+
+    if (offset + 8 + entryCount * 8 != size) {
+        return ERROR_MALFORMED;
+    }
+
+    parser->copyBuffer(&mChunkOffsets64, offset, size);
+
+    return OK;
+}
+
+}  // namespace android
+
diff --git a/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.h b/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.h
new file mode 100644
index 0000000..e5945ac
--- /dev/null
+++ b/media/libmediaplayerservice/nuplayer/mp4/TrackFragment.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TRACK_FRAGMENT_H_
+
+#define TRACK_FRAGMENT_H_
+
+#include "Parser.h"
+
+namespace android {
+
+struct Parser::TrackFragment : public RefBase {
+    TrackFragment() {}
+
+    virtual status_t getSample(SampleInfo *info) = 0;
+    virtual void advance() = 0;
+
+    virtual status_t signalCompletion() = 0;
+    virtual bool complete() const = 0;
+
+protected:
+    virtual ~TrackFragment() {}
+
+private:
+    DISALLOW_EVIL_CONSTRUCTORS(TrackFragment);
+};
+
+struct Parser::DynamicTrackFragment : public Parser::TrackFragment {
+    DynamicTrackFragment();
+
+    virtual status_t getSample(SampleInfo *info);
+    virtual void advance();
+
+    void addSample(
+            off64_t dataOffset, size_t sampleSize,
+            uint32_t presentationTime,
+            size_t sampleDescIndex,
+            uint32_t flags);
+
+    // No more samples will be added to this fragment.
+    virtual status_t signalCompletion();
+
+    virtual bool complete() const;
+
+protected:
+    virtual ~DynamicTrackFragment();
+
+private:
+    bool mComplete;
+    size_t mSampleIndex;
+    Vector<SampleInfo> mSamples;
+
+    DISALLOW_EVIL_CONSTRUCTORS(DynamicTrackFragment);
+};
+
+struct Parser::StaticTrackFragment : public Parser::TrackFragment {
+    StaticTrackFragment();
+
+    virtual status_t getSample(SampleInfo *info);
+    virtual void advance();
+
+    virtual status_t signalCompletion();
+    virtual bool complete() const;
+
+    status_t parseSampleSizes(
+            Parser *parser, uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseCompactSampleSizes(
+            Parser *parser, uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseSampleToChunk(
+            Parser *parser, uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseChunkOffsets(
+            Parser *parser, uint32_t type, size_t offset, uint64_t size);
+
+    status_t parseChunkOffsets64(
+            Parser *parser, uint32_t type, size_t offset, uint64_t size);
+
+protected:
+    virtual ~StaticTrackFragment();
+
+private:
+    size_t mSampleIndex;
+    size_t mSampleCount;
+
+    SampleInfo mSampleInfo;
+
+    sp<ABuffer> mSampleSizes;
+    sp<ABuffer> mCompactSampleSizes;
+
+    sp<ABuffer> mSampleToChunk;
+    ssize_t mSampleToChunkIndex;
+    size_t mSampleToChunkRemaining;
+
+    sp<ABuffer> mChunkOffsets;
+    sp<ABuffer> mChunkOffsets64;
+    uint32_t mPrevChunkIndex;
+    uint64_t mNextSampleOffset;
+
+    void updateSampleInfo();
+    void fixSampleToChunkTableIfNecessary();
+
+    DISALLOW_EVIL_CONSTRUCTORS(StaticTrackFragment);
+};
+
+}  // namespace android
+
+#endif  // TRACK_FRAGMENT_H_
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index e5b4d75..3fd0f85 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -102,10 +102,6 @@
         chromium_http_stub.cpp
 LOCAL_CPPFLAGS += -DCHROMIUM_AVAILABLE=1
 
-ifneq ($(TARGET_BUILD_PDK), true)
-LOCAL_REQUIRED_MODULES := libstagefright_chromium_http
-endif
-
 LOCAL_SHARED_LIBRARIES += libstlport
 include external/stlport/libstlport.mk
 
@@ -119,6 +115,8 @@
 
 LOCAL_MODULE:= libstagefright
 
+LOCAL_MODULE_TAGS := optional
+
 include $(BUILD_SHARED_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp
index 8b01ac6..dc42f91 100644
--- a/media/libstagefright/foundation/AMessage.cpp
+++ b/media/libstagefright/foundation/AMessage.cpp
@@ -25,6 +25,7 @@
 #include "AString.h"
 
 #include <binder/Parcel.h>
+#include <media/stagefright/foundation/hexdump.h>
 
 namespace android {
 
@@ -399,9 +400,20 @@
                         "RefBase *%s = %p", item.mName, item.u.refValue);
                 break;
             case kTypeBuffer:
-                tmp = StringPrintf(
-                        "ABuffer *%s = %p", item.mName, item.u.refValue);
+            {
+                sp<ABuffer> buffer = static_cast<ABuffer *>(item.u.refValue);
+
+                if (buffer != NULL && buffer->size() <= 64) {
+                    tmp = StringPrintf("Buffer %s = {\n", item.mName);
+                    hexdump(buffer->data(), buffer->size(), indent + 4, &tmp);
+                    appendIndent(&tmp, indent + 2);
+                    tmp.append("}");
+                } else {
+                    tmp = StringPrintf(
+                            "Buffer *%s = %p", item.mName, buffer.get());
+                }
                 break;
+            }
             case kTypeMessage:
                 tmp = StringPrintf(
                         "AMessage %s = %s",
diff --git a/media/libstagefright/foundation/hexdump.cpp b/media/libstagefright/foundation/hexdump.cpp
index 16c1ca5..a44d832 100644
--- a/media/libstagefright/foundation/hexdump.cpp
+++ b/media/libstagefright/foundation/hexdump.cpp
@@ -29,13 +29,25 @@
 
 namespace android {
 
-void hexdump(const void *_data, size_t size) {
+static void appendIndent(AString *s, int32_t indent) {
+    static const char kWhitespace[] =
+        "                                        "
+        "                                        ";
+
+    CHECK_LT((size_t)indent, sizeof(kWhitespace));
+
+    s->append(kWhitespace, indent);
+}
+
+void hexdump(const void *_data, size_t size, size_t indent, AString *appendTo) {
     const uint8_t *data = (const uint8_t *)_data;
 
     size_t offset = 0;
     while (offset < size) {
         AString line;
 
+        appendIndent(&line, indent);
+
         char tmp[32];
         sprintf(tmp, "%08lx:  ", (unsigned long)offset);
 
@@ -67,7 +79,12 @@
             }
         }
 
-        ALOGI("%s", line.c_str());
+        if (appendTo != NULL) {
+            appendTo->append(line);
+            appendTo->append("\n");
+        } else {
+            ALOGI("%s", line.c_str());
+        }
 
         offset += 16;
     }
