OSDN Git Service

Special mode for ESQueue that allows for earlier dequeuing of access units
authorAndreas Huber <andih@google.com>
Fri, 31 Aug 2012 17:36:25 +0000 (10:36 -0700)
committerAndreas Huber <andih@google.com>
Fri, 31 Aug 2012 20:47:48 +0000 (13:47 -0700)
if it's know beforehand that each PES packet contains exactly one access unit.
Currently this optimization is only supported for H.264 video.

Change-Id: I0888027cc7e9850307484b11dba1191cf6bfac83

media/libstagefright/mpeg2ts/ESQueue.cpp
media/libstagefright/mpeg2ts/ESQueue.h

index 1cab077..e58e9bf 100644 (file)
@@ -33,8 +33,9 @@
 
 namespace android {
 
-ElementaryStreamQueue::ElementaryStreamQueue(Mode mode)
-    : mMode(mode) {
+ElementaryStreamQueue::ElementaryStreamQueue(Mode mode, uint32_t flags)
+    : mMode(mode),
+      mFlags(flags) {
 }
 
 sp<MetaData> ElementaryStreamQueue::getFormat() {
@@ -289,6 +290,31 @@ status_t ElementaryStreamQueue::appendData(
 }
 
 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnit() {
+    if ((mFlags & kFlag_AlignedData) && mMode == H264) {
+        if (mRangeInfos.empty()) {
+            return NULL;
+        }
+
+        RangeInfo info = *mRangeInfos.begin();
+        mRangeInfos.erase(mRangeInfos.begin());
+
+        sp<ABuffer> accessUnit = new ABuffer(info.mLength);
+        memcpy(accessUnit->data(), mBuffer->data(), info.mLength);
+        accessUnit->meta()->setInt64("timeUs", info.mTimestampUs);
+
+        memmove(mBuffer->data(),
+                mBuffer->data() + info.mLength,
+                mBuffer->size() - info.mLength);
+
+        mBuffer->setRange(0, mBuffer->size() - info.mLength);
+
+        if (mFormat == NULL) {
+            mFormat = MakeAVCCodecSpecificData(accessUnit);
+        }
+
+        return accessUnit;
+    }
+
     switch (mMode) {
         case H264:
             return dequeueAccessUnitH264();
@@ -436,8 +462,8 @@ struct NALPosition {
 
 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() {
     const uint8_t *data = mBuffer->data();
-    size_t size = mBuffer->size();
 
+    size_t size = mBuffer->size();
     Vector<NALPosition> nals;
 
     size_t totalSize = 0;
index 4035ed3..72aa2e7 100644 (file)
@@ -36,7 +36,12 @@ struct ElementaryStreamQueue {
         MPEG_VIDEO,
         MPEG4_VIDEO,
     };
-    ElementaryStreamQueue(Mode mode);
+
+    enum Flags {
+        // Data appended to the queue is always at access unit boundaries.
+        kFlag_AlignedData = 1,
+    };
+    ElementaryStreamQueue(Mode mode, uint32_t flags = 0);
 
     status_t appendData(const void *data, size_t size, int64_t timeUs);
     void clear(bool clearFormat);
@@ -52,6 +57,7 @@ private:
     };
 
     Mode mMode;
+    uint32_t mFlags;
 
     sp<ABuffer> mBuffer;
     List<RangeInfo> mRangeInfos;