component_coda9_enc_encoder.c 33 KB

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