Initial support for a true streaming player for mpeg2 transport streams.

Change-Id: I153eec439d260a5524b21270e16d36940ec3161a
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index e7f1d6d..c0963a6 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -40,7 +40,8 @@
 enum player_type {
     PV_PLAYER = 1,
     SONIVOX_PLAYER = 2,
-    STAGEFRIGHT_PLAYER = 4,
+    STAGEFRIGHT_PLAYER = 3,
+    NU_PLAYER = 4,
     // Test players are available only in the 'test' and 'eng' builds.
     // The shared library with the test player is passed passed as an
     // argument to the 'test:' url in the setDataSource call.
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
new file mode 100644
index 0000000..940470d
--- /dev/null
+++ b/include/media/stagefright/ACodec.h
@@ -0,0 +1,152 @@
+#ifndef A_CODEC_H_
+
+#define A_CODEC_H_
+
+#include <stdint.h>
+#include <android/native_window.h>
+#include <media/IOMX.h>
+#include <media/stagefright/foundation/AHierarchicalStateMachine.h>
+
+namespace android {
+
+struct ABuffer;
+struct MemoryDealer;
+
+struct ACodec : public AHierarchicalStateMachine {
+    enum {
+        kWhatFillThisBuffer    = 'fill',
+        kWhatDrainThisBuffer   = 'drai',
+        kWhatEOS               = 'eos ',
+        kWhatShutdownCompleted = 'scom',
+        kWhatFlushCompleted    = 'fcom',
+    };
+
+    ACodec();
+
+    void setNotificationMessage(const sp<AMessage> &msg);
+    void initiateSetup(const sp<AMessage> &msg);
+    void signalFlush();
+    void signalResume();
+    void initiateShutdown();
+
+protected:
+    virtual ~ACodec();
+
+private:
+    struct BaseState;
+    struct UninitializedState;
+    struct LoadedToIdleState;
+    struct IdleToExecutingState;
+    struct ExecutingState;
+    struct OutputPortSettingsChangedState;
+    struct ExecutingToIdleState;
+    struct IdleToLoadedState;
+    struct ErrorState;
+    struct FlushingState;
+
+    enum {
+        kWhatSetup                   = 'setu',
+        kWhatOMXMessage              = 'omx ',
+        kWhatInputBufferFilled       = 'inpF',
+        kWhatOutputBufferDrained     = 'outD',
+        kWhatShutdown                = 'shut',
+        kWhatFlush                   = 'flus',
+        kWhatResume                  = 'resm',
+        kWhatDrainDeferredMessages   = 'drai',
+    };
+
+    enum {
+        kPortIndexInput  = 0,
+        kPortIndexOutput = 1
+    };
+
+    struct BufferInfo {
+        enum Status {
+            OWNED_BY_US,
+            OWNED_BY_COMPONENT,
+            OWNED_BY_UPSTREAM,
+            OWNED_BY_DOWNSTREAM,
+            OWNED_BY_NATIVE_WINDOW,
+        };
+
+        IOMX::buffer_id mBufferID;
+        Status mStatus;
+
+        sp<ABuffer> mData;
+        sp<GraphicBuffer> mGraphicBuffer;
+    };
+
+    sp<AMessage> mNotify;
+
+    sp<UninitializedState> mUninitializedState;
+    sp<LoadedToIdleState> mLoadedToIdleState;
+    sp<IdleToExecutingState> mIdleToExecutingState;
+    sp<ExecutingState> mExecutingState;
+    sp<OutputPortSettingsChangedState> mOutputPortSettingsChangedState;
+    sp<ExecutingToIdleState> mExecutingToIdleState;
+    sp<IdleToLoadedState> mIdleToLoadedState;
+    sp<ErrorState> mErrorState;
+    sp<FlushingState> mFlushingState;
+
+    AString mComponentName;
+    sp<IOMX> mOMX;
+    IOMX::node_id mNode;
+    sp<MemoryDealer> mDealer[2];
+
+    sp<ANativeWindow> mNativeWindow;
+
+    Vector<BufferInfo> mBuffers[2];
+    bool mPortEOS[2];
+
+    List<sp<AMessage> > mDeferredQueue;
+
+    status_t allocateBuffersOnPort(OMX_U32 portIndex);
+    status_t freeBuffersOnPort(OMX_U32 portIndex);
+    status_t freeBuffer(OMX_U32 portIndex, size_t i);
+
+    status_t allocateOutputBuffersFromNativeWindow();
+    status_t cancelBufferToNativeWindow(BufferInfo *info);
+    status_t freeOutputBuffersOwnedByNativeWindow();
+    BufferInfo *dequeueBufferFromNativeWindow();
+
+    BufferInfo *findBufferByID(
+            uint32_t portIndex, IOMX::buffer_id bufferID,
+            ssize_t *index = NULL);
+
+    void setComponentRole(bool isEncoder, const char *mime);
+    void configureCodec(const char *mime, const sp<AMessage> &msg);
+
+    status_t setVideoPortFormatType(
+            OMX_U32 portIndex,
+            OMX_VIDEO_CODINGTYPE compressionFormat,
+            OMX_COLOR_FORMATTYPE colorFormat);
+
+    status_t setSupportedOutputFormat();
+
+    status_t setupVideoDecoder(
+            const char *mime, int32_t width, int32_t height);
+
+    status_t setVideoFormatOnPort(
+            OMX_U32 portIndex,
+            int32_t width, int32_t height,
+            OMX_VIDEO_CODINGTYPE compressionFormat);
+
+    status_t setupAACDecoder(int32_t numChannels, int32_t sampleRate);
+    status_t setMinBufferSize(OMX_U32 portIndex, size_t size);
+
+    status_t initNativeWindow();
+
+    // Returns true iff all buffers on the given port have status OWNED_BY_US.
+    bool allYourBuffersAreBelongToUs(OMX_U32 portIndex);
+
+    bool allYourBuffersAreBelongToUs();
+
+    void deferMessage(const sp<AMessage> &msg);
+    void processDeferredMessages();
+
+    DISALLOW_EVIL_CONSTRUCTORS(ACodec);
+};
+
+}  // namespace android
+
+#endif  // A_CODEC_H_
diff --git a/include/media/stagefright/foundation/ADebug.h b/include/media/stagefright/foundation/ADebug.h
index 69021d8..eb5e494 100644
--- a/include/media/stagefright/foundation/ADebug.h
+++ b/include/media/stagefright/foundation/ADebug.h
@@ -32,6 +32,7 @@
 #define CHECK(condition)                                \
     LOG_ALWAYS_FATAL_IF(                                \
             !(condition),                               \
+            "%s",                                       \
             __FILE__ ":" LITERAL_TO_STRING(__LINE__)    \
             " CHECK(" #condition ") failed.")
 
@@ -58,10 +59,12 @@
     do {                                                                \
         AString ___res = Compare_##suffix(x, y);                        \
         if (!___res.empty()) {                                          \
-            LOG_ALWAYS_FATAL(                                           \
-                    __FILE__ ":" LITERAL_TO_STRING(__LINE__)            \
-                    " CHECK_" #suffix "( " #x "," #y ") failed: %s",    \
-                    ___res.c_str());                                    \
+            AString ___full =                                           \
+                __FILE__ ":" LITERAL_TO_STRING(__LINE__)                \
+                    " CHECK_" #suffix "( " #x "," #y ") failed: ";      \
+            ___full.append(___res);                                     \
+                                                                        \
+            LOG_ALWAYS_FATAL("%s", ___full.c_str());                    \
         }                                                               \
     } while (false)
 
diff --git a/include/media/stagefright/foundation/AHierarchicalStateMachine.h b/include/media/stagefright/foundation/AHierarchicalStateMachine.h
new file mode 100644
index 0000000..b5786fb
--- /dev/null
+++ b/include/media/stagefright/foundation/AHierarchicalStateMachine.h
@@ -0,0 +1,49 @@
+#ifndef A_HIERARCHICAL_STATE_MACHINE_H_
+
+#define A_HIERARCHICAL_STATE_MACHINE_H_
+
+#include <media/stagefright/foundation/AHandler.h>
+
+namespace android {
+
+struct AState : public RefBase {
+    AState(const sp<AState> &parentState = NULL);
+
+    sp<AState> parentState();
+
+protected:
+    virtual ~AState();
+
+    virtual void stateEntered();
+    virtual void stateExited();
+
+    virtual bool onMessageReceived(const sp<AMessage> &msg) = 0;
+
+private:
+    friend struct AHierarchicalStateMachine;
+
+    sp<AState> mParentState;
+
+    DISALLOW_EVIL_CONSTRUCTORS(AState);
+};
+
+struct AHierarchicalStateMachine : public AHandler {
+    AHierarchicalStateMachine();
+
+protected:
+    virtual ~AHierarchicalStateMachine();
+
+    virtual void onMessageReceived(const sp<AMessage> &msg);
+
+    // Only to be called in response to a message.
+    void changeState(const sp<AState> &state);
+
+private:
+    sp<AState> mState;
+
+    DISALLOW_EVIL_CONSTRUCTORS(AHierarchicalStateMachine);
+};
+
+}  // namespace android
+
+#endif  // A_HIERARCHICAL_STATE_MACHINE_H_
diff --git a/include/media/stagefright/foundation/AMessage.h b/include/media/stagefright/foundation/AMessage.h
index 2fbdddc..941f6b9 100644
--- a/include/media/stagefright/foundation/AMessage.h
+++ b/include/media/stagefright/foundation/AMessage.h
@@ -40,6 +40,8 @@
     void setTarget(ALooper::handler_id target);
     ALooper::handler_id target() const;
 
+    void clear();
+
     void setInt32(const char *name, int32_t value);
     void setInt64(const char *name, int64_t value);
     void setSize(const char *name, size_t value);
@@ -106,7 +108,6 @@
     Item mItems[kMaxNumItems];
     size_t mNumItems;
 
-    void clear();
     Item *allocateItem(const char *name);
     void freeItem(Item *item);
     const Item *findItem(const char *name, Type type) const;