component_enc_encoder.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218
  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. #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. typedef enum {
  39. ENC_INT_STATUS_NONE, // Interrupt not asserted yet
  40. ENC_INT_STATUS_FULL, // Need more buffer
  41. ENC_INT_STATUS_DONE, // Interrupt asserted
  42. ENC_INT_STATUS_LOW_LATENCY,
  43. ENC_INT_STATUS_TIMEOUT, // Interrupt not asserted during given time.
  44. ENC_INT_STATUS_SRC_RELEASED,
  45. } ENC_INT_STATUS;
  46. typedef enum {
  47. ENCODER_STATE_OPEN,
  48. ENCODER_STATE_INIT_SEQ,
  49. ENCODER_STATE_REGISTER_FB,
  50. ENCODER_STATE_ENCODE_HEADER,
  51. ENCODER_STATE_ENCODING,
  52. } EncoderState;
  53. typedef struct {
  54. EncHandle handle;
  55. TestEncConfig testEncConfig;
  56. EncOpenParam encOpenParam;
  57. ParamEncNeedFrameBufferNum fbCount;
  58. Uint32 fbCountValid;
  59. Uint32 frameIdx;
  60. #ifdef SUPPORT_LOOK_AHEAD_RC
  61. Uint32 encPicCnt;
  62. #endif
  63. vpu_buffer_t vbCustomLambda;
  64. vpu_buffer_t vbScalingList;
  65. Uint32 customLambda[NUM_CUSTOM_LAMBDA];
  66. UserScalingList scalingList;
  67. vpu_buffer_t vbCustomMap[MAX_REG_FRAME];
  68. EncoderState state;
  69. BOOL stateDoing;
  70. EncInitialInfo initialInfo;
  71. Queue* encOutQ;
  72. EncParam encParam;
  73. Int32 encodedSrcFrmIdxArr[ENC_SRC_BUF_NUM];
  74. ParamEncBitstreamBuffer bsBuf;
  75. BOOL fullInterrupt;
  76. Uint32 changedCount;
  77. Uint64 startTimeout;
  78. #ifdef SUPPORT_LOOK_AHEAD_RC
  79. int larcEnable;
  80. int larcPass;
  81. int larcSize;
  82. EncLarcInfo larcInfo;
  83. int larcPass2Started;
  84. int larcPass1Finish;
  85. #endif
  86. Uint32 cyclePerTick;
  87. vpu_buffer_t *bsBuffer[20];
  88. } EncoderContext;
  89. static BOOL FindEsBuffer(EncoderContext* ctx, PhysicalAddress addr, vpu_buffer_t* bs)
  90. {
  91. Uint32 i;
  92. for (i=0; i<ctx->bsBuf.num; i++) {
  93. if (addr == ctx->bsBuf.bs[i].phys_addr) {
  94. *bs = ctx->bsBuf.bs[i];
  95. return TRUE;
  96. }
  97. }
  98. return FALSE;
  99. }
  100. static void SetEncPicParam(ComponentImpl* com, PortContainerYuv* in, EncParam* encParam)
  101. {
  102. EncoderContext* ctx = (EncoderContext*)com->context;
  103. TestEncConfig testEncConfig = ctx->testEncConfig;
  104. Uint32 frameIdx = ctx->frameIdx;
  105. Int32 srcFbWidth = VPU_ALIGN8(ctx->encOpenParam.picWidth);
  106. Int32 srcFbHeight = VPU_ALIGN8(ctx->encOpenParam.picHeight);
  107. Uint32 productId;
  108. vpu_buffer_t* buf = (vpu_buffer_t*)Queue_Peek(ctx->encOutQ);
  109. productId = VPU_GetProductId(ctx->encOpenParam.coreIdx);
  110. encParam->picStreamBufferAddr = buf->phys_addr;
  111. encParam->picStreamBufferSize = buf->size;
  112. encParam->srcIdx = in->srcFbIndex;
  113. encParam->srcEndFlag = in->last;
  114. encParam->sourceFrame = &in->fb;
  115. encParam->sourceFrame->sourceLBurstEn = 0;
  116. if (testEncConfig.useAsLongtermPeriod > 0 && testEncConfig.refLongtermPeriod > 0) {
  117. encParam->useCurSrcAsLongtermPic = (frameIdx % testEncConfig.useAsLongtermPeriod) == 0 ? 1 : 0;
  118. encParam->useLongtermRef = (frameIdx % testEncConfig.refLongtermPeriod) == 0 ? 1 : 0;
  119. }
  120. encParam->skipPicture = 0;
  121. encParam->forceAllCtuCoefDropEnable = 0;
  122. encParam->forcePicQpEnable = 0;
  123. encParam->forcePicQpI = 0;
  124. encParam->forcePicQpP = 0;
  125. encParam->forcePicQpB = 0;
  126. encParam->forcePicTypeEnable = 0;
  127. encParam->forcePicType = 0;
  128. if (testEncConfig.forceIdrPicIdx == frameIdx) {
  129. encParam->forcePicTypeEnable = 1;
  130. encParam->forcePicType = 3; // IDR
  131. }
  132. // FW will encode header data implicitly when changing the header syntaxes
  133. encParam->codeOption.implicitHeaderEncode = 1;
  134. encParam->codeOption.encodeAUD = testEncConfig.encAUD;
  135. encParam->codeOption.encodeEOS = testEncConfig.encEOS;
  136. encParam->codeOption.encodeEOB = testEncConfig.encEOB;
  137. // set custom map param
  138. if (productId != PRODUCT_ID_521)
  139. encParam->customMapOpt.roiAvgQp = testEncConfig.roi_avg_qp;
  140. encParam->customMapOpt.customLambdaMapEnable = testEncConfig.lambda_map_enable;
  141. encParam->customMapOpt.customModeMapEnable = testEncConfig.mode_map_flag & 0x1;
  142. encParam->customMapOpt.customCoefDropEnable = (testEncConfig.mode_map_flag & 0x2) >> 1;
  143. encParam->customMapOpt.customRoiMapEnable = testEncConfig.roi_enable;
  144. if (in->prevMapReuse == FALSE) {
  145. // packaging roi/lambda/mode data to custom map buffer.
  146. if (encParam->customMapOpt.customRoiMapEnable || encParam->customMapOpt.customLambdaMapEnable ||
  147. encParam->customMapOpt.customModeMapEnable || encParam->customMapOpt.customCoefDropEnable) {
  148. SetMapData(testEncConfig.coreIdx, testEncConfig, ctx->encOpenParam, encParam, srcFbWidth, srcFbHeight, ctx->vbCustomMap[encParam->srcIdx].phys_addr);
  149. }
  150. // host should set proper value.
  151. // set weighted prediction param.
  152. if ((testEncConfig.wp_param_flag & 0x1)) {
  153. char lineStr[256] = {0,};
  154. Uint32 meanY, meanCb, meanCr, sigmaY, sigmaCb, sigmaCr;
  155. Uint32 maxMean = (ctx->encOpenParam.bitstreamFormat == STD_AVC) ? 0xffff : ((1 << ctx->encOpenParam.EncStdParam.waveParam.internalBitDepth) - 1);
  156. Uint32 maxSigma = (ctx->encOpenParam.bitstreamFormat == STD_AVC) ? 0xffff : ((1 << (ctx->encOpenParam.EncStdParam.waveParam.internalBitDepth + 6)) - 1);
  157. fgets(lineStr, 256, testEncConfig.wp_param_file);
  158. sscanf(lineStr, "%d %d %d %d %d %d\n", &meanY, &meanCb, &meanCr, &sigmaY, &sigmaCb, &sigmaCr);
  159. meanY = max(min(maxMean, meanY), 0);
  160. meanCb = max(min(maxMean, meanCb), 0);
  161. meanCr = max(min(maxMean, meanCr), 0);
  162. sigmaY = max(min(maxSigma, sigmaY), 0);
  163. sigmaCb = max(min(maxSigma, sigmaCb), 0);
  164. sigmaCr = max(min(maxSigma, sigmaCr), 0);
  165. // set weighted prediction param.
  166. encParam->wpPixSigmaY = sigmaY;
  167. encParam->wpPixSigmaCb = sigmaCb;
  168. encParam->wpPixSigmaCr = sigmaCr;
  169. encParam->wpPixMeanY = meanY;
  170. encParam->wpPixMeanCb = meanCb;
  171. encParam->wpPixMeanCr = meanCr;
  172. }
  173. }
  174. }
  175. static BOOL RegisterFrameBuffers(ComponentImpl* com)
  176. {
  177. EncoderContext* ctx= (EncoderContext*)com->context;
  178. FrameBuffer* pReconFb = NULL;
  179. FrameBuffer* pSrcFb = NULL;
  180. FrameBufferAllocInfo srcFbAllocInfo;
  181. Uint32 reconFbStride = 0;
  182. Uint32 reconFbHeight = 0;
  183. ParamEncFrameBuffer paramFb;
  184. RetCode result;
  185. CNMComponentParamRet ret;
  186. BOOL success;
  187. Uint32 idx;
  188. EncInfo* pEncInfo = VPU_HANDLE_TO_ENCINFO(ctx->handle);
  189. ctx->stateDoing = TRUE;
  190. ret = ComponentGetParameter(com, com->srcPort.connectedComponent, GET_PARAM_YUVFEEDER_FRAME_BUF, (void*)&paramFb);
  191. if (ComponentParamReturnTest(ret, &success) == FALSE) return success;
  192. pReconFb = paramFb.reconFb;
  193. reconFbStride = paramFb.reconFbAllocInfo.stride;
  194. reconFbHeight = paramFb.reconFbAllocInfo.height;
  195. if (pEncInfo->productCode == WAVE521C_DUAL_CODE) {
  196. TiledMapType mapType = ctx->encOpenParam.EncStdParam.waveParam.internalBitDepth==8?COMPRESSED_FRAME_MAP_DUAL_CORE_8BIT:COMPRESSED_FRAME_MAP_DUAL_CORE_10BIT;
  197. result = VPU_EncRegisterFrameBuffer(ctx->handle, pReconFb, ctx->fbCount.reconFbNum, reconFbStride, reconFbHeight, mapType);
  198. }
  199. else
  200. result = VPU_EncRegisterFrameBuffer(ctx->handle, pReconFb, ctx->fbCount.reconFbNum, reconFbStride, reconFbHeight, COMPRESSED_FRAME_MAP);
  201. if (result != RETCODE_SUCCESS) {
  202. VLOG(ERR, "%s:%d Failed to VPU_EncRegisterFrameBuffer(%d)\n", __FUNCTION__, __LINE__, result);
  203. ChekcAndPrintDebugInfo(ctx->handle, TRUE, result);
  204. return FALSE;
  205. }
  206. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_REGISTER_FB, NULL);
  207. pSrcFb = paramFb.srcFb;
  208. srcFbAllocInfo = paramFb.srcFbAllocInfo;
  209. result = VPU_EncAllocateFrameBuffer(ctx->handle, srcFbAllocInfo, pSrcFb);
  210. if (result != RETCODE_SUCCESS) {
  211. VLOG(ERR, "VPU_EncAllocateFrameBuffer fail to allocate source frame buffer\n");
  212. ChekcAndPrintDebugInfo(ctx->handle, TRUE, result);
  213. return FALSE;
  214. }
  215. if (ctx->testEncConfig.roi_enable || ctx->testEncConfig.lambda_map_enable || ctx->testEncConfig.mode_map_flag) {
  216. for (idx = 0; idx < ctx->fbCount.srcFbNum; idx++) {
  217. ctx->vbCustomMap[idx].size = (ctx->encOpenParam.bitstreamFormat == STD_AVC) ? MAX_MB_NUM : MAX_CTU_NUM * 8;
  218. if (vdi_allocate_dma_memory(ctx->testEncConfig.coreIdx, &ctx->vbCustomMap[idx], ENC_ETC, ctx->handle->instIndex) < 0) {
  219. VLOG(ERR, "fail to allocate ROI buffer\n");
  220. return FALSE;
  221. }
  222. }
  223. }
  224. ctx->stateDoing = FALSE;
  225. return TRUE;
  226. }
  227. static CNMComponentParamRet GetParameterEncoder(ComponentImpl* from, ComponentImpl* com, GetParameterCMD commandType, void* data)
  228. {
  229. EncoderContext* ctx = (EncoderContext*)com->context;
  230. BOOL result = TRUE;
  231. ParamEncNeedFrameBufferNum* fbCount;
  232. PortContainerYuv* container;
  233. ParamVpuStatus* status;
  234. QueueStatusInfo cqInfo;
  235. #ifdef SUPPORT_LOOK_AHEAD_RC
  236. EncLarcInfo *larcInfo;
  237. #endif
  238. switch(commandType) {
  239. case GET_PARAM_COM_IS_CONTAINER_CONUSUMED:
  240. container = (PortContainerYuv*)data;
  241. if (ctx->encodedSrcFrmIdxArr[container->srcFbIndex]) {
  242. ctx->encodedSrcFrmIdxArr[container->srcFbIndex] = 0;
  243. container->consumed = TRUE;
  244. }
  245. break;
  246. case GET_PARAM_ENC_HANDLE:
  247. if (ctx->handle == NULL) return CNM_COMPONENT_PARAM_NOT_READY;
  248. *(EncHandle*)data = ctx->handle;
  249. break;
  250. case GET_PARAM_ENC_FRAME_BUF_NUM:
  251. if (ctx->fbCountValid == FALSE) return CNM_COMPONENT_PARAM_NOT_READY;
  252. fbCount = (ParamEncNeedFrameBufferNum*)data;
  253. fbCount->reconFbNum = ctx->fbCount.reconFbNum;
  254. fbCount->srcFbNum = ctx->fbCount.srcFbNum;
  255. break;
  256. case GET_PARAM_ENC_FRAME_BUF_REGISTERED:
  257. if (ctx->state <= ENCODER_STATE_REGISTER_FB) return CNM_COMPONENT_PARAM_NOT_READY;
  258. *(BOOL*)data = TRUE;
  259. break;
  260. #ifdef SUPPORT_LOOK_AHEAD_RC
  261. case GET_PARAM_ENC_LARC_INFO:
  262. if ( ctx->larcEnable == FALSE ) {
  263. result = FALSE;
  264. break;
  265. }
  266. larcInfo = (EncLarcInfo*)data;
  267. if ( ctx->larcPass == LOOK_AHEAD_RC_PASS1 ) {
  268. larcInfo->Pass1encPicCnt = ctx->encPicCnt;
  269. larcInfo->larcPass1Finish = ctx->larcPass1Finish;
  270. osal_memcpy(larcInfo->larcData, ctx->larcInfo.larcData, sizeof(larcInfo->larcData));
  271. }
  272. else {
  273. larcInfo->Pass2encPicCnt = ctx->encPicCnt;
  274. }
  275. break;
  276. #endif
  277. case GET_PARAM_VPU_STATUS:
  278. if (ctx->state != ENCODER_STATE_ENCODING) return CNM_COMPONENT_PARAM_NOT_READY;
  279. VPU_EncGiveCommand(ctx->handle, ENC_GET_QUEUE_STATUS, &cqInfo);
  280. status = (ParamVpuStatus*)data;
  281. status->cq = cqInfo;
  282. break;
  283. default:
  284. result = FALSE;
  285. break;
  286. }
  287. return (result == TRUE) ? CNM_COMPONENT_PARAM_SUCCESS : CNM_COMPONENT_PARAM_FAILURE;
  288. }
  289. static CNMComponentParamRet SetParameterEncoder(ComponentImpl* from, ComponentImpl* com, SetParameterCMD commandType, void* data)
  290. {
  291. BOOL result = TRUE;
  292. switch (commandType) {
  293. case SET_PARAM_COM_PAUSE:
  294. com->pause = *(BOOL*)data;
  295. break;
  296. default:
  297. VLOG(ERR, "Unknown SetParameterCMD Type : %d\n", commandType);
  298. result = FALSE;
  299. break;
  300. }
  301. return (result == TRUE) ? CNM_COMPONENT_PARAM_SUCCESS : CNM_COMPONENT_PARAM_FAILURE;
  302. }
  303. static ENC_INT_STATUS HandlingInterruptFlag(ComponentImpl* com)
  304. {
  305. EncoderContext* ctx = (EncoderContext*)com->context;
  306. EncHandle handle = ctx->handle;
  307. Int32 interruptFlag = 0;
  308. Uint32 interruptWaitTime = VPU_WAIT_TIME_OUT_CQ;
  309. Uint32 interruptTimeout = VPU_ENC_TIMEOUT;
  310. ENC_INT_STATUS status = ENC_INT_STATUS_NONE;
  311. if (ctx->startTimeout == 0ULL) {
  312. ctx->startTimeout = osal_gettime();
  313. }
  314. do {
  315. interruptFlag = VPU_WaitInterruptEx(handle, interruptWaitTime);
  316. if (INTERRUPT_TIMEOUT_VALUE == interruptFlag) {
  317. Uint64 currentTimeout = osal_gettime();
  318. if ((currentTimeout - ctx->startTimeout) > interruptTimeout) {
  319. VLOG(ERR, "<%s:%d> startTimeout(%lld) currentTime(%lld) diff(%d)\n",
  320. __FUNCTION__, __LINE__, ctx->startTimeout, currentTimeout, (Uint32)(currentTimeout - ctx->startTimeout));
  321. CNMErrorSet(CNM_ERROR_HANGUP);
  322. status = ENC_INT_STATUS_TIMEOUT;
  323. break;
  324. }
  325. interruptFlag = 0;
  326. }
  327. if (interruptFlag < 0) {
  328. VLOG(ERR, "<%s:%d> interruptFlag is negative value! %08x\n", __FUNCTION__, __LINE__, interruptFlag);
  329. }
  330. if (interruptFlag > 0) {
  331. VPU_ClearInterruptEx(handle, interruptFlag);
  332. ctx->startTimeout = 0ULL;
  333. if (interruptFlag & (1<<INT_WAVE5_ENC_SET_PARAM)) {
  334. status = ENC_INT_STATUS_DONE;
  335. break;
  336. }
  337. if (interruptFlag & (1<<INT_WAVE5_ENC_PIC)) {
  338. status = ENC_INT_STATUS_DONE;
  339. break;
  340. }
  341. if (interruptFlag & (1<<INT_WAVE5_BSBUF_FULL)) {
  342. status = ENC_INT_STATUS_FULL;
  343. break;
  344. }
  345. if (interruptFlag & (1<<INT_WAVE5_ENC_LOW_LATENCY)) {
  346. status = ENC_INT_STATUS_LOW_LATENCY;
  347. }
  348. #ifdef SUPPORT_SOURCE_RELEASE_INTERRUPT
  349. if (interruptFlag & (1 << INT_WAVE5_ENC_SRC_RELEASE)) {
  350. status = ENC_INT_STATUS_SRC_RELEASED;
  351. }
  352. #endif
  353. }
  354. } while (FALSE);
  355. return status;
  356. }
  357. static BOOL SetSequenceInfo(ComponentImpl* com)
  358. {
  359. EncoderContext* ctx = (EncoderContext*)com->context;
  360. EncHandle handle = ctx->handle;
  361. RetCode ret = RETCODE_SUCCESS;
  362. ENC_INT_STATUS status;
  363. EncInitialInfo* initialInfo = &ctx->initialInfo;
  364. CNMComListenerEncCompleteSeq lsnpCompleteSeq = {0};
  365. #ifdef SUPPORT_LOOK_AHEAD_RC
  366. if ( ctx->larcPass == LOOK_AHEAD_RC_PASS2 && ctx->larcPass2Started == FALSE) {
  367. BOOL success;
  368. ret = ComponentGetParameter(com, com->srcPort.connectedComponent, GET_PARAM_ENC_LARC_INFO, &ctx->larcInfo);
  369. if (ComponentParamReturnTest(ret, &success) == FALSE) {
  370. return success;
  371. }
  372. ctx->stateDoing = FALSE;
  373. if ( ctx->larcInfo.Pass1encPicCnt < ctx->larcSize && FALSE == ctx->larcInfo.larcPass1Finish) {
  374. ctx->stateDoing = TRUE;
  375. return success;
  376. }
  377. if (ctx->larcInfo.larcPass1Finish == TRUE)
  378. ctx->larcInfo.larcData[ctx->larcInfo.Pass1encPicCnt][0] = -1;
  379. ctx->larcPass2Started = TRUE;
  380. if ( ctx->larcPass == LOOK_AHEAD_RC_PASS2 ) {
  381. VPU_EncGiveCommand(handle, ENC_SET_LARC_DATA, &ctx->larcInfo);
  382. }
  383. }
  384. #endif
  385. if (ctx->stateDoing == FALSE) {
  386. do {
  387. ret = VPU_EncIssueSeqInit(handle);
  388. } while (ret == RETCODE_QUEUEING_FAILURE && com->terminate == FALSE);
  389. if (ret != RETCODE_SUCCESS) {
  390. VLOG(ERR, "%s:%d Failed to VPU_EncIssueSeqInit() ret(%d)\n", __FUNCTION__, __LINE__, ret);
  391. ChekcAndPrintDebugInfo(ctx->handle, TRUE, ret);
  392. return FALSE;
  393. }
  394. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_ISSUE_SEQ, NULL);
  395. }
  396. ctx->stateDoing = TRUE;
  397. while (com->terminate == FALSE) {
  398. if ((status=HandlingInterruptFlag(com)) == ENC_INT_STATUS_DONE) {
  399. break;
  400. }
  401. else if (status == ENC_INT_STATUS_NONE) {
  402. return TRUE;
  403. }
  404. else if (status == ENC_INT_STATUS_TIMEOUT) {
  405. VLOG(INFO, "%s:%d INSTANCE #%d INTERRUPT TIMEOUT\n", __FUNCTION__, __LINE__, handle->instIndex);
  406. HandleEncoderError(ctx->handle, ctx->frameIdx, NULL);
  407. return FALSE;
  408. }
  409. else {
  410. VLOG(INFO, "%s:%d Unknown interrupt status: %d\n", __FUNCTION__, __LINE__, status);
  411. return FALSE;
  412. }
  413. }
  414. if ((ret=VPU_EncCompleteSeqInit(handle, initialInfo)) != RETCODE_SUCCESS) {
  415. VLOG(ERR, "%s:%d FAILED TO ENC_PIC_HDR: ret(%d), SEQERR(%08x)\n",
  416. __FUNCTION__, __LINE__, ret, initialInfo->seqInitErrReason);
  417. ChekcAndPrintDebugInfo(ctx->handle, TRUE, ret);
  418. return FALSE;
  419. }
  420. lsnpCompleteSeq.handle = handle;
  421. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_COMPLETE_SEQ, (void*)&lsnpCompleteSeq);
  422. ctx->fbCount.reconFbNum = initialInfo->minFrameBufferCount;
  423. ctx->fbCount.srcFbNum = initialInfo->minSrcFrameCount + COMMAND_QUEUE_DEPTH + EXTRA_SRC_BUFFER_NUM;
  424. if ( ctx->encOpenParam.sourceBufCount > ctx->fbCount.srcFbNum)
  425. ctx->fbCount.srcFbNum = ctx->encOpenParam.sourceBufCount;
  426. ctx->fbCountValid = TRUE;
  427. VLOG(INFO, "[ENCODER] Required reconFbCount=%d, srcFbCount=%d, outNum=%d, %dx%d\n",
  428. ctx->fbCount.reconFbNum, ctx->fbCount.srcFbNum, ctx->testEncConfig.outNum, ctx->encOpenParam.picWidth, ctx->encOpenParam.picHeight);
  429. ctx->stateDoing = FALSE;
  430. return TRUE;
  431. }
  432. static BOOL EncodeHeader(ComponentImpl* com)
  433. {
  434. EncoderContext* ctx = (EncoderContext*)com->context;
  435. EncHandle handle = ctx->handle;
  436. RetCode ret = RETCODE_SUCCESS;
  437. EncHeaderParam encHeaderParam;
  438. vpu_buffer_t* buf;
  439. ctx->stateDoing = TRUE;
  440. buf = Queue_Dequeue(ctx->encOutQ);
  441. osal_memset(&encHeaderParam, 0x00, sizeof(EncHeaderParam));
  442. encHeaderParam.buf = buf->phys_addr;
  443. encHeaderParam.size = buf->size;
  444. if (ctx->encOpenParam.bitstreamFormat == STD_HEVC) {
  445. encHeaderParam.headerType = CODEOPT_ENC_VPS | CODEOPT_ENC_SPS | CODEOPT_ENC_PPS;
  446. }
  447. else {
  448. // H.264
  449. encHeaderParam.headerType = CODEOPT_ENC_SPS | CODEOPT_ENC_PPS;
  450. }
  451. while(1) {
  452. ret = VPU_EncGiveCommand(handle, ENC_PUT_VIDEO_HEADER, &encHeaderParam);
  453. if ( ret != RETCODE_QUEUEING_FAILURE )
  454. break;
  455. #if defined(HAPS_SIM) || defined(CNM_SIM_DPI_INTERFACE)
  456. osal_msleep(1);
  457. #endif
  458. }
  459. DisplayEncodedInformation(ctx->handle, ctx->encOpenParam.bitstreamFormat, 0, NULL, 0, 0, ctx->testEncConfig.performance);
  460. ctx->stateDoing = FALSE;
  461. return TRUE;
  462. }
  463. static BOOL Encode(ComponentImpl* com, PortContainerYuv* in, PortContainerES* out)
  464. {
  465. EncoderContext* ctx = (EncoderContext*)com->context;
  466. BOOL doEncode = FALSE;
  467. BOOL doChangeParam = FALSE;
  468. EncParam* encParam = &ctx->encParam;
  469. EncOutputInfo encOutputInfo;
  470. ENC_INT_STATUS intStatus;
  471. RetCode result;
  472. CNMComListenerHandlingInt lsnpHandlingInt = {0};
  473. CNMComListenerEncDone lsnpPicDone = {0};
  474. CNMComListenerDecReadyOneFrame lsnpReadyOneFrame = {0,};
  475. ENC_QUERY_WRPTR_SEL encWrPtrSel = GET_ENC_PIC_DONE_WRPTR;
  476. QueueStatusInfo qStatus;
  477. int i=0;
  478. #ifdef SUPPORT_LOOK_AHEAD_RC
  479. CNMComponentParamRet ret;
  480. BOOL success;
  481. #endif
  482. lsnpReadyOneFrame.handle = ctx->handle;
  483. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_READY_ONE_FRAME, &lsnpReadyOneFrame);
  484. #ifdef SUPPORT_LOOK_AHEAD_RC
  485. if ( ctx->larcPass == LOOK_AHEAD_RC_PASS1 ) {
  486. ret = ComponentGetParameter(com, com->sinkPort.connectedComponent, GET_PARAM_ENC_LARC_INFO, &ctx->larcInfo);
  487. if (ComponentParamReturnTest(ret, &success) == FALSE) {
  488. if (in) in->reuse = TRUE;
  489. if (out) out->reuse = TRUE;
  490. return success;
  491. }
  492. if (!(ctx->larcInfo.Pass2encPicCnt + LOOK_AHEAD_RC_DATA_SIZE > ctx->frameIdx)) {
  493. if (in) in->reuse = TRUE;
  494. if (out) out->reuse = TRUE;
  495. return TRUE;
  496. }
  497. }
  498. if ( ctx->larcPass == LOOK_AHEAD_RC_PASS2 ) {
  499. ret = ComponentGetParameter(com, com->srcPort.connectedComponent, GET_PARAM_ENC_LARC_INFO, &ctx->larcInfo);
  500. if (ComponentParamReturnTest(ret, &success) == FALSE) {
  501. return success;
  502. }
  503. if ( !(ctx->larcInfo.Pass1encPicCnt > ctx->frameIdx + ctx->larcSize) && ctx->larcInfo.larcPass1Finish == FALSE) {
  504. if (in) in->reuse = TRUE;
  505. if (out) out->reuse = TRUE;
  506. return TRUE;
  507. }
  508. for (i = 0; i < 3; i++) {
  509. if ( ctx->larcInfo.larcPass1Finish == TRUE && ctx->larcInfo.Pass1encPicCnt <= ctx->frameIdx + ctx->larcSize - 1) {//-larcSize-1:already set in Wave5VpuEncSetLarcData
  510. encParam->larcData[i] = -1;
  511. break;
  512. }
  513. else
  514. encParam->larcData[i] = ctx->larcInfo.larcData[(ctx->frameIdx+ctx->larcSize-1) % LOOK_AHEAD_RC_DATA_SIZE][i];
  515. }
  516. }
  517. #endif
  518. ctx->stateDoing = TRUE;
  519. if (out) {
  520. if (out->buf.phys_addr != 0) {
  521. Queue_Enqueue(ctx->encOutQ, (void*)&out->buf);
  522. out->buf.phys_addr = 0;
  523. out->buf.size = 0;
  524. }
  525. if (encParam->srcEndFlag == TRUE) {
  526. doEncode = (BOOL)(Queue_Get_Cnt(ctx->encOutQ) > 0);
  527. }
  528. }
  529. if (in) {
  530. if (Queue_Get_Cnt(ctx->encOutQ) > 0) {
  531. SetEncPicParam(com, in, encParam);
  532. doEncode = TRUE;
  533. in->prevMapReuse = TRUE;
  534. }
  535. }
  536. if (TRUE == com->pause)
  537. doEncode = FALSE;
  538. VPU_EncGiveCommand(ctx->handle, ENC_GET_QUEUE_STATUS, &qStatus);
  539. if (COMMAND_QUEUE_DEPTH == qStatus.instanceQueueCount) {
  540. doEncode = FALSE;
  541. }
  542. if ((ctx->testEncConfig.numChangeParam > ctx->changedCount) &&
  543. (ctx->testEncConfig.changeParam[ctx->changedCount].setParaChgFrmNum == ctx->frameIdx)) {
  544. doChangeParam = TRUE;
  545. }
  546. if (doChangeParam == TRUE) {
  547. result = SetChangeParam(ctx->handle, ctx->testEncConfig, ctx->encOpenParam, ctx->changedCount);
  548. if (result == RETCODE_SUCCESS) {
  549. VLOG(TRACE, "ENC_SET_PARA_CHANGE queue success\n");
  550. ctx->changedCount++;
  551. }
  552. else if (result == RETCODE_QUEUEING_FAILURE) { // Just retry
  553. VLOG(INFO, "ENC_SET_PARA_CHANGE Queue Full\n");
  554. doEncode = FALSE;
  555. }
  556. else { // Error
  557. VLOG(ERR, "VPU_EncGiveCommand[ENC_SET_PARA_CHANGE] failed Error code is 0x%x \n", result);
  558. ChekcAndPrintDebugInfo(ctx->handle, TRUE, result);
  559. return FALSE;
  560. }
  561. }
  562. /* The simple load balancer : To use this function, call InitLoadBalancer() before decoding process. */
  563. if (TRUE == doEncode) {
  564. if (in) in->reuse = TRUE;
  565. doEncode = LoadBalancerGetMyTurn(ctx->handle->instIndex);
  566. }
  567. if (doEncode == TRUE) {
  568. CNMComListenerEncStartOneFrame lsn;
  569. result = VPU_EncStartOneFrame(ctx->handle, encParam);
  570. if (result == RETCODE_SUCCESS) {
  571. /* The simple load balancer : pass its turn */
  572. LoadBalancerSetNextTurn();
  573. if (in) in->prevMapReuse = FALSE;
  574. Queue_Dequeue(ctx->encOutQ);
  575. ctx->frameIdx++;
  576. if (in) in->reuse = FALSE;
  577. if (out) out->reuse = FALSE;
  578. }
  579. else if (result == RETCODE_QUEUEING_FAILURE) { // Just retry
  580. // Just retry
  581. VPU_EncGiveCommand(ctx->handle, ENC_GET_QUEUE_STATUS, (void*)&qStatus);
  582. if (qStatus.instanceQueueCount == 0) {
  583. VLOG(ERR, "<%s:%d> The queue is empty but it can't add a command\n", __FUNCTION__, __LINE__);
  584. return FALSE;
  585. }
  586. }
  587. else { // Error
  588. VLOG(ERR, "VPU_EncStartOneFrame failed Error code is 0x%x \n", result);
  589. ChekcAndPrintDebugInfo(ctx->handle, TRUE, result);
  590. CNMErrorSet(CNM_ERROR_HANGUP);
  591. HandleEncoderError(ctx->handle, ctx->frameIdx, NULL);
  592. return FALSE;
  593. }
  594. lsn.handle = ctx->handle;
  595. lsn.result = result;
  596. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_START_ONE_FRAME, (void*)&lsn);
  597. #ifdef SUPPORT_TESTCASE_CQ_16
  598. if (lsn.result == COMMAND_QUEUE_NOT_FULL) {
  599. if (out) {
  600. out->size = 0;
  601. out->reuse = FALSE;
  602. }
  603. return TRUE; /* Try again */
  604. }
  605. #endif
  606. }
  607. if ((intStatus=HandlingInterruptFlag(com)) == ENC_INT_STATUS_TIMEOUT) {
  608. HandleEncoderError(ctx->handle, ctx->frameIdx, NULL);
  609. VPU_SWReset(ctx->testEncConfig.coreIdx, SW_RESET_SAFETY, ctx->handle);
  610. return FALSE;
  611. }
  612. else if (intStatus == ENC_INT_STATUS_FULL || intStatus == ENC_INT_STATUS_LOW_LATENCY) {
  613. CNMComListenerEncFull lsnpFull;
  614. PhysicalAddress paRdPtr;
  615. PhysicalAddress paWrPtr;
  616. int size;
  617. encWrPtrSel = (intStatus==ENC_INT_STATUS_FULL) ? GET_ENC_BSBUF_FULL_WRPTR : GET_ENC_LOW_LATENCY_WRPTR;
  618. VPU_EncGiveCommand(ctx->handle, ENC_WRPTR_SEL, &encWrPtrSel);
  619. VPU_EncGetBitstreamBuffer(ctx->handle, &paRdPtr, &paWrPtr, &size);
  620. VLOG(TRACE, "<%s:%d> INT_BSBUF_FULL inst=%d, %p, %p\n", __FUNCTION__, __LINE__, ctx->handle->instIndex, paRdPtr, paWrPtr);
  621. lsnpFull.handle = ctx->handle;
  622. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_FULL_INTERRUPT, (void*)&lsnpFull);
  623. if ( out ) {
  624. if (ctx->encOpenParam.ringBufferEnable == TRUE) {
  625. out->buf.phys_addr = paRdPtr;
  626. out->buf.size = size;
  627. out->size = size;
  628. out->reuse = FALSE;
  629. out->streamBufFull = TRUE;
  630. out->rdPtr = paRdPtr;
  631. out->wrPtr = paWrPtr;
  632. out->paBsBufStart = ctx->encOpenParam.bitstreamBuffer;
  633. out->paBsBufEnd = ctx->encOpenParam.bitstreamBuffer + ctx->encOpenParam.bitstreamBufferSize;
  634. }
  635. else {
  636. if (FindEsBuffer(ctx, paRdPtr, &out->buf) == FALSE) {
  637. VLOG(ERR, "%s:%d Failed to find buffer(%p)\n", __FUNCTION__, __LINE__, paRdPtr);
  638. return FALSE;
  639. }
  640. out->size = size;
  641. out->reuse = FALSE;
  642. out->streamBufFull = TRUE;
  643. }
  644. }
  645. ctx->fullInterrupt = TRUE;
  646. return TRUE;
  647. }
  648. #ifdef SUPPORT_SOURCE_RELEASE_INTERRUPT
  649. else if (intStatus == ENC_INT_STATUS_SRC_RELEASED) {
  650. Uint32 srcBufFlag = 0;
  651. VPU_EncGiveCommand(ctx->handle, ENC_GET_SRC_BUF_FLAG, &srcBufFlag);
  652. for (i = 0; i < ctx->fbCount.srcFbNum; i++) {
  653. if ( (srcBufFlag >> i) & 0x01) {
  654. ctx->encodedSrcFrmIdxArr[i] = 1;
  655. }
  656. }
  657. return TRUE;
  658. }
  659. #endif
  660. else if (intStatus == ENC_INT_STATUS_NONE) {
  661. if (out) {
  662. out->size = 0;
  663. out->reuse = FALSE;
  664. }
  665. return TRUE; /* Try again */
  666. }
  667. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_HANDLING_INT, (void*)&lsnpHandlingInt);
  668. VPU_EncGiveCommand(ctx->handle, ENC_WRPTR_SEL, &encWrPtrSel);
  669. osal_memset(&encOutputInfo, 0x00, sizeof(EncOutputInfo));
  670. encOutputInfo.result = VPU_EncGetOutputInfo(ctx->handle, &encOutputInfo);
  671. if (encOutputInfo.result == RETCODE_REPORT_NOT_READY) {
  672. return TRUE; /* Not encoded yet */
  673. }
  674. else if (encOutputInfo.result == RETCODE_VLC_BUF_FULL) {
  675. VLOG(ERR, "VLC BUFFER FULL!!! ALLOCATE MORE TASK BUFFER(%d)!!!\n", ONE_TASKBUF_SIZE_FOR_CQ);
  676. }
  677. else if (encOutputInfo.result != RETCODE_SUCCESS) {
  678. /* ERROR */
  679. VLOG(ERR, "Failed to encode error = %d, %x\n", encOutputInfo.result, encOutputInfo.errorReason);
  680. ChekcAndPrintDebugInfo(ctx->handle, TRUE, encOutputInfo.result);
  681. HandleEncoderError(ctx->handle, encOutputInfo.encPicCnt, &encOutputInfo);
  682. VPU_SWReset(ctx->testEncConfig.coreIdx, SW_RESET_SAFETY, ctx->handle);
  683. return FALSE;
  684. }
  685. else {
  686. ;/* SUCCESS */
  687. }
  688. if (encOutputInfo.reconFrameIndex == RECON_IDX_FLAG_CHANGE_PARAM) {
  689. VLOG(TRACE, "CHANGE PARAMETER!\n");
  690. return TRUE; /* Try again */
  691. }
  692. else {
  693. DisplayEncodedInformation(ctx->handle, ctx->encOpenParam.bitstreamFormat, ctx->frameIdx, &encOutputInfo, encParam->srcEndFlag, encParam->srcIdx, ctx->testEncConfig.performance);
  694. }
  695. lsnpPicDone.handle = ctx->handle;
  696. lsnpPicDone.output = &encOutputInfo;
  697. lsnpPicDone.fullInterrupted = ctx->fullInterrupt;
  698. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_GET_OUTPUT_INFO, (void*)&lsnpPicDone);
  699. if ( encOutputInfo.result != RETCODE_SUCCESS )
  700. return FALSE;
  701. for (i = 0; i < ctx->fbCount.srcFbNum; i++) {
  702. if ( (encOutputInfo.releaseSrcFlag >> i) & 0x01) {
  703. ctx->encodedSrcFrmIdxArr[i] = 1;
  704. }
  705. }
  706. ctx->fullInterrupt = FALSE;
  707. if ( out ) {
  708. if (ctx->encOpenParam.ringBufferEnable == TRUE) {
  709. out->buf.phys_addr = encOutputInfo.rdPtr;
  710. out->size = encOutputInfo.bitstreamSize;
  711. out->reuse = (BOOL)(out->size == 0);
  712. }
  713. else {
  714. if (FindEsBuffer(ctx, encOutputInfo.bitstreamBuffer, &out->buf) == FALSE) {
  715. VLOG(ERR, "%s:%d Failed to find buffer(%p)\n", __FUNCTION__, __LINE__, encOutputInfo.bitstreamBuffer);
  716. return FALSE;
  717. }
  718. out->size = encOutputInfo.bitstreamSize;
  719. out->reuse = (BOOL)(out->size == 0);
  720. }
  721. }
  722. // Finished encoding a frame
  723. if (encOutputInfo.reconFrameIndex == RECON_IDX_FLAG_ENC_END) {
  724. if (ctx->testEncConfig.outNum != encOutputInfo.encPicCnt && ctx->testEncConfig.outNum != -1) {
  725. VLOG(ERR, "outnum(%d) != encoded cnt(%d)\n", ctx->testEncConfig.outNum, encOutputInfo.encPicCnt);
  726. return FALSE;
  727. }
  728. #ifdef SUPPORT_LOOK_AHEAD_RC
  729. if (TRUE == ctx->larcEnable && ctx->larcPass == LOOK_AHEAD_RC_PASS1) {
  730. //no terminate here. PASS2 will terminate PASS1 component
  731. ctx->larcPass1Finish = TRUE;
  732. if (out) out->reuse = FALSE;
  733. ctx->stateDoing = FALSE;
  734. }
  735. else {
  736. #endif
  737. if(out) out->last = TRUE; // Send finish signal
  738. if(out) out->reuse = FALSE;
  739. ctx->stateDoing = FALSE;
  740. com->terminate = TRUE;
  741. #ifdef SUPPORT_LOOK_AHEAD_RC
  742. }
  743. #endif
  744. //to read remain data
  745. if (ctx->encOpenParam.ringBufferEnable == TRUE && ctx->encOpenParam.ringBufferWrapEnable == FALSE) {
  746. if(out) out->rdPtr = encOutputInfo.rdPtr;
  747. if(out) out->wrPtr = encOutputInfo.wrPtr;
  748. if(out) out->size = encOutputInfo.wrPtr - encOutputInfo.rdPtr;
  749. }
  750. }
  751. #ifdef SUPPORT_LOOK_AHEAD_RC
  752. ctx->encPicCnt = encOutputInfo.encPicCnt;
  753. if (ctx->larcPass == LOOK_AHEAD_RC_PASS1
  754. && encOutputInfo.reconFrameIndex != RECON_IDX_FLAG_HEADER_ONLY
  755. && encOutputInfo.bitstreamSize > 0) {
  756. for (i = 0; i < 3; i++) {
  757. ctx->larcInfo.larcData[(ctx->encPicCnt-1) % LOOK_AHEAD_RC_DATA_SIZE][i] = encOutputInfo.larcData[i];
  758. }
  759. }
  760. #endif
  761. return TRUE;
  762. }
  763. static BOOL AllocateCustomBuffer(EncHandle handle, ComponentImpl* com)
  764. {
  765. EncoderContext* ctx = (EncoderContext*)com->context;
  766. TestEncConfig testEncConfig = ctx->testEncConfig;
  767. EncInfo* pEncInfo;
  768. EncOpenParam* pOpenParam;
  769. EncWaveParam* pParam;
  770. pEncInfo = &handle->CodecInfo->encInfo;
  771. pOpenParam = &pEncInfo->openParam;
  772. pParam = &pOpenParam->EncStdParam.waveParam;
  773. /* Allocate Buffer and Set Data */
  774. if (pParam->scalingListEnable) {
  775. ctx->vbScalingList.size = 0x1000;
  776. if (vdi_allocate_dma_memory(testEncConfig.coreIdx, &ctx->vbScalingList, ENC_ETC, ctx->handle->instIndex) < 0) {
  777. VLOG(ERR, "fail to allocate scaling list buffer\n");
  778. return FALSE;
  779. }
  780. pParam->userScalingListAddr = ctx->vbScalingList.phys_addr;
  781. parse_user_scaling_list(&ctx->scalingList, testEncConfig.scaling_list_file, testEncConfig.stdMode);
  782. vdi_write_memory(testEncConfig.coreIdx, ctx->vbScalingList.phys_addr, (unsigned char*)&ctx->scalingList, ctx->vbScalingList.size, VDI_LITTLE_ENDIAN);
  783. }
  784. if (pParam->customLambdaEnable) {
  785. ctx->vbCustomLambda.size = 0x200;
  786. if (vdi_allocate_dma_memory(testEncConfig.coreIdx, &ctx->vbCustomLambda, ENC_ETC, ctx->handle->instIndex) < 0) {
  787. VLOG(ERR, "fail to allocate Lambda map buffer\n");
  788. return FALSE;
  789. }
  790. pParam->customLambdaAddr = ctx->vbCustomLambda.phys_addr;
  791. parse_custom_lambda(ctx->customLambda, testEncConfig.custom_lambda_file);
  792. vdi_write_memory(testEncConfig.coreIdx, ctx->vbCustomLambda.phys_addr, (unsigned char*)&ctx->customLambda[0], ctx->vbCustomLambda.size, VDI_LITTLE_ENDIAN);
  793. }
  794. return TRUE;
  795. }
  796. static BOOL OpenEncoder(ComponentImpl* com)
  797. {
  798. EncoderContext* ctx = (EncoderContext*)com->context;
  799. SecAxiUse secAxiUse;
  800. MirrorDirection mirrorDirection;
  801. RetCode result;
  802. CNMComListenerEncOpen lspn = {0};
  803. ctx->stateDoing = TRUE;
  804. ctx->encOpenParam.bitstreamBuffer = ctx->bsBuf.bs[0].phys_addr;
  805. ctx->encOpenParam.bitstreamBufferSize = ctx->bsBuf.bs[0].size;
  806. if ((result = VPU_EncOpen(&ctx->handle, &ctx->encOpenParam)) != RETCODE_SUCCESS) {
  807. VLOG(ERR, "VPU_EncOpen failed Error code is 0x%x \n", result);
  808. if ( result == RETCODE_VPU_RESPONSE_TIMEOUT ) {
  809. CNMErrorSet(CNM_ERROR_HANGUP);
  810. }
  811. CNMAppStop();
  812. return FALSE;
  813. }
  814. //VPU_EncGiveCommand(ctx->handle, ENABLE_LOGGING, 0);
  815. LoadBalancerAddInstance(ctx->handle->instIndex);
  816. if (AllocateCustomBuffer(ctx->handle, com) == FALSE) return FALSE;
  817. lspn.handle = ctx->handle;
  818. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_OPEN, (void*)&lspn);
  819. if (ctx->testEncConfig.rotAngle != 0 || ctx->testEncConfig.mirDir != 0) {
  820. VPU_EncGiveCommand(ctx->handle, ENABLE_ROTATION, 0);
  821. VPU_EncGiveCommand(ctx->handle, ENABLE_MIRRORING, 0);
  822. VPU_EncGiveCommand(ctx->handle, SET_ROTATION_ANGLE, &ctx->testEncConfig.rotAngle);
  823. mirrorDirection = (MirrorDirection)ctx->testEncConfig.mirDir;
  824. VPU_EncGiveCommand(ctx->handle, SET_MIRROR_DIRECTION, &mirrorDirection);
  825. }
  826. osal_memset(&secAxiUse, 0x00, sizeof(SecAxiUse));
  827. secAxiUse.u.wave.useEncRdoEnable = (ctx->testEncConfig.secondaryAXI & 0x1) ? TRUE : FALSE; //USE_RDO_INTERNAL_BUF
  828. secAxiUse.u.wave.useEncLfEnable = (ctx->testEncConfig.secondaryAXI & 0x2) ? TRUE : FALSE; //USE_LF_INTERNAL_BUF
  829. VPU_EncGiveCommand(ctx->handle, SET_SEC_AXI, &secAxiUse);
  830. VPU_EncGiveCommand(ctx->handle, SET_CYCLE_PER_TICK, (void*)&ctx->cyclePerTick);
  831. ctx->stateDoing = FALSE;
  832. return TRUE;
  833. }
  834. static BOOL ExecuteEncoder(ComponentImpl* com, PortContainer* in, PortContainer* out)
  835. {
  836. EncoderContext* ctx = (EncoderContext*)com->context;
  837. BOOL ret;
  838. switch (ctx->state) {
  839. case ENCODER_STATE_OPEN:
  840. ret = OpenEncoder(com);
  841. if (ctx->stateDoing == FALSE) ctx->state = ENCODER_STATE_INIT_SEQ;
  842. break;
  843. case ENCODER_STATE_INIT_SEQ:
  844. ret = SetSequenceInfo(com);
  845. if (ctx->stateDoing == FALSE) ctx->state = ENCODER_STATE_REGISTER_FB;
  846. break;
  847. case ENCODER_STATE_REGISTER_FB:
  848. ret = RegisterFrameBuffers(com);
  849. if (ctx->stateDoing == FALSE) ctx->state = ENCODER_STATE_ENCODE_HEADER;
  850. break;
  851. case ENCODER_STATE_ENCODE_HEADER:
  852. ret = EncodeHeader(com);
  853. if (ctx->stateDoing == FALSE) ctx->state = ENCODER_STATE_ENCODING;
  854. break;
  855. case ENCODER_STATE_ENCODING:
  856. ret = Encode(com, (PortContainerYuv*)in, (PortContainerES*)out);
  857. break;
  858. default:
  859. ret = FALSE;
  860. break;
  861. }
  862. if (ret == FALSE || com->terminate == TRUE) {
  863. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_ENCODED_ALL, (void*)ctx->handle);
  864. if (out != NULL) {
  865. out->reuse = FALSE;
  866. out->last = TRUE;
  867. }
  868. }
  869. return ret;
  870. }
  871. static BOOL PrepareEncoder(ComponentImpl* com, BOOL* done)
  872. {
  873. EncoderContext* ctx = (EncoderContext*)com->context;
  874. TestEncConfig* testEncConfig = &ctx->testEncConfig;
  875. CNMComponentParamRet ret;
  876. BOOL success;
  877. Uint32 i;
  878. *done = FALSE;
  879. ret = ComponentGetParameter(com, com->sinkPort.connectedComponent, GET_PARAM_READER_BITSTREAM_BUF, &ctx->bsBuf);
  880. if (ComponentParamReturnTest(ret, &success) == FALSE) return success;
  881. if (ctx->encOpenParam.ringBufferEnable == TRUE) {
  882. ctx->encOutQ = Queue_Create(com->numSinkPortQueue, sizeof(vpu_buffer_t));
  883. for (i=0; i<com->numSinkPortQueue; i++) {
  884. if ( i < ctx->bsBuf.num) {
  885. ctx->bsBuffer[i] = &ctx->bsBuf.bs[i]; }
  886. else {
  887. ctx->bsBuffer[i] = osal_malloc(sizeof(vpu_buffer_t));
  888. osal_memcpy(ctx->bsBuffer[i], ctx->bsBuffer[0], sizeof(vpu_buffer_t));
  889. }
  890. Queue_Enqueue(ctx->encOutQ, (void*)&ctx->bsBuffer[i]);//same addr enqueue
  891. }
  892. } else {
  893. ctx->encOutQ = Queue_Create(ctx->bsBuf.num, sizeof(vpu_buffer_t));
  894. for (i=0; i<ctx->bsBuf.num; i++) {
  895. Queue_Enqueue(ctx->encOutQ, (void*)&ctx->bsBuf.bs[i]);
  896. }
  897. }
  898. /* Open Data File*/
  899. if (ctx->encOpenParam.EncStdParam.waveParam.scalingListEnable) {
  900. if (testEncConfig) {
  901. ChangePathStyle(testEncConfig->scaling_list_fileName);
  902. if ((testEncConfig->scaling_list_file = osal_fopen(testEncConfig->scaling_list_fileName, "r")) == NULL) {
  903. VLOG(ERR, "fail to open scaling list file, %s\n", testEncConfig->scaling_list_fileName);
  904. return FALSE;
  905. }
  906. }
  907. }
  908. if (ctx->encOpenParam.EncStdParam.waveParam.customLambdaEnable) {
  909. if (testEncConfig) {
  910. ChangePathStyle(testEncConfig->custom_lambda_fileName);
  911. if ((testEncConfig->custom_lambda_file = osal_fopen(testEncConfig->custom_lambda_fileName, "r")) == NULL) {
  912. VLOG(ERR, "fail to open custom lambda file, %s\n", testEncConfig->custom_lambda_fileName);
  913. return FALSE;
  914. }
  915. }
  916. }
  917. if (testEncConfig->roi_enable) {
  918. ChangePathStyle(testEncConfig->roi_file_name);
  919. if ((testEncConfig->roi_file = osal_fopen(testEncConfig->roi_file_name, "r")) == NULL) {
  920. VLOG(ERR, "fail to open ROI file, %s\n", testEncConfig->roi_file_name);
  921. return FALSE;
  922. }
  923. }
  924. if (testEncConfig->lambda_map_enable) {
  925. ChangePathStyle(testEncConfig->lambda_map_fileName);
  926. if ((testEncConfig->lambda_map_file = osal_fopen(testEncConfig->lambda_map_fileName, "r")) == NULL) {
  927. VLOG(ERR, "fail to open lambda map file, %s\n", testEncConfig->lambda_map_fileName);
  928. return FALSE;
  929. }
  930. }
  931. if (testEncConfig->mode_map_flag) {
  932. ChangePathStyle(testEncConfig->mode_map_fileName);
  933. if ((testEncConfig->mode_map_file = osal_fopen(testEncConfig->mode_map_fileName, "r")) == NULL) {
  934. VLOG(ERR, "fail to open custom mode map file, %s\n", testEncConfig->mode_map_fileName);
  935. return FALSE;
  936. }
  937. }
  938. if (testEncConfig->wp_param_flag & 0x1) {
  939. ChangePathStyle(testEncConfig->wp_param_fileName);
  940. if ((testEncConfig->wp_param_file = osal_fopen(testEncConfig->wp_param_fileName, "r")) == NULL) {
  941. VLOG(ERR, "fail to open Weight Param file, %s\n", testEncConfig->wp_param_fileName);
  942. return FALSE;
  943. }
  944. }
  945. *done = TRUE;
  946. return TRUE;
  947. }
  948. static void ReleaseEncoder(ComponentImpl* com)
  949. {
  950. // Nothing to do
  951. }
  952. static BOOL DestroyEncoder(ComponentImpl* com)
  953. {
  954. EncoderContext* ctx = (EncoderContext*)com->context;
  955. Uint32 i = 0;
  956. BOOL success = TRUE;
  957. ENC_INT_STATUS intStatus;
  958. if ( NULL == ctx )
  959. return FALSE;
  960. if ( ctx && ctx->handle) {
  961. LoadBalancerRemoveInstance(ctx->handle->instIndex);
  962. }
  963. while (VPU_EncClose(ctx->handle) == RETCODE_VPU_STILL_RUNNING) {
  964. if ((intStatus = HandlingInterruptFlag(com)) == ENC_INT_STATUS_TIMEOUT) {
  965. HandleEncoderError(ctx->handle, ctx->frameIdx, NULL);
  966. VLOG(ERR, "NO RESPONSE FROM VPU_EncClose2()\n");
  967. success = FALSE;
  968. break;
  969. }
  970. else if (intStatus == ENC_INT_STATUS_DONE) {
  971. EncOutputInfo outputInfo;
  972. VLOG(INFO, "VPU_EncClose() : CLEAR REMAIN INTERRUPT\n");
  973. VPU_EncGetOutputInfo(ctx->handle, &outputInfo);
  974. continue;
  975. }
  976. osal_msleep(10);
  977. }
  978. ComponentNotifyListeners(com, COMPONENT_EVENT_ENC_CLOSE, NULL);
  979. for (i = 0; i < ctx->fbCount.srcFbNum; i++) {
  980. if (ctx->vbCustomMap[i].size)
  981. vdi_free_dma_memory(ctx->testEncConfig.coreIdx, &ctx->vbCustomMap[i], ENC_ETC, ctx->handle->instIndex);
  982. }
  983. if (ctx->vbCustomLambda.size)
  984. vdi_free_dma_memory(ctx->testEncConfig.coreIdx, &ctx->vbCustomLambda, ENC_ETC, ctx->handle->instIndex);
  985. if (ctx->vbScalingList.size)
  986. vdi_free_dma_memory(ctx->testEncConfig.coreIdx, &ctx->vbScalingList, ENC_ETC, ctx->handle->instIndex);
  987. if (ctx->testEncConfig.roi_file)
  988. osal_fclose(ctx->testEncConfig.roi_file);
  989. if (ctx->testEncConfig.lambda_map_file)
  990. osal_fclose(ctx->testEncConfig.lambda_map_file);
  991. if (ctx->testEncConfig.mode_map_file)
  992. osal_fclose(ctx->testEncConfig.mode_map_file);
  993. if (ctx->testEncConfig.scaling_list_file)
  994. osal_fclose(ctx->testEncConfig.scaling_list_file);
  995. if (ctx->testEncConfig.custom_lambda_file)
  996. osal_fclose(ctx->testEncConfig.custom_lambda_file);
  997. if (ctx->testEncConfig.wp_param_file)
  998. osal_fclose(ctx->testEncConfig.wp_param_file);
  999. if (ctx->encOutQ) Queue_Destroy(ctx->encOutQ);
  1000. VPU_DeInit(ctx->testEncConfig.coreIdx);
  1001. osal_free(ctx);
  1002. return success;
  1003. }
  1004. static Component CreateEncoder(ComponentImpl* com, CNMComponentConfig* componentParam)
  1005. {
  1006. EncoderContext* ctx;
  1007. RetCode retCode;
  1008. Uint32 coreIdx = componentParam->testEncConfig.coreIdx;
  1009. Uint16* firmware = (Uint16*)componentParam->bitcode;
  1010. Uint32 firmwareSize = componentParam->sizeOfBitcode;
  1011. Uint32 i;
  1012. VpuAttr productInfo;
  1013. retCode = VPU_InitWithBitcode(coreIdx, firmware, firmwareSize);
  1014. if (retCode != RETCODE_SUCCESS && retCode != RETCODE_CALLED_BEFORE) {
  1015. VLOG(INFO, "%s:%d Failed to VPU_InitWidthBitCode, ret(%08x)\n", __FUNCTION__, __LINE__, retCode);
  1016. return FALSE;
  1017. }
  1018. com->context = osal_malloc(sizeof(EncoderContext));
  1019. ctx = (EncoderContext*)com->context;
  1020. osal_memset((void*)ctx, 0, sizeof(EncoderContext));
  1021. retCode = PrintVpuProductInfo(coreIdx, &productInfo);
  1022. if (retCode == RETCODE_VPU_RESPONSE_TIMEOUT ) {
  1023. CNMErrorSet(CNM_ERROR_HANGUP);
  1024. VLOG(INFO, "<%s:%d> Failed to PrintVpuProductInfo()\n", __FUNCTION__, __LINE__);
  1025. HandleEncoderError(ctx->handle, 0, NULL);
  1026. return FALSE;
  1027. }
  1028. ctx->cyclePerTick = 32768;
  1029. if (TRUE == productInfo.supportNewTimer)
  1030. ctx->cyclePerTick = 256;
  1031. ctx->handle = NULL;
  1032. ctx->frameIdx = 0;
  1033. ctx->fbCount.reconFbNum = 0;
  1034. ctx->fbCount.srcFbNum = 0;
  1035. ctx->testEncConfig = componentParam->testEncConfig;
  1036. ctx->encOpenParam = componentParam->encOpenParam;
  1037. for (i=0; i<ENC_SRC_BUF_NUM ; i++ ) {
  1038. ctx->encodedSrcFrmIdxArr[i] = 0;
  1039. }
  1040. osal_memset(&ctx->vbCustomLambda, 0x00, sizeof(vpu_buffer_t));
  1041. osal_memset(&ctx->vbScalingList, 0x00, sizeof(vpu_buffer_t));
  1042. osal_memset(&ctx->scalingList, 0x00, sizeof(UserScalingList));
  1043. osal_memset(&ctx->customLambda[0], 0x00, sizeof(ctx->customLambda));
  1044. osal_memset(ctx->vbCustomMap, 0x00, sizeof(ctx->vbCustomMap));
  1045. if (ctx->encOpenParam.ringBufferEnable)
  1046. com->numSinkPortQueue = 10;
  1047. else
  1048. com->numSinkPortQueue = componentParam->encOpenParam.streamBufCount;
  1049. #ifdef SUPPORT_LOOK_AHEAD_RC
  1050. ctx->larcEnable = ctx->encOpenParam.EncStdParam.waveParam.larcEnable;
  1051. if (TRUE == ctx->larcEnable) {
  1052. ctx->larcPass = ctx->encOpenParam.EncStdParam.waveParam.larcPass;
  1053. ctx->larcSize = ctx->encOpenParam.EncStdParam.waveParam.larcSize;
  1054. osal_memset((void*)ctx->larcInfo.larcData, -1, sizeof(ctx->larcInfo.larcData));
  1055. }
  1056. #endif
  1057. return (Component)com;
  1058. }
  1059. ComponentImpl waveEncoderComponentImpl = {
  1060. "wave_encoder",
  1061. NULL,
  1062. {0,},
  1063. {0,},
  1064. sizeof(PortContainerES),
  1065. 5, /* encoder's numSinkPortQueue(relates to streambufcount) */
  1066. CreateEncoder,
  1067. GetParameterEncoder,
  1068. SetParameterEncoder,
  1069. PrepareEncoder,
  1070. ExecuteEncoder,
  1071. ReleaseEncoder,
  1072. DestroyEncoder
  1073. };