MediaPlayer: overhaul buffering monitor scheme.

GenericSource: buffering monitor runs on a separate looper since readBuffer()
call can be blocked for long time.
  When paused, dequeueAccess() returns -EWOULDBLOCK.
  For audio offload, take into account cached data in downstream components.
NuPlayerDecoderPassThrough: flush out aggregate buffer when source doesn't have
data available.

Bug: 24295007
Change-Id: I535a438d96ee902c9b4baa7c84ed7e5063a23964
(cherry picked from commit 32ce83cf93e4eb14c9937e4b850e044f9f7fdf2c)
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index 2db5557..2fd703e 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -77,6 +77,8 @@
 
     virtual bool isStreaming() const;
 
+    virtual void setOffloadAudio(bool offload);
+
 protected:
     virtual ~GenericSource();
 
@@ -111,6 +113,83 @@
         sp<AnotherPacketSource> mPackets;
     };
 
+    // Helper to monitor buffering status. The polling happens every second.
+    // When necessary, it will send out buffering events to the player.
+    struct BufferingMonitor : public AHandler {
+    public:
+        BufferingMonitor(const sp<AMessage> &notify);
+
+        // Set up state.
+        void prepare(const sp<NuCachedSource2> &cachedSource,
+                const sp<WVMExtractor> &wvmExtractor,
+                int64_t durationUs,
+                int64_t bitrate,
+                bool isStreaming);
+        // Stop and reset buffering monitor.
+        void stop();
+        // Cancel the current monitor task.
+        void cancelPollBuffering();
+        // Restart the monitor task.
+        void restartPollBuffering();
+        // Stop buffering task and send out corresponding events.
+        void stopBufferingIfNecessary();
+        // Make sure data source is getting data.
+        void ensureCacheIsFetching();
+        // Update media time of just extracted buffer from data source.
+        void updateQueuedTime(bool isAudio, int64_t timeUs);
+
+        // Set the offload mode.
+        void setOffloadAudio(bool offload);
+        // Update media time of last dequeued buffer which is sent to the decoder.
+        void updateDequeuedBufferTime(int64_t mediaUs);
+
+    protected:
+        virtual ~BufferingMonitor();
+        virtual void onMessageReceived(const sp<AMessage> &msg);
+
+    private:
+        enum {
+            kWhatPollBuffering,
+        };
+
+        sp<AMessage> mNotify;
+
+        sp<NuCachedSource2> mCachedSource;
+        sp<WVMExtractor> mWVMExtractor;
+        int64_t mDurationUs;
+        int64_t mBitrate;
+        bool mIsStreaming;
+
+        int64_t mAudioTimeUs;
+        int64_t mVideoTimeUs;
+        int32_t mPollBufferingGeneration;
+        bool mPrepareBuffering;
+        bool mBuffering;
+        int32_t mPrevBufferPercentage;
+
+        mutable Mutex mLock;
+
+        bool mOffloadAudio;
+        int64_t mFirstDequeuedBufferRealUs;
+        int64_t mFirstDequeuedBufferMediaUs;
+        int64_t mlastDequeuedBufferMediaUs;
+
+        void prepare_l(const sp<NuCachedSource2> &cachedSource,
+                const sp<WVMExtractor> &wvmExtractor,
+                int64_t durationUs,
+                int64_t bitrate,
+                bool isStreaming);
+        void cancelPollBuffering_l();
+        void notifyBufferingUpdate_l(int32_t percentage);
+        void startBufferingIfNecessary_l();
+        void stopBufferingIfNecessary_l();
+        void sendCacheStats_l();
+        void ensureCacheIsFetching_l();
+        int64_t getLastReadPosition_l();
+        void onPollBuffering_l();
+        void schedulePollBuffering_l();
+    };
+
     Vector<sp<IMediaSource> > mSources;
     Track mAudioTrack;
     int64_t mAudioTimeUs;
@@ -147,17 +226,15 @@
     bool mStarted;
     bool mStopRead;
     int64_t mBitrate;
-    int32_t mPollBufferingGeneration;
+    sp<BufferingMonitor> mBufferingMonitor;
     uint32_t mPendingReadBufferTypes;
-    bool mBuffering;
-    bool mPrepareBuffering;
-    int32_t mPrevBufferPercentage;
     sp<ABuffer> mGlobalTimedText;
 
     mutable Mutex mReadBufferLock;
     mutable Mutex mDisconnectLock;
 
     sp<ALooper> mLooper;
+    sp<ALooper> mBufferingMonitorLooper;
 
     void resetDataSource();
 
@@ -212,16 +289,6 @@
     void queueDiscontinuityIfNeeded(
             bool seeking, bool formatChange, media_track_type trackType, Track *track);
 
-    void schedulePollBuffering();
-    void cancelPollBuffering();
-    void restartPollBuffering();
-    void onPollBuffering();
-    void notifyBufferingUpdate(int32_t percentage);
-    void startBufferingIfNecessary();
-    void stopBufferingIfNecessary();
-    void sendCacheStats();
-    void ensureCacheIsFetching();
-
     DISALLOW_EVIL_CONSTRUCTORS(GenericSource);
 };