blob: 619152970e2946c96c4d82fbf1fce33a91e357c8 [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"
Song Zhaoebb53bb2020-07-10 17:57:34 -070021#include "aml_avsync_log.h"
Song Zhao6859d412020-06-15 17:16:04 -070022
Song Zhaobf35d4a2020-06-18 22:36:29 -070023#define VIDEO_DEVICE "/dev/amvideo"
Song Zhao6859d412020-06-15 17:16:04 -070024#define TSYNC_ENABLE "/sys/class/tsync/enable"
25#define TSYNC_PCRSCR "/sys/class/tsync/pts_pcrscr"
26#define TSYNC_EVENT "/sys/class/tsync/event"
Song Zhaobf35d4a2020-06-18 22:36:29 -070027#define TSYNC_MODE "/sys/class/tsync/mode"
28
29#define _A_M 'S'
30#define AMSTREAM_IOC_SET_VSYNC_UPINT _IOW((_A_M), 0x89, int)
31#define AMSTREAM_IOC_SET_VIDEOPEEK _IOW(_A_M, 0xbf, unsigned int)
Song Zhao6859d412020-06-15 17:16:04 -070032
33static int config_sys_node(const char* path, const char* value)
34{
35 int fd;
36 fd = open(path, O_RDWR);
37 if (fd < 0) {
Song Zhaoebb53bb2020-07-10 17:57:34 -070038 log_error("fail to open %s\n", path);
Song Zhao6859d412020-06-15 17:16:04 -070039 return -1;
40 }
41 if (write(fd, value, strlen(value)) != strlen(value)) {
Song Zhaoebb53bb2020-07-10 17:57:34 -070042 log_error("fail to write %s to %s\n", value, path);
Song Zhao6859d412020-06-15 17:16:04 -070043 close(fd);
44 return -1;
45 }
46 close(fd);
47
48 return 0;
49}
50
51static int get_sysfs_uint32(const char *path, uint32_t *value)
52{
53 int fd;
54 char valstr[64];
55 uint32_t val = 0;
56
57 fd = open(path, O_RDONLY);
58 if (fd >= 0) {
59 memset(valstr, 0, 64);
60 read(fd, valstr, 64 - 1);
61 valstr[strlen(valstr)] = '\0';
62 close(fd);
63 } else {
Song Zhaoebb53bb2020-07-10 17:57:34 -070064 log_error("unable to open file %s\n", path);
Song Zhao6859d412020-06-15 17:16:04 -070065 return -1;
66 }
67 if (sscanf(valstr, "0x%x", &val) < 1) {
Song Zhaoebb53bb2020-07-10 17:57:34 -070068 log_error("unable to get pts from: %s", valstr);
Song Zhao6859d412020-06-15 17:16:04 -070069 return -1;
70 }
71 *value = val;
72 return 0;
73}
74
Song Zhaobf35d4a2020-06-18 22:36:29 -070075int tsync_enable(int session, bool enable)
Song Zhao6859d412020-06-15 17:16:04 -070076{
77 const char *val;
78
79 if (enable)
80 val = "1";
81 else
82 val = "0";
Song Zhaoebb53bb2020-07-10 17:57:34 -070083 log_info("%s", val);
Song Zhaobf35d4a2020-06-18 22:36:29 -070084 return config_sys_node(TSYNC_ENABLE, val);
Song Zhao6859d412020-06-15 17:16:04 -070085}
86
87uint32_t tsync_get_pcr(int session)
88{
89 uint32_t pcr = 0;
90
91 get_sysfs_uint32(TSYNC_PCRSCR, &pcr);
92 return pcr;
93}
94
95//uint32_t tsync_get_vpts(int session);
96
97int tsync_send_video_start(int session, uint32_t vpts)
98{
99 char val[50];
100
101 snprintf(val, sizeof(val), "VIDEO_START:0x%x", vpts);
Song Zhaoebb53bb2020-07-10 17:57:34 -0700102 log_info("%s", val);
Song Zhao6859d412020-06-15 17:16:04 -0700103 return config_sys_node(TSYNC_EVENT, val);
104}
105
106int tsync_send_video_pause(int session, bool pause)
107{
108 const char *val;
109
110 if (pause)
111 val = "VIDEO_PAUSE:0x1";
112 else
113 val = "VIDEO_PAUSE:0x0";
Song Zhaoebb53bb2020-07-10 17:57:34 -0700114 log_info("%s", val);
Song Zhao6859d412020-06-15 17:16:04 -0700115 return config_sys_node(TSYNC_EVENT, val);
116}
117
118int tsync_send_video_disc(int session, uint32_t vpts)
119{
120 char val[50];
121
122 snprintf(val, sizeof(val), "VIDEO_TSTAMP_DISCONTINUITY:0x%x", vpts);
Song Zhaoebb53bb2020-07-10 17:57:34 -0700123 log_info("%s", val);
Song Zhao6859d412020-06-15 17:16:04 -0700124 return config_sys_node(TSYNC_EVENT, val);
125}
Song Zhaobf35d4a2020-06-18 22:36:29 -0700126
127int tsync_set_pcr(int session, uint32_t pcr)
128{
129 char val[20];
130
131 snprintf(val, sizeof(val), "%u", pcr);
132 config_sys_node(TSYNC_PCRSCR, val);
133 return 0;
134}
135
136static int video_device_ioctl(int ctl, int value)
137{
138 int video_fd;
139
140 video_fd = open(VIDEO_DEVICE, O_RDWR);
141 if (video_fd < 0) {
142 return -1;
143 }
144
Song Zhaoebb53bb2020-07-10 17:57:34 -0700145 ioctl(video_fd, ctl, value);
Song Zhaobf35d4a2020-06-18 22:36:29 -0700146
147 close(video_fd);
148
149 return 0;
150}
151
152int tsync_set_pts_inc_mode(int session, bool enable)
153{
154 return video_device_ioctl(AMSTREAM_IOC_SET_VSYNC_UPINT, enable);
155}
156
157int tsync_set_mode(int session, enum sync_mode mode)
158{
159 const char* val = NULL;
160 if (mode == AV_SYNC_MODE_VMASTER)
161 val = "0";
162 else if (mode == AV_SYNC_MODE_AMASTER)
163 val = "1";
164 else if (mode == AV_SYNC_MODE_PCR_MASTER)
165 val = "2";
166 return config_sys_node(TSYNC_MODE, val);
167}
168
169int tsync_set_video_peek_mode(int session)
170{
171 return video_device_ioctl(AMSTREAM_IOC_SET_VIDEOPEEK, 0);
172}