component_dec_renderer.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  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. typedef struct {
  28. DecHandle handle; /*!<< A decoder handle */
  29. osal_thread_t threadHandle;
  30. TestDecConfig testDecConfig;
  31. Uint32 framebufStride;
  32. Uint32 displayPeriodTime;
  33. FrameBuffer pFrame[MAX_REG_FRAME];
  34. vpu_buffer_t pFbMem[MAX_REG_FRAME];
  35. BOOL enablePPU;
  36. FrameBuffer pPPUFrame[MAX_REG_FRAME];
  37. vpu_buffer_t pPPUFbMem[MAX_REG_FRAME];
  38. Queue* ppuQ;
  39. BOOL fbAllocated;
  40. ParamDecNeedFrameBufferNum fbCount;
  41. Queue* seqMemQ;
  42. osal_mutex_t lock;
  43. char outputPath[256];
  44. FILE* fpOutput[OUTPUT_FP_NUMBER];
  45. BOOL MemoryOptimization;
  46. int totalBufferNumber;
  47. int currentBufferNumber;
  48. FrameBuffer pLinearFrame[MAX_REG_FRAME];
  49. vpu_buffer_t pLinearFbMem[MAX_REG_FRAME];
  50. } RendererContext;
  51. typedef struct SequenceMemInfo {
  52. Uint32 nonLinearNum;
  53. Uint32 linearNum;
  54. Uint32 remainingCount;
  55. Uint32 sequenceNo;
  56. vpu_buffer_t pFbMem[MAX_REG_FRAME];
  57. vpu_buffer_t vbFbcYTbl[MAX_REG_FRAME];
  58. vpu_buffer_t vbFbcCTbl[MAX_REG_FRAME];
  59. vpu_buffer_t vbTask;
  60. } SequenceMemInfo;
  61. static void FreeFrameBuffer(DecHandle handle, Uint32 idx, SequenceMemInfo* info)
  62. {
  63. Int32 coreIdx = handle->coreIdx;
  64. if (info->pFbMem[idx].size > 0) {
  65. if (idx < info->nonLinearNum)
  66. vdi_free_dma_memory(coreIdx, &info->pFbMem[idx], DEC_FBC, handle->instIndex);
  67. else
  68. vdi_free_dma_memory(coreIdx, &info->pFbMem[idx], DEC_FB_LINEAR, handle->instIndex);
  69. osal_memset((void*)&info->pFbMem[idx], 0x00, sizeof(vpu_buffer_t));
  70. }
  71. if (info->vbFbcYTbl[idx].size > 0) {
  72. vdi_free_dma_memory(coreIdx, &info->vbFbcYTbl[idx], DEC_FBCY_TBL, handle->instIndex);
  73. osal_memset((void*)&info->vbFbcYTbl[idx], 0x00, sizeof(vpu_buffer_t));
  74. }
  75. if (info->vbFbcCTbl[idx].size > 0) {
  76. vdi_free_dma_memory(coreIdx, &info->vbFbcCTbl[idx], DEC_FBCC_TBL, handle->instIndex);
  77. osal_memset((void*)&info->vbFbcCTbl[idx], 0x00, sizeof(vpu_buffer_t));
  78. }
  79. if (info->vbTask.size > 0) {
  80. vdi_free_dma_memory(coreIdx, &info->vbTask, DEC_TASK, handle->instIndex);
  81. osal_memset((void*)&info->vbTask, 0x00, sizeof(vpu_buffer_t));
  82. }
  83. }
  84. static BOOL SetParamFreeFrameBuffers(ComponentImpl* com, Uint32 fbFlags)
  85. {
  86. RendererContext* ctx = (RendererContext*)com->context;
  87. BOOL remainingFbs[MAX_REG_FRAME] = {0};
  88. Uint32 idx;
  89. Uint32 fbIndex;
  90. BOOL wtlEnable = ctx->testDecConfig.enableWTL;
  91. DecGetFramebufInfo curFbInfo;
  92. Uint32 coreIdx = ctx->testDecConfig.coreIdx;
  93. SequenceMemInfo seqMem = {0};
  94. osal_mutex_lock(ctx->lock);
  95. VPU_DecGiveCommand(ctx->handle, DEC_GET_FRAMEBUF_INFO, (void*)&curFbInfo);
  96. if (PRODUCT_ID_W_SERIES(ctx->testDecConfig.productId)) {
  97. for (idx=0; idx<MAX_GDI_IDX; idx++) {
  98. fbIndex = idx;
  99. if ((fbFlags>>idx) & 0x01) {
  100. if (wtlEnable == TRUE) {
  101. fbIndex = VPU_CONVERT_WTL_INDEX(ctx->handle, idx);
  102. }
  103. seqMem.remainingCount++;
  104. remainingFbs[fbIndex] = TRUE;
  105. }
  106. }
  107. }
  108. seqMem.nonLinearNum = ctx->fbCount.nonLinearNum;
  109. seqMem.linearNum = ctx->fbCount.linearNum;
  110. osal_memcpy((void*)seqMem.pFbMem, ctx->pFbMem, sizeof(ctx->pFbMem));
  111. osal_memcpy((void*)seqMem.vbFbcYTbl, curFbInfo.vbFbcYTbl, sizeof(curFbInfo.vbFbcYTbl));
  112. osal_memcpy((void*)seqMem.vbFbcCTbl, curFbInfo.vbFbcCTbl, sizeof(curFbInfo.vbFbcCTbl));
  113. osal_memcpy((void*)&seqMem.vbTask, &curFbInfo.vbTask, sizeof(curFbInfo.vbTask));
  114. for (idx=0; idx<MAX_REG_FRAME; idx++) {
  115. if (remainingFbs[idx] == FALSE) {
  116. FreeFrameBuffer(ctx->handle, idx, &seqMem);
  117. }
  118. // Free a mvcol buffer
  119. if(curFbInfo.vbMvCol[idx].size > 0) {
  120. vdi_free_dma_memory(coreIdx, &curFbInfo.vbMvCol[idx], DEC_MV, ctx->handle->instIndex);
  121. }
  122. }
  123. if (seqMem.remainingCount > 0) {
  124. Queue_Enqueue(ctx->seqMemQ, (void*)&seqMem);
  125. }
  126. ctx->fbAllocated = FALSE;
  127. osal_mutex_unlock(ctx->lock);
  128. return TRUE;
  129. }
  130. static BOOL ReallocateFrameBuffers(ComponentImpl* com, ParamDecReallocFB* param)
  131. {
  132. RendererContext* ctx = (RendererContext*)com->context;
  133. Int32 fbcIndex = param->compressedIdx;
  134. Int32 linearIndex = param->linearIdx;
  135. vpu_buffer_t* pFbMem = ctx->pFbMem;
  136. FrameBuffer* pFrame = ctx->pFrame;
  137. FrameBuffer* newFbs = param->newFbs;
  138. if (fbcIndex >= 0) {
  139. /* Release the FBC framebuffer */
  140. vdi_free_dma_memory(ctx->testDecConfig.coreIdx, &pFbMem[fbcIndex], DEC_FBC, ctx->handle->instIndex);
  141. osal_memset((void*)&pFbMem[fbcIndex], 0x00, sizeof(vpu_buffer_t));
  142. }
  143. if (linearIndex >= 0) {
  144. /* Release the linear framebuffer */
  145. vdi_free_dma_memory(ctx->testDecConfig.coreIdx, &pFbMem[linearIndex], DEC_FB_LINEAR, ctx->handle->instIndex);
  146. osal_memset((void*)&pFbMem[linearIndex], 0x00, sizeof(vpu_buffer_t));
  147. }
  148. if (fbcIndex >= 0) {
  149. newFbs[0].myIndex = fbcIndex;
  150. newFbs[0].width = param->width;
  151. newFbs[0].height = param->height;
  152. pFrame[fbcIndex] = newFbs[0];
  153. }
  154. if (linearIndex >= 0) {
  155. newFbs[1].myIndex = linearIndex;
  156. newFbs[1].width = param->width;
  157. newFbs[1].height = param->height;
  158. pFrame[linearIndex] = newFbs[1];
  159. }
  160. return TRUE;
  161. }
  162. void Render_DecClrDispFlag(void *context, int index)
  163. {
  164. RendererContext* ctx = (RendererContext*)context;
  165. VPU_DecClrDispFlag(ctx->handle, index);
  166. }
  167. static void DisplayFrame(RendererContext* ctx, DecOutputInfo* result)
  168. {
  169. Int32 productID = ctx->testDecConfig.productId;
  170. osal_mutex_lock(ctx->lock);
  171. if (result->indexFrameDisplay >= 0) {
  172. DecInitialInfo initialInfo;
  173. VPU_DecGiveCommand(ctx->handle, DEC_GET_SEQ_INFO, &initialInfo);
  174. // No renderer device
  175. if (PRODUCT_ID_W_SERIES(productID) && initialInfo.sequenceNo != result->sequenceNo) {
  176. // Free a framebuffer of previous sequence
  177. SequenceMemInfo* memInfo = Queue_Peek(ctx->seqMemQ);
  178. if (memInfo != NULL) {
  179. FreeFrameBuffer(ctx->handle, result->indexFrameDisplay, memInfo);
  180. if (memInfo->remainingCount == 0) {
  181. VLOG(ERR, "%s:%d remainingCout must be greater than zero\n", __FUNCTION__, __LINE__);
  182. }
  183. memInfo->remainingCount--;
  184. if (memInfo->remainingCount == 0) {
  185. Queue_Dequeue(ctx->seqMemQ);
  186. }
  187. }
  188. }
  189. else {
  190. VPU_DecClrDispFlag(ctx->handle, result->indexFrameDisplay);
  191. }
  192. }
  193. osal_mutex_unlock(ctx->lock);
  194. }
  195. static BOOL FlushFrameBuffers(ComponentImpl* com, Uint32* flushedIndexes)
  196. {
  197. PortContainerDisplay* srcData;
  198. RendererContext* ctx = (RendererContext*)com->context;
  199. Int32 idx = 0;
  200. osal_mutex_lock(ctx->lock);
  201. if (flushedIndexes) *flushedIndexes = 0;
  202. while ((srcData=(PortContainerDisplay*)ComponentPortGetData(&com->srcPort)) != NULL) {
  203. idx = srcData->decInfo.indexFrameDisplay;
  204. if (0 <= idx) {
  205. VPU_DecClrDispFlag(ctx->handle, idx);
  206. if (flushedIndexes) *flushedIndexes |= (1<<idx);
  207. }
  208. ComponentPortSetData(&com->srcPort, (PortContainer*)srcData);
  209. }
  210. osal_mutex_unlock(ctx->lock);
  211. return TRUE;
  212. }
  213. void SetRenderTotalBufferNumber(ComponentImpl* com, Uint32 number)
  214. {
  215. RendererContext* ctx = (RendererContext*)com->context;
  216. ctx->fbCount.linearNum = ctx->totalBufferNumber = number;
  217. }
  218. void* AllocateFrameBuffer2(ComponentImpl* com, Uint32 size)
  219. {
  220. RendererContext* ctx = (RendererContext*)com->context;
  221. int i = 0;
  222. if (ctx->handle == NULL) {
  223. ctx->MemoryOptimization = FALSE;
  224. return NULL;
  225. }
  226. for (i = 0;i < MAX_REG_FRAME; i ++){
  227. if (ctx->pLinearFbMem[i].phys_addr == 0)
  228. {
  229. VLOG(INFO, "Found empty frame at index %d\r\n", i);
  230. break;
  231. }
  232. }
  233. if (i == MAX_REG_FRAME)
  234. {
  235. VLOG(ERR, "Could not found empty frame at index\r\n");
  236. return NULL;
  237. }
  238. // TODO: Adjust ctx->fbCount
  239. void *ret = AllocateDecFrameBuffer2(ctx->handle, &ctx->testDecConfig, size, &ctx->pLinearFrame[i], &ctx->pLinearFbMem[i]);
  240. ctx->currentBufferNumber ++;
  241. return ret;
  242. }
  243. BOOL AttachDMABuffer(ComponentImpl* com, Uint64 virtAddress, Uint32 size)
  244. {
  245. BOOL ret = FALSE;
  246. RendererContext* ctx = (RendererContext*)com->context;
  247. int i = 0;
  248. if (ctx->handle == NULL) {
  249. ctx->MemoryOptimization = FALSE;
  250. return FALSE;
  251. }
  252. for (i = 0;i < MAX_REG_FRAME; i ++){
  253. if (ctx->pLinearFbMem[i].phys_addr == 0)
  254. {
  255. VLOG(INFO, "Found empty frame at index %d\r\n", i);
  256. break;
  257. }
  258. }
  259. if (i == MAX_REG_FRAME)
  260. {
  261. VLOG(ERR, "Could not found empty frame at index\r\n");
  262. return FALSE;
  263. }
  264. ret = AttachDecDMABuffer(ctx->handle, &ctx->testDecConfig, virtAddress, size, &ctx->pLinearFrame[i], &ctx->pLinearFbMem[i]);
  265. ctx->currentBufferNumber ++;
  266. return ret;
  267. }
  268. static BOOL AllocateFrameBuffer(ComponentImpl* com)
  269. {
  270. RendererContext* ctx = (RendererContext*)com->context;
  271. BOOL success;
  272. Uint32 compressedNum;
  273. Uint32 linearNum;
  274. CNMComponentParamRet ret;
  275. ret = ComponentGetParameter(com, com->srcPort.connectedComponent, GET_PARAM_DEC_FRAME_BUF_NUM, &ctx->fbCount);
  276. if (ComponentParamReturnTest(ret, &success) == FALSE) {
  277. return success;
  278. }
  279. osal_memset((void*)ctx->pFbMem, 0x00, sizeof(ctx->pFbMem));
  280. osal_memset((void*)ctx->pFrame, 0x00, sizeof(ctx->pFrame));
  281. compressedNum = ctx->fbCount.nonLinearNum;
  282. linearNum = ctx->fbCount.linearNum;
  283. if (compressedNum == 0 && linearNum == 0) {
  284. VLOG(ERR, "%s:%d The number of framebuffers are zero. compressed %d, linear: %d\n",
  285. __FUNCTION__, __LINE__, compressedNum, linearNum);
  286. return FALSE;
  287. }
  288. if (ctx->MemoryOptimization){
  289. linearNum = 0;
  290. }
  291. if (AllocateDecFrameBuffer(ctx->handle, &ctx->testDecConfig, compressedNum, linearNum, ctx->pFrame, ctx->pFbMem, &ctx->framebufStride) == FALSE) {
  292. VLOG(INFO, "%s:%d Failed to AllocateDecFrameBuffer()\n", __FUNCTION__, __LINE__);
  293. return FALSE;
  294. }
  295. ctx->fbAllocated = TRUE;
  296. return TRUE;
  297. }
  298. static BOOL AllocatePPUFrameBuffer(ComponentImpl* com)
  299. {
  300. RendererContext* ctx = (RendererContext*)com->context;
  301. TestDecConfig* decConfig = &(ctx->testDecConfig);
  302. BOOL resOf = FALSE;
  303. osal_memset((void*)ctx->pPPUFbMem, 0x00, sizeof(ctx->pPPUFbMem));
  304. osal_memset((void*)ctx->pPPUFrame, 0x00, sizeof(ctx->pPPUFrame));
  305. if(PRODUCT_ID_960 == decConfig->productId || PRODUCT_ID_980 == decConfig->productId) {
  306. if (FALSE == Coda9AllocateDecPPUFrameBuffer(&(ctx->enablePPU), ctx->handle, &ctx->testDecConfig, ctx->pPPUFrame, ctx->pPPUFbMem, ctx->ppuQ)) {
  307. VLOG(INFO, "%s:%d Failed to Coda9AllocateDecPPUFrameBuffer()\n", __FUNCTION__, __LINE__);
  308. }
  309. resOf = TRUE;
  310. }
  311. return resOf;
  312. }
  313. static CNMComponentParamRet GetParameterRenderer(ComponentImpl* from, ComponentImpl* com, GetParameterCMD commandType, void* data)
  314. {
  315. RendererContext* ctx = (RendererContext*)com->context;
  316. ParamDecFrameBuffer* allocFb = NULL;
  317. ParamDecPPUFrameBuffer* allocPPUFb = NULL;
  318. PortContainer* container;
  319. if (ctx->fbAllocated == FALSE) return CNM_COMPONENT_PARAM_NOT_READY;
  320. switch(commandType) {
  321. case GET_PARAM_COM_IS_CONTAINER_CONUSUMED:
  322. // This query command is sent from the comonponent core.
  323. // If input data are consumed in sequence, it should return TRUE through PortContainer::consumed.
  324. container = (PortContainer*)data;
  325. container->consumed = TRUE;
  326. break;
  327. case GET_PARAM_RENDERER_FRAME_BUF:
  328. if (ctx->MemoryOptimization){
  329. if (ctx->currentBufferNumber < ctx->totalBufferNumber) return CNM_COMPONENT_PARAM_NOT_READY;
  330. int i = 0;
  331. for (i = 0;i < MAX_REG_FRAME; i ++) {
  332. if (ctx->pFbMem[i].phys_addr == 0) {
  333. break;
  334. }
  335. }
  336. VLOG(INFO, "The start index of LINEAR buffer = %d\n", i);
  337. for (int j = 0; j < MAX_REG_FRAME; j ++) {
  338. if (ctx->pLinearFbMem[j].phys_addr != 0) {
  339. memcpy(&ctx->pFbMem[i + j], &ctx->pLinearFbMem[j], sizeof(vpu_buffer_t));
  340. memcpy(&ctx->pFrame[i + j], &ctx->pLinearFrame[j], sizeof(FrameBuffer));
  341. }
  342. }
  343. }
  344. //TODO: Adjust Liner number
  345. allocFb = (ParamDecFrameBuffer*)data;
  346. allocFb->stride = ctx->framebufStride;
  347. allocFb->linearNum = ctx->fbCount.linearNum;
  348. allocFb->nonLinearNum = ctx->fbCount.nonLinearNum;
  349. allocFb->fb = ctx->pFrame;
  350. break;
  351. case GET_PARAM_RENDERER_PPU_FRAME_BUF:
  352. allocPPUFb = (ParamDecPPUFrameBuffer*)data;
  353. if (TRUE == AllocatePPUFrameBuffer(com)) {
  354. allocPPUFb->enablePPU = ctx->enablePPU;
  355. allocPPUFb->ppuQ = ctx->ppuQ;
  356. allocPPUFb->fb = ctx->pPPUFrame;
  357. }
  358. else {
  359. allocPPUFb->enablePPU = FALSE;
  360. allocPPUFb->ppuQ = NULL;
  361. allocPPUFb->fb = NULL;
  362. }
  363. break;
  364. default:
  365. return CNM_COMPONENT_PARAM_NOT_FOUND;
  366. }
  367. return CNM_COMPONENT_PARAM_SUCCESS;
  368. }
  369. static CNMComponentParamRet SetParameterRenderer(ComponentImpl* from, ComponentImpl* com, SetParameterCMD commandType, void* data)
  370. {
  371. RendererContext* ctx = (RendererContext*)com->context;
  372. BOOL result = TRUE;
  373. UNREFERENCED_PARAMETER(ctx);
  374. switch(commandType) {
  375. case SET_PARAM_RENDERER_REALLOC_FRAMEBUFFER:
  376. result = ReallocateFrameBuffers(com, (ParamDecReallocFB*)data);
  377. break;
  378. case SET_PARAM_RENDERER_FREE_FRAMEBUFFERS:
  379. result = SetParamFreeFrameBuffers(com, *(Uint32*)data);
  380. break;
  381. case SET_PARAM_RENDERER_FLUSH:
  382. result = FlushFrameBuffers(com, (Uint32*)data);
  383. break;
  384. case SET_PARAM_RENDERER_ALLOC_FRAMEBUFFERS:
  385. result = AllocateFrameBuffer(com);
  386. break;
  387. case SET_PARAM_RENDERER_CHANGE_COM_STATE:
  388. result = ComponentChangeState(com, *(Uint32*)data);
  389. break;
  390. default:
  391. return CNM_COMPONENT_PARAM_NOT_FOUND;
  392. }
  393. if (result == TRUE) return CNM_COMPONENT_PARAM_SUCCESS;
  394. else return CNM_COMPONENT_PARAM_FAILURE;
  395. }
  396. static BOOL ExecuteRenderer(ComponentImpl* com, PortContainer* in, PortContainer* out)
  397. {
  398. RendererContext* ctx = (RendererContext*)com->context;
  399. PortContainerDisplay* srcData = (PortContainerDisplay*)in;
  400. Int32 indexFrameDisplay;
  401. TestDecConfig* decConfig = &ctx->testDecConfig;
  402. if (TRUE == com->pause) {
  403. return TRUE;
  404. }
  405. #ifdef USE_FEEDING_METHOD_BUFFER
  406. PortContainerExternal *output = (PortContainerExternal*)ComponentPortPeekData(&com->sinkPort);
  407. if (output == NULL) {
  408. in->reuse = TRUE;
  409. return TRUE;
  410. }
  411. #endif
  412. in->reuse = TRUE;
  413. indexFrameDisplay = srcData->decInfo.indexFrameDisplay;
  414. if (indexFrameDisplay == DISPLAY_IDX_FLAG_SEQ_END) {
  415. while ((output = (PortContainerExternal*)ComponentPortGetData(&com->sinkPort)) != NULL)
  416. {
  417. output->nFlags = 0x1;
  418. output->nFilledLen = 0;
  419. ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_FILL_BUFFER_DONE, (void *)output);
  420. }
  421. com->terminate = TRUE;
  422. ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_DECODED_ALL, NULL);
  423. }
  424. else if (indexFrameDisplay >= 0) {
  425. VpuRect rcDisplay = {0,};
  426. TiledMapType mapType = srcData->decInfo.dispFrame.mapType;
  427. rcDisplay.right = srcData->decInfo.dispPicWidth;
  428. rcDisplay.bottom = srcData->decInfo.dispPicHeight;
  429. #ifdef USE_FEEDING_METHOD_BUFFER
  430. Uint32 width, height, bpp;
  431. size_t sizeYuv;
  432. Uint32 count = 0, total_count = 0;
  433. if (ctx->MemoryOptimization){
  434. uint8_t *dmaBuffer = NULL;
  435. if (FALSE ==GetYUVFromFrameBuffer2(NULL, &dmaBuffer, output->nFilledLen, ctx->handle, &srcData->decInfo.dispFrame, rcDisplay, &width, &height, &bpp, &sizeYuv)) {
  436. VLOG(ERR, "GetYUVFromFrameBuffer2 FAIL!\n");
  437. }
  438. total_count = Queue_Get_Cnt(com->sinkPort.inputQ);
  439. while (output->pBuffer != dmaBuffer)
  440. {
  441. output = (PortContainerExternal*)ComponentPortGetData(&com->sinkPort);
  442. Queue_Enqueue(com->sinkPort.inputQ, (void *)output);
  443. output = (PortContainerExternal*)ComponentPortPeekData(&com->sinkPort);
  444. VLOG(INFO, "pBuffer = %p, dmaBuffer = %p, index = %d/%d\n", output->pBuffer, dmaBuffer, count, total_count);
  445. if (count >= total_count)
  446. {
  447. VLOG(ERR, "A wrong Frame Found\n");
  448. output->nFilledLen = 0;
  449. break;
  450. }
  451. count ++;
  452. }
  453. } else {
  454. if (FALSE ==GetYUVFromFrameBuffer2(output->pBuffer, NULL, output->nFilledLen, ctx->handle, &srcData->decInfo.dispFrame, rcDisplay, &width, &height, &bpp, &sizeYuv)) {
  455. VLOG(ERR, "GetYUVFromFrameBuffer2 FAIL!\n");
  456. }
  457. }
  458. output->nFilledLen = sizeYuv;
  459. output->index = srcData->decInfo.indexFrameDisplay;
  460. if(srcData->last)
  461. output->nFlags |= 0x1;
  462. if(ComponentPortGetData(&com->sinkPort))
  463. {
  464. ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_FILL_BUFFER_DONE, (void *)output);
  465. }
  466. (void)DisplayFrame;
  467. (void)decConfig;
  468. (void)mapType;
  469. #else
  470. if (decConfig->scaleDownWidth > 0 || decConfig->scaleDownHeight > 0) {
  471. rcDisplay.right = VPU_CEIL(srcData->decInfo.dispPicWidth, 16);
  472. }
  473. if (strlen((const char*)decConfig->outputPath) > 0) {
  474. if (ctx->fpOutput[0] == NULL) {
  475. if (OpenDisplayBufferFile(decConfig->bitFormat, decConfig->outputPath, rcDisplay, mapType, ctx->fpOutput) == FALSE) {
  476. return FALSE;
  477. }
  478. }
  479. SaveDisplayBufferToFile(ctx->handle, decConfig->bitFormat, srcData->decInfo.dispFrame, rcDisplay, ctx->fpOutput);
  480. }
  481. DisplayFrame(ctx, &srcData->decInfo);
  482. #endif
  483. //osal_msleep(ctx->displayPeriodTime);
  484. }
  485. srcData->consumed = TRUE;
  486. srcData->reuse = FALSE;
  487. if (srcData->last == TRUE) {
  488. ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_DECODED_ALL, NULL);
  489. while ((output = (PortContainerExternal*)ComponentPortGetData(&com->sinkPort)) != NULL)
  490. {
  491. output->nFlags = 0x1;
  492. output->nFilledLen = 0;
  493. VLOG(ERR, "Flush output port\r\n");
  494. ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_FILL_BUFFER_DONE, (void *)output);
  495. }
  496. com->terminate = TRUE;
  497. }
  498. return TRUE;
  499. }
  500. static BOOL PrepareRenderer(ComponentImpl* com, BOOL* done)
  501. {
  502. RendererContext* ctx = (RendererContext*)com->context;
  503. BOOL ret;
  504. if (ctx->handle == NULL) {
  505. CNMComponentParamRet paramRet;
  506. BOOL success;
  507. paramRet = ComponentGetParameter(com, com->srcPort.connectedComponent, GET_PARAM_DEC_HANDLE, &ctx->handle);
  508. if (ComponentParamReturnTest(paramRet, &success) == FALSE) {
  509. return success;
  510. }
  511. }
  512. if ((ret=AllocateFrameBuffer(com)) == FALSE || ctx->fbAllocated == FALSE) {
  513. return ret;
  514. }
  515. ComponentNotifyListeners(com, COMPONENT_EVENT_DEC_REGISTER_FB, &ctx->pFrame[0]);
  516. // Nothing to do
  517. *done = TRUE;
  518. return TRUE;
  519. }
  520. static void ReleaseRenderer(ComponentImpl* com)
  521. {
  522. RendererContext* ctx = (RendererContext*)com->context;
  523. Uint32 coreIdx = ctx->testDecConfig.coreIdx;
  524. Uint32 i;
  525. for (i=0; i<MAX_REG_FRAME; i++) {
  526. if (ctx->pFbMem[i].size) {
  527. if (i < ctx->fbCount.linearNum)
  528. vdi_free_dma_memory(coreIdx, &ctx->pFbMem[i], DEC_FBC, ctx->handle->instIndex);
  529. else
  530. vdi_free_dma_memory(coreIdx, &ctx->pFbMem[i], DEC_FB_LINEAR, ctx->handle->instIndex);
  531. }
  532. }
  533. for (i=0; i<MAX_REG_FRAME; i++) {
  534. if (ctx->pPPUFrame[i].size) vdi_free_dma_memory(coreIdx, &ctx->pPPUFbMem[i], DEC_ETC, ctx->handle->instIndex);
  535. }
  536. }
  537. static BOOL DestroyRenderer(ComponentImpl* com)
  538. {
  539. RendererContext* ctx = (RendererContext*)com->context;
  540. CloseDisplayBufferFile(ctx->fpOutput);
  541. Queue_Destroy(ctx->seqMemQ);
  542. Queue_Destroy(ctx->ppuQ);
  543. osal_mutex_destroy(ctx->lock);
  544. osal_free(ctx);
  545. return TRUE;
  546. }
  547. static Component CreateRenderer(ComponentImpl* com, CNMComponentConfig* componentParam)
  548. {
  549. RendererContext* ctx;
  550. com->context = (RendererContext*)osal_malloc(sizeof(RendererContext));
  551. osal_memset(com->context, 0, sizeof(RendererContext));
  552. ctx = com->context;
  553. osal_memset(ctx->pLinearFbMem, 0, sizeof(ctx->pLinearFbMem));
  554. osal_memset(ctx->pLinearFrame, 0, sizeof(ctx->pLinearFrame));
  555. osal_memcpy((void*)&ctx->testDecConfig, (void*)&componentParam->testDecConfig, sizeof(TestDecConfig));
  556. if (componentParam->testDecConfig.fps > 0)
  557. ctx->displayPeriodTime = (1000 / componentParam->testDecConfig.fps);
  558. else
  559. ctx->displayPeriodTime = 1000/30;
  560. ctx->fbAllocated = FALSE;
  561. ctx->seqMemQ = Queue_Create(10, sizeof(SequenceMemInfo));
  562. ctx->lock = osal_mutex_create();
  563. ctx->ppuQ = Queue_Create(MAX_REG_FRAME, sizeof(FrameBuffer));
  564. ctx->MemoryOptimization = FALSE;
  565. ctx->totalBufferNumber = 10;
  566. ctx->currentBufferNumber = 0;
  567. return (Component)com;
  568. }
  569. ComponentImpl rendererComponentImpl = {
  570. "renderer",
  571. NULL,
  572. {0,},
  573. {0,},
  574. sizeof(PortContainer), /* No output */
  575. 5,
  576. CreateRenderer,
  577. GetParameterRenderer,
  578. SetParameterRenderer,
  579. PrepareRenderer,
  580. ExecuteRenderer,
  581. ReleaseRenderer,
  582. DestroyRenderer
  583. };