component.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  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. com->state = COMPONENT_STATE_TERMINATED;
  334. }
  335. ComponentState ComponentExecute(Component component)
  336. {
  337. ComponentImpl* com = (ComponentImpl*)component;
  338. if (com == NULL) {
  339. VLOG(ERR, "%s:%d Invalid handle\n", __FUNCTION__, __LINE__);
  340. return COMPONENT_STATE_TERMINATED;
  341. }
  342. if (supportThread) {
  343. com->thread = osal_thread_create(DoThreadWork, (void*)com);
  344. }
  345. else {
  346. DoYourJob(com);
  347. }
  348. return com->state;
  349. }
  350. void ComponentStop(Component component)
  351. {
  352. ComponentImpl* com = (ComponentImpl*)component;
  353. if (com->terminate == FALSE) {
  354. com->terminate = TRUE;
  355. if (supportThread == FALSE) {
  356. com->state = COMPONENT_STATE_TERMINATED;
  357. WaitReturningPortData(com);
  358. }
  359. }
  360. }
  361. void ComponentRelease(Component component)
  362. {
  363. ComponentImpl* impl = (ComponentImpl*)component;
  364. if (impl) {
  365. impl->Release(impl);
  366. }
  367. return;
  368. }
  369. BOOL ComponentDestroy(Component component, BOOL* ret)
  370. {
  371. ComponentImpl* impl = (ComponentImpl*)component;
  372. BOOL success;
  373. if (impl == NULL) {
  374. VLOG(ERR, "%s:%d Invalid handle\n", __FUNCTION__, __LINE__);
  375. return FALSE;
  376. }
  377. if (ret) {
  378. *ret = impl->success;
  379. }
  380. ComponentPortDestroy(&impl->sinkPort);
  381. success = impl->Destroy(impl);
  382. Queue_Destroy(impl->usingQ);
  383. if (impl->internalData) osal_free(impl->internalData);
  384. osal_free(impl);
  385. return success;
  386. }
  387. static char* getParamName[GET_PARAM_MAX] = {
  388. "GET_PARAM_COM_STATE",
  389. "GET_PARAM_FEEDER_BITSTREAM_BUF",
  390. "GET_PARAM_DEC_HANDLE",
  391. "GET_PARAM_DEC_CODEC_INFO",
  392. "GET_PARAM_DEC_BITSTREAM_BUF_POS",
  393. "GET_PARAM_DEC_FRAME_BUF_NUM",
  394. "GET_PARAM_VPU_STATUS",
  395. "GET_PARAM_RENDERER_FRAME_BUF",
  396. "GET_PARAM_ENC_HANDLE",
  397. "GET_PARAM_ENC_FRAME_BUF_NUM",
  398. "GET_PARAM_ENC_FRAME_BUF_REGISTERED",
  399. "GET_PARAM_YUVFEEDER_FRAME_BUF",
  400. "GET_PARAM_READER_BITSTREAM_BUF",
  401. };
  402. CNMComponentParamRet ComponentGetParameter(Component from, Component to, GetParameterCMD commandType, void* data)
  403. {
  404. ComponentImpl* com = (ComponentImpl*)to;
  405. CNMComponentParamRet ret;
  406. if (com == NULL) {
  407. VLOG(ERR, "%s:%d Invalid handle or the port closed\n", __FUNCTION__, __LINE__);
  408. return CNM_COMPONENT_PARAM_FAILURE;
  409. }
  410. if (com->terminate == TRUE) {
  411. return CNM_COMPONENT_PARAM_TERMINATED;
  412. }
  413. else {
  414. if ((ret=com->GetParameter((ComponentImpl*)from, com, commandType, data)) == CNM_COMPONENT_PARAM_NOT_FOUND) {
  415. // Redirect a command.
  416. // Send a command other connected components.
  417. if (com->srcPort.connectedComponent == from) {
  418. // source component ----> current component -----> sink component
  419. to = com->sinkPort.connectedComponent;
  420. }
  421. else {
  422. // source component <---- current component <----- sink component
  423. to = com->srcPort.connectedComponent;
  424. }
  425. if (to == NULL) {
  426. VLOG(ERR, "%s:%d The command(%s) is not supported\n", __FUNCTION__, __LINE__, getParamName[commandType]);
  427. return CNM_COMPONENT_PARAM_FAILURE;
  428. }
  429. from = com;
  430. return ComponentGetParameter((Component*)from, to, commandType, data);
  431. }
  432. }
  433. return ret;
  434. }
  435. void ComponentNotifyListeners(Component component, Uint64 event, void* data)
  436. {
  437. ComponentImpl* com = (ComponentImpl*)component;
  438. Uint32 i = 0;
  439. Uint64 listeningEvents;
  440. void* context;
  441. ComponentListenerFunc update = NULL;
  442. for (i=0; i<com->numListeners; i++) {
  443. listeningEvents = com->listeners[i].events;
  444. update = com->listeners[i].update;
  445. context = com->listeners[i].context;
  446. if (listeningEvents & event) {
  447. update(component, event, data, context);
  448. }
  449. }
  450. }
  451. BOOL ComponentRegisterListener(Component component, Uint64 events, ComponentListenerFunc func, void* context)
  452. {
  453. ComponentImpl* com = (ComponentImpl*)component;
  454. Uint32 num;
  455. if (com == NULL) return FALSE;
  456. num = com->numListeners;
  457. if (num == MAX_NUM_LISTENERS) {
  458. VLOG(ERR, "%s:%d Failed to ComponentRegisterListener\n", __FUNCTION__, __LINE__);
  459. return FALSE;
  460. }
  461. com->listeners[num].events = events;
  462. com->listeners[num].update = func;
  463. com->listeners[num].context = context;
  464. com->numListeners = num+1;
  465. return TRUE;
  466. }
  467. CNMComponentParamRet ComponentSetParameter(Component from, Component to, SetParameterCMD commandType, void* data)
  468. {
  469. ComponentImpl* com = (ComponentImpl*)to;
  470. if (com == NULL) {
  471. VLOG(ERR, "%s:%d Invalid handle or the port closed\n", __FUNCTION__, __LINE__);
  472. return CNM_COMPONENT_PARAM_FAILURE;
  473. }
  474. if (com->terminate == TRUE) {
  475. return CNM_COMPONENT_PARAM_FAILURE;
  476. }
  477. else {
  478. if (com->SetParameter((ComponentImpl*)from, com, commandType, data) == FALSE) {
  479. // Redirect a command.
  480. // Send a command other connected components.
  481. if (com->srcPort.connectedComponent == from) {
  482. // source component ----> current component -----> sink component
  483. to = com->sinkPort.connectedComponent;
  484. }
  485. else {
  486. // source component <---- current component <----- sink component
  487. to = com->srcPort.connectedComponent;
  488. }
  489. if (to == NULL) {
  490. VLOG(ERR, "%s:%d The command(%d) is not supported\n", __FUNCTION__, __LINE__, commandType);
  491. return CNM_COMPONENT_PARAM_FAILURE;
  492. }
  493. from = com;
  494. return ComponentSetParameter((Component*)from, to, commandType, data);
  495. }
  496. }
  497. return CNM_COMPONENT_PARAM_SUCCESS;
  498. }
  499. void ComponentPortCreate(Port* port, Component owner, Uint32 depth, Uint32 size)
  500. {
  501. // Release the queues which are created previously.
  502. port->inputQ = Queue_Create_With_Lock(depth, size);
  503. port->outputQ = Queue_Create_With_Lock(depth, size);
  504. port->owner = owner;
  505. port->sequenceNo = 0;
  506. }
  507. void ComponentPortSetData(Port* port, PortContainer* data)
  508. {
  509. if (data == NULL) {
  510. // Silent error
  511. return;
  512. }
  513. data->consumed = FALSE;
  514. if (Queue_Enqueue(port->outputQ, (void*)data) == FALSE) {
  515. VLOG(INFO, "%s FAILURE\n", __FUNCTION__);
  516. }
  517. }
  518. PortContainer* ComponentPortPeekData(Port* port)
  519. {
  520. PortContainer* c = Queue_Peek(port->inputQ);
  521. if (c) {
  522. c->packetNo = port->sequenceNo;
  523. }
  524. return c;
  525. }
  526. PortContainer* ComponentPortGetData(Port* port)
  527. {
  528. PortContainer* c = Queue_Dequeue(port->inputQ);
  529. if (c) {
  530. port->sequenceNo++;
  531. }
  532. return c;
  533. }
  534. void* WaitBeforeComponentPortGetData(Port* port)
  535. {
  536. BOOL loop = TRUE;
  537. void* portData = NULL;
  538. while (loop) {
  539. if (Queue_Get_Cnt(port->inputQ) > 0) {
  540. portData = Queue_Dequeue(port->inputQ);
  541. loop = FALSE;
  542. }
  543. }
  544. return portData;
  545. }
  546. void ComponentPortDestroy(Port* port)
  547. {
  548. Queue_Destroy(port->inputQ);
  549. Queue_Destroy(port->outputQ);
  550. port->connectedComponent = NULL;
  551. }
  552. void ComponentPortWaitReadyStatus(Port* port)
  553. {
  554. while (port->outputQ && Queue_Get_Cnt(port->outputQ) > 0) {
  555. osal_msleep(1);
  556. }
  557. }
  558. BOOL ComponentPortHasInputData(Port* port)
  559. {
  560. return (Queue_Get_Cnt(port->inputQ) > 0);
  561. }
  562. Uint32 ComponentPortGetSize(Port* port)
  563. {
  564. return port->inputQ->size;
  565. }
  566. void ComponentPortFlush(Component component)
  567. {
  568. ComponentImpl* com = (ComponentImpl*)component;
  569. com->portFlush = TRUE;
  570. }
  571. ComponentState ComponentGetState(Component component)
  572. {
  573. ComponentImpl* com = (ComponentImpl*)component;
  574. if (com == NULL) {
  575. return COMPONENT_STATE_NONE;
  576. }
  577. return com->state;
  578. }
  579. BOOL ComponentChangeState(Component component, Uint32 state)
  580. {
  581. ComponentImpl* com = (ComponentImpl*)component;
  582. if (NULL != com) {
  583. if (COMPONENT_STATE_NONE < state && COMPONENT_STATE_MAX > state) {
  584. com->state = (ComponentState)state;
  585. return TRUE;
  586. }
  587. }
  588. return FALSE;
  589. }
  590. /* return TRUE - Go next step
  591. * FALSE - Retry
  592. */
  593. BOOL ComponentParamReturnTest(CNMComponentParamRet ret, BOOL* success)
  594. {
  595. BOOL retry = TRUE;
  596. switch (ret) {
  597. case CNM_COMPONENT_PARAM_FAILURE: retry = FALSE; *success = FALSE; break;
  598. case CNM_COMPONENT_PARAM_SUCCESS: retry = TRUE; *success = TRUE; break;
  599. case CNM_COMPONENT_PARAM_NOT_READY: retry = FALSE; *success = TRUE; break;
  600. case CNM_COMPONENT_PARAM_NOT_FOUND: retry = FALSE; *success = FALSE; break;
  601. case CNM_COMPONENT_PARAM_TERMINATED: retry = FALSE; *success = TRUE; break;
  602. default: retry = FALSE; *success = FALSE; break;
  603. }
  604. return retry;
  605. }