hv_mw_Channel_SearchSource.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. /**
  2. * @file Hv_Mw_Channel_SearchSource.c
  3. * @brief middlware channel Search source file.
  4. * @details This file provides the following functions: \n
  5. * (1) Initialization and de-initialization functions \n
  6. * (2) Start and stop functions \n
  7. * (3) Feed functions \n
  8. *
  9. * @author HiView SoC Software Team
  10. * @version 1.0.0
  11. * @date 2022-08-23
  12. * @copyright Copyright(c),2022-8, Hiview Software. All rights reserved.
  13. * @par History:
  14. * <table>
  15. * <tr><th>Author <th>Date <th>Change Description
  16. * <tr><td>HiView SoC Software Team <td>2022-08-23 <td>init
  17. * </table>
  18. */
  19. #include "hv_comm_DataBase.h"
  20. #include "hv_comm_Assert.h"
  21. #include "hv_drv_DpuCommon.h"
  22. #include "hv_mw_Channel_SearchSource.h"
  23. #include "hv_mw_InputPortManager.h"
  24. #include "hv_mw_SystemManager.h"
  25. #include "hv_mw_Video_TimingCheck.h"
  26. #ifdef CONFIG_USER_USB_OTA_ON
  27. #include "hv_mw_UsbTask.h"
  28. #endif
  29. static SearchStrategy s_astRealTimeMainSearchTable[] =
  30. {
  31. #if (HV_BOARD_CONFIG_HDMI_0 == PORT_VALID)
  32. {0, 0, 0},
  33. #endif
  34. #if (HV_BOARD_CONFIG_HDMI_1 == PORT_VALID)
  35. {1, 0, 0},
  36. #endif
  37. #if (HV_BOARD_CONFIG_DISPLAYPORT_0 == PORT_VALID)
  38. {2, 0, 0},
  39. #endif
  40. #if (HV_BOARD_CONFIG_DISPLAYPORT_1 == PORT_VALID)
  41. {3, 0, 0},
  42. #endif
  43. };
  44. static SearchStrategy stRealTimeSubSearchTable[] =
  45. {
  46. #if (HV_BOARD_CONFIG_HDMI_0 == PORT_VALID)
  47. {0, 0, 0},
  48. #endif
  49. #if (HV_BOARD_CONFIG_HDMI_1 == PORT_VALID)
  50. {1, 0, 0},
  51. #endif
  52. #if (HV_BOARD_CONFIG_DISPLAYPORT_0 == PORT_VALID)
  53. {2, 0, 0},
  54. #endif
  55. #if (HV_BOARD_CONFIG_DISPLAYPORT_1 == PORT_VALID)
  56. {3, 0, 0},
  57. #endif
  58. };
  59. static LinkPortIndex aenNosignalSearchPortTable[] =
  60. {
  61. #if (HV_BOARD_CONFIG_HDMI_0 == PORT_VALID)
  62. LINK_PORT_INDEX_HDMI_RX0,
  63. #endif
  64. #if (HV_BOARD_CONFIG_HDMI_1 == PORT_VALID)
  65. LINK_PORT_INDEX_HDMI_RX1,
  66. #endif
  67. #if (HV_BOARD_CONFIG_DISPLAYPORT_0 == PORT_VALID)
  68. LINK_PORT_INDEX_DP_RX0,
  69. #endif
  70. #if (HV_BOARD_CONFIG_DISPLAYPORT_1 == PORT_VALID)
  71. LINK_PORT_INDEX_DP_RX1,
  72. #endif
  73. };
  74. static BOOL CheckPortOnUsing(ChannelType enCurrentSearch, LinkPortIndex enMwPortIndex)
  75. {
  76. const ChannelManager* pstChannelManager = Hv_Mw_Channel_GetManager();
  77. HV_ASSERT_VALID_PTR_RET(pstChannelManager, HV_FALSE);
  78. #ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
  79. /*PIP关闭,端口必然未被占用*/
  80. if (0 == HV_COMMON_DATABASE_GET(UserData, ucPxPMode))
  81. {
  82. return HV_FALSE;
  83. }
  84. #if (HV_CONFIG_ON == HV_PROJECT_CONFIG_MAGNIFY)
  85. else if (1 == HV_COMMON_DATABASE_GET(UserData, bMagnifyGlassSw))
  86. {
  87. return HV_FALSE;
  88. }
  89. #endif
  90. #if (HV_CONFIG_ON == HV_PROJECT_CONFIG_DPU_BRIGHT_FRAME)
  91. else if (1 == HV_COMMON_DATABASE_GET(UserData, bBrightFrameEn))
  92. {
  93. return HV_FALSE;
  94. }
  95. #endif
  96. else
  97. #endif
  98. {
  99. /*当前搜索的通道是主通道,那么需要检查该端口是否被辅通道占用*/
  100. if (CHANNEL_TYPE_MAIN == enCurrentSearch)
  101. {
  102. #ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
  103. return (enMwPortIndex == pstChannelManager->astChannelData[1].enChannelSrcLinkPortIndex);
  104. #else
  105. return HV_FALSE;
  106. #endif
  107. }
  108. else/*当前搜索的通道是辅通道,那么需要检查该端口是否被主通道占用*/
  109. {
  110. return (enMwPortIndex == pstChannelManager->astChannelData[0].enChannelSrcLinkPortIndex);
  111. }
  112. }
  113. return HV_FALSE;
  114. }
  115. UCHAR8 Hv_Mw_Channel_ConvertMwToGuiPortIndex(LinkPortIndex enPortIndex)
  116. {
  117. UCHAR8 ucGuiPortIndex = 0;
  118. switch (enPortIndex)
  119. {
  120. #if (HV_BOARD_CONFIG_HDMI_0 == PORT_VALID)
  121. case LINK_PORT_INDEX_HDMI_RX0:
  122. {
  123. ucGuiPortIndex = 0;
  124. break;
  125. }
  126. #endif
  127. #if (HV_BOARD_CONFIG_HDMI_1 == PORT_VALID)
  128. case LINK_PORT_INDEX_HDMI_RX1:
  129. {
  130. ucGuiPortIndex = 1;
  131. break;
  132. }
  133. #endif
  134. #if (HV_BOARD_CONFIG_DISPLAYPORT_0 == PORT_VALID)
  135. case LINK_PORT_INDEX_DP_RX0:
  136. {
  137. ucGuiPortIndex = 2;
  138. break;
  139. }
  140. #endif
  141. #if (HV_BOARD_CONFIG_DISPLAYPORT_1 == PORT_VALID)
  142. case LINK_PORT_INDEX_DP_RX1:
  143. {
  144. ucGuiPortIndex = 3;
  145. break;
  146. }
  147. #endif
  148. default:
  149. {
  150. break;
  151. }
  152. }
  153. return ucGuiPortIndex;
  154. }
  155. LinkPortIndex Hv_Mw_Channel_ConvertGuiToMwPortIndex(UCHAR8 ucGuiPortIndex)
  156. {
  157. LinkPortIndex enPortIndex = LINK_PORT_INDEX_HDMI_RX0;
  158. switch (ucGuiPortIndex)
  159. {
  160. #if (HV_BOARD_CONFIG_HDMI_0 == PORT_VALID)
  161. case 0:
  162. {
  163. enPortIndex = LINK_PORT_INDEX_HDMI_RX0;
  164. break;
  165. }
  166. #endif
  167. #if (HV_BOARD_CONFIG_HDMI_1 == PORT_VALID)
  168. case 1:
  169. {
  170. enPortIndex = LINK_PORT_INDEX_HDMI_RX1;
  171. break;
  172. }
  173. #endif
  174. #if (HV_BOARD_CONFIG_DISPLAYPORT_0 == PORT_VALID)
  175. case 2:
  176. {
  177. enPortIndex = LINK_PORT_INDEX_DP_RX0;
  178. break;
  179. }
  180. #endif
  181. #if (HV_BOARD_CONFIG_DISPLAYPORT_1 == PORT_VALID)
  182. case 3:
  183. {
  184. enPortIndex = LINK_PORT_INDEX_DP_RX1;
  185. break;
  186. }
  187. #endif
  188. default:
  189. {
  190. break;
  191. }
  192. }
  193. return enPortIndex;
  194. }
  195. static Status SendTimingNotSuportToOsd(UINT32 uiCheckResult, ChannelType enChannelTye, LinkPortIndex enPortIndex)
  196. {
  197. HV_VOS_QUEUE_S *pOsdQueue = Hv_Mw_System_GetOsdQueue();
  198. HV_ASSERT_VALID_PTR(pOsdQueue);
  199. OsdEvent stOsdEvent = {0};
  200. stOsdEvent.usEventId = OSD_EVENT_SIGNAL_TIMING_NOT_SUPPORT; /*给OSD发NOT_SUPPORT消息分为NOT_SUPPORT和OUT_OF_RANGE两种,通过value区分*/
  201. stOsdEvent.usValue |= uiCheckResult & 0x00FF; /*ERROR_RX_TIMING_FREQ_OUT_OF_RANGE 11, ERROR_RX_TIMING_UNSUPPORT 14*/
  202. stOsdEvent.usValue |= (enChannelTye << 8) & 0x0F00;
  203. stOsdEvent.usValue |= (enPortIndex << 12) & 0xF000;
  204. HV_ASSERT_PEEK_TRUE(Hv_Vos_QueueSend(pOsdQueue, &stOsdEvent));
  205. HV_LOG_DEBUG(CHANNEL, "send OSD_EVENT_SIGNAL_TIMING_NOT_SUPPORT to OsdTask success usValue=0x%x!!!", stOsdEvent.usValue);
  206. return HV_SUCCESS;
  207. }
  208. static UINT32 GetCurrentPortSearchTimes(ChannelData* pstChannelData)
  209. {
  210. if (Hv_Mw_InputPort_GetCableStatus(pstChannelData->enChannelSrcLinkPortIndex))
  211. {
  212. return HV_PROJECT_CONFIG_CURRENT_PORT_SEARCHE_TIMES;
  213. }
  214. else
  215. {
  216. return HV_PROJECT_CONFIG_EACH_PORT_DISCONNECT_SEARCHE_TIMES;
  217. }
  218. }
  219. static UINT32 GetAllPortSearchTotalTimes(ChannelData* pstChannelData)
  220. {
  221. UINT32 uiAllPortSearchTotalTimes = 0;
  222. uiAllPortSearchTotalTimes += GetCurrentPortSearchTimes(pstChannelData);
  223. if (HV_TRUE == HV_COMMON_DATABASE_GET(UserData, bAutoVideoSrcSelSw))
  224. {
  225. #if (HV_BOARD_CONFIG_HDMI_0 == PORT_VALID)
  226. if ((Hv_Mw_InputPort_GetCableStatus(LINK_PORT_INDEX_HDMI_RX0)) && (LINK_PORT_INDEX_HDMI_RX0 != pstChannelData->enChannelSrcLinkPortIndex))
  227. {
  228. /*插线的端口搜索HV_PROJECT_CONFIG_EACH_PORT_SERARCH_MAX_TIMES*/
  229. uiAllPortSearchTotalTimes += HV_PROJECT_CONFIG_EACH_PORT_SERARCH_MAX_TIMES;
  230. }
  231. else if (LINK_PORT_INDEX_HDMI_RX0 != pstChannelData->enChannelSrcLinkPortIndex)
  232. {
  233. /*插线的端口搜索HV_PROJECT_CONFIG_EACH_PORT_DISCONNECT_SEARCHE_TIMES*/
  234. uiAllPortSearchTotalTimes += HV_PROJECT_CONFIG_EACH_PORT_DISCONNECT_SEARCHE_TIMES;
  235. }
  236. #endif
  237. #if (HV_BOARD_CONFIG_HDMI_1 == PORT_VALID)
  238. if ((Hv_Mw_InputPort_GetCableStatus(LINK_PORT_INDEX_HDMI_RX1)) && (LINK_PORT_INDEX_HDMI_RX1 != pstChannelData->enChannelSrcLinkPortIndex))
  239. {
  240. uiAllPortSearchTotalTimes += HV_PROJECT_CONFIG_EACH_PORT_SERARCH_MAX_TIMES;
  241. }
  242. else if (LINK_PORT_INDEX_HDMI_RX1 != pstChannelData->enChannelSrcLinkPortIndex)
  243. {
  244. uiAllPortSearchTotalTimes += HV_PROJECT_CONFIG_EACH_PORT_DISCONNECT_SEARCHE_TIMES;
  245. }
  246. #endif
  247. #if (HV_BOARD_CONFIG_DISPLAYPORT_0 == PORT_VALID)
  248. if ((Hv_Mw_InputPort_GetCableStatus(LINK_PORT_INDEX_DP_RX0)) && (LINK_PORT_INDEX_DP_RX0 != pstChannelData->enChannelSrcLinkPortIndex))
  249. {
  250. uiAllPortSearchTotalTimes += HV_PROJECT_CONFIG_EACH_PORT_SERARCH_MAX_TIMES;
  251. }
  252. else if (LINK_PORT_INDEX_DP_RX0 != pstChannelData->enChannelSrcLinkPortIndex)
  253. {
  254. uiAllPortSearchTotalTimes += HV_PROJECT_CONFIG_EACH_PORT_DISCONNECT_SEARCHE_TIMES;
  255. }
  256. #endif
  257. #if (HV_BOARD_CONFIG_DISPLAYPORT_1 == PORT_VALID)
  258. if ((Hv_Mw_InputPort_GetCableStatus(LINK_PORT_INDEX_DP_RX1)) && (LINK_PORT_INDEX_DP_RX1 != pstChannelData->enChannelSrcLinkPortIndex))
  259. {
  260. uiAllPortSearchTotalTimes += HV_PROJECT_CONFIG_EACH_PORT_SERARCH_MAX_TIMES;
  261. }
  262. else if (LINK_PORT_INDEX_DP_RX1 != pstChannelData->enChannelSrcLinkPortIndex)
  263. {
  264. uiAllPortSearchTotalTimes += HV_PROJECT_CONFIG_EACH_PORT_DISCONNECT_SEARCHE_TIMES;
  265. }
  266. #endif
  267. }
  268. HV_LOG_DEBUG(CHANNEL, "uiAllPortSearchTotalTimes=%u, enChannelSrcLinkPortIndex=%u", uiAllPortSearchTotalTimes, pstChannelData->enChannelSrcLinkPortIndex);
  269. return uiAllPortSearchTotalTimes;
  270. }
  271. static Status FixSearchInputPort(ChannelData* pstChannelData)
  272. {
  273. HV_ASSERT_VALID_PTR(pstChannelData);
  274. LinkPortIndex enMwPortIndex = pstChannelData->enChannelSrcLinkPortIndex;
  275. /*绑定RX端口, for hdcp/mute/rxdpll*/
  276. const InputPortManager* pstInputPortManager = Hv_Mw_InputPort_GetManagerPtr();
  277. pstInputPortManager->pfPreProcess(enMwPortIndex);
  278. Hv_Drv_DpuScaler_SetPortMux(pstChannelData->enChannelType, enMwPortIndex);
  279. pstInputPortManager->pfBindChannelPortIndex(pstChannelData->enChannelType, enMwPortIndex); /*固定搜索及时没有接RX也要绑定port,解决PXP只有一个信号时的交换源问题*/
  280. if (Hv_Mw_InputPort_GetCableStatus(enMwPortIndex))
  281. {
  282. if (HV_SUCCESS == pstInputPortManager->pfGetVideoPara(enMwPortIndex,pstChannelData))
  283. {
  284. pstChannelData->uiErrorCode = Hv_Mw_Video_TimingCheck(enMwPortIndex,pstChannelData);
  285. if (HV_SUCCESS == pstChannelData->uiErrorCode)
  286. {
  287. /*端口timing check成功*/
  288. HV_LOG_DEBUG(CHANNEL, "Fix Search Port %u Success on Channel=%u", enMwPortIndex, pstChannelData->enChannelType);
  289. return HV_SUCCESS;
  290. }
  291. else
  292. {
  293. /*失败发消息给OSD并停止搜索, 取消给osd发送,统一由channelmanager发送,否则会一直重复发*/
  294. //SendTimingNotSuportToOsd(pstChannelData->uiErrorCode, pstChannelData->enChannelType, enMwPortIndex);
  295. HV_LOG_WARN(CHANNEL, "Fix Search Port %u fail on Channel %u,error code %u", enMwPortIndex, pstChannelData->enChannelType,pstChannelData->uiErrorCode);
  296. return HV_FAILURE;
  297. }
  298. }
  299. else
  300. {
  301. /*失败继续搜索*/
  302. HV_LOG_DEBUG(CHANNEL, "Fix Get portIndex=%u timing parameter fail, ChannelType=%u!!!", enMwPortIndex, pstChannelData->enChannelType);
  303. }
  304. }
  305. else
  306. {
  307. pstInputPortManager->pfGetVideoPara(enMwPortIndex,pstChannelData);
  308. HV_LOG_DEBUG(CHANNEL, "Fix Cable not connect!!! portIndex = %u", enMwPortIndex);
  309. }
  310. return HV_CONTINUE;
  311. }
  312. /*信号源自动搜索方案: Hw_Mw_SearchTableInit 函数将备份端口设置为搜索的最高优先界级别(图像显示后每次都会更新备份端口)。
  313. 生成的表包含未插线端口。
  314. 自动搜索时,按照不插线跳过,插线端口搜索一定次数后,如果信号可以并且通过了check那么搜索结束。
  315. 否则继续搜索表中的下一个插线端口。
  316. 搜索一轮都结束后,清空搜索次数从新调用Hw_Mw_SearchTableInit,在继续搜索。在总搜索次数未超时前均执行以上策略
  317. 对于一个端口开始未插线跳过了,之后动态插线,在搜索完本轮已插线端口后下一轮会搜索到该端口。
  318. */
  319. static Status AutoSearchAllInputPort(ChannelData* pstChannelData)
  320. {
  321. SearchStrategy* pastSearchStrategy = NULL;
  322. USHORT16 usSearchTableSize = 0;
  323. UINT32 uiSearchCheckTimes = 0;
  324. HV_ASSERT_VALID_PTR(pstChannelData);
  325. if (CHANNEL_TYPE_MAIN == pstChannelData->enChannelType)
  326. {
  327. pastSearchStrategy = s_astRealTimeMainSearchTable;
  328. usSearchTableSize = ARRAY_SIZE(s_astRealTimeMainSearchTable);
  329. }
  330. else
  331. {
  332. pastSearchStrategy = stRealTimeSubSearchTable;
  333. usSearchTableSize = ARRAY_SIZE(stRealTimeSubSearchTable);
  334. }
  335. /*自动搜索时遍历RealTimeSearchTable*/
  336. for (USHORT16 usLoopIndex = 0; usLoopIndex < usSearchTableSize; usLoopIndex++)
  337. {
  338. LinkPortIndex enMwPortIndex = Hv_Mw_Channel_ConvertGuiToMwPortIndex(pastSearchStrategy[usLoopIndex].ucGuiPortIndex);
  339. if (HV_TRUE == pastSearchStrategy[usLoopIndex].ucSearched)/*判决端口是否被search过,仅搜索未被search端口*/
  340. {
  341. HV_LOG_INFO(CHANNEL, "port %u has been searched,quit", enMwPortIndex);
  342. pastSearchStrategy[usLoopIndex].usSearchTimes = 0;
  343. continue;
  344. }
  345. else/*端口没有被search过本次search该端口*/
  346. {
  347. HV_LOG_DEBUG(CHANNEL, "ucGuiPortIndex %u ,enMwPortIndex = %u", pastSearchStrategy[usLoopIndex].ucGuiPortIndex,enMwPortIndex);
  348. if (Hv_Mw_InputPort_GetCableStatus(enMwPortIndex))
  349. {
  350. #if (0 == HV_PROJECT_CONFIG_CHANNEL_USE_SAME_PORT)
  351. /*不允许使用相同端口*/
  352. if (CheckPortOnUsing(pstChannelData->enChannelType, enMwPortIndex))/*判决该端口是否被其他通道占用*/
  353. {
  354. HV_LOG_INFO(CHANNEL, "Other Channel is using portIndex=%u, current ChannelType=%u", enMwPortIndex, pstChannelData->enChannelType);
  355. pastSearchStrategy[usLoopIndex].ucSearched = HV_TRUE;
  356. continue;/*不允许主辅使用相同端口时,使用该端口正在被其他端口占用,跳过该端口的搜索*/
  357. }
  358. #endif
  359. pastSearchStrategy[usLoopIndex].usSearchTimes++;
  360. /*设置DPU IP从哪个PORT接收数据*/
  361. /*记录该端口用于判决端口占用,以及后续配置通路mux使用*/
  362. const InputPortManager* pstInputPortManager = Hv_Mw_InputPort_GetManagerPtr();
  363. pstInputPortManager->pfPreProcess(enMwPortIndex);
  364. Hv_Drv_DpuScaler_SetPortMux(pstChannelData->enChannelType, enMwPortIndex);
  365. /*绑定RX端口, for hdcp*/
  366. pstInputPortManager->pfBindChannelPortIndex(pstChannelData->enChannelType, enMwPortIndex);
  367. if (HV_SUCCESS == pstInputPortManager->pfGetVideoPara(enMwPortIndex,pstChannelData))
  368. {
  369. pstChannelData->uiErrorCode = Hv_Mw_Video_TimingCheck(enMwPortIndex,pstChannelData);
  370. if (HV_SUCCESS == pstChannelData->uiErrorCode)
  371. {
  372. /*端口timing check成功*/
  373. pstChannelData->enChannelSrcLinkPortIndex = enMwPortIndex;
  374. HV_LOG_DEBUG(CHANNEL, "Auto Search Port %u Success on Channel=%u", enMwPortIndex, pstChannelData->enChannelType);
  375. return HV_SUCCESS;
  376. }
  377. else
  378. {
  379. /*失败发消息给OSD并停止搜索, 取消给osd发送,统一由channelmanager发送,否则会一直重复发*/
  380. //SendTimingNotSuportToOsd(pstChannelData->uiErrorCode, pstChannelData->enChannelType, enMwPortIndex);
  381. HV_LOG_WARN(CHANNEL, "Auto Search Port %u fail on Channel %u,error code %u", enMwPortIndex, pstChannelData->enChannelType,pstChannelData->uiErrorCode);
  382. return HV_FAILURE;
  383. }
  384. }
  385. else
  386. {
  387. /*失败继续搜索*/
  388. HV_LOG_DEBUG(CHANNEL, "Auto Get portIndex=%u timing parameter fail, ChannelType=%u!!!", enMwPortIndex, pstChannelData->enChannelType);
  389. }
  390. if ((1 == HV_COMMON_DATABASE_GET(SystemData, bFactoryMode))
  391. && (1 == HV_COMMON_DATABASE_GET(SystemData, bBurnInEnable)))
  392. {
  393. uiSearchCheckTimes = HV_PROJECT_CONFIG_BURN_IN_EACH_PORT_SEARCH_TIMES;
  394. }
  395. else
  396. {
  397. if(pstChannelData->enChannelSrcLinkPortIndex == enMwPortIndex)
  398. {
  399. uiSearchCheckTimes = GetCurrentPortSearchTimes(pstChannelData); /*UI菜单当前设置的通道,增加搜索次数,防止异常通道切换*/
  400. }
  401. else
  402. {
  403. uiSearchCheckTimes = HV_PROJECT_CONFIG_EACH_PORT_SERARCH_MAX_TIMES;
  404. }
  405. }
  406. if (pastSearchStrategy[usLoopIndex].usSearchTimes > uiSearchCheckTimes)
  407. {
  408. HV_LOG_INFO(CHANNEL, "reach max search times!!! portIndex = %u, SearchTimes=%u", enMwPortIndex, uiSearchCheckTimes);
  409. pastSearchStrategy[usLoopIndex].usSearchTimes = 0;
  410. pastSearchStrategy[usLoopIndex].ucSearched = HV_TRUE;
  411. }
  412. /*每次只搜索一个PORT端口, 运行此处说明已经判断完该端口跳出循环*/
  413. break;
  414. }
  415. else/*如果该端口未插线*/
  416. {
  417. /*清除使用标志,清空搜索次数*/
  418. HV_LOG_DEBUG(CHANNEL, "Auto Cable not connect!!! portIndex = %u", enMwPortIndex);
  419. pastSearchStrategy[usLoopIndex].usSearchTimes = 0;
  420. pastSearchStrategy[usLoopIndex].ucSearched = HV_FALSE;
  421. /*未插线更新一下stRxVideoTiming.bIsNoSignal*/
  422. const InputPortManager* pstInputPortManager = Hv_Mw_InputPort_GetManagerPtr();
  423. pstInputPortManager->pfGetVideoPara(enMwPortIndex,pstChannelData);
  424. }
  425. }
  426. }
  427. /*判决是否完成一轮已插线端口的的搜索,如果完成了一轮的搜索,重新初始化search table,再继续搜索*/
  428. BOOL bAllSearched = HV_TRUE;
  429. for (USHORT16 usLoopIndex = 0; usLoopIndex < usSearchTableSize; usLoopIndex++)
  430. {
  431. LinkPortIndex enMwPortIndex = Hv_Mw_Channel_ConvertGuiToMwPortIndex(pastSearchStrategy[usLoopIndex].ucGuiPortIndex);
  432. HV_LOG_DEBUG(CHANNEL, "enMwPortIndex[%u] searchTimes=%u,ChannelType=%u,",
  433. enMwPortIndex,
  434. pastSearchStrategy[usLoopIndex].usSearchTimes,
  435. pstChannelData->enChannelType);
  436. HV_LOG_DEBUG(CHANNEL, "cable state=%u ChannelType=%u, ucSearched=%u",
  437. Hv_Mw_InputPort_GetCableStatus(enMwPortIndex),
  438. pstChannelData->enChannelType,
  439. pastSearchStrategy[usLoopIndex].ucSearched);
  440. if (Hv_Mw_InputPort_GetCableStatus(enMwPortIndex) && (HV_FALSE == pastSearchStrategy[usLoopIndex].ucSearched))
  441. {
  442. bAllSearched = HV_FALSE;
  443. }
  444. }
  445. if (bAllSearched)
  446. {
  447. HV_LOG_DEBUG(CHANNEL, "All Connect Port has searched,init table again!!! ChannelType=%u", pstChannelData->enChannelType);
  448. Hw_Mw_SearchTable_Init(pstChannelData);
  449. }
  450. return HV_CONTINUE;
  451. }
  452. VOID Hw_Mw_AudioPath_Mux(const ChannelData* pstChannelData,ChannelType enChannelType)
  453. {
  454. HV_ASSERT_VALID_PTR_VOID(pstChannelData);
  455. const InputPortManager* pstInputPortManager = Hv_Mw_InputPort_GetManagerPtr();
  456. UCHAR8 ucCurrentPortIndex = 0;
  457. SearchStrategy* pastSearchStrategy = NULL;
  458. USHORT16 usSearchTableSize = 0;
  459. BOOL bAudioFlag = HV_DISABLE;
  460. if (CHANNEL_TYPE_MAIN == enChannelType)
  461. {
  462. ucCurrentPortIndex = pstChannelData->enChannelSrcLinkPortIndex;
  463. pastSearchStrategy = s_astRealTimeMainSearchTable;
  464. usSearchTableSize = ARRAY_SIZE(s_astRealTimeMainSearchTable);
  465. if ((CHANNEL_TYPE_MAIN == HV_COMMON_DATABASE_GET(UserData, ucAudioSource)))
  466. {
  467. bAudioFlag = HV_ENABLE;
  468. }
  469. }
  470. #ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
  471. else
  472. {
  473. ucCurrentPortIndex = pstChannelData->enChannelSrcLinkPortIndex;
  474. pastSearchStrategy = stRealTimeSubSearchTable;
  475. usSearchTableSize = ARRAY_SIZE(stRealTimeSubSearchTable);
  476. if ((CHANNEL_TYPE_SUB == HV_COMMON_DATABASE_GET(UserData, ucAudioSource)))
  477. {
  478. bAudioFlag = HV_ENABLE;
  479. }
  480. }
  481. #endif
  482. HV_ASSERT_TRUE_VOID(usSearchTableSize > 0);
  483. if(HV_ENABLE == bAudioFlag)
  484. {
  485. for (USHORT16 usLoopIndex = 0; usLoopIndex < usSearchTableSize; usLoopIndex++)
  486. {
  487. if(pastSearchStrategy[usLoopIndex].ucGuiPortIndex != Hv_Mw_Channel_ConvertMwToGuiPortIndex(ucCurrentPortIndex))
  488. {
  489. HV_LOG_DEBUG(CHANNEL, "Stop port %u audio", Hv_Mw_Channel_ConvertGuiToMwPortIndex(pastSearchStrategy[usLoopIndex].ucGuiPortIndex));
  490. pstInputPortManager->pfStopAudio(Hv_Mw_Channel_ConvertGuiToMwPortIndex(pastSearchStrategy[usLoopIndex].ucGuiPortIndex));
  491. }
  492. else
  493. {
  494. if(LINK_PORT_INDEX_INVALID == pstChannelData->enChannelSrcLinkPortIndex)
  495. {
  496. HV_LOG_DEBUG(CHANNEL, "Stop port %u audio", Hv_Mw_Channel_ConvertGuiToMwPortIndex(pastSearchStrategy[usLoopIndex].ucGuiPortIndex));
  497. pstInputPortManager->pfStopAudio(Hv_Mw_Channel_ConvertGuiToMwPortIndex(pastSearchStrategy[usLoopIndex].ucGuiPortIndex));
  498. }
  499. }
  500. }
  501. }
  502. else
  503. {
  504. const ChannelManager* pstChannelManager = Hv_Mw_Channel_GetManager();
  505. UCHAR8 ucAudioSource = HV_COMMON_DATABASE_GET(UserData, ucAudioSource);
  506. for (USHORT16 usLoopIndex = 0; usLoopIndex < usSearchTableSize; usLoopIndex++)
  507. {
  508. HV_LOG_DEBUG(CHANNEL, "Stop port %u audio", Hv_Mw_Channel_ConvertGuiToMwPortIndex(pastSearchStrategy[usLoopIndex].ucGuiPortIndex));
  509. if(pastSearchStrategy[usLoopIndex].ucGuiPortIndex != pstChannelManager->astChannelData[ucAudioSource].enChannelSrcLinkPortIndex)
  510. {
  511. pstInputPortManager->pfStopAudio(Hv_Mw_Channel_ConvertGuiToMwPortIndex(pastSearchStrategy[usLoopIndex].ucGuiPortIndex));
  512. }
  513. }
  514. }
  515. return;
  516. }
  517. /*辅助函数:交换两个元素*/
  518. static VOID SwapObject(USHORT16 *usA, USHORT16 *usB)
  519. {
  520. USHORT16 usTemp = *usA;
  521. *usA = *usB;
  522. *usB = usTemp;
  523. }
  524. /*辅助函数:对数组进行排序(从小到大)*/
  525. static VOID SortArray(USHORT16 ausArr[], USHORT16 usStart, USHORT16 usEnd)
  526. {
  527. for (int i = usStart; i < usEnd - 1; i++)
  528. {
  529. for (int j = usStart; j < usEnd - 1; j++)
  530. {
  531. if (ausArr[j] > ausArr[j + 1])
  532. {
  533. SwapObject(&ausArr[j], &ausArr[j + 1]);
  534. }
  535. }
  536. }
  537. }
  538. static VOID CustomSortArr(USHORT16 ausPortArr[], USHORT16 usSearchTableSize)
  539. {
  540. USHORT16 usPivot = ausPortArr[0];
  541. USHORT16 i, j;
  542. /* 分割数组*/
  543. USHORT16 ausLeft[usSearchTableSize], ausRight[usSearchTableSize];
  544. USHORT16 usLeftSize = 0, usRightSize = 0;
  545. for (i = 1; i < usSearchTableSize; i++)
  546. {
  547. if (ausPortArr[i] > usPivot)
  548. {
  549. ausRight[usRightSize++] = ausPortArr[i];
  550. } else {
  551. ausLeft[usLeftSize++] = ausPortArr[i];
  552. }
  553. }
  554. /*对分割后的数组进行排序*/
  555. SortArray(ausRight, 0, usRightSize);
  556. SortArray(ausLeft, 0, usLeftSize);
  557. /*合并结果*/
  558. USHORT16 usIndex = 1;
  559. for (i = 0; i < usRightSize; i++)
  560. {
  561. ausPortArr[usIndex++] = ausRight[i];
  562. }
  563. for (i = 0; i < usLeftSize; i++)
  564. {
  565. ausPortArr[usIndex++] = ausLeft[i];
  566. }
  567. }
  568. VOID Hw_Mw_SearchTable_Init(ChannelData* pstChannelData)
  569. {
  570. HV_ASSERT_VALID_PTR_VOID(pstChannelData);
  571. UCHAR8 ucCurrentPortIndex = 0;
  572. SearchStrategy* pastSearchStrategy = NULL;
  573. USHORT16 usSearchTableSize = 0;
  574. if (CHANNEL_TYPE_MAIN == pstChannelData->enChannelType)
  575. {
  576. ucCurrentPortIndex = pstChannelData->enChannelSrcLinkPortIndex;
  577. pastSearchStrategy = s_astRealTimeMainSearchTable;
  578. usSearchTableSize = ARRAY_SIZE(s_astRealTimeMainSearchTable);
  579. }
  580. #ifdef CONFIG_USER_DOUBLE_CHANNEL_ON
  581. else
  582. {
  583. ucCurrentPortIndex = pstChannelData->enChannelSrcLinkPortIndex;
  584. pastSearchStrategy = stRealTimeSubSearchTable;
  585. usSearchTableSize = ARRAY_SIZE(stRealTimeSubSearchTable);
  586. }
  587. #endif
  588. HV_ASSERT_TRUE_VOID(usSearchTableSize > 0);
  589. for (USHORT16 usLoopIndex = 0; usLoopIndex < usSearchTableSize; usLoopIndex++)
  590. {
  591. if(pastSearchStrategy[usLoopIndex].ucGuiPortIndex == ucCurrentPortIndex)
  592. {
  593. pastSearchStrategy[usLoopIndex].ucGuiPortIndex = pastSearchStrategy[0].ucGuiPortIndex;
  594. pastSearchStrategy[0].ucGuiPortIndex = ucCurrentPortIndex;
  595. break;
  596. }
  597. }
  598. USHORT16 ausPortArr[usSearchTableSize];
  599. for (USHORT16 usLoopIndex = 0; usLoopIndex < usSearchTableSize; usLoopIndex++)
  600. {
  601. ausPortArr[usLoopIndex] = pastSearchStrategy[usLoopIndex].ucGuiPortIndex;
  602. }
  603. CustomSortArr(ausPortArr, usSearchTableSize);
  604. for (USHORT16 usLoopIndex = 0; usLoopIndex < usSearchTableSize; usLoopIndex++)
  605. {
  606. pastSearchStrategy[usLoopIndex].ucGuiPortIndex = ausPortArr[usLoopIndex];
  607. }
  608. for (USHORT16 usLoopIndex = 0; usLoopIndex < usSearchTableSize; usLoopIndex++)
  609. {
  610. pastSearchStrategy[usLoopIndex].usSearchTimes = 0;
  611. pastSearchStrategy[usLoopIndex].ucSearched = HV_FALSE;
  612. }
  613. return;
  614. }
  615. #if (HV_CONFIG_ON == HV_PROJECT_CONFIG_MAGNIFY)
  616. static Status MagnifyGlassSearchSourceMode(ChannelData* pstChannelData)
  617. {
  618. HV_ASSERT_VALID_PTR(pstChannelData);
  619. const ChannelManager* pstChannelManager = Hv_Mw_Channel_GetManager();
  620. const InputPortManager* pstInputPortManager = Hv_Mw_InputPort_GetManagerPtr();
  621. pstInputPortManager->pfGetVideoPara(pstChannelData->enChannelSrcLinkPortIndex, pstChannelData);
  622. /*放大镜使用PIP模式,辅通道的信号源使用主通道正常显示的信号源*/
  623. if (CHANNEL_STATE_ACTIVE == pstChannelManager->astChannelData[0].enCurrentCHState)
  624. {
  625. LinkPortIndex enMwPortIndex = pstChannelManager->astChannelData[0].enChannelSrcLinkPortIndex;
  626. pstInputPortManager->pfPreProcess(enMwPortIndex);
  627. Hv_Drv_DpuScaler_SetPortMux(pstChannelData->enChannelType, enMwPortIndex);
  628. /*绑定RX端口, for hdcp*/
  629. pstInputPortManager->pfBindChannelPortIndex(pstChannelData->enChannelType, enMwPortIndex);
  630. pstChannelData->enChannelSrcLinkPortIndex = enMwPortIndex;
  631. return HV_SUCCESS;
  632. }
  633. else
  634. {
  635. HV_LOG_DEBUG(CHANNEL, "sub magnify search, main not active.");
  636. /*do nothing*/
  637. }
  638. return HV_CONTINUE;
  639. }
  640. #endif
  641. Status Hw_Mw_Channel_SearchSuitableSource(ChannelData* pstChannelData)
  642. {
  643. HV_ASSERT_VALID_PTR(pstChannelData);
  644. Status uiResult = HV_CONTINUE;
  645. pstChannelData->usTotalSearchTimes++;
  646. #ifdef CONFIG_USER_USB_OTA_ON
  647. if(USB_STATE_OTA_IN_PROCESSING == Hv_Mw_USB_GetUsbState())
  648. {
  649. return HV_CONTINUE;
  650. }
  651. #endif
  652. if ((1 == HV_COMMON_DATABASE_GET(SystemData, bFactoryMode))
  653. && (1 == HV_COMMON_DATABASE_GET(SystemData, bBurnInEnable)))
  654. {
  655. if (pstChannelData->usTotalSearchTimes > HV_PROJECT_CONFIG_MAX_SEARCH_TIMERS_BURN_IN)
  656. {
  657. /*老化模式,加速失败切换到NoSignal态*/
  658. pstChannelData->usTotalSearchTimes = 0;
  659. return pstChannelData->uiErrorCode;
  660. }
  661. }
  662. else
  663. {
  664. if (pstChannelData->usTotalSearchTimes > GetAllPortSearchTotalTimes(pstChannelData))
  665. {
  666. /*失败切换到NoSignal态*/
  667. pstChannelData->usTotalSearchTimes = 0;
  668. return pstChannelData->uiErrorCode;
  669. }
  670. }
  671. #if (HV_CONFIG_ON == HV_PROJECT_CONFIG_MAGNIFY)
  672. /*开启了放大镜模式辅助通道强制需要等待主通道显示正常,并且直接使用主通道的信号源*/
  673. if ((CHANNEL_TYPE_SUB == pstChannelData->enChannelType)
  674. && (PXP_MODE_MAGNIFY_GLASS_ENABLE == Hv_Mw_Channel_GetPxpMode()))
  675. {
  676. uiResult = MagnifyGlassSearchSourceMode(pstChannelData);
  677. }
  678. else /*非放大镜模式*/
  679. #endif
  680. {
  681. if (HV_TRUE == HV_COMMON_DATABASE_GET(UserData, bAutoVideoSrcSelSw))
  682. {
  683. if((PXP_MODE_CLOSE == Hv_Mw_Channel_GetPxpMode()) || (PXP_MODE_MAGNIFY_GLASS_ENABLE == Hv_Mw_Channel_GetPxpMode()))
  684. {
  685. uiResult = AutoSearchAllInputPort(pstChannelData);
  686. }
  687. else
  688. {
  689. uiResult = FixSearchInputPort(pstChannelData);
  690. }
  691. }
  692. else
  693. {
  694. uiResult = FixSearchInputPort(pstChannelData);
  695. }
  696. }
  697. return uiResult;
  698. }
  699. Status Hw_Mw_Channel_NoSignal_SearchPort(ChannelData* pstChannelData)
  700. {
  701. HV_ASSERT_VALID_PTR(pstChannelData);
  702. USHORT16 usPortLoopIndex = 0;
  703. Status uiResult = HV_CONTINUE;
  704. HV_LOG_DEBUG(CHANNEL, "Nosignal SearchPort ChannelType= %u, port:%u", pstChannelData->enChannelType, pstChannelData->enChannelSrcLinkPortIndex);
  705. if (HV_TRUE == HV_COMMON_DATABASE_GET(UserData, bAutoVideoSrcSelSw) && (CHANNEL_TYPE_MAIN == pstChannelData->enChannelType))
  706. {
  707. const InputPortManager* pstInputPortManager = Hv_Mw_InputPort_GetManagerPtr();
  708. for (usPortLoopIndex = 0; usPortLoopIndex < ARRAY_SIZE(aenNosignalSearchPortTable); usPortLoopIndex++)
  709. {
  710. if (CheckPortOnUsing(pstChannelData->enChannelType, aenNosignalSearchPortTable[usPortLoopIndex]))/*判决该端口是否被其他通道占用*/
  711. {
  712. HV_LOG_INFO(CHANNEL, "Other Channel Is using portIndex=%u, current ChannelType=%u", aenNosignalSearchPortTable[usPortLoopIndex], pstChannelData->enChannelType);
  713. continue;/*不允许主辅使用相同端口时,使用该端口正在被其他端口占用,跳过该端口的搜索*/
  714. }
  715. if (HV_SUCCESS == pstInputPortManager->pfGetVideoPara(aenNosignalSearchPortTable[usPortLoopIndex], pstChannelData))
  716. {
  717. pstChannelData->uiErrorCode = Hv_Mw_Video_TimingCheck(aenNosignalSearchPortTable[usPortLoopIndex],pstChannelData);
  718. if (HV_SUCCESS == pstChannelData->uiErrorCode)
  719. {
  720. /*端口timing check成功*/
  721. pstChannelData->enChannelSrcLinkPortIndex = aenNosignalSearchPortTable[usPortLoopIndex];
  722. HV_LOG_DEBUG(CHANNEL, "Nosignal state Timing Check SUCCESS portIndex=%u ChannelType=%u",aenNosignalSearchPortTable[usPortLoopIndex], pstChannelData->enChannelType);
  723. return HV_SUCCESS;
  724. }
  725. else
  726. {
  727. /*失败发消息给OSD并停止搜索*/
  728. //SendTimingNotSuportToOsd(pstChannelData->uiErrorCode, pstChannelData->enChannelType, aenNosignalSearchPortTable[usPortLoopIndex]);
  729. HV_LOG_INFO(CHANNEL, "Nosignal state TimingCheck Error!!! uiCheckResult %u,portIndex= %u", pstChannelData->uiErrorCode,aenNosignalSearchPortTable[usPortLoopIndex]);
  730. return HV_FAILURE;
  731. }
  732. }
  733. else
  734. {
  735. HV_LOG_DEBUG(CHANNEL, "get port status Error!!! portIndex= %u, ChannelType=%u", aenNosignalSearchPortTable[usPortLoopIndex], pstChannelData->enChannelType);
  736. }
  737. }
  738. }
  739. else
  740. {
  741. if (CHANNEL_TYPE_MAIN == pstChannelData->enChannelType)
  742. {
  743. uiResult = FixSearchInputPort(pstChannelData);
  744. }
  745. else
  746. {
  747. #if (HV_CONFIG_ON == HV_PROJECT_CONFIG_MAGNIFY)
  748. if (PXP_MODE_MAGNIFY_GLASS_ENABLE == Hv_Mw_Channel_GetPxpMode())
  749. {
  750. uiResult = MagnifyGlassSearchSourceMode(pstChannelData);
  751. }
  752. else
  753. {
  754. uiResult = FixSearchInputPort(pstChannelData);
  755. }
  756. #else
  757. uiResult = FixSearchInputPort(pstChannelData);
  758. #endif
  759. }
  760. }
  761. return uiResult;
  762. }