H264CodeFrame.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /*------------------------------------------------------------------------------
  2. -- --
  3. -- This software is confidential and proprietary and may be used --
  4. -- only as expressly authorized by a licensing agreement from --
  5. -- --
  6. -- Hantro Products Oy. --
  7. -- --
  8. -- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
  9. -- ALL RIGHTS RESERVED --
  10. -- --
  11. -- The entire notice above must be reproduced --
  12. -- on all copies and should not be removed. --
  13. -- --
  14. --------------------------------------------------------------------------------
  15. --
  16. -- Description : Encode picture
  17. --
  18. ------------------------------------------------------------------------------*/
  19. /*------------------------------------------------------------------------------
  20. 1. Include headers
  21. ------------------------------------------------------------------------------*/
  22. #include "enccommon.h"
  23. #include "ewl.h"
  24. #include "H264CodeFrame.h"
  25. /*------------------------------------------------------------------------------
  26. 2. External compiler flags
  27. ------------------------------------------------------------------------------*/
  28. /*------------------------------------------------------------------------------
  29. 3. Module defines
  30. ------------------------------------------------------------------------------*/
  31. static const u32 h264Intra16Favor[52] = {
  32. 24, 24, 24, 26, 27, 30, 32, 35, 39, 43, 48, 53, 58, 64, 71, 78,
  33. 85, 93, 102, 111, 121, 131, 142, 154, 167, 180, 195, 211, 229,
  34. 248, 271, 296, 326, 361, 404, 457, 523, 607, 714, 852, 1034,
  35. 1272, 1588, 2008, 2568, 3318, 4323, 5672, 7486, 9928, 13216,
  36. 17648
  37. };
  38. /* H.264 motion estimation parameters */
  39. static const u32 h264InterFavor[52] = {
  40. 40, 40, 41, 42, 43, 44, 45, 48, 51, 53, 55, 60, 62, 67, 69, 72,
  41. 78, 84, 90, 96, 110, 120, 135, 152, 170, 189, 210, 235, 265,
  42. 297, 335, 376, 420, 470, 522, 572, 620, 670, 724, 770, 820,
  43. 867, 915, 970, 1020, 1076, 1132, 1180, 1230, 1275, 1320, 1370
  44. };
  45. /* Favor value for web cam use case, 1.3x larger */
  46. static const u32 h264InterFavorWebCam[52] = {
  47. 52, 52, 53, 54, 55, 57, 58, 62, 66, 68,
  48. 71, 78, 80, 87, 89, 93, 101, 109, 117, 124,
  49. 143, 156, 175, 197, 221, 245, 273, 305, 344, 386,
  50. 435, 488, 546, 611, 678, 743, 806, 871, 941, 1001,
  51. 1066, 1127, 1189, 1261, 1326, 1398, 1471, 1534, 1599, 1657,
  52. 1716, 1781
  53. };
  54. /* Penalty factor in 1/256 units for skip mode, 2550/(qp-1)-50 */
  55. static const u32 h264SkipSadPenalty[52] = {
  56. 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 233, 205, 182, 163, 146,
  57. 132, 120, 109, 100, 92, 84, 78, 71, 66, 61, 56, 52, 48, 44, 41,
  58. 38, 35, 32, 30, 27, 25, 23, 21, 19, 17, 15, 14, 12, 11, 9,
  59. 8, 7, 5, 4, 3, 2, 1
  60. };
  61. /* sqrt(2^((qp-12)/3))*8 */
  62. static const u32 h264DiffMvPenalty[52] =
  63. { 2, 2, 3, 3, 3, 4, 4, 4, 5, 6,
  64. 6, 7, 8, 9, 10, 11, 13, 14, 16, 18,
  65. 20, 23, 26, 29, 32, 36, 40, 45, 51, 57,
  66. 64, 72, 81, 91, 102, 114, 128, 144, 161, 181,
  67. 203, 228, 256, 287, 323, 362, 406, 456, 512, 575,
  68. 645, 724
  69. };
  70. /* 31*sqrt(2^((qp-12)/3))/4 */
  71. static const u32 h264DiffMvPenalty4p[52] =
  72. { 2, 2, 2, 3, 3, 3, 4, 4, 5, 5,
  73. 6, 7, 8, 9, 10, 11, 12, 14, 16, 17,
  74. 20, 22, 25, 28, 31, 35, 39, 44, 49, 55,
  75. 62, 70, 78, 88, 98, 110, 124, 139, 156, 175,
  76. 197, 221, 248, 278, 312, 351, 394, 442, 496, 557,
  77. 625, 701
  78. };
  79. /*------------------------------------------------------------------------------
  80. 4. Local function prototypes
  81. ------------------------------------------------------------------------------*/
  82. static void H264SetNewFrame(h264Instance_s * inst);
  83. /*------------------------------------------------------------------------------
  84. H264CodeFrame
  85. ------------------------------------------------------------------------------*/
  86. h264EncodeFrame_e H264CodeFrame(h264Instance_s * inst)
  87. {
  88. asicData_s *asic = &inst->asic;
  89. h264EncodeFrame_e ret;
  90. i32 status = ASIC_STATUS_ERROR;
  91. H264EncSliceReady slice;
  92. /* Reset callback struct */
  93. slice.slicesReadyPrev = 0;
  94. slice.slicesReady = 0;
  95. slice.sliceSizes = (u32 *) inst->asic.sizeTbl.nal.virtualAddress;
  96. slice.sliceSizes += inst->naluOffset;
  97. slice.pOutBuf = inst->pOutBuf;
  98. slice.pAppData = inst->pAppData;
  99. H264SetNewFrame(inst);
  100. EncAsicFrameStart(inst->asic.ewl, &inst->asic.regs);
  101. do {
  102. /* Encode one frame */
  103. i32 ewl_ret;
  104. /* Wait for IRQ for every slice or for complete frame */
  105. if ((inst->slice.sliceSize > 0) && inst->sliceReadyCbFunc)
  106. ewl_ret = EWLWaitHwRdy(asic->ewl, &slice.slicesReady);
  107. else
  108. ewl_ret = EWLWaitHwRdy(asic->ewl, NULL);
  109. if(ewl_ret != EWL_OK)
  110. {
  111. status = ASIC_STATUS_ERROR;
  112. if(ewl_ret == EWL_ERROR)
  113. {
  114. /* IRQ error => Stop and release HW */
  115. ret = H264ENCODE_SYSTEM_ERROR;
  116. }
  117. else /*if(ewl_ret == EWL_HW_WAIT_TIMEOUT) */
  118. {
  119. /* IRQ Timeout => Stop and release HW */
  120. ret = H264ENCODE_TIMEOUT;
  121. }
  122. EncAsicStop(asic->ewl);
  123. /* Release HW so that it can be used by other codecs */
  124. EWLReleaseHw(asic->ewl);
  125. }
  126. else
  127. {
  128. /* Check ASIC status bits and possibly release HW */
  129. status = EncAsicCheckStatus_V2(asic);
  130. switch (status)
  131. {
  132. case ASIC_STATUS_ERROR:
  133. ret = H264ENCODE_HW_ERROR;
  134. break;
  135. case ASIC_STATUS_SLICE_READY:
  136. ret = H264ENCODE_OK;
  137. /* Issue callback to application telling how many slices
  138. * are available. */
  139. if (inst->sliceReadyCbFunc &&
  140. (slice.slicesReadyPrev < slice.slicesReady))
  141. inst->sliceReadyCbFunc(&slice);
  142. slice.slicesReadyPrev = slice.slicesReady;
  143. break;
  144. case ASIC_STATUS_BUFF_FULL:
  145. ret = H264ENCODE_OK;
  146. inst->stream.overflow = ENCHW_YES;
  147. break;
  148. case ASIC_STATUS_HW_RESET:
  149. ret = H264ENCODE_HW_RESET;
  150. break;
  151. case ASIC_STATUS_FRAME_READY:
  152. {
  153. /* Stream header remainder ie. last not full 64-bit address
  154. * is counted in HW data. */
  155. const u32 hw_offset = inst->stream.byteCnt & (0x07U);
  156. inst->stream.byteCnt +=
  157. asic->regs.outputStrmSize - hw_offset;
  158. inst->stream.stream +=
  159. asic->regs.outputStrmSize - hw_offset;
  160. ret = H264ENCODE_OK;
  161. break;
  162. }
  163. default:
  164. /* should never get here */
  165. ASSERT(0);
  166. ret = H264ENCODE_HW_ERROR;
  167. }
  168. }
  169. } while (status == ASIC_STATUS_SLICE_READY);
  170. /* Reset the favor values for next frame */
  171. inst->asic.regs.intra16Favor = 0;
  172. inst->asic.regs.interFavor = 0;
  173. inst->asic.regs.skipPenalty = 1;
  174. inst->asic.regs.diffMvPenalty = 0;
  175. inst->asic.regs.diffMvPenalty4p = 0;
  176. return ret;
  177. }
  178. /*------------------------------------------------------------------------------
  179. Set encoding parameters at the beginning of a new frame.
  180. ------------------------------------------------------------------------------*/
  181. void H264SetNewFrame(h264Instance_s * inst)
  182. {
  183. asicData_s *asic = &inst->asic;
  184. regValues_s *regs = &inst->asic.regs;
  185. regs->outputStrmSize -= inst->stream.byteCnt;
  186. regs->outputStrmSize /= 8; /* 64-bit addresses */
  187. regs->outputStrmSize &= (~0x07); /* 8 multiple size */
  188. /* 64-bit aligned stream base address */
  189. regs->outputStrmBase += (inst->stream.byteCnt & (~0x07));
  190. /* bit offset in the last 64-bit word */
  191. regs->firstFreeBit = (inst->stream.byteCnt & 0x07) * 8;
  192. /* header remainder is byte aligned, max 7 bytes = 56 bits */
  193. if(regs->firstFreeBit != 0)
  194. {
  195. /* 64-bit aligned stream pointer */
  196. u8 *pTmp = (u8 *) ((size_t) (inst->stream.stream) & (u32) (~0x07));
  197. u32 val;
  198. /* Clear remaining bits */
  199. for (val = 6; val >= regs->firstFreeBit/8; val--)
  200. pTmp[val] = 0;
  201. val = pTmp[0] << 24;
  202. val |= pTmp[1] << 16;
  203. val |= pTmp[2] << 8;
  204. val |= pTmp[3];
  205. regs->strmStartMSB = val; /* 32 bits to MSB */
  206. if(regs->firstFreeBit > 32)
  207. {
  208. val = pTmp[4] << 24;
  209. val |= pTmp[5] << 16;
  210. val |= pTmp[6] << 8;
  211. regs->strmStartLSB = val;
  212. }
  213. else
  214. regs->strmStartLSB = 0;
  215. }
  216. else
  217. {
  218. regs->strmStartMSB = regs->strmStartLSB = 0;
  219. }
  220. if (inst->numViews > 1)
  221. regs->frameNum = inst->slice.frameNum/2;
  222. else
  223. regs->frameNum = inst->slice.frameNum;
  224. regs->idrPicId = inst->slice.idrPicId;
  225. /* Store the final register values in the register structure */
  226. regs->sliceSizeMbRows = inst->slice.sliceSize / inst->mbPerRow;
  227. regs->chromaQpIndexOffset = inst->picParameterSet.chromaQpIndexOffset;
  228. /* Enable slice ready interrupts if defined by config and slices in use */
  229. regs->sliceReadyInterrupt =
  230. ENC8290_SLICE_READY_INTERRUPT & (inst->slice.sliceSize > 0);
  231. regs->picInitQp = (u32) (inst->picParameterSet.picInitQpMinus26 + 26);
  232. regs->qp = inst->rateControl.qpHdr;
  233. regs->qpMin = inst->rateControl.qpMin;
  234. regs->qpMax = inst->rateControl.qpMax;
  235. if(inst->rateControl.mbRc)
  236. {
  237. regs->cpTarget = (u32 *) inst->rateControl.qpCtrl.wordCntTarget;
  238. regs->targetError = inst->rateControl.qpCtrl.wordError;
  239. regs->deltaQp = inst->rateControl.qpCtrl.qpChange;
  240. regs->cpDistanceMbs = inst->rateControl.qpCtrl.checkPointDistance;
  241. regs->cpTargetResults = (u32 *) inst->rateControl.qpCtrl.wordCntPrev;
  242. }
  243. else
  244. {
  245. regs->cpTarget = NULL;
  246. }
  247. regs->filterDisable = inst->slice.disableDeblocking;
  248. if(inst->slice.disableDeblocking != 1)
  249. {
  250. regs->sliceAlphaOffset = inst->slice.filterOffsetA / 2;
  251. regs->sliceBetaOffset = inst->slice.filterOffsetB / 2;
  252. }
  253. else
  254. {
  255. regs->sliceAlphaOffset = 0;
  256. regs->sliceBetaOffset = 0;
  257. }
  258. regs->transform8x8Mode = inst->picParameterSet.transform8x8Mode;
  259. /* CABAC mode 2 uses ppsId=0 (CAVLC) for intra frames and
  260. * ppsId=1 (CABAC) for inter frames */
  261. if (inst->picParameterSet.enableCabac == 2)
  262. {
  263. regs->ppsId = (inst->slice.sliceType == ISLICE) ? 0 : 1;
  264. regs->enableCabac = regs->ppsId;
  265. }
  266. else
  267. {
  268. regs->ppsId = 0;
  269. regs->enableCabac = inst->picParameterSet.enableCabac;
  270. }
  271. if(inst->picParameterSet.enableCabac)
  272. regs->cabacInitIdc = inst->slice.cabacInitIdc;
  273. regs->constrainedIntraPrediction =
  274. (inst->picParameterSet.constIntraPred == ENCHW_YES) ? 1 : 0;
  275. /* Select frame type based on viewMode and frame number */
  276. if (inst->slice.sliceType == ISLICE)
  277. regs->frameCodingType = ASIC_INTRA;
  278. else if ((inst->numViews > 1) && (inst->numRefBuffsLum == 1) &&
  279. (inst->slice.frameNum % 2) && (inst->slice.frameNum > 1))
  280. regs->frameCodingType = ASIC_MVC_REF_MOD;
  281. else if ((inst->numViews > 1) && (inst->slice.frameNum % 2))
  282. regs->frameCodingType = ASIC_MVC;
  283. else
  284. regs->frameCodingType = ASIC_INTER;
  285. /* Disable frame reconstruction for view=1 frames that are not used
  286. * as reference. */
  287. regs->recWriteDisable = (inst->numViews > 1) &&
  288. (inst->numRefBuffsLum == 1) && (inst->slice.frameNum % 2);
  289. if (inst->slice.quarterPixelMv == 0)
  290. inst->asic.regs.disableQuarterPixelMv = 1;
  291. else if (inst->slice.quarterPixelMv == 1)
  292. {
  293. /* Adaptive setting. When resolution larger than 720p = 3600 macroblocks
  294. * there is not enough time to do 1/4 pixel ME */
  295. if(inst->mbPerFrame > 3600)
  296. inst->asic.regs.disableQuarterPixelMv = 1;
  297. else
  298. inst->asic.regs.disableQuarterPixelMv = 0;
  299. }
  300. else
  301. inst->asic.regs.disableQuarterPixelMv = 0;
  302. /* If favor has not been set earlier by testId use default */
  303. if (regs->intra16Favor == 0)
  304. regs->intra16Favor = h264Intra16Favor[regs->qp];
  305. if (regs->interFavor == 0)
  306. regs->interFavor = h264InterFavor[regs->qp];
  307. if (regs->skipPenalty == 1) {
  308. i32 scaler = MAX(1, 200/(inst->mbPerRow+inst->mbPerCol));
  309. regs->skipPenalty = MIN(255, h264SkipSadPenalty[regs->qp]*scaler);
  310. }
  311. if (regs->diffMvPenalty == 0)
  312. regs->diffMvPenalty = h264DiffMvPenalty[regs->qp];
  313. if (regs->diffMvPenalty4p == 0)
  314. regs->diffMvPenalty4p = h264DiffMvPenalty4p[regs->qp];
  315. /* HW base address for NAL unit sizes is affected by start offset
  316. * and SW created NALUs. */
  317. regs->sizeTblBase.nal = asic->sizeTbl.nal.busAddress +
  318. inst->naluOffset*4 + inst->numNalus*4;
  319. regs->sizeTblPresent = 1;
  320. /* HW Base must be 64-bit aligned */
  321. ASSERT(regs->sizeTblBase.nal%8 == 0);
  322. /* MAD threshold range [0, 63*256] register 6-bits range [0,63] */
  323. regs->madThreshold = inst->mad.threshold / 256;
  324. regs->madQpDelta = inst->rateControl.mbQpAdjustment;
  325. /* MVC */
  326. regs->mvcAnchorPicFlag = inst->mvc.anchorPicFlag;
  327. regs->mvcPriorityId = inst->mvc.priorityId;
  328. regs->mvcViewId = inst->mvc.viewId;
  329. regs->mvcTemporalId = inst->mvc.temporalId;
  330. regs->mvcInterViewFlag = inst->mvc.interViewFlag;
  331. #if defined(TRACE_RECON) || defined(ASIC_WAVE_TRACE_TRIGGER)
  332. {
  333. u32 index;
  334. if(asic->regs.internalImageLumBaseW ==
  335. asic->internalImageLuma[0].busAddress)
  336. index = 0;
  337. else
  338. index = 1;
  339. EWLmemset(asic->internalImageLuma[index].virtualAddress, 0,
  340. asic->internalImageLuma[index].size);
  341. }
  342. #endif
  343. }