xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/IspFec/src/RkIspFecHwMgr.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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