component.c 21 KB

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