mediaplayer: smooth out videoplayback based on framerate

Bug: 14659809
Change-Id: I73f6c7224c51ac06487475f9ed395379111ad71f
diff --git a/media/libmediaplayerservice/VideoFrameScheduler.h b/media/libmediaplayerservice/VideoFrameScheduler.h
index 9119e45..19f0787 100644
--- a/media/libmediaplayerservice/VideoFrameScheduler.h
+++ b/media/libmediaplayerservice/VideoFrameScheduler.h
@@ -30,7 +30,9 @@
     VideoFrameScheduler();
 
     // (re)initialize scheduler
-    void init();
+    void init(float videoFps = -1);
+    // use in case of video render-time discontinuity, e.g. seek
+    void restart();
     // get adjusted nanotime for a video frame render at renderTime
     nsecs_t schedule(nsecs_t renderTime);
 
@@ -39,16 +41,52 @@
 
     void release();
 
+    static const size_t kHistorySize = 8;
+
 protected:
     virtual ~VideoFrameScheduler();
 
 private:
+    struct PLL {
+        PLL();
+
+        // reset PLL to new PLL
+        void reset(float fps = -1);
+        // keep current estimate, but restart phase
+        void restart();
+        // returns period
+        nsecs_t addSample(nsecs_t time);
+
+    private:
+        nsecs_t mPeriod;
+        nsecs_t mPhase;
+
+        bool    mPrimed;        // have an estimate for the period
+        size_t  mSamplesUsedForPriming;
+
+        nsecs_t mLastTime;      // last input time
+        nsecs_t mRefitAt;       // next input time to fit at
+
+        size_t  mNumSamples;    // can go past kHistorySize
+        nsecs_t mTimes[kHistorySize];
+
+        void test();
+        void fit(nsecs_t phase, nsecs_t period, size_t numSamples,
+                int64_t *a, int64_t *b, int64_t *err);
+        void prime(size_t numSamples);
+    };
+
     void updateVsync();
 
     nsecs_t mVsyncTime;        // vsync timing from display
     nsecs_t mVsyncPeriod;
     nsecs_t mVsyncRefreshAt;   // next time to refresh timing info
 
+    nsecs_t mLastVsyncTime;    // estimated vsync time for last frame
+    nsecs_t mTimeCorrection;   // running adjustment
+
+    PLL mPll;                  // PLL for video frame rate based on render time
+
     sp<ISurfaceComposer> mComposer;
 
     DISALLOW_EVIL_CONSTRUCTORS(VideoFrameScheduler);