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;
}