libdvr: Play PVR files, not start playing from 00:00. [1/3]

PD#SWPL-50464

Problem:
  Play PVR files, not start playing from 00:00

Solution:
1 add only update pid info api.
this used to deal only update info and not
to stop and start codec.
2 caculate rec time error when pcr is Suddenly bigger,
if pcr Suddenly bigger we this this pcr is error,\
we add an avg time.
3 get fake pid from prop and save in player.

Verify:
verify by t3

Signed-off-by: hualing chen <hualing.chen@amlogic.com>
Change-Id: Ie879d74703cff4cd3b97d42e0895ed6cf71ee169
diff --git a/src/segment.c b/src/segment.c
index 886be0d..3bd8938 100644
--- a/src/segment.c
+++ b/src/segment.c
@@ -29,6 +29,10 @@
   uint64_t        cur_time;                           /**< Current time save in index file */
   uint64_t        segment_id;                         /**< Current segment ID */
   char            location[MAX_SEGMENT_PATH_SIZE];    /**< Current time save in index file */
+  loff_t          first_offset;
+  loff_t          last_offset;
+  loff_t          last_record_offset;
+  float           avg_rate;
 } Segment_Context_t;
 
 /**\brief Segment file type*/
@@ -130,6 +134,7 @@
     p_ctx->first_pts = ULLONG_MAX;
     p_ctx->last_pts = ULLONG_MAX;
     p_ctx->last_record_pts = ULLONG_MAX;
+    p_ctx->avg_rate = 0.0;
   } else {
     DVR_DEBUG(1, "%s, unknow mode use default", __func__);
     p_ctx->ts_fd = open(ts_fname, O_RDONLY);
@@ -231,13 +236,14 @@
   if (p_ctx->first_pts == ULLONG_MAX) {
     DVR_DEBUG(1, "%s first pcr:%llu", __func__, pts);
     p_ctx->first_pts = pts;
+    p_ctx->first_offset = offset;
   }
   memset(buf, 0, sizeof(buf));
   if (p_ctx->last_pts == ULLONG_MAX) {
     /*Last pts is init value*/
     sprintf(buf, "{time=%llu, offset=%lld}", pts - p_ctx->first_pts, offset);
     p_ctx->cur_time = pts - p_ctx->first_pts;
-  DVR_DEBUG(1, "%s force pcr:%llu -1", __func__, pts);
+    DVR_DEBUG(1, "%s force pcr:%llu -1", __func__, pts);
   } else {
     /*Last pts has valid value*/
     int diff = pts - p_ctx->last_pts;
@@ -248,6 +254,8 @@
       sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
     } else {
       /*This is a normal pts, record it*/
+      //check if this pcr is transition.if true,add 200ms
+      //other case normal.
       p_ctx->cur_time += diff;
       DVR_DEBUG(1, "%s force pcr:%llu -1 diff [%d]", __func__, pts, diff);
       sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
@@ -263,7 +271,6 @@
     p_ctx->last_record_pts = pts;
   }
   p_ctx->last_pts = pts;
-
   return DVR_SUCCESS;
 }
 
@@ -298,7 +305,22 @@
       //p_ctx->cur_time = p_ctx->cur_time + PTS_DISCONTINE_DEVIATION;
     } else {
       /*This is a normal pts, record it*/
-      p_ctx->cur_time += diff;
+      loff_t off_diff = offset - p_ctx->last_offset;
+      float rate = (float) (off_diff) / (float)(diff);
+      if (p_ctx->avg_rate == 0.0) {
+            p_ctx->avg_rate = (float) offset / (float)(p_ctx->cur_time + diff);
+      }
+      if (diff >= 1000) {
+        DVR_DEBUG(1, "PTS TRANSITION ERROR last pcr[%llu]pts[%llu]pcr diff[%d]off[%llu]off_diff[%llu]rate[%f]avg rate[%f]4*rate[%d]av_diff[%d]",p_ctx->last_pts, pts, diff, offset,off_diff, rate, p_ctx->avg_rate, (int)(rate * 4), (int)(off_diff / p_ctx->avg_rate));
+        if (p_ctx->avg_rate != 0 && (int)(p_ctx->avg_rate) >= (int)(rate * 4)) {
+          diff = off_diff / p_ctx->avg_rate;
+          p_ctx->cur_time += diff;
+        } else {
+          p_ctx->cur_time += diff;
+        }
+      } else {
+         p_ctx->cur_time += diff;
+      }
       sprintf(buf, "\n{time=%llu, offset=%lld}", p_ctx->cur_time, offset);
     }
   }
@@ -310,9 +332,12 @@
     fflush(p_ctx->index_fp);
     fsync(fileno(p_ctx->index_fp));
     p_ctx->last_record_pts = pts;
+    p_ctx->last_record_offset = offset;
+    if (p_ctx->cur_time > 0)
+      p_ctx->avg_rate = (float) offset / (float)p_ctx->cur_time;
   }
   p_ctx->last_pts = pts;
-
+  p_ctx->last_offset = offset;
   return DVR_SUCCESS;
 }