blob: 4eaa41d692fbcb742e7e5ef91a336e2a5c45dfca [file] [log] [blame]
Song Zhaoea5a0412021-01-18 16:40:08 -08001/*
2 * Copyright (c) 2020 Amlogic, Inc. All rights reserved.
3 *
4 * This source code is subject to the terms and conditions defined in the
5 * file 'LICENSE' which is part of this source code package.
6 *
7 * Description:
8 * User space AV sync module.
9 *
10 * Author: song.zhao@amlogic.com
11 */
12#include <errno.h>
13#include <fcntl.h>
14#include <sys/types.h>
15#include <sys/stat.h>
16#include <sys/ioctl.h>
17#include <unistd.h>
18#include <linux/types.h>
19//#include <linux/amlogic/msync.h>
20#include "msync.h"
21#include "aml_avsync_log.h"
22#include "msync_util.h"
23
24#define MSYNC_DEV "/dev/aml_msync"
25
26int msync_create_session()
27{
28 int fd;
29
30 fd = open(MSYNC_DEV, O_RDONLY | O_CLOEXEC);
31 if (fd < 0) {
32 log_error("%s errno:%d", MSYNC_DEV, errno);
33 return -1;
34 }
35 return fd;
36}
37
38void msync_destory_session(int fd)
39{
40 close(fd);
41}
42
43int msync_session_set_mode(int fd, enum sync_mode mode)
44{
45 int rc;
46 uint32_t kmode;
47
48 if (mode == AV_SYNC_MODE_VMASTER)
49 kmode = AVS_MODE_V_MASTER;
50 else if (mode == AV_SYNC_MODE_AMASTER)
51 kmode = AVS_MODE_A_MASTER;
52 else if (mode == AV_SYNC_MODE_PCR_MASTER)
53 kmode = AVS_MODE_PCR_MASTER;
54 else if (mode == AV_SYNC_MODE_IPTV)
55 kmode = AVS_MODE_IPTV;
56 else if (mode == AV_SYNC_MODE_FREE_RUN)
57 kmode = AVS_MODE_FREE_RUN;
58
59 rc = ioctl(fd, AMSYNCS_IOC_SET_MODE, &kmode);
60 if (rc)
61 log_error("session[%d] set mode errno:%d", fd, errno);
62 return rc;
63}
64
65int msync_session_get_mode(int fd, enum sync_mode *mode)
66{
67 int rc;
68 uint32_t kmode;
69
70 rc = ioctl(fd, AMSYNCS_IOC_GET_MODE, &kmode);
71 if (rc) {
72 log_error("session[%d] set mode errno:%d", fd, errno);
73 return rc;
74 }
75
76 if (kmode == AVS_MODE_V_MASTER)
77 *mode = AV_SYNC_MODE_VMASTER;
78 else if (kmode == AVS_MODE_A_MASTER)
79 *mode = AV_SYNC_MODE_AMASTER;
80 else if (kmode == AVS_MODE_PCR_MASTER)
81 *mode = AV_SYNC_MODE_PCR_MASTER;
82 else if (kmode == AVS_MODE_IPTV)
83 *mode = AV_SYNC_MODE_IPTV;
84 else if (kmode == AVS_MODE_FREE_RUN)
85 *mode = AV_SYNC_MODE_FREE_RUN;
86
87 return rc;
88}
89
90int msync_session_get_start_policy(int fd, uint32_t *policy)
91{
92 int rc;
93 uint32_t kpolicy;
94
95 rc = ioctl(fd, AMSYNCS_IOC_GET_START_POLICY, &kpolicy);
96 if (rc)
97 log_error("session[%d] get start policy errno:%d", fd, errno);
98
99 if (kpolicy == AMSYNC_START_V_FIRST)
100 *policy = AV_SYNC_START_V_FIRST;
101 else if (kpolicy == AMSYNC_START_A_FIRST)
102 *policy = AV_SYNC_START_A_FIRST;
103 else if (kpolicy == AMSYNC_START_ASAP)
104 *policy = AV_SYNC_START_ASAP;
105 else if (kpolicy == AMSYNC_START_ALIGN)
106 *policy = AV_SYNC_START_ALIGN;
107 else
108 *policy = AV_SYNC_START_NONE;
109 return rc;
110}
111int msync_session_set_start_policy(int fd, uint32_t policy)
112{
113 int rc;
114 uint32_t kpolicy;
115
116 if (policy == AV_SYNC_START_V_FIRST)
117 kpolicy = AMSYNC_START_V_FIRST;
118 else if (policy == AV_SYNC_START_A_FIRST)
119 kpolicy = AMSYNC_START_A_FIRST;
120 else if (policy == AV_SYNC_START_ASAP)
121 kpolicy = AMSYNC_START_ASAP;
122 else if (policy == AV_SYNC_START_ALIGN)
123 kpolicy = AMSYNC_START_ALIGN;
124 else
125 return -1;
126
127 rc = ioctl(fd, AMSYNCS_IOC_SET_START_POLICY, &kpolicy);
128 if (rc)
129 log_error("session[%d] set start policy errno:%d", fd, errno);
130 return rc;
131}
132
133static int msync_session_set_event(int fd, enum avs_event event, uint32_t value)
134{
135 struct session_event sevent;
136 int rc;
137
138 sevent.event = event;
139 sevent.value = value;
140
141 rc = ioctl(fd, AMSYNCS_IOC_SEND_EVENT, &sevent);
142 if (rc)
143 log_error("session[%d] send %d errno:%d", fd, event, errno);
144 return rc;
145}
146
147
148int msync_session_set_pause(int fd, bool pause)
149{
150 if (pause)
151 return msync_session_set_event(fd, AVS_PAUSE, 0);
152 else
153 return msync_session_set_event(fd, AVS_RESUME, 0);
154}
155
156int msync_session_get_wall(int fd, uint32_t *wall, uint32_t *interval)
157{
158 int rc;
159 struct pts_wall pwall;
160
161 rc = ioctl(fd, AMSYNCS_IOC_GET_WALL, &pwall);
162 if (rc)
163 log_error("session[%d] get wall errno:%d", fd, errno);
164
165 *wall = pwall.wall_clock;
166 if (interval)
167 *interval = pwall.interval;
168 return rc;
169}
170
171int msync_session_set_video_start(int fd, pts90K pts)
172{
173 return msync_session_set_event(fd, AVS_VIDEO_START, pts);
174}
175
176int msync_session_set_audio_start(int fd, pts90K pts, pts90K delay, uint32_t *mode)
177{
178 struct audio_start start;
179 int rc;
180
181 if (!mode)
182 return -EINVAL;
183
184 start.pts = pts;
185 start.delay = delay;
186 start.mode = 0;
187
188 rc = ioctl(fd, AMSYNCS_IOC_AUDIO_START, &start);
189 if (rc)
190 log_error("session[%d] audio start errno:%d", fd, errno);
191 else
192 *mode = start.mode;
193
194 return rc;
195}
196
197int msync_session_set_video_dis(int fd, pts90K pts)
198{
199 return msync_session_set_event(fd, AVS_VIDEO_TSTAMP_DISCONTINUITY, pts);
200}
201
202int msync_session_set_audio_dis(int fd, pts90K pts)
203{
204 return msync_session_set_event(fd, AVS_AUDIO_TSTAMP_DISCONTINUITY, pts);
205}
206
207int msync_session_set_rate(int fd, float speed)
208{
209 uint32_t krate = 1000*speed;
210 int rc;
211
212
213 rc = ioctl(fd, AMSYNCS_IOC_SET_RATE, &krate);
214 if (rc)
215 log_error("fd[%d] set rate errno:%d", fd, errno);
216 return rc;
217}
218
219int msync_session_get_rate(int fd, float *speed)
220{
221 uint32_t krate;
222 int rc;
223
224
225 rc = ioctl(fd, AMSYNCS_IOC_GET_RATE, &krate);
226 if (rc) {
227 log_error("fd[%d] get rate errno:%d", fd, errno);
228 return rc;
229 }
230 *speed = (float)krate/1000;
231 return 0;
232}
233
234int msync_session_set_name(int fd, const char* name)
235{
236 int rc;
237
238 rc = ioctl(fd, AMSYNCS_IOC_SET_NAME, name);
239 if (rc)
240 log_error("session[%d] set name errno:%d", fd, errno);
241 return rc;
242}
243
244int msync_session_update_vpts(int fd, uint32_t system, uint32_t pts, uint32_t delay)
245{
246 int rc;
247 struct pts_tri ts;
248
249 ts.wall_clock = system;
250 ts.pts = pts;
251 ts.delay = delay;
252
253 rc = ioctl(fd, AMSYNCS_IOC_SET_V_TS, &ts);
254 if (rc)
255 log_error("session[%d] set vts errno:%d", fd, errno);
256 return rc;
257}
258
259int msync_session_update_apts(int fd, uint32_t system, uint32_t pts, uint32_t delay)
260{
261 int rc;
262 struct pts_tri ts;
263
264 ts.wall_clock = system;
265 ts.pts = pts;
266 ts.delay = delay;
267
268 rc = ioctl(fd, AMSYNCS_IOC_SET_A_TS, &ts);
269 if (rc)
270 log_error("session[%d] set ats errno:%d", fd, errno);
271 return rc;
272}
273
274int msync_session_set_audio_stop(int fd)
275{
276 return msync_session_set_event(fd, AVS_AUDIO_STOP, 0);
277}
278
279int msync_session_set_video_stop(int fd)
280{
281 return msync_session_set_event(fd, AVS_VIDEO_STOP, 0);
282}
283
Song Zhaoe208d692021-04-19 15:38:52 -0700284int msync_session_get_stat (int fd, enum sync_mode *mode,
285 bool *v_active, bool *a_active, bool *v_timeout)
Song Zhaoea5a0412021-01-18 16:40:08 -0800286{
287 int rc;
288 struct session_sync_stat stat;
289
290 rc = ioctl(fd, AMSYNCS_IOC_GET_SYNC_STAT, &stat);
291 if (rc) {
292 log_error("fd[%d] get state errno:%d", fd, errno);
293 return rc;
294 }
295
296 switch (stat.mode) {
297 case AVS_MODE_A_MASTER:
298 *mode = AV_SYNC_MODE_AMASTER;
299 break;
300 case AVS_MODE_V_MASTER:
301 *mode = AV_SYNC_MODE_VMASTER;
302 break;
303 case AVS_MODE_PCR_MASTER:
304 *mode = AV_SYNC_MODE_PCR_MASTER;
305 break;
306 case AVS_MODE_IPTV:
307 *mode = AV_SYNC_MODE_IPTV;
308 break;
309 case AVS_MODE_FREE_RUN:
310 *mode = AV_SYNC_MODE_FREE_RUN;
311 break;
312 }
313 if (v_active)
314 *v_active = stat.v_active;
315 if (a_active)
316 *a_active = stat.a_active;
Song Zhaoe208d692021-04-19 15:38:52 -0700317 if (v_timeout)
318 *v_timeout = stat.v_timeout;
Song Zhaoea5a0412021-01-18 16:40:08 -0800319
320 return rc;
321}
322
323bool msync_clock_started(int fd)
324{
325 uint32_t start = 0;
326 int rc;
327
328
329 rc = ioctl(fd, AMSYNCS_IOC_GET_CLOCK_START, &start);
330 if (rc)
331 log_error("session[%d] set clock start errno:%d", fd, errno);
332 return start != 0;
333}
334
335int msync_session_set_pcr(int fd, pts90K pts)
336{
337 int rc;
338 uint32_t pcr = pts;
339
340 rc = ioctl(fd, AMSYNCS_IOC_SET_PCR, &pcr);
341 if (rc)
342 log_error("session[%d] set pcr %u errno:%d", fd, pcr, errno);
343
344 return rc;
345}
346
347int msync_session_get_pcr(int fd, pts90K *pts)
348{
349 int rc;
350 uint32_t pcr;
351
352 rc = ioctl(fd, AMSYNCS_IOC_GET_PCR, &pcr);
353 if (rc)
354 log_error("session[%d] set pcr %u errno:%d", fd, pcr, errno);
355 else
356 *pts = pcr;
357
358 return rc;
359}