The qcom OMX video decoders do not allocate output buffer memory at the time OMX_AllocateBuffer is called, wait until we received the first FILL_BUFFER_DONE notification until we rely on the buffer data ptr.
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index bb7677d..2f61cbe 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -166,6 +166,7 @@
             OMX_U32 flags;
             OMX_TICKS timestamp;
             OMX_PTR platform_private;
+            OMX_PTR data_ptr;
         } extended_buffer_data;
 
     } u;
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index ac2f662..82dd2b5 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -94,6 +94,7 @@
         kRequiresFlushCompleteEmulation      = 16,
         kRequiresAllocateBufferOnOutputPorts = 32,
         kRequiresFlushBeforeShutdown         = 64,
+        kDefersOutputBufferAllocation        = 128,
     };
 
     struct BufferInfo {
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 2686489..986dcb2 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -301,8 +301,8 @@
         quirks |= kRequiresAllocateBufferOnOutputPorts;
     }
     if (!strncmp(componentName, "OMX.qcom.video.decoder.", 23)) {
-        // XXX Required on P....on only.
         quirks |= kRequiresAllocateBufferOnOutputPorts;
+        quirks |= kDefersOutputBufferAllocation;
     }
 
     if (!strncmp(componentName, "OMX.TI.", 7)) {
@@ -1237,8 +1237,15 @@
         info.mMediaBuffer = NULL;
 
         if (portIndex == kPortIndexOutput) {
-            info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize);
-            info.mMediaBuffer->setObserver(this);
+            if (!(mOMXLivesLocally
+                        && (mQuirks & kRequiresAllocateBufferOnOutputPorts)
+                        && (mQuirks & kDefersOutputBufferAllocation))) {
+                // If the node does not fill in the buffer ptr at this time,
+                // we will defer creating the MediaBuffer until receiving
+                // the first FILL_BUFFER_DONE notification instead.
+                info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize);
+                info.mMediaBuffer->setObserver(this);
+            }
         }
 
         mPortBuffers[portIndex].push(info);
@@ -1346,6 +1353,22 @@
             } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
                 CHECK_EQ(mPortStatus[kPortIndexOutput], ENABLED);
 
+                if (info->mMediaBuffer == NULL) {
+                    CHECK(mOMXLivesLocally);
+                    CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts);
+                    CHECK(mQuirks & kDefersOutputBufferAllocation);
+
+                    // The qcom video decoders on Nexus don't actually allocate
+                    // output buffer memory on a call to OMX_AllocateBuffer
+                    // the "pBuffer" member of the OMX_BUFFERHEADERTYPE
+                    // structure is only filled in later.
+
+                    info->mMediaBuffer = new MediaBuffer(
+                            msg.u.extended_buffer_data.data_ptr,
+                            info->mSize);
+                    info->mMediaBuffer->setObserver(this);
+                }
+
                 MediaBuffer *buffer = info->mMediaBuffer;
 
                 buffer->set_range(
diff --git a/media/libstagefright/SampleIterator.cpp b/media/libstagefright/SampleIterator.cpp
index faad42b..7155c61 100644
--- a/media/libstagefright/SampleIterator.cpp
+++ b/media/libstagefright/SampleIterator.cpp
@@ -54,6 +54,10 @@
 status_t SampleIterator::seekTo(uint32_t sampleIndex) {
     LOGV("seekTo(%d)", sampleIndex);
 
+    if (sampleIndex >= mTable->mNumSampleSizes) {
+        return ERROR_END_OF_STREAM;
+    }
+
     if (mTable->mSampleToChunkOffset < 0
             || mTable->mChunkOffsetOffset < 0
             || mTable->mSampleSizeOffset < 0
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 313a9ed..dfba74f 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -276,8 +276,6 @@
 }
 
 const char *StagefrightMetadataRetriever::extractMetadata(int keyCode) {
-    LOGV("extractMetadata %d", keyCode);
-
     if (mExtractor == NULL) {
         return NULL;
     }
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 918d055..9ca060d 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -365,6 +365,7 @@
     msg.u.extended_buffer_data.flags = pBuffer->nFlags;
     msg.u.extended_buffer_data.timestamp = pBuffer->nTimeStamp;
     msg.u.extended_buffer_data.platform_private = pBuffer->pPlatformPrivate;
+    msg.u.extended_buffer_data.data_ptr = pBuffer->pBuffer;
 
     mDispatcher->post(msg);