MediaCodec refactoring part 1-a: buffers become separate class

MediaCodecBuffer is meant to replace ABuffer and MediaBuffer in
communication between framework components. As the first step, replace
use of ABuffer in MediaCodec with MediaCodecBuffer, and adjust related
classes accordingly.

MediaCodec.getBuffer() and related APIs now returns MediaCodecBuffers;
thus change MediaCodec clients to use MediaCodecBuffer accordingly.

Test: manually tested for key use cases (Camera, YouTube and Play Movies)
Change-Id: Iba7ce131645e75ce5ddbf497fb793ab38b7f245b
diff --git a/include/media/MediaCodecBuffer.h b/include/media/MediaCodecBuffer.h
new file mode 100644
index 0000000..2df81dd
--- /dev/null
+++ b/include/media/MediaCodecBuffer.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2016, 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 MEDIA_CODEC_BUFFER_H_
+
+#define MEDIA_CODEC_BUFFER_H_
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+struct ABuffer;
+struct AMessage;
+class MediaBufferBase;
+
+/**
+ * Buffers used by MediaCodec.
+ */
+class MediaCodecBuffer : public RefBase {
+public:
+    MediaCodecBuffer(const sp<AMessage> &format, const sp<ABuffer> &buffer);
+
+    /**
+     * MediaCodec will release all references to the buffer when it's done using
+     * it, so the destructor should return the buffer to the owner, such as OMX
+     * components, buffer allocators, surfaces, etc.
+     */
+    virtual ~MediaCodecBuffer() = default;
+
+    // ABuffer-like interface
+    uint8_t *base();
+    uint8_t *data();
+    size_t capacity() const;
+    size_t size() const;
+    size_t offset() const;
+    // Default implementation calls ABuffer::setRange() and returns OK.
+    virtual status_t setRange(size_t offset, size_t size);
+    // TODO: These can be removed if we finish replacing all MediaBuffer's.
+    MediaBufferBase *getMediaBufferBase();
+    void setMediaBufferBase(MediaBufferBase *mediaBuffer);
+
+    // TODO: Specify each field for meta/format.
+    sp<AMessage> meta();
+    sp<AMessage> format();
+
+private:
+    MediaCodecBuffer() = delete;
+
+    const sp<AMessage> mMeta;
+    const sp<AMessage> mFormat;
+    const sp<ABuffer> mBuffer;
+    MediaBufferBase *mMediaBufferBase;
+};
+
+}  // namespace android
+
+#endif  // MEDIA_CODEC_BUFFER_H_
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index faf62ad..6f6f2f9 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -35,6 +35,7 @@
 namespace android {
 
 struct ABuffer;
+class MediaCodecBuffer;
 struct MemoryDealer;
 struct DescribeColorFormat2Params;
 struct DataConverter;
@@ -74,7 +75,7 @@
     struct PortDescription : public CodecBase::PortDescription {
         size_t countBuffers();
         IOMX::buffer_id bufferIDAt(size_t index) const;
-        sp<ABuffer> bufferAt(size_t index) const;
+        sp<MediaCodecBuffer> bufferAt(size_t index) const;
         sp<NativeHandle> handleAt(size_t index) const;
         sp<RefBase> memRefAt(size_t index) const;
 
@@ -82,13 +83,13 @@
         friend struct ACodec;
 
         Vector<IOMX::buffer_id> mBufferIDs;
-        Vector<sp<ABuffer> > mBuffers;
+        Vector<sp<MediaCodecBuffer>> mBuffers;
         Vector<sp<NativeHandle> > mHandles;
         Vector<sp<RefBase> > mMemRefs;
 
         PortDescription();
         void addBuffer(
-                IOMX::buffer_id id, const sp<ABuffer> &buffer,
+                IOMX::buffer_id id, const sp<MediaCodecBuffer> &buffer,
                 const sp<NativeHandle> &handle, const sp<RefBase> &memRef);
 
         DISALLOW_EVIL_CONSTRUCTORS(PortDescription);
@@ -186,11 +187,12 @@
         Status mStatus;
         unsigned mDequeuedAt;
 
-        sp<ABuffer> mData;      // the client's buffer; if not using data conversion, this is the
-                                // codec buffer; otherwise, it is allocated separately
-        sp<RefBase> mMemRef;    // and a reference to the IMemory, so it does not go away
-        sp<ABuffer> mCodecData; // the codec's buffer
-        sp<RefBase> mCodecRef;  // and a reference to the IMemory
+        sp<MediaCodecBuffer> mData;  // the client's buffer; if not using data conversion, this is
+                                     // the codec buffer; otherwise, it is allocated separately
+        sp<RefBase> mMemRef;         // and a reference to the IMemory, so it does not go away
+        sp<MediaCodecBuffer> mCodecData;  // the codec's buffer
+        sp<RefBase> mCodecRef;            // and a reference to the IMemory
+
         sp<GraphicBuffer> mGraphicBuffer;
         sp<NativeHandle> mNativeHandle;
         int mFenceFd;
@@ -204,6 +206,8 @@
         // Log error, if the current fence is not a read/write fence.
         void checkReadFence(const char *dbg);
         void checkWriteFence(const char *dbg);
+
+        sp<MediaCodecBuffer> alloc(const sp<AMessage> &format);
     };
 
     static const char *_asString(BufferInfo::Status s);
diff --git a/include/media/stagefright/CodecBase.h b/include/media/stagefright/CodecBase.h
index be2835d..92a5593 100644
--- a/include/media/stagefright/CodecBase.h
+++ b/include/media/stagefright/CodecBase.h
@@ -34,7 +34,7 @@
 
 namespace android {
 
-struct ABuffer;
+class MediaCodecBuffer;
 struct PersistentSurface;
 
 struct CodecBase : public AHandler, /* static */ ColorUtils {
@@ -88,7 +88,7 @@
     struct PortDescription : public RefBase {
         virtual size_t countBuffers() = 0;
         virtual IOMX::buffer_id bufferIDAt(size_t index) const = 0;
-        virtual sp<ABuffer> bufferAt(size_t index) const = 0;
+        virtual sp<MediaCodecBuffer> bufferAt(size_t index) const = 0;
         virtual sp<NativeHandle> handleAt(size_t index) const { return NULL; };
         virtual sp<RefBase> memRefAt(size_t index) const { return NULL; }
 
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index 8291cec..98780ce 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -35,6 +35,7 @@
 struct CodecBase;
 struct IBatteryStats;
 struct ICrypto;
+class MediaCodecBuffer;
 class IMemory;
 struct MemoryDealer;
 class IResourceManagerClient;
@@ -149,14 +150,14 @@
     status_t getOutputFormat(sp<AMessage> *format) const;
     status_t getInputFormat(sp<AMessage> *format) const;
 
-    status_t getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const;
+    status_t getWidevineLegacyBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const;
 
-    status_t getInputBuffers(Vector<sp<ABuffer> > *buffers) const;
-    status_t getOutputBuffers(Vector<sp<ABuffer> > *buffers) const;
+    status_t getInputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const;
+    status_t getOutputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const;
 
-    status_t getOutputBuffer(size_t index, sp<ABuffer> *buffer);
+    status_t getOutputBuffer(size_t index, sp<MediaCodecBuffer> *buffer);
     status_t getOutputFormat(size_t index, sp<AMessage> *format);
-    status_t getInputBuffer(size_t index, sp<ABuffer> *buffer);
+    status_t getInputBuffer(size_t index, sp<MediaCodecBuffer> *buffer);
 
     status_t setSurface(const sp<Surface> &nativeWindow);
 
@@ -253,10 +254,10 @@
 
     struct BufferInfo {
         uint32_t mBufferID;
-        sp<ABuffer> mData;
+        sp<MediaCodecBuffer> mData;
         sp<NativeHandle> mNativeHandle;
         sp<RefBase> mMemRef;
-        sp<ABuffer> mEncryptedData;
+        sp<MediaCodecBuffer> mEncryptedData;
         sp<IMemory> mSharedEncryptedBuffer;
         sp<AMessage> mNotify;
         sp<AMessage> mFormat;
@@ -367,7 +368,7 @@
 
     status_t getBufferAndFormat(
             size_t portIndex, size_t index,
-            sp<ABuffer> *buffer, sp<AMessage> *format);
+            sp<MediaCodecBuffer> *buffer, sp<AMessage> *format);
 
     bool handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false);
     bool handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false);
@@ -389,7 +390,7 @@
 
     status_t onSetParameters(const sp<AMessage> &params);
 
-    status_t amendOutputFormatWithCodecSpecificData(const sp<ABuffer> &buffer);
+    status_t amendOutputFormatWithCodecSpecificData(const sp<MediaCodecBuffer> &buffer);
     void updateBatteryStat();
     bool isExecuting() const;
 
diff --git a/include/media/stagefright/MediaFilter.h b/include/media/stagefright/MediaFilter.h
index d0a572c..6aa87e8 100644
--- a/include/media/stagefright/MediaFilter.h
+++ b/include/media/stagefright/MediaFilter.h
@@ -21,7 +21,6 @@
 
 namespace android {
 
-struct ABuffer;
 struct GraphicBufferListener;
 struct MemoryDealer;
 struct SimpleFilter;
@@ -51,7 +50,7 @@
     struct PortDescription : public CodecBase::PortDescription {
         virtual size_t countBuffers();
         virtual IOMX::buffer_id bufferIDAt(size_t index) const;
-        virtual sp<ABuffer> bufferAt(size_t index) const;
+        virtual sp<MediaCodecBuffer> bufferAt(size_t index) const;
 
     protected:
         PortDescription();
@@ -60,9 +59,9 @@
         friend struct MediaFilter;
 
         Vector<IOMX::buffer_id> mBufferIDs;
-        Vector<sp<ABuffer> > mBuffers;
+        Vector<sp<MediaCodecBuffer> > mBuffers;
 
-        void addBuffer(IOMX::buffer_id id, const sp<ABuffer> &buffer);
+        void addBuffer(IOMX::buffer_id id, const sp<MediaCodecBuffer> &buffer);
 
         DISALLOW_EVIL_CONSTRUCTORS(PortDescription);
     };
@@ -82,7 +81,7 @@
         int32_t mOutputFlags;
         Status mStatus;
 
-        sp<ABuffer> mData;
+        sp<MediaCodecBuffer> mData;
     };
 
     enum State {
diff --git a/include/media/stagefright/SkipCutBuffer.h b/include/media/stagefright/SkipCutBuffer.h
index 61f9949..0fb5690 100644
--- a/include/media/stagefright/SkipCutBuffer.h
+++ b/include/media/stagefright/SkipCutBuffer.h
@@ -18,6 +18,7 @@
 
 #define SKIP_CUT_BUFFER_H_
 
+#include <media/MediaCodecBuffer.h>
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/foundation/ABuffer.h>
 
@@ -39,6 +40,7 @@
     // After this, the caller should continue processing the buffer as usual.
     void submit(MediaBuffer *buffer);
     void submit(const sp<ABuffer>& buffer);    // same as above, but with an ABuffer
+    void submit(const sp<MediaCodecBuffer>& buffer);    // same as above, but with an ABuffer
     void clear();
     size_t size(); // how many bytes are currently stored in the buffer
 
@@ -48,6 +50,8 @@
  private:
     void write(const char *src, size_t num);
     size_t read(char *dst, size_t num);
+    template <typename T>
+    void submitInternal(const sp<T>& buffer);
     int32_t mSkip;
     int32_t mFrontPadding;
     int32_t mBackPadding;