summaryrefslogtreecommitdiff
path: root/tvapi/libtv/tvin/CSourceConnectDetect.cpp (plain)
blob: ad44ad12be1a4915bee71864a2607df6874ee4b8
1#include "CTvin.h"
2#include <CTvLog.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <unistd.h>
6#include <sys/prctl.h>
7#include <fcntl.h>
8#include <errno.h>
9
10#include <cutils/log.h>
11
12#include "../tvutils/tvutils.h"
13#include "../tvconfig/tvconfig.h"
14
15#ifdef LOG_TAG
16#undef LOG_TAG
17#define LOG_TAG "CSourceConnectDetect"
18#endif
19
20#define CC_DETECT_SOURCE_AV2 (0)
21
22#define CC_DEBUG_AV_SAMPLE_BUF (1)
23
24#define CC_AV_PLUG_OUT_ADC_DEF_THRESHOLD (28) // voltage / 1800 * 1023
25#define CC_AV_PLUG_IN_ADC_DEF_THRESHOLD (70) // voltage / 1800 * 1023
26
27CTvin::CSourceConnectDetect::CSourceConnectDetect(CTvin *pTvin)
28{
29 for (int i = 0; i < SOURCE_MAX; i++) {
30 mSourceDetectTable[i] = SOURCE_INVALID;
31 mSourceDetectPreStatusBuf[i] = CC_SOURCE_PLUG_OUT;
32 mSourceDetectCurStatusBuf[i] = CC_SOURCE_PLUG_OUT;
33 }
34
35 for (int i = 0; i < CC_AV_DETECT_SAMPLE_DATA_MAX_LEN; i++) {
36 mAV1SampleDataBuf[i] = 0;
37 mAV2SampleDataBuf[i] = 0;
38 }
39
40#if CC_DETECT_SOURCE_AV2 == 1
41 mSourceDetectTable[0] = SOURCE_AV1;
42 mSourceDetectTable[1] = SOURCE_AV2;
43 mSourceDetectTable[2] = SOURCE_HDMI1;
44 mSourceDetectTable[3] = SOURCE_HDMI2;
45 mSourceDetectTable[4] = SOURCE_HDMI3;
46#else
47 mSourceDetectTable[0] = SOURCE_AV1;
48 mSourceDetectTable[1] = SOURCE_HDMI1;
49 mSourceDetectTable[2] = SOURCE_HDMI2;
50 mSourceDetectTable[3] = SOURCE_HDMI3;
51#endif
52
53 mSourceDetectSleepTime = 200; //default 200ms
54
55 mAVDetectMethod = CC_AV_DETECT_METHOD_ADC_PLUG_OUT;
56 mAVDetectPlugOutADCThreshold = CC_AV_PLUG_OUT_ADC_DEF_THRESHOLD;
57 mAVDetectPlugInADCThreshold = CC_AV_PLUG_IN_ADC_DEF_THRESHOLD;
58 mAVDetectPlugInDutyCycle = 70;
59 mAVDetectPlugOutDutyCycle = 70;
60 mAVDetectSampleSize = 15;
61 mAV1DetectADCChan = 2;
62 mAV2DetectADCChan = 3;
63
64 mpObserver = NULL;
65 mpTvin = pTvin;
66}
67
68CTvin::CSourceConnectDetect::~CSourceConnectDetect()
69{
70}
71
72int CTvin::CSourceConnectDetect::startDetect()
73{
74 refreshDetectSources();
75 refreshDetectAVInfo();
76 this->run();
77
78 return 0;
79}
80
81int CTvin::CSourceConnectDetect::refreshDetectSources()
82{
83 int cur_index = 0;
84 char *token = NULL;
85 const char *strDelimit = ",";
86 const char *config_value = NULL;
87 char data_str[CC_CFG_VALUE_STR_MAX_LEN] = { 0 };
88
89 config_value = config_get_str("TV", "tvin.SourceConnectDetect.sources", "null");
90 if (strcasecmp(config_value, "null") == 0) {
91 return 0;
92 }
93
94 for (int i = 0; i < SOURCE_MAX; i++) {
95 mSourceDetectTable[i] = SOURCE_INVALID;
96 mSourceDetectPreStatusBuf[i] = CC_SOURCE_PLUG_OUT;
97 mSourceDetectCurStatusBuf[i] = CC_SOURCE_PLUG_OUT;
98 }
99
100 cur_index = 0;
101 memset((void *)data_str, 0, sizeof(data_str));
102 strncpy(data_str, config_value, sizeof(data_str) - 1);
103 token = strtok(data_str, strDelimit);
104 while (token != NULL) {
105 if (strcasecmp(token, "SOURCE_AV1") == 0) {
106 mSourceDetectTable[cur_index] = SOURCE_AV1;
107 cur_index += 1;
108 //LOGD("%s, add detect source SOURCE_AV1.\n", __FUNCTION__);
109 } else if (strcasecmp(token, "SOURCE_AV2") == 0) {
110 mSourceDetectTable[cur_index] = SOURCE_AV2;
111 cur_index += 1;
112 //LOGD("%s, add detect source SOURCE_AV2.\n", __FUNCTION__);
113 } else if (strcasecmp(token, "SOURCE_HDMI1") == 0) {
114 mSourceDetectTable[cur_index] = SOURCE_HDMI1;
115 cur_index += 1;
116 //LOGD("%s, add detect source SOURCE_HDMI1.\n", __FUNCTION__);
117 } else if (strcasecmp(token, "SOURCE_HDMI2") == 0) {
118 mSourceDetectTable[cur_index] = SOURCE_HDMI2;
119 cur_index += 1;
120 //LOGD("%s, add detect source SOURCE_HDMI2.\n", __FUNCTION__);
121 } else if (strcasecmp(token, "SOURCE_HDMI3") == 0) {
122 mSourceDetectTable[cur_index] = SOURCE_HDMI3;
123 cur_index += 1;
124 //LOGD("%s, add detect source SOURCE_HDMI3.\n", __FUNCTION__);
125 }
126
127 token = strtok(NULL, strDelimit);
128 }
129
130 return 0;
131}
132
133int CTvin::CSourceConnectDetect::refreshDetectAVInfo()
134{
135 int cur_index = 0;
136 char *token = NULL;
137 const char *strDelimit = ",";
138 const char *config_value = NULL;
139 char data_str[CC_CFG_VALUE_STR_MAX_LEN] = { 0 };
140
141 config_value = config_get_str("TV", "tvin.SourceConnectDetect.av.info", "null");
142 if (strcasecmp(config_value, "null") == 0) {
143 return 0;
144 }
145
146 cur_index = 0;
147 memset((void *)data_str, 0, sizeof(data_str));
148 strncpy(data_str, config_value, sizeof(data_str) - 1);
149 token = strtok(data_str, strDelimit);
150 while (token != NULL) {
151 if (cur_index == 0) {
152 mAV1DetectADCChan = strtol(token, NULL, 10);
153 } else if (cur_index == 1) {
154 mAV2DetectADCChan = strtol(token, NULL, 10);
155 } else if (cur_index == 2) {
156 mAVDetectSampleSize = strtol(token, NULL, 10);
157 } else if (cur_index == 3) {
158 mAVDetectMethod = strtol(token, NULL, 10);
159 } else if (cur_index == 4) {
160 mAVDetectPlugInDutyCycle = strtol(token, NULL, 10);
161 } else if (cur_index == 5) {
162 mAVDetectPlugOutDutyCycle = strtol(token, NULL, 10);
163 } else if (cur_index == 6) {
164 mAVDetectPlugInADCThreshold = strtol(token, NULL, 10);
165 } else if (cur_index == 7) {
166 mAVDetectPlugOutADCThreshold = strtol(token, NULL, 10);
167 }
168
169 cur_index += 1;
170 token = strtok(NULL, strDelimit);
171 }
172
173 return 0;
174}
175
176int CTvin::CSourceConnectDetect::GetSourceConnectStatus(int source_input)
177{
178 for (int i = 0; i < SOURCE_MAX; i++) {
179 if (mSourceDetectTable[i] == source_input) {
180 return mSourceDetectCurStatusBuf[i];
181 }
182 }
183
184 return CC_SOURCE_PLUG_OUT;
185}
186
187bool CTvin::CSourceConnectDetect::threadLoop()
188{
189 if ( mpObserver == NULL ) {
190 return false;
191 }
192
193 LOGD("%s, entering...\n", "TV");
194
195 prctl(PR_SET_NAME, (unsigned long)"CSourceConnectDetect thread loop");
196
197 mpTvin->VDIN_OpenHDMIPinMuxOn(true);
198
199 while (!exitPending()) { //requietexit() or requietexitWait() not call
200 DetectSources();
201
202 usleep(mSourceDetectSleepTime * 1000);
203 }
204
205 LOGD("%s, exiting...\n", "TV");
206 //return true, run again, return false,not run.
207 return false;
208}
209
210int CTvin::CSourceConnectDetect::DetectSources()
211{
212 int i = 0, cur_source = 0;
213
214 for (i = 0; i < SOURCE_MAX; i++) {
215 cur_source = mSourceDetectTable[i];
216 if (cur_source == SOURCE_AV1 || cur_source == SOURCE_AV2) {
217 mSourceDetectCurStatusBuf[i] = DetectAVSource(cur_source);
218 } else if (cur_source == SOURCE_HDMI1 || cur_source == SOURCE_HDMI2 || cur_source == SOURCE_HDMI3) {
219 mSourceDetectCurStatusBuf[i] = DetectHDMISource(cur_source);
220 }
221 }
222
223 for (i = 0; i < SOURCE_MAX; i++) {
224 if (mSourceDetectCurStatusBuf[i] != mSourceDetectPreStatusBuf[i]) {
225 mSourceDetectPreStatusBuf[i] = mSourceDetectCurStatusBuf[i];
226 LOGD("%s, Source id = %d, Source plug status = %d\n", "TV", mSourceDetectTable[i], mSourceDetectCurStatusBuf[i]);
227
228#if CC_DEBUG_AV_SAMPLE_BUF == 1
229 int *cur_sample_buf = NULL;
230
231 if (mSourceDetectTable[i] == SOURCE_AV1) {
232 cur_sample_buf = mAV1SampleDataBuf;
233 } else if (mSourceDetectTable[i] == SOURCE_AV2) {
234 cur_sample_buf = mAV2SampleDataBuf;
235 }
236
237 if (cur_sample_buf != NULL) {
238 for (int j = 0; j < mAVDetectSampleSize; j++) {
239 LOGD("%s, cur_sample_buf[%d] = %d\n", "TV", j, cur_sample_buf[j]);
240 }
241 LOGD("%s, \n\n\n", "TV", i, cur_sample_buf[i]);
242 }
243#endif
244
245 mpObserver->onSourceConnect(mSourceDetectTable[i], mSourceDetectCurStatusBuf[i]);
246 }
247 }
248
249 return 0;
250}
251
252int CTvin::CSourceConnectDetect::DetectAVSource(int source_input)
253{
254 int i = 0, plug_in_cnt = 0, plug_out_cnt = 0;
255 int detect_adc_chan = -1, cur_adc_val = 0;
256 int *cur_sample_ind = 0;
257 int *cur_sample_buf = NULL;
258
259 if (source_input == SOURCE_AV1) {
260 detect_adc_chan = mAV1DetectADCChan;
261 cur_sample_ind = &mAV1CurSampleInd;
262 cur_sample_buf = mAV1SampleDataBuf;
263 } else if (source_input == SOURCE_AV2) {
264 detect_adc_chan = mAV2DetectADCChan;
265 cur_sample_ind = &mAV2CurSampleInd;
266 cur_sample_buf = mAV2SampleDataBuf;
267 } else {
268 return CC_SOURCE_PLUG_OUT;
269 }
270
271 cur_adc_val = ReadADCSpecialChannelValue(detect_adc_chan);
272 *cur_sample_ind = *cur_sample_ind % mAVDetectSampleSize;
273 cur_sample_buf[*cur_sample_ind] = cur_adc_val;
274 *cur_sample_ind = (*cur_sample_ind + 1 ) % mAVDetectSampleSize;
275
276 plug_in_cnt = 0;
277 plug_out_cnt = 0;
278 for (i = 0; i < mAVDetectSampleSize; i++) {
279 if (cur_sample_buf[i] >= mAVDetectPlugInADCThreshold) {
280 plug_in_cnt += 1;
281 } else if (cur_sample_buf[i] <= mAVDetectPlugOutADCThreshold) {
282 plug_out_cnt += 1;
283 }
284 }
285
286 if (mAVDetectMethod == CC_AV_DETECT_METHOD_ADC_PLUG_IN) {
287 if ((plug_in_cnt * 100 / mAVDetectSampleSize) >= mAVDetectPlugInDutyCycle) {
288 return CC_SOURCE_PLUG_IN;
289 }
290
291 return CC_SOURCE_PLUG_OUT;
292 } else if (mAVDetectMethod == CC_AV_DETECT_METHOD_ADC_PLUG_OUT) {
293 if ((plug_out_cnt * 100 / mAVDetectSampleSize) >= mAVDetectPlugOutDutyCycle) {
294 return CC_SOURCE_PLUG_OUT;
295 }
296
297 return CC_SOURCE_PLUG_IN;
298 }
299
300 return CC_SOURCE_PLUG_OUT;
301}
302
303int CTvin::CSourceConnectDetect::DetectHDMISource(int source_input)
304{
305 int source_port = CTvin::Tvin_GetSourcePortBySourceInput((tv_source_input_t)source_input);
306
307 if (mpTvin->VDIN_GetPortConnect(source_port) == true) {
308 return CC_SOURCE_PLUG_IN;
309 }
310
311 return CC_SOURCE_PLUG_OUT;
312}
313