1
2 /*
3 * Copyright (c) 2022 Rockchip Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 #include "RkIspFecHwMgr.h"
20
21 #include <dirent.h>
22 #include <dlfcn.h>
23 #include <fcntl.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <sys/ioctl.h>
27 #include <sys/mman.h>
28 #include <sys/time.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <linux/videodev2.h>
32
33 namespace RKISPFEC {
34
35 RkIspFecHwMgr* RkIspFecHwMgr::mInstance = NULL;
36 pthread_mutex_t RkIspFecHwMgr::mMutex = PTHREAD_MUTEX_INITIALIZER;
37 pthread_cond_t RkIspFecHwMgr::mCond = PTHREAD_COND_INITIALIZER;
38 int RkIspFecHwMgr::mRefCnt = 0;
39
40 #define SEARCH_MAX_VIDEO_NODES 128
41
RkIspFecHwMgr()42 RkIspFecHwMgr::RkIspFecHwMgr()
43 {
44 mFecVdNum = 0;
45 mFecVdPath[0][0] = '\0';
46 mFecVdPath[1][0] = '\0';
47 mFecHw[0] = NULL;
48 mFecHw[1] = NULL;
49
50 findFecEntry();
51
52 for (int i = 0; i < mFecVdNum; i++) {
53 mFecHw[i] = new RkIspFecHw(mFecVdPath[i]);
54 }
55 printf("I: %s constructor done !\n", __FUNCTION__);
56 }
57
~RkIspFecHwMgr()58 RkIspFecHwMgr::~RkIspFecHwMgr()
59 {
60 for (int i = 0; i < mFecVdNum; i++) {
61 delete mFecHw[i];
62 }
63
64 }
65
getInstance()66 RkIspFecHwMgr* RkIspFecHwMgr::getInstance()
67 {
68 RkIspFecHwMgr* mgr = NULL;
69 int ret = pthread_mutex_lock (&mMutex);
70
71 if (!mInstance)
72 mgr = new RkIspFecHwMgr();
73 else
74 mgr = mInstance;
75
76 mRefCnt++;
77 ret = pthread_mutex_unlock (&mMutex);
78
79 return mgr;
80 }
81
82 void
deinit()83 RkIspFecHwMgr::deinit()
84 {
85 int ret = pthread_mutex_lock (&mMutex);
86
87 if (mRefCnt > 0 && mRefCnt--) {
88 if (mInstance && mRefCnt == 0) {
89 delete mInstance;
90 mInstance = NULL;
91 }
92 }
93
94 ret = pthread_mutex_unlock (&mMutex);
95
96 return;
97 }
98
readFileList(const char * basePath)99 int RkIspFecHwMgr::readFileList(const char *basePath) {
100 DIR *dir;
101 int found = -1;
102 struct dirent *ptr;
103 char filename[1000];
104
105 if ((dir = opendir(basePath)) == NULL) {
106 printf("E: Open dir error...\n");
107 return found;
108 }
109
110 while ((ptr = readdir(dir)) != NULL) {
111 if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
112 /// current dir OR parrent dir
113 continue;
114 } else if (ptr->d_type == 8) {
115 /// file, check video*/name whether has rkispp_fec info
116 if (strcmp(ptr->d_name, "name") == 0) {
117 memset(filename, '\0', sizeof(filename));
118 strcpy(filename, basePath);
119 strcat(filename, "/");
120 strcat(filename, ptr->d_name);
121 FILE *fp = fopen(filename, "rb");
122 if (fp) {
123 char buf[128];
124 const char* ret = fgets(buf, 128, fp);
125 // printf("buf=%s\n", buf);
126 if (strstr(buf, "rkispp_fec") != NULL) {
127 printf("found ispp fec node\n");
128 found = 1;
129 fclose(fp);
130 break;
131 }
132 fclose(fp);
133 }
134 }
135 } else if (ptr->d_type == 10) {
136 // TODO: nothing
137 } else if (ptr->d_type == 4) {
138 // TODO: nothing
139 }
140 }
141 closedir(dir);
142 return found;
143 }
144
findFecEntry()145 void RkIspFecHwMgr::findFecEntry() {
146 int found = -1;
147 char path[128] = {0};
148
149 for (int i = 0; i < SEARCH_MAX_VIDEO_NODES; i++) {
150 memset(path, 0, sizeof(path));
151 snprintf(path, sizeof(path), "/sys/class/video4linux/video%d", i);
152 if (0 == access(path, F_OK)) {
153 found = readFileList(path);
154 if (found > 0) {
155 sprintf(mFecVdPath[mFecVdNum], "/dev/video%d", i);
156 mFecVdNum++;
157 if (mFecVdNum == 2)
158 break;
159 }
160 }
161 }
162
163 if (mFecVdNum == 0)
164 printf("E: not found fec hw !\n");
165 else {
166 printf("I: found %d hw !\n", mFecVdNum);
167 }
168
169 return;
170 }
171
172 int
selectFecHw()173 RkIspFecHwMgr::selectFecHw()
174 {
175 int fecHw = -1;
176
177 if (mFecVdNum <= 0)
178 return fecHw;
179
180 int ret = pthread_mutex_lock (&mMutex);
181
182 if (mFecHw[0] && !mIsFecHwWking[0]) {
183 fecHw = 0;
184 mIsFecHwWking[0] = true;
185 } else if (mFecHw[1] && !mIsFecHwWking[1]) {
186 fecHw = 1;
187 mIsFecHwWking[1] = true;
188 } else {
189 // wait for fecHw0
190 ret = pthread_cond_wait (&mCond, &mMutex);
191 fecHw = 0;
192 mIsFecHwWking[0] = true;
193 }
194 ret = pthread_mutex_unlock (&mMutex);
195
196 return fecHw;
197 }
198
199 int
process(struct rkispp_fec_in_out & param)200 RkIspFecHwMgr::process(struct rkispp_fec_in_out& param)
201 {
202 int fecHw = selectFecHw();
203 int ret = -1;
204
205 if (fecHw != -1) {
206 ret = mFecHw[fecHw]->process(param);
207 if (ret) {
208 printf("E: process error:%d \n", ret);
209 }
210 ret |= pthread_mutex_lock (&mMutex);
211 mIsFecHwWking[fecHw] = false;
212 pthread_cond_broadcast(&mCond);
213 ret |= pthread_mutex_unlock (&mMutex);
214 } else {
215 printf("E: no fecHw exsist \n");
216 }
217
218 return ret;
219 }
220
221 };
222