blob: ec97b2b2eab36b42a19222ecb450bd0ebed62e5d [file] [log] [blame]
Song Zhao6859d412020-06-15 17:16:04 -07001/*
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: tsync warrper. Single instance ONLY. Session will be ignored
8 * Author: song.zhao@amlogic.com
9 */
10
11#include <stdbool.h>
12#include <stdlib.h>
13#include <stdio.h>
14#include <sys/types.h>
15#include <sys/stat.h>
16#include <fcntl.h>
17#include <unistd.h>
18#include <string.h>
Song Zhaobf35d4a2020-06-18 22:36:29 -070019#include <sys/ioctl.h>
Song Zhao6859d412020-06-15 17:16:04 -070020#include "tsync.h"
21
Song Zhaobf35d4a2020-06-18 22:36:29 -070022#define VIDEO_DEVICE "/dev/amvideo"
Song Zhao6859d412020-06-15 17:16:04 -070023#define TSYNC_ENABLE "/sys/class/tsync/enable"
24#define TSYNC_PCRSCR "/sys/class/tsync/pts_pcrscr"
25#define TSYNC_EVENT "/sys/class/tsync/event"
Song Zhaobf35d4a2020-06-18 22:36:29 -070026#define TSYNC_MODE "/sys/class/tsync/mode"
27
28#define _A_M 'S'
29#define AMSTREAM_IOC_SET_VSYNC_UPINT _IOW((_A_M), 0x89, int)
30#define AMSTREAM_IOC_SET_VIDEOPEEK _IOW(_A_M, 0xbf, unsigned int)
Song Zhao6859d412020-06-15 17:16:04 -070031
32static int config_sys_node(const char* path, const char* value)
33{
34 int fd;
35 fd = open(path, O_RDWR);
36 if (fd < 0) {
37 printf("fail to open %s\n", path);
38 return -1;
39 }
40 if (write(fd, value, strlen(value)) != strlen(value)) {
41 printf("fail to write %s to %s\n", value, path);
42 close(fd);
43 return -1;
44 }
45 close(fd);
46
47 return 0;
48}
49
50static int get_sysfs_uint32(const char *path, uint32_t *value)
51{
52 int fd;
53 char valstr[64];
54 uint32_t val = 0;
55
56 fd = open(path, O_RDONLY);
57 if (fd >= 0) {
58 memset(valstr, 0, 64);
59 read(fd, valstr, 64 - 1);
60 valstr[strlen(valstr)] = '\0';
61 close(fd);
62 } else {
63 printf("unable to open file %s\n", path);
64 return -1;
65 }
66 if (sscanf(valstr, "0x%x", &val) < 1) {
67 printf("unable to get pts from: %s", valstr);
68 return -1;
69 }
70 *value = val;
71 return 0;
72}
73
Song Zhaobf35d4a2020-06-18 22:36:29 -070074int tsync_enable(int session, bool enable)
Song Zhao6859d412020-06-15 17:16:04 -070075{
76 const char *val;
77
78 if (enable)
79 val = "1";
80 else
81 val = "0";
Song Zhaobf35d4a2020-06-18 22:36:29 -070082 return config_sys_node(TSYNC_ENABLE, val);
Song Zhao6859d412020-06-15 17:16:04 -070083}
84
85uint32_t tsync_get_pcr(int session)
86{
87 uint32_t pcr = 0;
88
89 get_sysfs_uint32(TSYNC_PCRSCR, &pcr);
90 return pcr;
91}
92
93//uint32_t tsync_get_vpts(int session);
94
95int tsync_send_video_start(int session, uint32_t vpts)
96{
97 char val[50];
98
99 snprintf(val, sizeof(val), "VIDEO_START:0x%x", vpts);
100 return config_sys_node(TSYNC_EVENT, val);
101}
102
103int tsync_send_video_pause(int session, bool pause)
104{
105 const char *val;
106
107 if (pause)
108 val = "VIDEO_PAUSE:0x1";
109 else
110 val = "VIDEO_PAUSE:0x0";
111 return config_sys_node(TSYNC_EVENT, val);
112}
113
114int tsync_send_video_disc(int session, uint32_t vpts)
115{
116 char val[50];
117
118 snprintf(val, sizeof(val), "VIDEO_TSTAMP_DISCONTINUITY:0x%x", vpts);
119 return config_sys_node(TSYNC_EVENT, val);
120}
Song Zhaobf35d4a2020-06-18 22:36:29 -0700121
122int tsync_set_pcr(int session, uint32_t pcr)
123{
124 char val[20];
125
126 snprintf(val, sizeof(val), "%u", pcr);
127 config_sys_node(TSYNC_PCRSCR, val);
128 return 0;
129}
130
131static int video_device_ioctl(int ctl, int value)
132{
133 int video_fd;
134
135 video_fd = open(VIDEO_DEVICE, O_RDWR);
136 if (video_fd < 0) {
137 return -1;
138 }
139
140 ioctl(video_fd, ctl, &value);
141
142 close(video_fd);
143
144 return 0;
145}
146
147int tsync_set_pts_inc_mode(int session, bool enable)
148{
149 return video_device_ioctl(AMSTREAM_IOC_SET_VSYNC_UPINT, enable);
150}
151
152int tsync_set_mode(int session, enum sync_mode mode)
153{
154 const char* val = NULL;
155 if (mode == AV_SYNC_MODE_VMASTER)
156 val = "0";
157 else if (mode == AV_SYNC_MODE_AMASTER)
158 val = "1";
159 else if (mode == AV_SYNC_MODE_PCR_MASTER)
160 val = "2";
161 return config_sys_node(TSYNC_MODE, val);
162}
163
164int tsync_set_video_peek_mode(int session)
165{
166 return video_device_ioctl(AMSTREAM_IOC_SET_VIDEOPEEK, 0);
167}