component.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. /*
  2. * Copyright (c) 2019, Chips&Media
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright notice,
  11. * this list of conditions and the following disclaimer in the documentation
  12. * and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  15. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  18. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  21. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include <string.h>
  26. #include "component.h"
  27. #include "cnm_app.h"
  28. #include <sys/prctl.h>
  29. #ifdef PLATFORM_NON_OS
  30. BOOL supportThread = FALSE;
  31. #else
  32. BOOL supportThread = TRUE;
  33. #endif
  34. #define DEFAULT_NO_RESPONSE_TIMEOUT 720 // in second
  35. typedef struct ClockData {
  36. BOOL start;
  37. Uint64 lastClock; /* in millisecond */
  38. } ClockData;
  39. /*
  40. * component_list.h is generated in the makefiles.
  41. * See Wave5xxDecV2.mak or Wave5xxEncV2.mak.
  42. */
  43. #include "component_list.h"
  44. static void SetupSinkPort(ComponentImpl* component, ComponentImpl* connectedComponent)
  45. {
  46. component->sinkPort.connectedComponent = (Component)connectedComponent;
  47. }
  48. static void SetupSrcPort(ComponentImpl* component, ComponentImpl* connectedComponent, Port sinkPort)
  49. {
  50. Port* srcPort = &component->srcPort;
  51. component->srcPort.inputQ = sinkPort.outputQ;
  52. component->srcPort.outputQ = sinkPort.inputQ;
  53. component->srcPort.owner = component;
  54. component->srcPort.connectedComponent = connectedComponent;
  55. component->usingQ = Queue_Create_With_Lock(srcPort->inputQ->size, srcPort->inputQ->itemSize);
  56. }
  57. Component ComponentCreate(const char* componentName, CNMComponentConfig* componentParam)
  58. {
  59. ComponentImpl* instance = NULL;
  60. ComponentImpl* com;
  61. Uint32 i=0;
  62. while ((com=componentList[i++])) {
  63. if (strcmp(componentName, com->name) == 0) break;
  64. }
  65. if (com == NULL) {
  66. VLOG(ERR, "%s:%d Can't find %s component\n", __FUNCTION__, __LINE__, componentName);
  67. return NULL;
  68. }
  69. // Create an instance.
  70. instance = (ComponentImpl*)osal_malloc(sizeof(ComponentImpl));
  71. osal_memcpy(instance, com, sizeof(ComponentImpl));
  72. if (instance->Create(instance, componentParam) == NULL) {
  73. osal_free(instance);
  74. instance= NULL;
  75. }
  76. else {
  77. Port* port = &instance->sinkPort;
  78. Uint32 size = instance->containerSize;
  79. void* data = osal_malloc(size);
  80. osal_memset((void*)data, 0x00, size);
  81. ComponentPortCreate(port, instance, instance->numSinkPortQueue, size);
  82. // Fill input queue
  83. for (i=0; i<instance->numSinkPortQueue; i++) {
  84. Queue_Enqueue(port->inputQ, data);
  85. }
  86. osal_free(data);
  87. instance->state = COMPONENT_STATE_CREATED;
  88. instance->type = CNM_COMPONENT_TYPE_ISOLATION;
  89. if (instance->Hz) {
  90. ClockData* clk = (ClockData*)osal_malloc(sizeof(ClockData));
  91. clk->start = FALSE;
  92. clk->lastClock = 0ULL;
  93. instance->internalData = (void*)clk;
  94. }
  95. }
  96. return (Component)instance;
  97. }
  98. BOOL ComponentSetupTunnel(Component fromComponent, Component toComponent)
  99. {
  100. ComponentImpl* src = (ComponentImpl*)fromComponent;
  101. ComponentImpl* sink = (ComponentImpl*)toComponent;
  102. BOOL hasComponent;
  103. if (fromComponent == NULL) {
  104. VLOG(ERR, "%s:%d Invalid handle\n", __FUNCTION__, __LINE__);
  105. return FALSE;
  106. }
  107. if (toComponent == NULL) {
  108. VLOG(ERR, "%s:%d Invalid handle\n", __FUNCTION__, __LINE__);
  109. return FALSE;
  110. }
  111. SetupSinkPort(src, sink);
  112. SetupSrcPort(sink, src, src->sinkPort);
  113. hasComponent = (BOOL)(src->srcPort.connectedComponent != NULL);
  114. src->type = (hasComponent == FALSE) ? CNM_COMPONENT_TYPE_SOURCE : CNM_COMPONENT_TYPE_FILTER;
  115. hasComponent = (BOOL)(sink->sinkPort.connectedComponent != NULL);
  116. sink->type = (hasComponent == FALSE) ? CNM_COMPONENT_TYPE_SINK : CNM_COMPONENT_TYPE_FILTER;
  117. #ifdef SUPPORT_LOOK_AHEAD_RC
  118. if ( !strcmp(src->name, "yuvfeeder") ) {
  119. src->type = CNM_COMPONENT_TYPE_SOURCE;
  120. }
  121. if ( !strcmp(src->name, "reader") ) {
  122. src->type = CNM_COMPONENT_TYPE_SINK;
  123. }
  124. #endif
  125. return TRUE;
  126. }
  127. void ComponentWaitState(Component component, ComponentState state)
  128. {
  129. ComponentImpl* imp = (ComponentImpl*)component;
  130. if (imp == NULL) return;
  131. do {
  132. osal_msleep(1);
  133. } while (imp->state < state);
  134. }
  135. static void WaitReturningPortData(ComponentImpl* com)
  136. {
  137. PortContainer* container;
  138. while ((container=(PortContainer*)Queue_Dequeue(com->usingQ))) {
  139. ComponentPortSetData(&com->srcPort, container);
  140. }
  141. while ((container=ComponentPortGetData(&com->srcPort))) {
  142. ComponentPortSetData(&com->srcPort, container);
  143. }
  144. }
  145. Int32 ComponentWait(Component component)
  146. {
  147. ComponentImpl* com = (ComponentImpl*)component;
  148. Int32 ret;
  149. Int32 retval;
  150. if (supportThread == FALSE || com->thread == NULL) {
  151. return (com->state != COMPONENT_STATE_TERMINATED) ? 2 : 0;
  152. }
  153. if ((ret=osal_thread_timedjoin(com->thread, (void**)&retval, 100)) == 0) {
  154. com->thread = NULL;
  155. WaitReturningPortData(com);
  156. }
  157. return ret;
  158. }
  159. static BOOL HasPortData(ComponentImpl* com, PortContainer** in, PortContainer** out)
  160. {
  161. BOOL success = FALSE;
  162. *in = NULL;
  163. *out = NULL;
  164. switch (com->type) {
  165. case CNM_COMPONENT_TYPE_SOURCE:
  166. if ((*out=ComponentPortPeekData(&com->sinkPort)) != NULL) {
  167. success = TRUE;
  168. }
  169. break;
  170. case CNM_COMPONENT_TYPE_FILTER:
  171. *in=ComponentPortPeekData(&com->srcPort);
  172. *out=ComponentPortPeekData(&com->sinkPort);
  173. /* A filter component needs an container for output */
  174. success = (BOOL)(*out != NULL);
  175. break;
  176. case CNM_COMPONENT_TYPE_SINK:
  177. if ((*in=ComponentPortPeekData(&com->srcPort)) != NULL) {
  178. success = TRUE;
  179. }
  180. break;
  181. default:
  182. /* SINGLE COMPONENT */
  183. success = TRUE;
  184. break;
  185. }
  186. if (*in) (*in)->reuse = TRUE;
  187. if (*out) (*out)->reuse = TRUE;
  188. return success;
  189. }
  190. static BOOL ReturnPortContainer(ComponentImpl* com, BOOL inputConsumed, BOOL hasOutput)
  191. {
  192. BOOL doReturn = FALSE;
  193. BOOL returned = FALSE;
  194. switch (com->type) {
  195. case CNM_COMPONENT_TYPE_FILTER:
  196. doReturn = (BOOL)(hasOutput || inputConsumed);
  197. break;
  198. case CNM_COMPONENT_TYPE_SINK:
  199. doReturn = inputConsumed;
  200. break;
  201. default:
  202. doReturn = FALSE;
  203. break;
  204. }
  205. if (doReturn) {
  206. PortContainer* container;
  207. Uint32 i, numItems = Queue_Get_Cnt(com->usingQ);
  208. for (i=0; i<numItems; i++) {
  209. container=(PortContainer*)Queue_Dequeue(com->usingQ);
  210. if (container == NULL) break;
  211. // Intentionally infinite loop to debug easily
  212. ComponentGetParameter(NULL, com, GET_PARAM_COM_IS_CONTAINER_CONUSUMED, (void*)container);
  213. if (container->consumed == TRUE) {
  214. ComponentPortSetData(&com->srcPort, container);
  215. // Return the used source data
  216. returned = TRUE;
  217. break;
  218. }
  219. else {
  220. Queue_Enqueue(com->usingQ, container);
  221. }
  222. }
  223. }
  224. return returned;
  225. }
  226. static void SendClockSignal(ComponentImpl* com)
  227. {
  228. if (com->Hz) {
  229. PortContainerClock data;
  230. ClockData* clk = (ClockData*)com->internalData;
  231. BOOL send = FALSE;
  232. if (clk->start == FALSE) {
  233. clk->start = TRUE;
  234. clk->lastClock = osal_gettime();
  235. send = TRUE;
  236. }
  237. else {
  238. Uint32 diff = osal_gettime() - clk->lastClock;
  239. send = (diff >= com->Hz);
  240. }
  241. if (send == TRUE) {
  242. data.type = CNM_PORT_CONTAINER_TYPE_CLOCK;
  243. com->Execute(com, (PortContainer*)&data, NULL);
  244. }
  245. }
  246. }
  247. static BOOL Execute(ComponentImpl* com)
  248. {
  249. PortContainer* in = NULL;
  250. PortContainer* out = NULL;
  251. BOOL success = TRUE;
  252. SendClockSignal(com);
  253. if (HasPortData(com, &in, &out) == TRUE) {
  254. if ((success=com->Execute(com, in, out)) == FALSE) {
  255. com->terminate = TRUE;
  256. }
  257. if (in && in->reuse == FALSE) {
  258. Queue_Enqueue(com->usingQ, (void*)in);
  259. // The "in" container still exists in a source port. It removes the container from the source port.
  260. ComponentPortGetData(&com->srcPort);
  261. }
  262. if (out && out->reuse == FALSE) {
  263. // The "out" container still exists in a sink port. It removes the container from the the sink port.
  264. // If the container has no content, it has to be reused.
  265. ComponentPortGetData(&com->sinkPort);
  266. // Send data to the sink component
  267. ComponentPortSetData(&com->sinkPort, out);
  268. }
  269. // Return a consumed container to the source port.
  270. ReturnPortContainer(com, (in && in->consumed), (out && out->reuse == FALSE));
  271. }
  272. if (com->portFlush == TRUE) {
  273. // Flush all data in the source port
  274. void* data;
  275. while ((data=Queue_Dequeue(com->usingQ))) {
  276. ComponentPortSetData(&com->srcPort, data);
  277. }
  278. while ((data=ComponentPortGetData(&com->srcPort))) {
  279. ComponentPortSetData(&com->srcPort, data);
  280. }
  281. com->portFlush = FALSE;
  282. }
  283. return success;
  284. }
  285. static void DoYourJob(ComponentImpl* com)
  286. {
  287. BOOL success;
  288. BOOL done = FALSE;
  289. ComponentImpl* sinkComponent;
  290. if (CNMErrorGet() == CNM_ERROR_HANGUP) {
  291. com->terminate = TRUE;
  292. }
  293. else {
  294. switch (com->state) {
  295. case COMPONENT_STATE_CREATED:
  296. if ((success=com->Prepare(com, &done)) == TRUE) {
  297. if (done == TRUE) com->state = COMPONENT_STATE_PREPARED;
  298. }
  299. break;
  300. case COMPONENT_STATE_PREPARED:
  301. if ((success=Execute(com)) == TRUE) {
  302. com->state = COMPONENT_STATE_EXECUTED;
  303. }
  304. break;
  305. case COMPONENT_STATE_EXECUTED:
  306. success = Execute(com);
  307. break;
  308. default:
  309. success = FALSE;
  310. break;
  311. }
  312. if ((com->success=success) == FALSE) {
  313. com->terminate = TRUE;
  314. }
  315. }
  316. /* Check if connected components are terminated */
  317. sinkComponent = (ComponentImpl*)com->sinkPort.connectedComponent;
  318. if (sinkComponent && sinkComponent->terminate == TRUE) {
  319. com->terminate = TRUE;
  320. }
  321. if (com->terminate == TRUE) {
  322. com->state = COMPONENT_STATE_TERMINATED;
  323. }
  324. }
  325. static void DoThreadWork(void* arg)
  326. {
  327. ComponentImpl* com = (ComponentImpl*)arg;
  328. prctl(PR_SET_NAME, com->name);
  329. while (com->terminate == FALSE) {
  330. DoYourJob(com);
  331. osal_msleep(2); // To yield schedule
  332. }
  333. ComponentNotifyListeners(com, COMPONENT_EVENT_TERMINATED, NULL);
  334. com->state = COMPONENT_STATE_TERMINATED;
  335. }
  336. ComponentState ComponentExecute(Component component)
  337. {
  338. ComponentImpl* com = (ComponentImpl*)component;
  339. if (com == NULL) {
  340. VLOG(ERR, "%s:%d Invalid handle\n", __FUNCTION__, __LINE__);
  341. return COMPONENT_STATE_TERMINATED;
  342. }
  343. if (supportThread) {
  344. com->thread = osal_thread_create(DoThreadWork, (void*)com);
  345. }
  346. else {
  347. DoYourJob(com);
  348. }
  349. return com->state;
  350. }
  351. void ComponentStop(Component component)
  352. {
  353. ComponentImpl* com = (ComponentImpl*)component;
  354. if (com->terminate == FALSE) {
  355. com->terminate = TRUE;
  356. if (supportThread == FALSE) {
  357. com->state = COMPONENT_STATE_TERMINATED;
  358. WaitReturningPortData(com);
  359. }
  360. }
  361. }
  362. void ComponentRelease(Component component)
  363. {
  364. ComponentImpl* impl = (ComponentImpl*)component;
  365. if (impl) {
  366. impl->Release(impl);
  367. }
  368. return;
  369. }
  370. BOOL ComponentDestroy(Component component, BOOL* ret)
  371. {
  372. ComponentImpl* impl = (ComponentImpl*)component;
  373. BOOL success;
  374. if (impl == NULL) {
  375. VLOG(ERR, "%s:%d Invalid handle\n", __FUNCTION__, __LINE__);
  376. return FALSE;
  377. }
  378. if (ret) {
  379. *ret = impl->success;
  380. }
  381. ComponentPortDestroy(&impl->sinkPort);
  382. success = impl->Destroy(impl);
  383. Queue_Destroy(impl->usingQ);
  384. if (impl->internalData) osal_free(impl->internalData);
  385. osal_free(impl);
  386. return success;
  387. }
  388. static char* getParamName[GET_PARAM_MAX] = {
  389. "GET_PARAM_COM_STATE",
  390. "GET_PARAM_FEEDER_BITSTREAM_BUF",
  391. "GET_PARAM_DEC_HANDLE",
  392. "GET_PARAM_DEC_CODEC_INFO",
  393. "GET_PARAM_DEC_BITSTREAM_BUF_POS",
  394. "GET_PARAM_DEC_FRAME_BUF_NUM",
  395. "GET_PARAM_VPU_STATUS",
  396. "GET_PARAM_RENDERER_FRAME_BUF",
  397. "GET_PARAM_ENC_HANDLE",
  398. "GET_PARAM_ENC_FRAME_BUF_NUM",
  399. "GET_PARAM_ENC_FRAME_BUF_REGISTERED",
  400. "GET_PARAM_YUVFEEDER_FRAME_BUF",
  401. "GET_PARAM_READER_BITSTREAM_BUF",
  402. };
  403. CNMComponentParamRet ComponentGetParameter(Component from, Component to, GetParameterCMD commandType, void* data)
  404. {
  405. ComponentImpl* com = (ComponentImpl*)to;
  406. CNMComponentParamRet ret;
  407. if (com == NULL) {
  408. VLOG(ERR, "%s:%d Invalid handle or the port closed\n", __FUNCTION__, __LINE__);
  409. return CNM_COMPONENT_PARAM_FAILURE;
  410. }
  411. if (com->terminate == TRUE) {
  412. return CNM_COMPONENT_PARAM_TERMINATED;
  413. }
  414. else {
  415. if ((ret=com->GetParameter((ComponentImpl*)from, com, commandType, data)) == CNM_COMPONENT_PARAM_NOT_FOUND) {
  416. // Redirect a command.
  417. // Send a command other connected components.
  418. if (com->srcPort.connectedComponent == from) {
  419. // source component ----> current component -----> sink component
  420. to = com->sinkPort.connectedComponent;
  421. }
  422. else {
  423. // source component <---- current component <----- sink component
  424. to = com->srcPort.connectedComponent;
  425. }
  426. if (to == NULL) {
  427. VLOG(ERR, "%s:%d The command(%s) is not supported\n", __FUNCTION__, __LINE__, getParamName[commandType]);
  428. return CNM_COMPONENT_PARAM_FAILURE;
  429. }
  430. from = com;
  431. return ComponentGetParameter((Component*)from, to, commandType, data);
  432. }
  433. }
  434. return ret;
  435. }
  436. void ComponentNotifyListeners(Component component, Uint64 event, void* data)
  437. {
  438. ComponentImpl* com = (ComponentImpl*)component;
  439. Uint32 i = 0;
  440. Uint64 listeningEvents;
  441. void* context;
  442. ComponentListenerFunc update = NULL;
  443. for (i=0; i<com->numListeners; i++) {
  444. listeningEvents = com->listeners[i].events;
  445. update = com->listeners[i].update;
  446. context = com->listeners[i].context;
  447. if (listeningEvents & event) {
  448. update(component, event, data, context);
  449. }
  450. }
  451. }
  452. BOOL ComponentRegisterListener(Component component, Uint64 events, ComponentListenerFunc func, void* context)
  453. {
  454. ComponentImpl* com = (ComponentImpl*)component;
  455. Uint32 num;
  456. if (com == NULL) return FALSE;
  457. num = com->numListeners;
  458. if (num == MAX_NUM_LISTENERS) {
  459. VLOG(ERR, "%s:%d Failed to ComponentRegisterListener\n", __FUNCTION__, __LINE__);
  460. return FALSE;
  461. }
  462. com->listeners[num].events = events;
  463. com->listeners[num].update = func;
  464. com->listeners[num].context = context;
  465. com->numListeners = num+1;
  466. return TRUE;
  467. }
  468. CNMComponentParamRet ComponentSetParameter(Component from, Component to, SetParameterCMD commandType, void* data)
  469. {
  470. ComponentImpl* com = (ComponentImpl*)to;
  471. if (com == NULL) {
  472. VLOG(ERR, "%s:%d Invalid handle or the port closed\n", __FUNCTION__, __LINE__);
  473. return CNM_COMPONENT_PARAM_FAILURE;
  474. }
  475. if (com->terminate == TRUE) {
  476. return CNM_COMPONENT_PARAM_FAILURE;
  477. }
  478. else {
  479. if (com->SetParameter((ComponentImpl*)from, com, commandType, data) == FALSE) {
  480. // Redirect a command.
  481. // Send a command other connected components.
  482. if (com->srcPort.connectedComponent == from) {
  483. // source component ----> current component -----> sink component
  484. to = com->sinkPort.connectedComponent;
  485. }
  486. else {
  487. // source component <---- current component <----- sink component
  488. to = com->srcPort.connectedComponent;
  489. }
  490. if (to == NULL) {
  491. VLOG(ERR, "%s:%d The command(%d) is not supported\n", __FUNCTION__, __LINE__, commandType);
  492. return CNM_COMPONENT_PARAM_FAILURE;
  493. }
  494. from = com;
  495. return ComponentSetParameter((Component*)from, to, commandType, data);
  496. }
  497. }
  498. return CNM_COMPONENT_PARAM_SUCCESS;
  499. }
  500. void ComponentPortCreate(Port* port, Component owner, Uint32 depth, Uint32 size)
  501. {
  502. // Release the queues which are created previously.
  503. port->inputQ = Queue_Create_With_Lock(depth, size);
  504. port->outputQ = Queue_Create_With_Lock(depth, size);
  505. port->owner = owner;
  506. port->sequenceNo = 0;
  507. }
  508. void ComponentPortSetData(Port* port, PortContainer* data)
  509. {
  510. if (data == NULL) {
  511. // Silent error
  512. return;
  513. }
  514. data->consumed = FALSE;
  515. if (Queue_Enqueue(port->outputQ, (void*)data) == FALSE) {
  516. VLOG(INFO, "%s FAILURE\n", __FUNCTION__);
  517. }
  518. }
  519. PortContainer* ComponentPortPeekData(Port* port)
  520. {
  521. PortContainer* c = Queue_Peek(port->inputQ);
  522. if (c) {
  523. c->packetNo = port->sequenceNo;
  524. }
  525. return c;
  526. }
  527. PortContainer* ComponentPortGetData(Port* port)
  528. {
  529. PortContainer* c = Queue_Dequeue(port->inputQ);
  530. if (c) {
  531. port->sequenceNo++;
  532. }
  533. return c;
  534. }
  535. void* WaitBeforeComponentPortGetData(Port* port)
  536. {
  537. BOOL loop = TRUE;
  538. void* portData = NULL;
  539. while (loop) {
  540. if (Queue_Get_Cnt(port->inputQ) > 0) {
  541. portData = Queue_Dequeue(port->inputQ);
  542. loop = FALSE;
  543. }
  544. }
  545. return portData;
  546. }
  547. void ComponentPortDestroy(Port* port)
  548. {
  549. Queue_Destroy(port->inputQ);
  550. Queue_Destroy(port->outputQ);
  551. port->connectedComponent = NULL;
  552. }
  553. void ComponentPortWaitReadyStatus(Port* port)
  554. {
  555. while (port->outputQ && Queue_Get_Cnt(port->outputQ) > 0) {
  556. osal_msleep(1);
  557. }
  558. }
  559. BOOL ComponentPortHasInputData(Port* port)
  560. {
  561. return (Queue_Get_Cnt(port->inputQ) > 0);
  562. }
  563. Uint32 ComponentPortGetSize(Port* port)
  564. {
  565. return port->inputQ->size;
  566. }
  567. void ComponentPortFlush(Component component)
  568. {
  569. ComponentImpl* com = (ComponentImpl*)component;
  570. com->portFlush = TRUE;
  571. }
  572. ComponentState ComponentGetState(Component component)
  573. {
  574. ComponentImpl* com = (ComponentImpl*)component;
  575. if (com == NULL) {
  576. return COMPONENT_STATE_NONE;
  577. }
  578. return com->state;
  579. }
  580. BOOL ComponentChangeState(Component component, Uint32 state)
  581. {
  582. ComponentImpl* com = (ComponentImpl*)component;
  583. if (NULL != com) {
  584. if (COMPONENT_STATE_NONE < state && COMPONENT_STATE_MAX > state) {
  585. com->state = (ComponentState)state;
  586. return TRUE;
  587. }
  588. }
  589. return FALSE;
  590. }
  591. /* return TRUE - Go next step
  592. * FALSE - Retry
  593. */
  594. BOOL ComponentParamReturnTest(CNMComponentParamRet ret, BOOL* success)
  595. {
  596. BOOL retry = TRUE;
  597. switch (ret) {
  598. case CNM_COMPONENT_PARAM_FAILURE: retry = FALSE; *success = FALSE; break;
  599. case CNM_COMPONENT_PARAM_SUCCESS: retry = TRUE; *success = TRUE; break;
  600. case CNM_COMPONENT_PARAM_NOT_READY: retry = FALSE; *success = TRUE; break;
  601. case CNM_COMPONENT_PARAM_NOT_FOUND: retry = FALSE; *success = FALSE; break;
  602. case CNM_COMPONENT_PARAM_TERMINATED: retry = FALSE; *success = TRUE; break;
  603. default: retry = FALSE; *success = FALSE; break;
  604. }
  605. return retry;
  606. }