avsync-lib: expose pos/mono time pair [1/1]

PD#TV-89282

Problem:
HbbTV need more accurate position.

Solution:
Add av_sync_get_pos() to get pts/mono time pair.

Verify:
T5W + Sandia

Change-Id: I02fcf6d911fd16053cd81711298e55ca45c09047
Signed-off-by: song.zhao@amlogic.com
diff --git a/src/aml_avsync.h b/src/aml_avsync.h
index 888f819..7749c7f 100644
--- a/src/aml_avsync.h
+++ b/src/aml_avsync.h
@@ -389,6 +389,18 @@
  */
 int av_sync_get_clock(void *sync, pts90K *pts);
 
+/* get render position and system mono raw time pair.
+ * pts type depends on sync_type of av_sync_create/av_sync_attach
+ * Params:
+ *   @sync: AV sync module handle
+ *   @pts: last rendered pts
+ *   @mono_clock: CLOCK_MONOTONIC_RAW in nanosecond of the last rendered
+ *                frame. 0 is invalid.
+ * Return:
+ *   0 for OK, or error code
+ */
+int av_sync_get_pos(void *sync, pts90K *pts, uint64_t *mono_clock);
+
 /* set session name for debugging purpose
  * The session name will be listed from /sys/class/aml_msync/list_session
  * Params:
diff --git a/src/avsync.c b/src/avsync.c
index fda9951..1a97261 100644
--- a/src/avsync.c
+++ b/src/avsync.c
@@ -833,13 +833,14 @@
     }
 
     if (avsync->last_frame) {
-        if (enter_last_frame != avsync->last_frame)
+        if (enter_last_frame != avsync->last_frame) {
             log_debug("[%d]pop %u", avsync->session_id, avsync->last_frame->pts);
+            /* don't update vpts for out_lier */
+            if (avsync->last_frame->duration != -1)
+                msync_session_update_vpts(avsync->fd, systime,
+                  avsync->last_frame->pts + avsync->extra_delay, interval * avsync->delay);
+        }
         log_trace("[%d]pop=%u, stc=%u, QNum=%d", avsync->session_id, avsync->last_frame->pts, systime, queue_size(avsync->frame_q));
-        /* don't update vpts for out_lier */
-        if (avsync->last_frame->duration != -1)
-            msync_session_update_vpts(avsync->fd, systime,
-                avsync->last_frame->pts, interval * avsync->delay);
     } else
         if (enter_last_frame != avsync->last_frame)
             log_debug("[%d]pop (nil)", avsync->session_id);
@@ -1472,6 +1473,20 @@
     return ret;
 }
 
+int av_sync_get_pos(void *sync, pts90K *pts, uint64_t *mono_clock)
+{
+    struct av_sync_session *avsync = (struct av_sync_session *)sync;
+
+    if (!avsync || !pts)
+        return -1;
+
+    if (avsync->type != AV_SYNC_TYPE_AUDIO &&
+        avsync->type != AV_SYNC_TYPE_VIDEO)
+        return -2;
+    return msync_session_get_pts(avsync->fd, pts,
+        mono_clock, avsync->type == AV_SYNC_TYPE_VIDEO);
+}
+
 int av_sync_get_clock(void *sync, pts90K *pts)
 {
     struct av_sync_session *avsync = (struct av_sync_session *)sync;
diff --git a/src/msync.h b/src/msync.h
index b2d5c2c..fa708c6 100644
--- a/src/msync.h
+++ b/src/msync.h
@@ -25,6 +25,7 @@
 	uint32_t wall_clock;
 	uint32_t pts;
 	uint32_t delay;
+	uint64_t mono_ts;
 };
 
 struct pcr_pair {
diff --git a/src/msync_util.c b/src/msync_util.c
index f866d29..3765087 100644
--- a/src/msync_util.c
+++ b/src/msync_util.c
@@ -183,6 +183,28 @@
     return rc;
 }
 
+int msync_session_get_pts(int fd, pts90K *p_pts, uint64_t *mono_ts, bool is_video)
+{
+    int rc;
+    struct pts_tri pts;
+
+    if (is_video)
+        rc = ioctl(fd, AMSYNCS_IOC_GET_V_TS, &pts);
+    else
+        rc = ioctl(fd, AMSYNCS_IOC_GET_A_TS, &pts);
+
+    if (rc) {
+        log_error("session[%d] get ts errno:%d", fd, errno);
+        return rc;
+    }
+
+    if (p_pts)
+        *p_pts = pts.pts;
+    if (mono_ts)
+        *mono_ts = pts.mono_ts;
+    return rc;
+}
+
 int msync_session_set_video_start(int fd, pts90K pts)
 {
     return msync_session_set_event(fd, AVS_VIDEO_START, pts);
@@ -260,10 +282,17 @@
 {
     int rc;
     struct pts_tri ts;
+    struct timespec now;
+    uint64_t mono_ns;
+
+    clock_gettime(CLOCK_MONOTONIC_RAW, &now);
+    mono_ns = now.tv_sec * 1000000000LL + now.tv_nsec;
+    mono_ns += delay / 9 * 100000;
 
     ts.wall_clock = system;
     ts.pts = pts;
     ts.delay = delay;
+    ts.mono_ts = mono_ns;
 
     rc = ioctl(fd, AMSYNCS_IOC_SET_V_TS, &ts);
     if (rc)
@@ -275,10 +304,17 @@
 {
     int rc;
     struct pts_tri ts;
+    struct timespec now;
+    uint64_t mono_ns;
+
+    clock_gettime(CLOCK_MONOTONIC_RAW, &now);
+    mono_ns = now.tv_sec * 1000000000LL + now.tv_nsec;
+    mono_ns += delay / 9 * 100000;
 
     ts.wall_clock = system;
     ts.pts = pts;
     ts.delay = delay;
+    ts.mono_ts = mono_ns;
 
     rc = ioctl(fd, AMSYNCS_IOC_SET_A_TS, &ts);
     if (rc)
diff --git a/src/msync_util.h b/src/msync_util.h
index e861fcf..d6dea62 100644
--- a/src/msync_util.h
+++ b/src/msync_util.h
@@ -46,6 +46,7 @@
 int msync_session_set_start_policy(int fd, uint32_t policy, int timeout);
 int msync_session_set_pause(int fd, bool pause);
 int msync_session_set_video_start(int fd, pts90K pts);
+int msync_session_get_pts(int fd, pts90K *p_pts, uint64_t *mono_ts, bool is_video);
 int msync_session_get_wall(int fd, uint32_t *wall, uint32_t *interval);
 int msync_session_set_video_start(int fd, pts90K pts);
 int msync_session_set_audio_start(int fd, pts90K pts, pts90K delay, uint32_t *mode);