component_coda9_enc_encoder.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  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 <time.h>
  28. #include <sys/time.h>
  29. #include "cnm_app.h"
  30. #include "component.h"
  31. #include "misc/debug.h"
  32. #include "misc/bw_monitor.h"
  33. #ifndef min
  34. #define min(a,b) (((a) < (b)) ? (a) : (b))
  35. #endif
  36. #ifndef max
  37. #define max(a,b) (((a) > (b)) ? (a) : (b))
  38. #endif
  39. #define DEFAULT_READ_SIZE 1460 // = MTU(ethernet) - (IP_HEADER+TCP_HEADER)
  40. #define MAX_SIZE_ENC_HEADER 256
  41. #define MAX_SIZE_ENCODED_STREAM_BUF 0x700000 // only for RingBuffer
  42. typedef enum {
  43. ENC_INT_STATUS_NONE, // Interrupt not asserted yet
  44. ENC_INT_STATUS_FULL, // Need more buffer
  45. ENC_INT_STATUS_DONE, // Interrupt asserted
  46. ENC_INT_STATUS_LOW_LATENCY,
  47. ENC_INT_STATUS_TIMEOUT, // Interrupt not asserted during given time.
  48. ENC_INT_STATUS_BUF_FULL,
  49. } ENC_INT_STATUS;
  50. typedef enum {
  51. ENCODER_STATE_OPEN,
  52. ENCODER_STATE_INIT_SEQ,
  53. ENCODER_STATE_REGISTER_FB,
  54. ENCODER_STATE_ENCODE_HEADER,
  55. ENCODER_STATE_ENCODING,
  56. } EncoderState;
  57. typedef struct {
  58. BOOL fieldDone;
  59. Int32 iPicCnt;
  60. ENC_CFG encCfg;
  61. BOOL isDroppedPic;
  62. } CODA980Ctx;
  63. typedef struct {
  64. EncHandle handle;
  65. TestEncConfig testEncConfig;
  66. EncOpenParam encOpenParam;
  67. ParamEncNeedFrameBufferNum fbCount;
  68. Uint32 frameIdx;
  69. vpu_buffer_t vbCustomLambda;
  70. vpu_buffer_t vbScalingList;
  71. Uint32 customLambda[NUM_CUSTOM_LAMBDA];
  72. UserScalingList scalingList;
  73. vpu_buffer_t vbCustomMap[MAX_REG_FRAME];
  74. EncoderState state;
  75. BOOL stateDoing;
  76. EncInitialInfo initialInfo;
  77. Queue* encOutQ;
  78. EncParam encParam;
  79. Int32 encodedReConFrmIdx;
  80. ParamEncBitstreamBuffer bsBuf;
  81. BOOL fullInterrupt;
  82. Uint32 changedCount;
  83. Uint64 startTimeout;
  84. EncodedStreamBufInfo encStreamBufInfo;
  85. Int32 encHeaderSize;
  86. Uint8* encHeaderBuf; //EncodedHeaderBufInfo
  87. //CODA980 variable
  88. CODA980Ctx ctx980;
  89. Uint32 cyclePerTick;
  90. BOOL readBsWhenFullInterrupt;
  91. } EncoderContext;
  92. BOOL HandleEncFullInterrupt(ComponentImpl* com, EncoderContext* ctx, PortContainerES* out)
  93. {
  94. Int32 streamSize =0;
  95. PhysicalAddress paRdPtr;
  96. PhysicalAddress paWrPtr;
  97. Uint32 fullStreamSize = 0;
  98. EncInfo* encInfo = NULL;
  99. VPU_EncGetBitstreamBuffer(ctx->handle, &paRdPtr, &paWrPtr, &streamSize);
  100. VLOG(TRACE, "<%s:%d> INT_BSBUF_FULL %p, %p\n", __FUNCTION__, __LINE__, paRdPtr, paWrPtr);
  101. fullStreamSize = streamSize;
  102. encInfo = VPU_HANDLE_TO_ENCINFO(ctx->handle);
  103. if (NULL == encInfo) {
  104. VLOG(ERR, "<%s:%d> NULL point exception\n", __FUNCTION__, __LINE__);
  105. return FALSE;
  106. }
  107. out->paBsBufStart = encInfo->streamBufStartAddr;
  108. out->paBsBufEnd = encInfo->streamBufEndAddr;
  109. out->rdPtr = paRdPtr;
  110. out->wrPtr = paWrPtr;
  111. out->size = fullStreamSize;
  112. return TRUE;
  113. }
  114. BOOL MakeEncHeader(EncoderContext* ctx, EncHeaderParam encHeaderParam) {
  115. if ((MAX_SIZE_ENC_HEADER-1) < ctx->encHeaderSize + encHeaderParam.size) {
  116. VLOG(WARN, "Enc Header Buffer overrun\n");
  117. return FALSE;
  118. }
  119. if (NULL != ctx->encHeaderBuf) {
  120. vdi_read_memory(ctx->testEncConfig.coreIdx, encHeaderParam.buf, ctx->encHeaderBuf+ctx->encHeaderSize, encHeaderParam.size, ctx->testEncConfig.stream_endian);
  121. ctx->encHeaderSize = ctx->encHeaderSize + encHeaderParam.size;
  122. } else {
  123. VLOG(ERR, "%s:%d NULL point Exception: %s\n", __FUNCTION__, __LINE__);
  124. return FALSE;
  125. }
  126. return TRUE;
  127. }
  128. static BOOL FindEsBuffer(EncoderContext* ctx, PhysicalAddress addr, vpu_buffer_t* bs)
  129. {
  130. Uint32 i;
  131. for (i=0; i<ctx->bsBuf.num; i++) {
  132. if (addr == ctx->bsBuf.bs[i].phys_addr) {
  133. *bs = ctx->bsBuf.bs[i];
  134. return TRUE;
  135. }
  136. }
  137. return FALSE;
  138. }
  139. //The name of function should be renamed appropriately.
  140. //only for CODA980
  141. static void SetEncPicParam(ComponentImpl* com, PortContainerYuv* in, EncParam* encParam)
  142. {
  143. EncoderContext* ctx = (EncoderContext*)com->context;
  144. vpu_buffer_t* buf = (vpu_buffer_t*)Queue_Peek(ctx->encOutQ);
  145. EncInfo* pEncInfo = VPU_HANDLE_TO_ENCINFO(ctx->handle);
  146. encParam->picStreamBufferAddr = buf->phys_addr;
  147. encParam->picStreamBufferSize = buf->size;
  148. encParam->srcIdx = in->srcFbIndex;
  149. encParam->srcEndFlag = in->last;
  150. encParam->sourceFrame = &in->fb;
  151. encParam->sourceFrame->sourceLBurstEn = FALSE;
  152. encParam->sourceFrame->endian = ctx->encOpenParam.frameEndian;
  153. encParam->sourceFrame->cbcrInterleave = ctx->encOpenParam.cbcrInterleave;
  154. encParam->skipPicture = 0;
  155. if (FALSE == ctx->testEncConfig.ringBufferEnable) {
  156. pEncInfo->streamBufStartAddr = buf->phys_addr;
  157. pEncInfo->streamBufEndAddr = buf->phys_addr + ctx->encOpenParam.bitstreamBufferSize;
  158. }
  159. }
  160. static BOOL RegisterFrameBuffers(ComponentImpl* com)
  161. {
  162. EncoderContext* ctx= (EncoderContext*)com->context;
  163. FrameBuffer* pReconFb = NULL;
  164. FrameBuffer* pSrcFb = NULL;
  165. FrameBufferAllocInfo srcFbAllocInfo;
  166. FrameBufferAllocInfo reconFbAllocInfo;
  167. Uint32 reconFbStride = 0;
  168. Uint32 reconFbHeight = 0;
  169. ParamEncFrameBuffer paramFb;
  170. RetCode result;
  171. CNMComponentParamRet ret;
  172. BOOL success;
  173. ctx->stateDoing = TRUE;
  174. ret = ComponentGetParameter(com, com->srcPort.connectedComponent, GET_PARAM_YUVFEEDER_FRAME_BUF, (void*)&paramFb);
  175. if (ComponentParamReturnTest(ret, &success) == FALSE) return success;
  176. //Reconstructed frame buffers
  177. pReconFb = paramFb.reconFb;
  178. reconFbStride = paramFb.reconFbAllocInfo.stride;
  179. reconFbHeight = paramFb.reconFbAllocInfo.height;
  180. reconFbAllocInfo = paramFb.reconFbAllocInfo;
  181. if(0 != reconFbStride && 0 !=reconFbHeight) {
  182. if (VPU_EncAllocateFrameBuffer(ctx->handle, reconFbAllocInfo, pReconFb) != RETCODE_SUCCESS) {
  183. VLOG(ERR, "VPU_EncAllocateFrameBuffer fail to allocate reconstructed frame buffers\n");
  184. return FALSE;
  185. }
  186. }
  187. result = VPU_EncRegisterFrameBuffer(ctx->handle, pReconFb, ctx->fbCount.reconFbNum, reconFbStride, reconFbHeight, (TiledMapType)reconFbAllocInfo.mapType);
  188. if (result != RETCODE_SUCCESS) {
  189. VLOG(ERR, "%s:%d Failed to VPU_EncRegisterFrameBuffer(%d)\n", __FUNCTION__, __LINE__, result);
  190. return FALSE;
  191. }
  192. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_REGISTER_FB, NULL);
  193. //Reference frame buffers
  194. pSrcFb = paramFb.srcFb;
  195. srcFbAllocInfo = paramFb.srcFbAllocInfo;
  196. if(0 != srcFbAllocInfo.stride && 0 !=srcFbAllocInfo.height ) {
  197. if (VPU_EncAllocateFrameBuffer(ctx->handle, srcFbAllocInfo, pSrcFb) != RETCODE_SUCCESS) {
  198. VLOG(ERR, "VPU_EncAllocateFrameBuffer fail to allocate source frame buffers\n");
  199. return FALSE;
  200. }
  201. }
  202. if (NULL == ctx->encStreamBufInfo.encodedStreamBuf) {
  203. ctx->encStreamBufInfo.encodedStreamBufSize = MAX_SIZE_ENCODED_STREAM_BUF;
  204. //ctx->encStreamBufInfo.encodedStreamBufSize = ctx->encOpenParam.bitstreamBufferSize;
  205. ctx->encStreamBufInfo.encodedStreamBuf = (Uint8 *)osal_malloc(ctx->encStreamBufInfo.encodedStreamBufSize);
  206. if (NULL != ctx->encStreamBufInfo.encodedStreamBuf) {
  207. osal_memset(ctx->encStreamBufInfo.encodedStreamBuf, 0x00, ctx->encStreamBufInfo.encodedStreamBufSize);
  208. }
  209. else {
  210. VLOG(WARN, "%s:%d NULL point exception :: encodedStreamBuf\n",__FUNCTION__, __LINE__);
  211. }
  212. }
  213. ctx->stateDoing = FALSE;
  214. return TRUE;
  215. }
  216. static CNMComponentParamRet GetParameterEncoder(ComponentImpl* from, ComponentImpl* com, GetParameterCMD commandType, void* data)
  217. {
  218. EncoderContext* ctx = (EncoderContext*)com->context;
  219. BOOL result = TRUE;
  220. ParamEncNeedFrameBufferNum* fbCount;
  221. PortContainerYuv* container;
  222. switch(commandType) {
  223. case GET_PARAM_COM_IS_CONTAINER_CONUSUMED:
  224. container = (PortContainerYuv*)data;
  225. if (0 <= ctx->encodedReConFrmIdx) {
  226. container->consumed = TRUE;
  227. }
  228. break;
  229. case GET_PARAM_ENC_HANDLE:
  230. if (ctx->handle == NULL) return CNM_COMPONENT_PARAM_NOT_READY;
  231. *(EncHandle*)data = ctx->handle;
  232. break;
  233. case GET_PARAM_ENC_FRAME_BUF_NUM:
  234. if (ctx->fbCount.srcFbNum == 0) return CNM_COMPONENT_PARAM_NOT_READY;
  235. fbCount = (ParamEncNeedFrameBufferNum*)data;
  236. fbCount->reconFbNum = ctx->fbCount.reconFbNum;
  237. fbCount->srcFbNum = ctx->fbCount.srcFbNum;
  238. break;
  239. case GET_PARAM_ENC_FRAME_BUF_REGISTERED:
  240. if (ctx->state <= ENCODER_STATE_REGISTER_FB) return CNM_COMPONENT_PARAM_NOT_READY;
  241. *(BOOL*)data = TRUE;
  242. break;
  243. default:
  244. result = FALSE;
  245. break;
  246. }
  247. return (result == TRUE) ? CNM_COMPONENT_PARAM_SUCCESS : CNM_COMPONENT_PARAM_FAILURE;
  248. }
  249. static CNMComponentParamRet SetParameterEncoder(ComponentImpl* from, ComponentImpl* com, SetParameterCMD commandType, void* data)
  250. {
  251. BOOL result = TRUE;
  252. EncoderContext* ctx = (EncoderContext*)com->context;
  253. switch(commandType) {
  254. case SET_PARAM_COM_PAUSE:
  255. com->pause = *(BOOL*)data;
  256. break;
  257. case SET_PARAM_ENC_READ_BS_WHEN_FULL_INTERRUPT:
  258. ctx->readBsWhenFullInterrupt = *(BOOL*)data;
  259. break;
  260. default:
  261. VLOG(ERR, "Unknown SetParameterCMD Type : %d\n", commandType);
  262. result = FALSE;
  263. break;
  264. }
  265. return (result == TRUE) ? CNM_COMPONENT_PARAM_SUCCESS : CNM_COMPONENT_PARAM_FAILURE;
  266. }
  267. static ENC_INT_STATUS HandlingInterruptFlagNoCQ(ComponentImpl* com, InterruptBit waitInterrptFlag)
  268. {
  269. EncoderContext* ctx = (EncoderContext*)com->context;
  270. EncHandle handle = ctx->handle;
  271. Int32 interruptFlag = 0;
  272. Uint32 interruptWaitTime = VPU_WAIT_TIME_OUT;
  273. Uint32 interruptTimeout = VPU_ENC_TIMEOUT;
  274. ENC_INT_STATUS status = ENC_INT_STATUS_NONE;
  275. BOOL repeat = TRUE;
  276. ctx->startTimeout = osal_gettime();
  277. do {
  278. interruptFlag = VPU_WaitInterruptEx(handle, interruptWaitTime);
  279. if (INTERRUPT_TIMEOUT_VALUE == interruptFlag) {
  280. Uint64 currentTimeout = osal_gettime();
  281. if ((currentTimeout - ctx->startTimeout) > interruptTimeout) {
  282. CNMErrorSet(CNM_ERROR_HANGUP);
  283. VLOG(ERR, "\n INSNTANCE #%d INTERRUPT TIMEOUT.\n", handle->instIndex);
  284. status = ENC_INT_STATUS_TIMEOUT;
  285. break;
  286. }
  287. interruptFlag = 0;
  288. }
  289. if (0 > interruptFlag) {
  290. VLOG(ERR, "<%s:%d> interruptFlag is negative value! %08x\n", __FUNCTION__, __LINE__, interruptFlag);
  291. status = ENC_INT_STATUS_NONE;
  292. }
  293. if (interruptFlag & (1<<INT_BIT_BIT_BUF_FULL)) {
  294. status = ENC_INT_STATUS_BUF_FULL;
  295. break;
  296. }
  297. if (0 < interruptFlag) {
  298. VPU_ClearInterruptEx(handle, interruptFlag);
  299. }
  300. if (interruptFlag & (1 << waitInterrptFlag)) {
  301. status = ENC_INT_STATUS_DONE;
  302. repeat = FALSE;
  303. }
  304. } while (repeat);
  305. return status;
  306. }
  307. static BOOL SetSequenceInfo(ComponentImpl* com)
  308. {
  309. EncoderContext* ctx = (EncoderContext*)com->context;
  310. EncHandle handle = ctx->handle;
  311. RetCode ret = RETCODE_SUCCESS;
  312. EncInitialInfo* initialInfo = &ctx->initialInfo;
  313. CNMComListenerEncCompleteSeq lsnpCompleteSeq = {0};
  314. MaverickCacheConfig encCacheConfig;
  315. ret = VPU_EncGetInitialInfo(handle, initialInfo);
  316. if (ret != RETCODE_SUCCESS) {
  317. VLOG(ERR, "%s:%d FAILED TO ENC_PIC_HDR: ret(%d) \n", __FUNCTION__, __LINE__, ret);
  318. return FALSE;
  319. }
  320. osal_memset(&encCacheConfig, 0x00, sizeof(MaverickCacheConfig));
  321. MaverickCache2Config(
  322. &encCacheConfig,
  323. 0, //encoder
  324. ctx->encOpenParam.cbcrInterleave, // cb cr interleave
  325. 0, /* bypass */
  326. 0, /* burst */
  327. 3, /* merge mode */
  328. ctx->testEncConfig.mapType,
  329. 15 /* shape */);
  330. VPU_EncGiveCommand(handle, SET_CACHE_CONFIG, &encCacheConfig);
  331. lsnpCompleteSeq.handle = handle;
  332. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_COMPLETE_SEQ, (void*)&lsnpCompleteSeq);
  333. ctx->fbCount.reconFbNum = initialInfo->minFrameBufferCount;
  334. ctx->fbCount.srcFbNum = ENC_SRC_BUF_NUM; //2
  335. if ( ctx->encOpenParam.sourceBufCount > ctx->fbCount.srcFbNum) {
  336. //if you want to change the number of source buffers,
  337. //use a variable sourceBufCount of encOpenParam
  338. //ctx->fbCount.srcFbNum = ctx->encOpenParam.sourceBufCount;
  339. }
  340. VLOG(INFO, "[ENCODER] Required reconFbCount=%d, srcFbCount=%d, outNum=%d, %dx%d\n",
  341. ctx->fbCount.reconFbNum, ctx->fbCount.srcFbNum, ctx->testEncConfig.outNum, ctx->encOpenParam.picWidth, ctx->encOpenParam.picHeight);
  342. ctx->stateDoing = FALSE;
  343. return TRUE;
  344. }
  345. static BOOL EncodeHeader(ComponentImpl* com)
  346. {
  347. EncoderContext* ctx = (EncoderContext*)com->context;
  348. EncHandle handle = ctx->handle;
  349. RetCode ret = RETCODE_SUCCESS;
  350. EncHeaderParam encHeaderParam;
  351. vpu_buffer_t* buf;
  352. Int32 ringBufEnable =ctx->encOpenParam.ringBufferEnable;
  353. ctx->stateDoing = TRUE;
  354. ctx->encParam.forceIPicture = 0;
  355. ctx->encParam.skipPicture = 0;
  356. ctx->encParam.quantParam = ctx->testEncConfig.picQpY;
  357. if (FALSE == ringBufEnable && NULL == ctx->encHeaderBuf) {
  358. ctx->encHeaderSize =0;
  359. ctx->encHeaderBuf = (Uint8 *)osal_malloc(MAX_SIZE_ENC_HEADER);
  360. if (NULL != ctx->encHeaderBuf) {
  361. osal_memset(ctx->encHeaderBuf, 0x00, MAX_SIZE_ENC_HEADER);
  362. }
  363. else {
  364. VLOG(WARN, "%s:%d NULL point exception :: encHeaderBuf\n",__FUNCTION__, __LINE__);
  365. }
  366. }
  367. buf = Queue_Peek(ctx->encOutQ);
  368. osal_memset(&encHeaderParam, 0x00, sizeof(EncHeaderParam));
  369. encHeaderParam.zeroPaddingEnable = 0;
  370. encHeaderParam.buf = buf->phys_addr;
  371. encHeaderParam.size = buf->size;
  372. if (ctx->encOpenParam.bitstreamFormat == STD_MPEG4) {
  373. encHeaderParam.headerType = 0;
  374. if((ret =VPU_EncGiveCommand(handle, ENC_PUT_VIDEO_HEADER, &encHeaderParam)) != RETCODE_SUCCESS) {
  375. VLOG(ERR, "VPU_EncGiveCommand ( ENC_PUT_VIDEO_HEADER ) for VOL_HEADER failed Error code is 0x%x \n", ret);
  376. return FALSE;
  377. }
  378. if (FALSE == ringBufEnable) {
  379. MakeEncHeader(ctx, encHeaderParam);
  380. }
  381. #ifdef MP4_ENC_VOL_HEADER
  382. encHeaderParam.headerType = VOL_HEADER;
  383. if ((ret=VPU_EncGiveCommand(handle, ENC_PUT_VIDEO_HEADER, &encHeaderParam)) != RETCODE_SUCCESS) {
  384. VLOG(ERR, "VPU_EncGiveCommand ( ENC_PUT_VIDEO_HEADER ) for VOL_HEADER failed Error code is 0x%x \n", ret);
  385. return FALSE;
  386. }
  387. if (FALSE == ringBufEnable) {
  388. MakeEncHeader(ctx, encHeaderParam);
  389. }
  390. #endif
  391. }
  392. else if(ctx->encOpenParam.bitstreamFormat == STD_AVC) {
  393. encHeaderParam.headerType = SPS_RBSP;
  394. encHeaderParam.size = buf->size;
  395. if ((ret=VPU_EncGiveCommand(handle, ENC_PUT_VIDEO_HEADER, &encHeaderParam)) != RETCODE_SUCCESS) {
  396. VLOG(ERR, "VPU_EncGiveCommand ( ENC_PUT_VIDEO_HEADER ) for SPS_RBSP failed Error code is 0x%x \n", ret);
  397. return FALSE;
  398. }
  399. if (FALSE == ringBufEnable) {
  400. MakeEncHeader(ctx, encHeaderParam);
  401. }
  402. encHeaderParam.headerType = PPS_RBSP;
  403. encHeaderParam.size = buf->size;
  404. if ((ret =VPU_EncGiveCommand(handle, ENC_PUT_VIDEO_HEADER, &encHeaderParam))!= RETCODE_SUCCESS) {
  405. VLOG(ERR, "VPU_EncGiveCommand ( ENC_PUT_VIDEO_HEADER ) for PPS_RBSP failed Error code is 0x%x \n", ret);
  406. return FALSE;
  407. }
  408. if (FALSE == ringBufEnable) {
  409. MakeEncHeader(ctx, encHeaderParam);
  410. }
  411. }
  412. DisplayEncodedInformation(ctx->handle, ctx->encOpenParam.bitstreamFormat, 0, NULL, 0, 0, ctx->testEncConfig.performance, 0);
  413. ctx->stateDoing = FALSE;
  414. return TRUE;
  415. }
  416. static BOOL Encode(ComponentImpl* com, PortContainerYuv* in, PortContainerES* out)
  417. {
  418. EncoderContext* ctx = (EncoderContext*)com->context;
  419. BOOL doEncode = FALSE;
  420. EncParam* encParam = &ctx->encParam;
  421. EncOutputInfo encOutputInfo;
  422. ENC_INT_STATUS intStatus = ENC_INT_STATUS_NONE;
  423. RetCode result;
  424. CNMComListenerHandlingInt lsnpHandlingInt = {0};
  425. CNMComListenerEncDone lsnpPicDone = {0};
  426. CNMComListenerEncStartOneFrame lsn;
  427. PhysicalAddress rdPrt;
  428. PhysicalAddress wrPtr;
  429. Int32 lengthOfStream;
  430. EncInfo* encInfo = NULL;
  431. if (NULL == in) {
  432. //Just retry
  433. return TRUE;
  434. }
  435. lsnpPicDone.handle = ctx->handle;
  436. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_READY_ONE_FRAME, &lsnpPicDone);
  437. ctx->stateDoing = TRUE;
  438. if (out->buf.phys_addr != 0) {
  439. Queue_Enqueue(ctx->encOutQ, (void*)&out->buf);
  440. out->buf.phys_addr = 0;
  441. out->buf.size = 0;
  442. }
  443. if (FALSE == ctx->fullInterrupt) {
  444. if (encParam->srcEndFlag == TRUE) {
  445. doEncode = (BOOL)(Queue_Get_Cnt(ctx->encOutQ) > 0);
  446. }
  447. if (Queue_Get_Cnt(ctx->encOutQ) > 0) {
  448. SetEncPicParam(com, in, encParam);
  449. doEncode = TRUE;
  450. in->prevMapReuse = TRUE;
  451. }
  452. if(TRUE == in->last) {
  453. if (out) out->last = TRUE;
  454. if (out) out->reuse = FALSE;
  455. if (out) out->size = 0;
  456. ctx->stateDoing = FALSE;
  457. com->terminate = TRUE;
  458. VLOG(INFO, "End of YUV stream.\n");
  459. return TRUE;
  460. }
  461. } else {
  462. doEncode = FALSE;
  463. }
  464. if (TRUE == doEncode) {
  465. result = VPU_EncStartOneFrame(ctx->handle, encParam);
  466. if (RETCODE_SUCCESS == result) {
  467. if (in) in->prevMapReuse = FALSE;
  468. Queue_Dequeue(ctx->encOutQ);
  469. //ctx->frameIdx++;
  470. in->reuse = FALSE;
  471. out->reuse = FALSE;
  472. if(TRUE == ctx->testEncConfig.ringBufferEnable && NULL != ctx->encStreamBufInfo.encodedStreamBuf) {
  473. osal_memset(ctx->encStreamBufInfo.encodedStreamBuf, 0x00, ctx->encStreamBufInfo.encodedStreamBufSize);
  474. ctx->encStreamBufInfo.encodedStreamBufLength = 0;
  475. }
  476. }
  477. else { // Error
  478. VLOG(ERR, "VPU_EncStartOneFrame failed Error code is 0x%x \n", result);
  479. HandleEncoderError(ctx->handle, ctx->frameIdx, NULL);
  480. return FALSE;
  481. }
  482. lsn.handle = ctx->handle;
  483. lsn.result = result;
  484. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_START_ONE_FRAME, (void*)&lsn);
  485. } else {
  486. if (FALSE == ctx->fullInterrupt) {
  487. //VLOG(TRACE, "waiting for reader!!! \n");
  488. out->reuse = FALSE;
  489. return TRUE;
  490. }
  491. }
  492. ctx->fullInterrupt = FALSE;
  493. {
  494. if ((intStatus = HandlingInterruptFlagNoCQ(com, INT_BIT_PIC_RUN)) == ENC_INT_STATUS_TIMEOUT) {
  495. VLOG(ERR, "failed to HandlingInterruptFlagNoCQ() \n");
  496. HandleEncoderError(ctx->handle, ctx->frameIdx, NULL);
  497. VPU_SWReset(ctx->testEncConfig.coreIdx, SW_RESET_FORCE, ctx->handle);
  498. return FALSE;
  499. }
  500. else if (ENC_INT_STATUS_BUF_FULL == intStatus) {
  501. if (FALSE == HandleEncFullInterrupt(com, ctx, out) )
  502. {
  503. VLOG(ERR, "failed to HandleEncFullInterrupt() \n");
  504. return FALSE;
  505. }
  506. out->reuse = FALSE;
  507. out->streamBufFull = TRUE;
  508. in->reuse = TRUE;
  509. ctx->fullInterrupt = TRUE;
  510. return TRUE; //Go back to execution
  511. }
  512. else if (ENC_INT_STATUS_NONE == intStatus) {
  513. out->size = 0;
  514. out->reuse = FALSE;
  515. return TRUE; /* Try again */
  516. }
  517. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_HANDLING_INT, (void*)&lsnpHandlingInt);
  518. }
  519. osal_memset(&encOutputInfo, 0x00, sizeof(EncOutputInfo));
  520. encOutputInfo.result = VPU_EncGetOutputInfo(ctx->handle, &encOutputInfo);
  521. if (encOutputInfo.result == RETCODE_REPORT_NOT_READY) {
  522. return TRUE; /* Not encoded yet */
  523. }
  524. else if (encOutputInfo.result == RETCODE_VLC_BUF_FULL) {
  525. VLOG(ERR, "VLC BUFFER FULL!!! ALLOCATE MORE TASK BUFFER(%d)!!!\n", ONE_TASKBUF_SIZE_FOR_CQ);
  526. }
  527. else if (encOutputInfo.result != RETCODE_SUCCESS) {
  528. /* ERROR */
  529. HandleEncoderError(ctx->handle, encOutputInfo.encPicCnt, &encOutputInfo);
  530. VPU_SWReset(ctx->testEncConfig.coreIdx, SW_RESET_FORCE, ctx->handle);
  531. VLOG(ERR, "Failed to encode error = %d\n", encOutputInfo.result);
  532. return FALSE;
  533. }
  534. else {;
  535. /* SUCCESS */
  536. }
  537. DisplayEncodedInformation(ctx->handle, ctx->encOpenParam.bitstreamFormat, ctx->frameIdx, &encOutputInfo, encParam->srcEndFlag, encParam->srcIdx, ctx->testEncConfig.performance, ctx->cyclePerTick);
  538. if (FALSE == ctx->testEncConfig.ringBufferEnable && encOutputInfo.bitstreamWrapAround) {
  539. // If LineBuffer interrupt is set to 1, it is ok to work.
  540. VLOG(WARN, "Warning!! BitStream buffer wrap-arounded. prepare more large buffer. Consumed all remained stream\n");
  541. }
  542. lsnpPicDone.handle = ctx->handle;
  543. lsnpPicDone.output = &encOutputInfo;
  544. lsnpPicDone.fullInterrupted = ctx->fullInterrupt;
  545. if (TRUE == ctx->testEncConfig.ringBufferEnable) {
  546. ctx->encStreamBufInfo.ringBufferEnable = ctx->testEncConfig.ringBufferEnable;
  547. osal_memcpy(&(lsnpPicDone.encodedStreamInfo), &(ctx->encStreamBufInfo), sizeof(EncodedStreamBufInfo));
  548. }
  549. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_GET_OUTPUT_INFO, (void*)&lsnpPicDone);
  550. if ( encOutputInfo.result != RETCODE_SUCCESS )
  551. return FALSE;
  552. ctx->encodedReConFrmIdx = encOutputInfo.encSrcIdx;
  553. if (0 > ctx->encodedReConFrmIdx) {
  554. VLOG(WARN, "negative value of encodedReConFrmIdx : %d\n", ctx->encodedReConFrmIdx);
  555. }
  556. ctx->fullInterrupt = FALSE;
  557. if (out) {
  558. encInfo = VPU_HANDLE_TO_ENCINFO(ctx->handle);
  559. VPU_EncGetBitstreamBuffer(ctx->handle, &rdPrt, &wrPtr, &lengthOfStream);
  560. if (in) in->reuse = FALSE;
  561. out->rdPtr = rdPrt;
  562. out->wrPtr = wrPtr;
  563. out->paBsBufStart = encInfo->streamBufStartAddr;
  564. out->paBsBufEnd = encInfo->streamBufEndAddr;
  565. if (TRUE == ctx->testEncConfig.ringBufferEnable) {
  566. out->buf.phys_addr = ctx->encOpenParam.bitstreamBuffer;
  567. out->size = lengthOfStream;
  568. //VLOG(TRACE, "addr : %x\n", out->rdPtr);
  569. } else {
  570. out->size = lengthOfStream;
  571. if (FALSE == FindEsBuffer(ctx, encOutputInfo.bitstreamBuffer, &out->buf)) {
  572. VLOG(ERR, "%s:%d Failed to find buffer(%p)\n", __FUNCTION__, __LINE__, encOutputInfo.bitstreamBuffer);
  573. return FALSE;
  574. }
  575. }
  576. out->reuse = (BOOL)(out->size == 0);
  577. }
  578. // Finished encoding a frame
  579. if(ctx->testEncConfig.outNum != -1 && ctx->frameIdx > (ctx->testEncConfig.outNum-1)) {
  580. if (ctx->testEncConfig.outNum != ctx->frameIdx) {
  581. VLOG(ERR, "outnum(%d) != encoded cnt(%d)\n", ctx->testEncConfig.outNum, ctx->frameIdx);
  582. return FALSE;
  583. }
  584. if(out) out->last = TRUE; // Send finish signal
  585. if(out) out->reuse = FALSE;
  586. ctx->stateDoing = FALSE;
  587. com->terminate = TRUE;
  588. }
  589. ctx->frameIdx++;
  590. return TRUE;
  591. }
  592. static BOOL OpenEncoder(ComponentImpl* com)
  593. {
  594. EncoderContext* ctx = (EncoderContext*)com->context;
  595. SecAxiUse secAxiUse;
  596. MirrorDirection mirrorDirection;
  597. RetCode result;
  598. CNMComListenerEncOpen lspn = {0};
  599. ctx->stateDoing = TRUE;
  600. ctx->encOpenParam.bitstreamBuffer = ctx->bsBuf.bs[0].phys_addr;
  601. ctx->encOpenParam.bitstreamBufferSize = ctx->bsBuf.bs[0].size;
  602. if ((result = VPU_EncOpen(&ctx->handle, &ctx->encOpenParam)) != RETCODE_SUCCESS) {
  603. VLOG(ERR, "VPU_EncOpen failed Error code is 0x%x \n", result);
  604. if ( result == RETCODE_VPU_RESPONSE_TIMEOUT ) {
  605. CNMErrorSet(CNM_ERROR_HANGUP);
  606. }
  607. CNMAppStop();
  608. return FALSE;
  609. }
  610. lspn.handle = ctx->handle;
  611. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_OPEN, (void*)&lspn);
  612. //Show register Logs
  613. //VPU_DecGiveCommand(ctx->handle, ENABLE_LOGGING, 0);
  614. if (ctx->testEncConfig.rotAngle != 0 || ctx->testEncConfig.mirDir != 0) {
  615. VPU_EncGiveCommand(ctx->handle, ENABLE_ROTATION, 0);
  616. VPU_EncGiveCommand(ctx->handle, ENABLE_MIRRORING, 0);
  617. VPU_EncGiveCommand(ctx->handle, SET_ROTATION_ANGLE, &ctx->testEncConfig.rotAngle);
  618. mirrorDirection = (MirrorDirection)ctx->testEncConfig.mirDir;
  619. VPU_EncGiveCommand(ctx->handle, SET_MIRROR_DIRECTION, &mirrorDirection);
  620. }
  621. osal_memset(&secAxiUse, 0x00, sizeof(SecAxiUse));
  622. secAxiUse.u.coda9.useBitEnable = (ctx->testEncConfig.secondaryAXI>>0) & 0x01;
  623. secAxiUse.u.coda9.useIpEnable = (ctx->testEncConfig.secondaryAXI>>1) & 0x01;
  624. secAxiUse.u.coda9.useDbkYEnable = (ctx->testEncConfig.secondaryAXI>>2) & 0x01;
  625. secAxiUse.u.coda9.useDbkCEnable = (ctx->testEncConfig.secondaryAXI>>3) & 0x01;
  626. secAxiUse.u.coda9.useBtpEnable = (ctx->testEncConfig.secondaryAXI>>4) & 0x01;
  627. secAxiUse.u.coda9.useOvlEnable = (ctx->testEncConfig.secondaryAXI>>5) & 0x01;
  628. VPU_EncGiveCommand(ctx->handle, SET_SEC_AXI, &secAxiUse);
  629. ctx->stateDoing = FALSE;
  630. return TRUE;
  631. }
  632. static BOOL ExecuteEncoder(ComponentImpl* com, PortContainer* in, PortContainer* out)
  633. {
  634. EncoderContext* ctx = (EncoderContext*)com->context;
  635. BOOL ret;
  636. switch (ctx->state) {
  637. case ENCODER_STATE_OPEN:
  638. ret = OpenEncoder(com);
  639. if (ctx->stateDoing == FALSE) ctx->state = ENCODER_STATE_INIT_SEQ;
  640. break;
  641. case ENCODER_STATE_INIT_SEQ:
  642. ret = SetSequenceInfo(com);
  643. if (ctx->stateDoing == FALSE) ctx->state = ENCODER_STATE_REGISTER_FB;
  644. break;
  645. case ENCODER_STATE_REGISTER_FB:
  646. ret = RegisterFrameBuffers(com);
  647. if (ctx->stateDoing == FALSE) ctx->state = ENCODER_STATE_ENCODE_HEADER;
  648. break;
  649. case ENCODER_STATE_ENCODE_HEADER:
  650. ret = EncodeHeader(com);
  651. if (ctx->stateDoing == FALSE) ctx->state = ENCODER_STATE_ENCODING;
  652. break;
  653. case ENCODER_STATE_ENCODING:
  654. ret = Encode(com, (PortContainerYuv*)in, (PortContainerES*)out);
  655. break;
  656. default:
  657. ret = FALSE;
  658. break;
  659. }
  660. if (ret == FALSE || com->terminate == TRUE) {
  661. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_ENCODED_ALL, (void*)ctx->handle);
  662. if (out != NULL) {
  663. out->reuse = FALSE;
  664. out->last = TRUE;
  665. }
  666. }
  667. return ret;
  668. }
  669. static BOOL PrepareEncoder(ComponentImpl* com, BOOL* done)
  670. {
  671. EncoderContext* ctx = (EncoderContext*)com->context;
  672. CNMComponentParamRet ret;
  673. BOOL success;
  674. Uint32 idx =0;
  675. Uint32 jdx =0;
  676. Uint32 num = 0;
  677. num = ComponentPortGetSize(&com->sinkPort);
  678. *done = FALSE;
  679. ret = ComponentGetParameter(com, com->sinkPort.connectedComponent, GET_PARAM_READER_BITSTREAM_BUF, &ctx->bsBuf);
  680. if (ComponentParamReturnTest(ret, &success) == FALSE) return success;
  681. if (num < ctx->bsBuf.num) {
  682. VLOG(ERR, "number of port is less than number of bitstream.\n");
  683. return FALSE;
  684. }
  685. ctx->encOutQ = Queue_Create(num, sizeof(vpu_buffer_t));
  686. if (1 == ctx->bsBuf.num) { //Ring-Buffer
  687. Queue_Enqueue(ctx->encOutQ, (void*)&ctx->bsBuf.bs[0]);
  688. } else {
  689. for (idx=0; idx<num; idx++) { //Line-Buffer
  690. if (jdx > (ctx->bsBuf.num - 1)) {
  691. jdx =0;
  692. }
  693. Queue_Enqueue(ctx->encOutQ, (void*)&ctx->bsBuf.bs[jdx]);
  694. jdx++;
  695. }
  696. }
  697. *done = TRUE;
  698. return TRUE;
  699. }
  700. static void ReleaseEncoder(ComponentImpl* com)
  701. {
  702. }
  703. static BOOL DestroyEncoder(ComponentImpl* com)
  704. {
  705. EncoderContext* ctx = (EncoderContext*)com->context;
  706. Uint32 i = 0;
  707. BOOL success = TRUE;
  708. VPU_EncClose(ctx->handle);
  709. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_CLOSE, NULL);
  710. for (i = 0; i < ctx->fbCount.srcFbNum; i++) {
  711. if (ctx->vbCustomMap[i].size)
  712. vdi_free_dma_memory(ctx->testEncConfig.coreIdx, &ctx->vbCustomMap[i], ENC_ETC, ctx->handle->instIndex);
  713. }
  714. if (ctx->encOutQ) Queue_Destroy(ctx->encOutQ);
  715. VPU_DeInit(ctx->testEncConfig.coreIdx);
  716. if (NULL != ctx->encHeaderBuf) {
  717. osal_free(ctx->encHeaderBuf);
  718. }
  719. if (NULL != ctx->encStreamBufInfo.encodedStreamBuf) {
  720. osal_free(ctx->encStreamBufInfo.encodedStreamBuf);
  721. }
  722. osal_free(ctx);
  723. return success;
  724. }
  725. static Component CreateEncoder(ComponentImpl* com, CNMComponentConfig* componentParam)
  726. {
  727. EncoderContext* ctx;
  728. RetCode retCode;
  729. Uint32 coreIdx = componentParam->testEncConfig.coreIdx;
  730. Uint16* firmware = (Uint16*)componentParam->bitcode;
  731. Uint32 firmwareSize = componentParam->sizeOfBitcode;
  732. retCode = VPU_InitWithBitcode(coreIdx, firmware, firmwareSize);
  733. if (retCode != RETCODE_SUCCESS && retCode != RETCODE_CALLED_BEFORE) {
  734. VLOG(INFO, "%s:%d Failed to VPU_InitWidthBitCode, ret(%08x)\n", __FUNCTION__, __LINE__, retCode);
  735. return FALSE;
  736. }
  737. com->context = osal_malloc(sizeof(EncoderContext));
  738. ctx = (EncoderContext*)com->context;
  739. osal_memset((void*)ctx, 0, sizeof(EncoderContext));
  740. ctx->handle = NULL;
  741. ctx->frameIdx = 0;
  742. ctx->fbCount.reconFbNum = 0;
  743. ctx->fbCount.srcFbNum = 0;
  744. ctx->testEncConfig = componentParam->testEncConfig;
  745. ctx->encOpenParam = componentParam->encOpenParam;
  746. ctx->encHeaderSize = 0;
  747. ctx->encHeaderBuf = NULL;
  748. ctx->encodedReConFrmIdx = 0;
  749. ctx->ctx980.encCfg = componentParam->encCfg;
  750. osal_memset(&(ctx->encStreamBufInfo), 0x00, sizeof(EncodedStreamBufInfo));
  751. ctx->ctx980.fieldDone = FALSE;
  752. return (Component)com;
  753. }
  754. ComponentImpl coda9EncoderComponentImpl = {
  755. "coda9_encoder",
  756. NULL,
  757. {0,},
  758. {0,},
  759. sizeof(PortContainerES),
  760. 5, /* encoder's numSinkPortQueue(related to streambufcount) */
  761. CreateEncoder,
  762. GetParameterEncoder,
  763. SetParameterEncoder,
  764. PrepareEncoder,
  765. ExecuteEncoder,
  766. ReleaseEncoder,
  767. DestroyEncoder
  768. };