blob: 6bc9c32482381e57be544b7167a4ebdf43af9dc2 [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
284int msync_session_get_stat (int fd, enum sync_mode *mode, bool *v_active, bool *a_active)
285{
286 int rc;
287 struct session_sync_stat stat;
288
289 rc = ioctl(fd, AMSYNCS_IOC_GET_SYNC_STAT, &stat);
290 if (rc) {
291 log_error("fd[%d] get state errno:%d", fd, errno);
292 return rc;
293 }
294
295 switch (stat.mode) {
296 case AVS_MODE_A_MASTER:
297 *mode = AV_SYNC_MODE_AMASTER;
298 break;
299 case AVS_MODE_V_MASTER:
300 *mode = AV_SYNC_MODE_VMASTER;
301 break;
302 case AVS_MODE_PCR_MASTER:
303 *mode = AV_SYNC_MODE_PCR_MASTER;
304 break;
305 case AVS_MODE_IPTV:
306 *mode = AV_SYNC_MODE_IPTV;
307 break;
308 case AVS_MODE_FREE_RUN:
309 *mode = AV_SYNC_MODE_FREE_RUN;
310 break;
311 }
312 if (v_active)
313 *v_active = stat.v_active;
314 if (a_active)
315 *a_active = stat.a_active;
316
317 return rc;
318}
319
320bool msync_clock_started(int fd)
321{
322 uint32_t start = 0;
323 int rc;
324
325
326 rc = ioctl(fd, AMSYNCS_IOC_GET_CLOCK_START, &start);
327 if (rc)
328 log_error("session[%d] set clock start errno:%d", fd, errno);
329 return start != 0;
330}
331
332int msync_session_set_pcr(int fd, pts90K pts)
333{
334 int rc;
335 uint32_t pcr = pts;
336
337 rc = ioctl(fd, AMSYNCS_IOC_SET_PCR, &pcr);
338 if (rc)
339 log_error("session[%d] set pcr %u errno:%d", fd, pcr, errno);
340
341 return rc;
342}
343
344int msync_session_get_pcr(int fd, pts90K *pts)
345{
346 int rc;
347 uint32_t pcr;
348
349 rc = ioctl(fd, AMSYNCS_IOC_GET_PCR, &pcr);
350 if (rc)
351 log_error("session[%d] set pcr %u errno:%d", fd, pcr, errno);
352 else
353 *pts = pcr;
354
355 return rc;
356}