H264Init.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  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. -- Abstract : Encoder initialization and setup
  17. --
  18. ------------------------------------------------------------------------------*/
  19. /*------------------------------------------------------------------------------
  20. 1. Include headers
  21. ------------------------------------------------------------------------------*/
  22. #include "H264Init.h"
  23. #include "enccommon.h"
  24. #include "ewl.h"
  25. /*------------------------------------------------------------------------------
  26. 2. External compiler flags
  27. --------------------------------------------------------------------------------
  28. --------------------------------------------------------------------------------
  29. 3. Module defines
  30. ------------------------------------------------------------------------------*/
  31. #define H264ENC_MIN_ENC_WIDTH 132 /* 144 - 12 pixels overfill */
  32. #define H264ENC_MAX_ENC_WIDTH 4080
  33. #define H264ENC_MIN_ENC_HEIGHT 96
  34. #define H264ENC_MAX_ENC_HEIGHT 4080
  35. #define H264ENC_MAX_MBS_PER_PIC 65025 /* 4080x4080 */
  36. /* Level 51 MB limit is increased to enable max resolution */
  37. #define H264ENC_MAX_LEVEL 51
  38. #define H264ENC_DEFAULT_QP 26
  39. /*------------------------------------------------------------------------------
  40. 4. Local function prototypes
  41. ------------------------------------------------------------------------------*/
  42. static bool_e SetParameter(h264Instance_s * inst,
  43. const H264EncConfig * pEncCfg);
  44. static bool_e CheckParameter(const h264Instance_s * inst);
  45. /*------------------------------------------------------------------------------
  46. H264CheckCfg
  47. Function checks that the configuration is valid.
  48. Input pEncCfg Pointer to configuration structure.
  49. Return ENCHW_OK The configuration is valid.
  50. ENCHW_NOK Some of the parameters in configuration are not valid.
  51. ------------------------------------------------------------------------------*/
  52. bool_e H264CheckCfg(const H264EncConfig * pEncCfg)
  53. {
  54. ASSERT(pEncCfg);
  55. if ((pEncCfg->streamType != H264ENC_BYTE_STREAM) &&
  56. (pEncCfg->streamType != H264ENC_NAL_UNIT_STREAM))
  57. return ENCHW_NOK;
  58. /* Encoded image width limits, multiple of 4 */
  59. if(pEncCfg->width < H264ENC_MIN_ENC_WIDTH ||
  60. pEncCfg->width > H264ENC_MAX_ENC_WIDTH || (pEncCfg->width & 0x3) != 0)
  61. return ENCHW_NOK;
  62. /* Encoded image height limits, multiple of 2 */
  63. if(pEncCfg->height < H264ENC_MIN_ENC_HEIGHT ||
  64. pEncCfg->height > H264ENC_MAX_ENC_HEIGHT || (pEncCfg->height & 0x1) != 0)
  65. return ENCHW_NOK;
  66. /* total macroblocks per picture limit */
  67. if(((pEncCfg->height + 15) / 16) * ((pEncCfg->width + 15) / 16) >
  68. H264ENC_MAX_MBS_PER_PIC)
  69. {
  70. return ENCHW_NOK;
  71. }
  72. /* Check frame rate */
  73. if(pEncCfg->frameRateNum < 1 || pEncCfg->frameRateNum > ((1 << 20) - 1))
  74. return ENCHW_NOK;
  75. if(pEncCfg->frameRateDenom < 1)
  76. {
  77. return ENCHW_NOK;
  78. }
  79. /* special allowal of 1000/1001, 0.99 fps by customer request */
  80. if(pEncCfg->frameRateDenom > pEncCfg->frameRateNum &&
  81. !(pEncCfg->frameRateDenom == 1001 && pEncCfg->frameRateNum == 1000))
  82. {
  83. return ENCHW_NOK;
  84. }
  85. /* check level */
  86. if((pEncCfg->level > H264ENC_MAX_LEVEL) &&
  87. (pEncCfg->level != H264ENC_LEVEL_1_b))
  88. {
  89. return ENCHW_NOK;
  90. }
  91. /* check HW limitations */
  92. {
  93. EWLHwConfig_t cfg = EWLReadAsicConfig();
  94. /* is H.264 encoding supported */
  95. if(cfg.h264Enabled == EWL_HW_CONFIG_NOT_SUPPORTED)
  96. {
  97. return ENCHW_NOK;
  98. }
  99. /* max width supported */
  100. if(cfg.maxEncodedWidth < pEncCfg->width)
  101. {
  102. return ENCHW_NOK;
  103. }
  104. }
  105. return ENCHW_OK;
  106. }
  107. /*------------------------------------------------------------------------------
  108. H264Init
  109. Function initializes the Encoder and create new encoder instance.
  110. Input pEncCfg Encoder configuration.
  111. instAddr Pointer to instance will be stored in this address
  112. Return H264ENC_OK
  113. H264ENC_MEMORY_ERROR
  114. H264ENC_EWL_ERROR
  115. H264ENC_EWL_MEMORY_ERROR
  116. H264ENC_INVALID_ARGUMENT
  117. ------------------------------------------------------------------------------*/
  118. H264EncRet H264Init(const H264EncConfig * pEncCfg, h264Instance_s ** instAddr)
  119. {
  120. h264Instance_s *inst = NULL;
  121. const void *ewl = NULL;
  122. H264EncRet ret = H264ENC_OK;
  123. EWLInitParam_t param;
  124. ASSERT(pEncCfg);
  125. ASSERT(instAddr);
  126. *instAddr = NULL;
  127. param.clientType = EWL_CLIENT_TYPE_H264_ENC;
  128. /* Init EWL */
  129. if((ewl = EWLInit(&param)) == NULL)
  130. return H264ENC_EWL_ERROR;
  131. /* Encoder instance */
  132. inst = (h264Instance_s *) EWLcalloc(1, sizeof(h264Instance_s));
  133. if(inst == NULL)
  134. {
  135. ret = H264ENC_MEMORY_ERROR;
  136. goto err;
  137. }
  138. /* Default values */
  139. H264SeqParameterSetInit(&inst->seqParameterSet);
  140. H264PicParameterSetInit(&inst->picParameterSet);
  141. H264SliceInit(&inst->slice);
  142. /* Set parameters depending on user config */
  143. if(SetParameter(inst, pEncCfg) != ENCHW_OK)
  144. {
  145. ret = H264ENC_INVALID_ARGUMENT;
  146. goto err;
  147. }
  148. /* Check and init the rest of parameters */
  149. if(CheckParameter(inst) != ENCHW_OK)
  150. {
  151. ret = H264ENC_INVALID_ARGUMENT;
  152. goto err;
  153. }
  154. if(H264InitRc(&inst->rateControl) != ENCHW_OK)
  155. {
  156. return H264ENC_INVALID_ARGUMENT;
  157. }
  158. /* Initialize ASIC */
  159. inst->asic.ewl = ewl;
  160. (void) EncAsicControllerInit(&inst->asic);
  161. /* Allocate internal SW/HW shared memories */
  162. if(EncAsicMemAlloc_V2(&inst->asic,
  163. (u32) inst->preProcess.lumWidth,
  164. (u32) inst->preProcess.lumHeight,
  165. ASIC_H264, inst->numRefBuffsLum,
  166. inst->numRefBuffsChr) != ENCHW_OK)
  167. {
  168. ret = H264ENC_EWL_MEMORY_ERROR;
  169. goto err;
  170. }
  171. *instAddr = inst;
  172. /* init VUI */
  173. {
  174. const h264VirtualBuffer_s *vb = &inst->rateControl.virtualBuffer;
  175. H264SpsSetVuiTimigInfo(&inst->seqParameterSet,
  176. vb->timeScale, vb->unitsInTic);
  177. }
  178. if(inst->seqParameterSet.levelIdc >= 31)
  179. inst->asic.regs.h264Inter4x4Disabled = 1;
  180. else
  181. inst->asic.regs.h264Inter4x4Disabled = 0;
  182. inst->asic.regs.skipPenalty = 1;
  183. return ret;
  184. err:
  185. if(inst != NULL)
  186. EWLfree(inst);
  187. if(ewl != NULL)
  188. (void) EWLRelease(ewl);
  189. return ret;
  190. }
  191. /*------------------------------------------------------------------------------
  192. H264Shutdown
  193. Function frees the encoder instance.
  194. Input h264Instance_s * Pointer to the encoder instance to be freed.
  195. After this the pointer is no longer valid.
  196. ------------------------------------------------------------------------------*/
  197. void H264Shutdown(h264Instance_s * data)
  198. {
  199. const void *ewl;
  200. ASSERT(data);
  201. ewl = data->asic.ewl;
  202. EncAsicMemFree_V2(&data->asic);
  203. EWLfree(data);
  204. (void) EWLRelease(ewl);
  205. }
  206. /*------------------------------------------------------------------------------
  207. SetParameter
  208. Set all parameters in instance to valid values depending on user config.
  209. ------------------------------------------------------------------------------*/
  210. bool_e SetParameter(h264Instance_s * inst, const H264EncConfig * pEncCfg)
  211. {
  212. i32 width, height, tmp, bps;
  213. ASSERT(inst);
  214. /* Internal images, next macroblock boundary */
  215. width = 16 * ((pEncCfg->width + 15) / 16);
  216. height = 16 * ((pEncCfg->height + 15) / 16);
  217. /* stream type */
  218. if(pEncCfg->streamType == H264ENC_BYTE_STREAM)
  219. {
  220. inst->asic.regs.h264StrmMode = ASIC_H264_BYTE_STREAM;
  221. inst->picParameterSet.byteStream = ENCHW_YES;
  222. inst->seqParameterSet.byteStream = ENCHW_YES;
  223. inst->rateControl.sei.byteStream = ENCHW_YES;
  224. inst->slice.byteStream = ENCHW_YES;
  225. }
  226. else
  227. {
  228. inst->asic.regs.h264StrmMode = ASIC_H264_NAL_UNIT;
  229. inst->picParameterSet.byteStream = ENCHW_NO;
  230. inst->seqParameterSet.byteStream = ENCHW_NO;
  231. inst->rateControl.sei.byteStream = ENCHW_NO;
  232. inst->slice.byteStream = ENCHW_NO;
  233. }
  234. if(pEncCfg->viewMode == H264ENC_BASE_VIEW_SINGLE_BUFFER)
  235. {
  236. inst->numViews = 1;
  237. inst->numRefBuffsLum = 1;
  238. inst->numRefBuffsChr = 2;
  239. }
  240. else if(pEncCfg->viewMode == H264ENC_BASE_VIEW_DOUBLE_BUFFER)
  241. {
  242. inst->numViews = 1;
  243. inst->numRefBuffsLum = 2;
  244. inst->numRefBuffsChr = 2;
  245. }
  246. else if(pEncCfg->viewMode == H264ENC_MVC_STEREO_INTER_VIEW_PRED)
  247. {
  248. inst->numViews = 2;
  249. inst->numRefBuffsLum = 1;
  250. inst->numRefBuffsChr = 2;
  251. }
  252. else
  253. {
  254. inst->numViews = 2;
  255. inst->numRefBuffsLum = 2;
  256. inst->numRefBuffsChr = 3;
  257. }
  258. /* Slice */
  259. inst->slice.sliceSize = 0;
  260. /* Macroblock */
  261. inst->mbPerFrame = width / 16 * height / 16;
  262. inst->mbPerRow = width / 16;
  263. inst->mbPerCol = height / 16;
  264. /* Disable intra and ROI areas by default */
  265. inst->asic.regs.intraAreaTop = inst->asic.regs.intraAreaBottom = inst->mbPerCol;
  266. inst->asic.regs.intraAreaLeft = inst->asic.regs.intraAreaRight = inst->mbPerRow;
  267. inst->asic.regs.roi1Top = inst->asic.regs.roi1Bottom = inst->mbPerCol;
  268. inst->asic.regs.roi1Left = inst->asic.regs.roi1Right = inst->mbPerRow;
  269. inst->asic.regs.roi2Top = inst->asic.regs.roi2Bottom = inst->mbPerCol;
  270. inst->asic.regs.roi2Left = inst->asic.regs.roi2Right = inst->mbPerRow;
  271. /* Sequence parameter set */
  272. inst->seqParameterSet.levelIdc = pEncCfg->level;
  273. inst->seqParameterSet.picWidthInMbsMinus1 = width / 16 - 1;
  274. inst->seqParameterSet.picHeightInMapUnitsMinus1 = height / 16 - 1;
  275. /* Set cropping parameters if required */
  276. if( pEncCfg->width%16 || pEncCfg->height%16 )
  277. {
  278. inst->seqParameterSet.frameCropping = ENCHW_YES;
  279. inst->seqParameterSet.frameCropRightOffset = (width - pEncCfg->width) / 2 ;
  280. inst->seqParameterSet.frameCropBottomOffset = (height - pEncCfg->height) / 2;
  281. }
  282. /* Level 1b is indicated with levelIdc == 11 and constraintSet3 */
  283. if(pEncCfg->level == H264ENC_LEVEL_1_b)
  284. {
  285. inst->seqParameterSet.levelIdc = 11;
  286. inst->seqParameterSet.constraintSet3 = ENCHW_YES;
  287. }
  288. /* Get the index for the table of level maximum values */
  289. tmp = H264GetLevelIndex(inst->seqParameterSet.levelIdc);
  290. if(tmp == INVALID_LEVEL)
  291. return ENCHW_NOK;
  292. inst->seqParameterSet.levelIdx = tmp;
  293. #if 1 /* enforce maximum frame size in level */
  294. if(inst->mbPerFrame > H264MaxFS[inst->seqParameterSet.levelIdx])
  295. {
  296. return ENCHW_NOK;
  297. }
  298. #endif
  299. #if 0 /* enforce macroblock rate limit in level */
  300. {
  301. u32 mb_rate =
  302. (pEncCfg->frameRateNum * inst->mbPerFrame) /
  303. pEncCfg->frameRateDenom;
  304. if(mb_rate > H264MaxMBPS[inst->seqParameterSet.levelIdx])
  305. {
  306. return ENCHW_NOK;
  307. }
  308. }
  309. #endif
  310. /* Picture parameter set */
  311. inst->picParameterSet.picInitQpMinus26 = (i32) H264ENC_DEFAULT_QP - 26;
  312. /* Rate control setup */
  313. /* Maximum bitrate for the specified level */
  314. bps = H264MaxBR[inst->seqParameterSet.levelIdx];
  315. {
  316. h264RateControl_s *rc = &inst->rateControl;
  317. rc->outRateDenom = pEncCfg->frameRateDenom;
  318. rc->outRateNum = pEncCfg->frameRateNum;
  319. rc->mbPerPic = (width / 16) * (height / 16);
  320. rc->mbRows = height / 16;
  321. {
  322. h264VirtualBuffer_s *vb = &rc->virtualBuffer;
  323. vb->bitRate = bps;
  324. vb->unitsInTic = pEncCfg->frameRateDenom;
  325. vb->timeScale = pEncCfg->frameRateNum;
  326. vb->bufferSize = H264MaxCPBS[inst->seqParameterSet.levelIdx];
  327. }
  328. rc->hrd = ENCHW_YES;
  329. rc->picRc = ENCHW_YES;
  330. rc->mbRc = ENCHW_YES;
  331. rc->picSkip = ENCHW_NO;
  332. rc->qpHdr = H264ENC_DEFAULT_QP;
  333. rc->qpMin = 10;
  334. rc->qpMax = 51;
  335. rc->frameCoded = ENCHW_YES;
  336. rc->sliceTypeCur = ISLICE;
  337. rc->sliceTypePrev = PSLICE;
  338. rc->gopLen = 150;
  339. /* Default initial value for intra QP delta */
  340. rc->intraQpDelta = -3;
  341. rc->fixedIntraQp = 0;
  342. }
  343. /* no SEI by default */
  344. inst->rateControl.sei.enabled = ENCHW_NO;
  345. /* Pre processing */
  346. inst->preProcess.lumWidth = pEncCfg->width;
  347. inst->preProcess.lumWidthSrc =
  348. H264GetAllowedWidth(pEncCfg->width, H264ENC_YUV420_PLANAR);
  349. inst->preProcess.lumHeight = pEncCfg->height;
  350. inst->preProcess.lumHeightSrc = pEncCfg->height;
  351. inst->preProcess.horOffsetSrc = 0;
  352. inst->preProcess.verOffsetSrc = 0;
  353. inst->preProcess.rotation = ROTATE_0;
  354. inst->preProcess.inputFormat = H264ENC_YUV420_PLANAR;
  355. inst->preProcess.videoStab = 0;
  356. inst->preProcess.colorConversionType = 0;
  357. EncSetColorConversion(&inst->preProcess, &inst->asic);
  358. return ENCHW_OK;
  359. }
  360. /*------------------------------------------------------------------------------
  361. CheckParameter
  362. ------------------------------------------------------------------------------*/
  363. bool_e CheckParameter(const h264Instance_s * inst)
  364. {
  365. /* Check crop */
  366. if(EncPreProcessCheck(&inst->preProcess) != ENCHW_OK)
  367. {
  368. return ENCHW_NOK;
  369. }
  370. return ENCHW_OK;
  371. }
  372. /*------------------------------------------------------------------------------
  373. Round the width to the next multiple of 8 or 16 depending on YUV type.
  374. ------------------------------------------------------------------------------*/
  375. i32 H264GetAllowedWidth(i32 width, H264EncPictureType inputType)
  376. {
  377. if(inputType == H264ENC_YUV420_PLANAR)
  378. {
  379. /* Width must be multiple of 16 to make
  380. * chrominance row 64-bit aligned */
  381. return ((width + 15) / 16) * 16;
  382. }
  383. else
  384. { /* H264ENC_YUV420_SEMIPLANAR */
  385. /* H264ENC_YUV422_INTERLEAVED_YUYV */
  386. /* H264ENC_YUV422_INTERLEAVED_UYVY */
  387. return ((width + 7) / 8) * 8;
  388. }
  389. }