H264EncApi.c 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843
  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 : H264 Encoder API
  17. --
  18. ------------------------------------------------------------------------------*/
  19. /*------------------------------------------------------------------------------
  20. Version Information
  21. ------------------------------------------------------------------------------*/
  22. #define H264ENC_MAJOR_VERSION 1
  23. #define H264ENC_MINOR_VERSION 3
  24. #define H264ENC_BUILD_MAJOR 1
  25. #define H264ENC_BUILD_MINOR 14
  26. #define H264ENC_BUILD_REVISION 0
  27. #define H264ENC_SW_BUILD ((H264ENC_BUILD_MAJOR * 1000000) + \
  28. (H264ENC_BUILD_MINOR * 1000) + H264ENC_BUILD_REVISION)
  29. /*------------------------------------------------------------------------------
  30. 1. Include headers
  31. ------------------------------------------------------------------------------*/
  32. #include "h264encapi.h"
  33. #include "enccommon.h"
  34. #include "H264Instance.h"
  35. #include "H264Init.h"
  36. #include "H264PutBits.h"
  37. #include "H264CodeFrame.h"
  38. #include "H264Sei.h"
  39. #include "H264RateControl.h"
  40. #include "H264Cabac.h"
  41. #ifdef INTERNAL_TEST
  42. #include "H264TestId.h"
  43. #endif
  44. #ifdef VIDEOSTAB_ENABLED
  45. #include "vidstabcommon.h"
  46. #endif
  47. /*------------------------------------------------------------------------------
  48. 2. External compiler flags
  49. --------------------------------------------------------------------------------
  50. #define EVALUATION_LIMIT 300 max number of frames to encode
  51. --------------------------------------------------------------------------------
  52. 3. Module defines
  53. ------------------------------------------------------------------------------*/
  54. /* Parameter limits */
  55. #define H264ENCSTRMSTART_MIN_BUF 64
  56. #define H264ENCSTRMENCODE_MIN_BUF 4096
  57. #define H264ENC_MAX_PP_INPUT_WIDTH 8176
  58. #define H264ENC_MAX_PP_INPUT_HEIGHT 8176
  59. #define H264ENC_MAX_BITRATE (50000*1200) /* Level 4.1 limit */
  60. #define H264ENC_MAX_USER_DATA_SIZE 2048
  61. #define H264ENC_IDR_ID_MODULO 16
  62. #define H264_BUS_ADDRESS_VALID(bus_address) (((bus_address) != 0) && \
  63. ((bus_address & 0x07) == 0))
  64. /* HW ID check. H264EncInit() will fail if HW doesn't match. */
  65. #define HW_ID_MASK 0xFFFF0000
  66. #define HW_ID 0x82900000
  67. /* Tracing macro */
  68. #ifdef H264ENC_TRACE
  69. #define APITRACE(str) H264EncTrace(str)
  70. #else
  71. #define APITRACE(str)
  72. #endif
  73. /*------------------------------------------------------------------------------
  74. 4. Local function prototypes
  75. ------------------------------------------------------------------------------*/
  76. static void H264AddNaluSize(H264EncOut * pEncOut, u32 naluSizeBytes);
  77. static i32 VSCheckSize(u32 inputWidth, u32 inputHeight, u32 stabilizedWidth,
  78. u32 stabilizedHeight);
  79. static void H264PrefixNal(h264Instance_s *pEncInst);
  80. /*------------------------------------------------------------------------------
  81. Function name : H264EncGetApiVersion
  82. Description : Return the API version info
  83. Return type : H264EncApiVersion
  84. Argument : void
  85. ------------------------------------------------------------------------------*/
  86. H264EncApiVersion H264EncGetApiVersion(void)
  87. {
  88. H264EncApiVersion ver;
  89. ver.major = H264ENC_MAJOR_VERSION;
  90. ver.minor = H264ENC_MINOR_VERSION;
  91. APITRACE("H264EncGetApiVersion# OK");
  92. return ver;
  93. }
  94. /*------------------------------------------------------------------------------
  95. Function name : H264EncGetBuild
  96. Description : Return the SW and HW build information
  97. Return type : H264EncBuild
  98. Argument : void
  99. ------------------------------------------------------------------------------*/
  100. H264EncBuild H264EncGetBuild(void)
  101. {
  102. H264EncBuild ver;
  103. ver.swBuild = H264ENC_SW_BUILD;
  104. ver.hwBuild = EWLReadAsicID();
  105. APITRACE("H264EncGetBuild# OK");
  106. return (ver);
  107. }
  108. /*------------------------------------------------------------------------------
  109. Function name : H264EncInit
  110. Description : Initialize an encoder instance and returns it to application
  111. Return type : H264EncRet
  112. Argument : pEncCfg - initialization parameters
  113. instAddr - where to save the created instance
  114. ------------------------------------------------------------------------------*/
  115. H264EncRet H264EncInit(const H264EncConfig * pEncCfg, H264EncInst * instAddr)
  116. {
  117. H264EncRet ret;
  118. h264Instance_s *pEncInst = NULL;
  119. APITRACE("H264EncInit#");
  120. /* check that right shift on negative numbers is performed signed */
  121. /*lint -save -e* following check causes multiple lint messages */
  122. #if (((-1) >> 1) != (-1))
  123. #error Right bit-shifting (>>) does not preserve the sign
  124. #endif
  125. /*lint -restore */
  126. /* Check for illegal inputs */
  127. if(pEncCfg == NULL || instAddr == NULL)
  128. {
  129. APITRACE("H264EncInit: ERROR Null argument");
  130. return H264ENC_NULL_ARGUMENT;
  131. }
  132. /* Check for correct HW */
  133. if ((EWLReadAsicID() & HW_ID_MASK) != HW_ID)
  134. {
  135. APITRACE("H264EncInit: ERROR Invalid HW ID");
  136. return H264ENC_ERROR;
  137. }
  138. /* Check that configuration is valid */
  139. if(H264CheckCfg(pEncCfg) == ENCHW_NOK)
  140. {
  141. APITRACE("H264EncInit: ERROR Invalid configuration");
  142. return H264ENC_INVALID_ARGUMENT;
  143. }
  144. /* Initialize encoder instance and allocate memories */
  145. ret = H264Init(pEncCfg, &pEncInst);
  146. if(ret != H264ENC_OK)
  147. {
  148. APITRACE("H264EncInit: ERROR Initialization failed");
  149. return ret;
  150. }
  151. /* Status == INIT Initialization succesful */
  152. pEncInst->encStatus = H264ENCSTAT_INIT;
  153. pEncInst->inst = pEncInst; /* used as checksum */
  154. *instAddr = (H264EncInst) pEncInst;
  155. APITRACE("H264EncInit: OK");
  156. return H264ENC_OK;
  157. }
  158. /*------------------------------------------------------------------------------
  159. Function name : H264EncRelease
  160. Description : Releases encoder instance and all associated resource
  161. Return type : H264EncRet
  162. Argument : inst - the instance to be released
  163. ------------------------------------------------------------------------------*/
  164. H264EncRet H264EncRelease(H264EncInst inst)
  165. {
  166. h264Instance_s *pEncInst = (h264Instance_s *) inst;
  167. APITRACE("H264EncRelease#");
  168. /* Check for illegal inputs */
  169. if(pEncInst == NULL)
  170. {
  171. APITRACE("H264EncRelease: ERROR Null argument");
  172. return H264ENC_NULL_ARGUMENT;
  173. }
  174. /* Check for existing instance */
  175. if(pEncInst->inst != pEncInst)
  176. {
  177. APITRACE("H264EncRelease: ERROR Invalid instance");
  178. return H264ENC_INSTANCE_ERROR;
  179. }
  180. #ifdef TRACE_STREAM
  181. EncCloseStreamTrace();
  182. #endif
  183. H264Shutdown(pEncInst);
  184. APITRACE("H264EncRelease: OK");
  185. return H264ENC_OK;
  186. }
  187. /*------------------------------------------------------------------------------
  188. Function name : H264EncSetCodingCtrl
  189. Description : Sets encoding parameters
  190. Return type : H264EncRet
  191. Argument : inst - the instance in use
  192. pCodeParams - user provided parameters
  193. ------------------------------------------------------------------------------*/
  194. H264EncRet H264EncSetCodingCtrl(H264EncInst inst,
  195. const H264EncCodingCtrl * pCodeParams)
  196. {
  197. h264Instance_s *pEncInst = (h264Instance_s *) inst;
  198. regValues_s *regs = &pEncInst->asic.regs;
  199. APITRACE("H264EncSetCodingCtrl#");
  200. /* Check for illegal inputs */
  201. if((pEncInst == NULL) || (pCodeParams == NULL))
  202. {
  203. APITRACE("H264EncSetCodingCtrl: ERROR Null argument");
  204. return H264ENC_NULL_ARGUMENT;
  205. }
  206. /* Check for existing instance */
  207. if(pEncInst->inst != pEncInst)
  208. {
  209. APITRACE("H264EncSetCodingCtrl: ERROR Invalid instance");
  210. return H264ENC_INSTANCE_ERROR;
  211. }
  212. /* Check for invalid values */
  213. if(pCodeParams->sliceSize > pEncInst->mbPerCol)
  214. {
  215. APITRACE("H264EncSetCodingCtrl: ERROR Invalid sliceSize");
  216. return H264ENC_INVALID_ARGUMENT;
  217. }
  218. if(pCodeParams->cirStart > pEncInst->mbPerFrame ||
  219. pCodeParams->cirInterval > pEncInst->mbPerFrame)
  220. {
  221. APITRACE("H264EncSetCodingCtrl: ERROR Invalid CIR value");
  222. return H264ENC_INVALID_ARGUMENT;
  223. }
  224. if(pCodeParams->intraArea.enable) {
  225. if(!(pCodeParams->intraArea.top <= pCodeParams->intraArea.bottom &&
  226. pCodeParams->intraArea.bottom < pEncInst->mbPerCol &&
  227. pCodeParams->intraArea.left <= pCodeParams->intraArea.right &&
  228. pCodeParams->intraArea.right < pEncInst->mbPerRow))
  229. {
  230. APITRACE("H264EncSetCodingCtrl: ERROR Invalid intraArea");
  231. return H264ENC_INVALID_ARGUMENT;
  232. }
  233. }
  234. if(pCodeParams->roi1Area.enable) {
  235. if(!(pCodeParams->roi1Area.top <= pCodeParams->roi1Area.bottom &&
  236. pCodeParams->roi1Area.bottom < pEncInst->mbPerCol &&
  237. pCodeParams->roi1Area.left <= pCodeParams->roi1Area.right &&
  238. pCodeParams->roi1Area.right < pEncInst->mbPerRow))
  239. {
  240. APITRACE("H264EncSetCodingCtrl: ERROR Invalid roi1Area");
  241. return H264ENC_INVALID_ARGUMENT;
  242. }
  243. }
  244. if(pCodeParams->roi2Area.enable) {
  245. if(!(pCodeParams->roi2Area.top <= pCodeParams->roi2Area.bottom &&
  246. pCodeParams->roi2Area.bottom < pEncInst->mbPerCol &&
  247. pCodeParams->roi2Area.left <= pCodeParams->roi2Area.right &&
  248. pCodeParams->roi2Area.right < pEncInst->mbPerRow))
  249. {
  250. APITRACE("H264EncSetCodingCtrl: ERROR Invalid roi2Area");
  251. return H264ENC_INVALID_ARGUMENT;
  252. }
  253. }
  254. if(pCodeParams->roi1DeltaQp < -15 ||
  255. pCodeParams->roi1DeltaQp > 0 ||
  256. pCodeParams->roi2DeltaQp < -15 ||
  257. pCodeParams->roi2DeltaQp > 0)
  258. {
  259. APITRACE("H264EncSetCodingCtrl: ERROR Invalid ROI delta QP");
  260. return H264ENC_INVALID_ARGUMENT;
  261. }
  262. /* Check status, only slice size, CIR & ROI allowed to change after start */
  263. if(pEncInst->encStatus != H264ENCSTAT_INIT)
  264. {
  265. goto set_slice_size;
  266. }
  267. if(pCodeParams->constrainedIntraPrediction > 1 ||
  268. pCodeParams->disableDeblockingFilter > 2 ||
  269. pCodeParams->enableCabac > 2 ||
  270. pCodeParams->transform8x8Mode > 2 ||
  271. pCodeParams->quarterPixelMv > 2 ||
  272. pCodeParams->seiMessages > 1 || pCodeParams->videoFullRange > 1)
  273. {
  274. APITRACE("H264EncSetCodingCtrl: ERROR Invalid enable/disable");
  275. return H264ENC_INVALID_ARGUMENT;
  276. }
  277. if(pCodeParams->sampleAspectRatioWidth > 65535 ||
  278. pCodeParams->sampleAspectRatioHeight > 65535)
  279. {
  280. APITRACE("H264EncSetCodingCtrl: ERROR Invalid sampleAspectRatio");
  281. return H264ENC_INVALID_ARGUMENT;
  282. }
  283. if(pCodeParams->cabacInitIdc > 2)
  284. {
  285. APITRACE("H264EncSetCodingCtrl: ERROR Invalid cabacInitIdc");
  286. return H264ENC_INVALID_ARGUMENT;
  287. }
  288. /* Configure the values */
  289. if(pCodeParams->constrainedIntraPrediction == 0)
  290. pEncInst->picParameterSet.constIntraPred = ENCHW_NO;
  291. else
  292. pEncInst->picParameterSet.constIntraPred = ENCHW_YES;
  293. /* filter control header always present */
  294. pEncInst->picParameterSet.deblockingFilterControlPresent = ENCHW_YES;
  295. pEncInst->slice.disableDeblocking = pCodeParams->disableDeblockingFilter;
  296. pEncInst->picParameterSet.enableCabac = pCodeParams->enableCabac;
  297. pEncInst->slice.cabacInitIdc = pCodeParams->cabacInitIdc;
  298. if((pCodeParams->enableCabac == 0) || (pCodeParams->enableCabac == 2))
  299. pEncInst->picParameterSet.entropyCodingMode = ENCHW_NO;
  300. else
  301. pEncInst->picParameterSet.entropyCodingMode = ENCHW_YES;
  302. /* 8x8 mode: 2=enable, 1=adaptive (720p or bigger frame) */
  303. if ((pCodeParams->transform8x8Mode == 2) ||
  304. ((pCodeParams->transform8x8Mode == 1) &&
  305. (pEncInst->mbPerFrame >= 3600)))
  306. {
  307. pEncInst->picParameterSet.transform8x8Mode = ENCHW_YES;
  308. }
  309. H264SpsSetVuiAspectRatio(&pEncInst->seqParameterSet,
  310. pCodeParams->sampleAspectRatioWidth,
  311. pCodeParams->sampleAspectRatioHeight);
  312. H264SpsSetVuiVideoInfo(&pEncInst->seqParameterSet,
  313. pCodeParams->videoFullRange);
  314. /* SEI messages are written in the beginning of each frame */
  315. if(pCodeParams->seiMessages)
  316. pEncInst->rateControl.sei.enabled = ENCHW_YES;
  317. else
  318. pEncInst->rateControl.sei.enabled = ENCHW_NO;
  319. set_slice_size:
  320. /* Slice size is set in macroblock rows => convert to macroblocks */
  321. pEncInst->slice.sliceSize = pCodeParams->sliceSize * pEncInst->mbPerRow;
  322. pEncInst->slice.quarterPixelMv = pCodeParams->quarterPixelMv;
  323. /* Set CIR, intra forcing and ROI parameters */
  324. regs->cirStart = pCodeParams->cirStart;
  325. regs->cirInterval = pCodeParams->cirInterval;
  326. regs->intraSliceMap1 = pCodeParams->intraSliceMap1;
  327. regs->intraSliceMap2 = pCodeParams->intraSliceMap2;
  328. regs->intraSliceMap3 = pCodeParams->intraSliceMap3;
  329. if (pCodeParams->intraArea.enable) {
  330. regs->intraAreaTop = pCodeParams->intraArea.top;
  331. regs->intraAreaLeft = pCodeParams->intraArea.left;
  332. regs->intraAreaBottom = pCodeParams->intraArea.bottom;
  333. regs->intraAreaRight = pCodeParams->intraArea.right;
  334. }
  335. if (pCodeParams->roi1Area.enable) {
  336. regs->roi1Top = pCodeParams->roi1Area.top;
  337. regs->roi1Left = pCodeParams->roi1Area.left;
  338. regs->roi1Bottom = pCodeParams->roi1Area.bottom;
  339. regs->roi1Right = pCodeParams->roi1Area.right;
  340. }
  341. if (pCodeParams->roi2Area.enable) {
  342. regs->roi2Top = pCodeParams->roi2Area.top;
  343. regs->roi2Left = pCodeParams->roi2Area.left;
  344. regs->roi2Bottom = pCodeParams->roi2Area.bottom;
  345. regs->roi2Right = pCodeParams->roi2Area.right;
  346. }
  347. regs->roi1DeltaQp = -pCodeParams->roi1DeltaQp;
  348. regs->roi2DeltaQp = -pCodeParams->roi2DeltaQp;
  349. APITRACE("H264EncSetCodingCtrl: OK");
  350. return H264ENC_OK;
  351. }
  352. /*------------------------------------------------------------------------------
  353. Function name : H264EncGetCodingCtrl
  354. Description : Returns current encoding parameters
  355. Return type : H264EncRet
  356. Argument : inst - the instance in use
  357. pCodeParams - palce where parameters are returned
  358. ------------------------------------------------------------------------------*/
  359. H264EncRet H264EncGetCodingCtrl(H264EncInst inst,
  360. H264EncCodingCtrl * pCodeParams)
  361. {
  362. h264Instance_s *pEncInst = (h264Instance_s *) inst;
  363. regValues_s *regs = &pEncInst->asic.regs;
  364. APITRACE("H264EncGetCodingCtrl#");
  365. /* Check for illegal inputs */
  366. if((pEncInst == NULL) || (pCodeParams == NULL))
  367. {
  368. APITRACE("H264EncGetCodingCtrl: ERROR Null argument");
  369. return H264ENC_NULL_ARGUMENT;
  370. }
  371. /* Check for existing instance */
  372. if(pEncInst->inst != pEncInst)
  373. {
  374. APITRACE("H264EncGetCodingCtrl: ERROR Invalid instance");
  375. return H264ENC_INSTANCE_ERROR;
  376. }
  377. /* Get values */
  378. pCodeParams->constrainedIntraPrediction =
  379. (pEncInst->picParameterSet.constIntraPred == ENCHW_NO) ? 0 : 1;
  380. /* Slice size from macroblocks to macroblock rows */
  381. pCodeParams->sliceSize = pEncInst->slice.sliceSize / pEncInst->mbPerRow;
  382. pCodeParams->seiMessages =
  383. (pEncInst->rateControl.sei.enabled == ENCHW_YES) ? 1 : 0;
  384. pCodeParams->videoFullRange =
  385. (pEncInst->seqParameterSet.vui.videoFullRange == ENCHW_YES) ? 1 : 0;
  386. pCodeParams->sampleAspectRatioWidth =
  387. pEncInst->seqParameterSet.vui.sarWidth;
  388. pCodeParams->sampleAspectRatioHeight =
  389. pEncInst->seqParameterSet.vui.sarHeight;
  390. pCodeParams->disableDeblockingFilter = pEncInst->slice.disableDeblocking;
  391. pCodeParams->enableCabac = pEncInst->picParameterSet.enableCabac;
  392. pCodeParams->cabacInitIdc = pEncInst->slice.cabacInitIdc;
  393. pCodeParams->transform8x8Mode = pEncInst->picParameterSet.transform8x8Mode;
  394. pCodeParams->quarterPixelMv = pEncInst->slice.quarterPixelMv;
  395. pCodeParams->cirStart = regs->cirStart;
  396. pCodeParams->cirInterval = regs->cirInterval;
  397. pCodeParams->intraSliceMap1 = regs->intraSliceMap1;
  398. pCodeParams->intraSliceMap2 = regs->intraSliceMap2;
  399. pCodeParams->intraSliceMap3 = regs->intraSliceMap3;
  400. pCodeParams->intraArea.enable = regs->intraAreaTop < pEncInst->mbPerCol ? 1 : 0;
  401. pCodeParams->intraArea.top = regs->intraAreaTop;
  402. pCodeParams->intraArea.left = regs->intraAreaLeft;
  403. pCodeParams->intraArea.bottom = regs->intraAreaBottom;
  404. pCodeParams->intraArea.right = regs->intraAreaRight;
  405. pCodeParams->roi1Area.enable = regs->roi1Top < pEncInst->mbPerCol ? 1 : 0;
  406. pCodeParams->roi1Area.top = regs->roi1Top;
  407. pCodeParams->roi1Area.left = regs->roi1Left;
  408. pCodeParams->roi1Area.bottom = regs->roi1Bottom;
  409. pCodeParams->roi1Area.right = regs->roi1Right;
  410. pCodeParams->roi2Area.enable = regs->roi2Top < pEncInst->mbPerCol ? 1 : 0;
  411. pCodeParams->roi2Area.top = regs->roi2Top;
  412. pCodeParams->roi2Area.left = regs->roi2Left;
  413. pCodeParams->roi2Area.bottom = regs->roi2Bottom;
  414. pCodeParams->roi2Area.right = regs->roi2Right;
  415. pCodeParams->roi1DeltaQp = -regs->roi1DeltaQp;
  416. pCodeParams->roi2DeltaQp = -regs->roi2DeltaQp;
  417. APITRACE("H264EncGetCodingCtrl: OK");
  418. return H264ENC_OK;
  419. }
  420. /*------------------------------------------------------------------------------
  421. Function name : H264EncSetRateCtrl
  422. Description : Sets rate control parameters
  423. Return type : H264EncRet
  424. Argument : inst - the instance in use
  425. pRateCtrl - user provided parameters
  426. ------------------------------------------------------------------------------*/
  427. H264EncRet H264EncSetRateCtrl(H264EncInst inst,
  428. const H264EncRateCtrl * pRateCtrl)
  429. {
  430. h264Instance_s *pEncInst = (h264Instance_s *) inst;
  431. h264RateControl_s *rc;
  432. u32 i, tmp;
  433. APITRACE("H264EncSetRateCtrl#");
  434. /* Check for illegal inputs */
  435. if((pEncInst == NULL) || (pRateCtrl == NULL))
  436. {
  437. APITRACE("H264EncSetRateCtrl: ERROR Null argument");
  438. return H264ENC_NULL_ARGUMENT;
  439. }
  440. /* Check for existing instance */
  441. if(pEncInst->inst != pEncInst)
  442. {
  443. APITRACE("H264EncSetRateCtrl: ERROR Invalid instance");
  444. return H264ENC_INSTANCE_ERROR;
  445. }
  446. rc = &pEncInst->rateControl;
  447. /* after stream was started with HRD ON,
  448. * it is not allowed to change RC params */
  449. if(pEncInst->encStatus == H264ENCSTAT_START_FRAME && rc->hrd == ENCHW_YES)
  450. {
  451. APITRACE
  452. ("H264EncSetRateCtrl: ERROR Stream started with HRD ON. Not allowed to change any parameters");
  453. return H264ENC_INVALID_STATUS;
  454. }
  455. /* Check for invalid input values */
  456. if(pRateCtrl->pictureRc > 1 ||
  457. pRateCtrl->mbRc > 1 || pRateCtrl->pictureSkip > 1 || pRateCtrl->hrd > 1)
  458. {
  459. APITRACE("H264EncSetRateCtrl: ERROR Invalid enable/disable value");
  460. return H264ENC_INVALID_ARGUMENT;
  461. }
  462. if(pRateCtrl->qpHdr > 51 ||
  463. pRateCtrl->qpMin > 51 ||
  464. pRateCtrl->qpMax > 51 ||
  465. pRateCtrl->qpMax < pRateCtrl->qpMin)
  466. {
  467. APITRACE("H264EncSetRateCtrl: ERROR Invalid QP");
  468. return H264ENC_INVALID_ARGUMENT;
  469. }
  470. if((pRateCtrl->qpHdr != -1) &&
  471. (pRateCtrl->qpHdr < (i32)pRateCtrl->qpMin ||
  472. pRateCtrl->qpHdr > (i32)pRateCtrl->qpMax))
  473. {
  474. APITRACE("H264EncSetRateCtrl: ERROR QP out of range");
  475. return H264ENC_INVALID_ARGUMENT;
  476. }
  477. if((u32)(pRateCtrl->intraQpDelta + 12) > 24)
  478. {
  479. APITRACE("H264EncSetRateCtrl: ERROR intraQpDelta out of range");
  480. return H264ENC_INVALID_ARGUMENT;
  481. }
  482. if(pRateCtrl->fixedIntraQp > 51)
  483. {
  484. APITRACE("H264EncSetRateCtrl: ERROR fixedIntraQp out of range");
  485. return H264ENC_INVALID_ARGUMENT;
  486. }
  487. if(pRateCtrl->gopLen < 1 || pRateCtrl->gopLen > 300)
  488. {
  489. APITRACE("H264EncSetRateCtrl: ERROR Invalid GOP length");
  490. return H264ENC_INVALID_ARGUMENT;
  491. }
  492. /* Bitrate affects only when rate control is enabled */
  493. if((pRateCtrl->pictureRc || pRateCtrl->mbRc ||
  494. pRateCtrl->pictureSkip || pRateCtrl->hrd) &&
  495. (pRateCtrl->bitPerSecond < 10000 ||
  496. pRateCtrl->bitPerSecond > H264ENC_MAX_BITRATE))
  497. {
  498. APITRACE("H264EncSetRateCtrl: ERROR Invalid bitPerSecond");
  499. return H264ENC_INVALID_ARGUMENT;
  500. }
  501. {
  502. u32 cpbSize = pRateCtrl->hrdCpbSize;
  503. u32 bps = pRateCtrl->bitPerSecond;
  504. u32 level = pEncInst->seqParameterSet.levelIdx;
  505. /* Limit maximum bitrate based on resolution and frame rate */
  506. /* Saturates really high settings */
  507. /* bits per unpacked frame */
  508. tmp = 3 * 8 * pEncInst->mbPerFrame * 256 / 2;
  509. /* bits per second */
  510. tmp = H264Calculate(tmp, rc->outRateNum, rc->outRateDenom);
  511. if (bps > (tmp / 2))
  512. bps = tmp / 2;
  513. if(cpbSize == 0)
  514. cpbSize = H264MaxCPBS[level];
  515. else if(cpbSize == (u32) (-1))
  516. cpbSize = bps;
  517. /* Limit minimum CPB size based on average bits per frame */
  518. tmp = H264Calculate(bps, rc->outRateDenom, rc->outRateNum);
  519. cpbSize = MAX(cpbSize, tmp);
  520. /* cpbSize must be rounded so it is exactly the size written in stream */
  521. i = 0;
  522. tmp = cpbSize;
  523. while (4095 < (tmp >> (4 + i++)));
  524. cpbSize = (tmp >> (4 + i)) << (4 + i);
  525. /* if HRD is ON we have to obay all its limits */
  526. if(pRateCtrl->hrd != 0)
  527. {
  528. if(cpbSize > H264MaxCPBS[level])
  529. {
  530. APITRACE
  531. ("H264EncSetRateCtrl: ERROR. HRD is ON. hrdCpbSize higher than maximum allowed for stream level");
  532. return H264ENC_INVALID_ARGUMENT;
  533. }
  534. if(bps > H264MaxBR[level])
  535. {
  536. APITRACE
  537. ("H264EncSetRateCtrl: ERROR. HRD is ON. bitPerSecond higher than maximum allowed for stream level");
  538. return H264ENC_INVALID_ARGUMENT;
  539. }
  540. }
  541. rc->virtualBuffer.bufferSize = cpbSize;
  542. /* Set the parameters to rate control */
  543. if(pRateCtrl->pictureRc != 0)
  544. rc->picRc = ENCHW_YES;
  545. else
  546. rc->picRc = ENCHW_NO;
  547. if(pRateCtrl->mbRc != 0)
  548. rc->mbRc = ENCHW_YES;
  549. else
  550. rc->mbRc = ENCHW_NO;
  551. if(pRateCtrl->pictureSkip != 0)
  552. rc->picSkip = ENCHW_YES;
  553. else
  554. rc->picSkip = ENCHW_NO;
  555. if(pRateCtrl->hrd != 0)
  556. {
  557. rc->hrd = ENCHW_YES;
  558. rc->picRc = ENCHW_YES;
  559. }
  560. else
  561. rc->hrd = ENCHW_NO;
  562. rc->qpHdr = pRateCtrl->qpHdr;
  563. rc->qpMin = pRateCtrl->qpMin;
  564. rc->qpMax = pRateCtrl->qpMax;
  565. rc->virtualBuffer.bitRate = bps;
  566. rc->gopLen = pRateCtrl->gopLen;
  567. }
  568. rc->intraQpDelta = pRateCtrl->intraQpDelta;
  569. rc->fixedIntraQp = pRateCtrl->fixedIntraQp;
  570. rc->mbQpAdjustment = pRateCtrl->mbQpAdjustment;
  571. (void) H264InitRc(rc); /* new parameters checked already */
  572. APITRACE("H264EncSetRateCtrl: OK");
  573. return H264ENC_OK;
  574. }
  575. /*------------------------------------------------------------------------------
  576. Function name : H264EncGetRateCtrl
  577. Description : Return current rate control parameters
  578. Return type : H264EncRet
  579. Argument : inst - the instance in use
  580. pRateCtrl - place where parameters are returned
  581. ------------------------------------------------------------------------------*/
  582. H264EncRet H264EncGetRateCtrl(H264EncInst inst, H264EncRateCtrl * pRateCtrl)
  583. {
  584. h264Instance_s *pEncInst = (h264Instance_s *) inst;
  585. h264RateControl_s *rc;
  586. APITRACE("H264EncGetRateCtrl#");
  587. /* Check for illegal inputs */
  588. if((pEncInst == NULL) || (pRateCtrl == NULL))
  589. {
  590. APITRACE("H264EncGetRateCtrl: ERROR Null argument");
  591. return H264ENC_NULL_ARGUMENT;
  592. }
  593. /* Check for existing instance */
  594. if(pEncInst->inst != pEncInst)
  595. {
  596. APITRACE("H264EncGetRateCtrl: ERROR Invalid instance");
  597. return H264ENC_INSTANCE_ERROR;
  598. }
  599. /* Get the values */
  600. rc = &pEncInst->rateControl;
  601. pRateCtrl->pictureRc = rc->picRc == ENCHW_NO ? 0 : 1;
  602. pRateCtrl->mbRc = rc->mbRc == ENCHW_NO ? 0 : 1;
  603. pRateCtrl->pictureSkip = rc->picSkip == ENCHW_NO ? 0 : 1;
  604. pRateCtrl->qpHdr = rc->qpHdr;
  605. pRateCtrl->qpMin = rc->qpMin;
  606. pRateCtrl->qpMax = rc->qpMax;
  607. pRateCtrl->bitPerSecond = rc->virtualBuffer.bitRate;
  608. pRateCtrl->hrd = rc->hrd == ENCHW_NO ? 0 : 1;
  609. pRateCtrl->gopLen = rc->gopLen;
  610. pRateCtrl->hrdCpbSize = (u32) rc->virtualBuffer.bufferSize;
  611. pRateCtrl->intraQpDelta = rc->intraQpDelta;
  612. pRateCtrl->fixedIntraQp = rc->fixedIntraQp;
  613. APITRACE("H264EncGetRateCtrl: OK");
  614. return H264ENC_OK;
  615. }
  616. /*------------------------------------------------------------------------------
  617. Function name : VSCheckSize
  618. Description :
  619. Return type : i32
  620. Argument : u32 inputWidth
  621. Argument : u32 inputHeight
  622. Argument : u32 stabilizedWidth
  623. Argument : u32 stabilizedHeight
  624. ------------------------------------------------------------------------------*/
  625. i32 VSCheckSize(u32 inputWidth, u32 inputHeight, u32 stabilizedWidth,
  626. u32 stabilizedHeight)
  627. {
  628. /* Input picture minimum dimensions */
  629. if((inputWidth < 104) || (inputHeight < 104))
  630. return 1;
  631. /* Stabilized picture minimum values */
  632. if((stabilizedWidth < 96) || (stabilizedHeight < 96))
  633. return 1;
  634. /* Stabilized dimensions multiple of 4 */
  635. if(((stabilizedWidth & 3) != 0) || ((stabilizedHeight & 3) != 0))
  636. return 1;
  637. /* Edge >= 4 pixels, not checked because stabilization can be
  638. * used without cropping for scene detection
  639. if((inputWidth < (stabilizedWidth + 8)) ||
  640. (inputHeight < (stabilizedHeight + 8)))
  641. return 1; */
  642. return 0;
  643. }
  644. /*------------------------------------------------------------------------------
  645. Function name : H264EncSetPreProcessing
  646. Description : Sets the preprocessing parameters
  647. Return type : H264EncRet
  648. Argument : inst - encoder instance in use
  649. Argument : pPreProcCfg - user provided parameters
  650. ------------------------------------------------------------------------------*/
  651. H264EncRet H264EncSetPreProcessing(H264EncInst inst,
  652. const H264EncPreProcessingCfg * pPreProcCfg)
  653. {
  654. h264Instance_s *pEncInst = (h264Instance_s *) inst;
  655. preProcess_s pp_tmp;
  656. APITRACE("H264EncSetPreProcessing#");
  657. /* Check for illegal inputs */
  658. if((inst == NULL) || (pPreProcCfg == NULL))
  659. {
  660. APITRACE("H264EncSetPreProcessing: ERROR Null argument");
  661. return H264ENC_NULL_ARGUMENT;
  662. }
  663. /* Check for existing instance */
  664. if(pEncInst->inst != pEncInst)
  665. {
  666. APITRACE("H264EncSetPreProcessing: ERROR Invalid instance");
  667. return H264ENC_INSTANCE_ERROR;
  668. }
  669. /* check HW limitations */
  670. {
  671. EWLHwConfig_t cfg = EWLReadAsicConfig();
  672. /* is video stabilization supported? */
  673. if(cfg.vsEnabled == EWL_HW_CONFIG_NOT_SUPPORTED &&
  674. pPreProcCfg->videoStabilization != 0)
  675. {
  676. APITRACE("H264EncSetPreProcessing: ERROR Stabilization not supported");
  677. return H264ENC_INVALID_ARGUMENT;
  678. }
  679. if(cfg.rgbEnabled == EWL_HW_CONFIG_NOT_SUPPORTED &&
  680. pPreProcCfg->inputType >= H264ENC_RGB565 &&
  681. pPreProcCfg->inputType <= H264ENC_BGR101010)
  682. {
  683. APITRACE("H264EncSetPreProcessing: ERROR RGB input not supported");
  684. return H264ENC_INVALID_ARGUMENT;
  685. }
  686. }
  687. if(pPreProcCfg->origWidth > H264ENC_MAX_PP_INPUT_WIDTH ||
  688. pPreProcCfg->origHeight > H264ENC_MAX_PP_INPUT_HEIGHT)
  689. {
  690. APITRACE("H264EncSetPreProcessing: ERROR Too big input image");
  691. return H264ENC_INVALID_ARGUMENT;
  692. }
  693. if(pPreProcCfg->inputType > H264ENC_BGR101010)
  694. {
  695. APITRACE("H264EncSetPreProcessing: ERROR Invalid YUV type");
  696. return H264ENC_INVALID_ARGUMENT;
  697. }
  698. if(pPreProcCfg->rotation > H264ENC_ROTATE_90L)
  699. {
  700. APITRACE("H264EncSetPreProcessing: ERROR Invalid rotation");
  701. return H264ENC_INVALID_ARGUMENT;
  702. }
  703. pp_tmp.lumHeightSrc = pPreProcCfg->origHeight;
  704. pp_tmp.lumWidthSrc = pPreProcCfg->origWidth;
  705. if(pPreProcCfg->videoStabilization == 0)
  706. {
  707. pp_tmp.horOffsetSrc = pPreProcCfg->xOffset;
  708. pp_tmp.verOffsetSrc = pPreProcCfg->yOffset;
  709. }
  710. else
  711. {
  712. pp_tmp.horOffsetSrc = pp_tmp.verOffsetSrc = 0;
  713. }
  714. pp_tmp.lumWidth = pEncInst->preProcess.lumWidth;
  715. pp_tmp.lumHeight = pEncInst->preProcess.lumHeight;
  716. pp_tmp.rotation = pPreProcCfg->rotation;
  717. pp_tmp.inputFormat = pPreProcCfg->inputType;
  718. pp_tmp.videoStab = (pPreProcCfg->videoStabilization != 0) ? 1 : 0;
  719. /* Check for invalid values */
  720. if(EncPreProcessCheck(&pp_tmp) != ENCHW_OK)
  721. {
  722. APITRACE("H264EncSetPreProcessing: ERROR Invalid cropping values");
  723. return H264ENC_INVALID_ARGUMENT;
  724. }
  725. /* Set cropping parameters if required */
  726. if( pEncInst->preProcess.lumWidth%16 || pEncInst->preProcess.lumHeight%16 )
  727. {
  728. u32 fillRight = (pEncInst->preProcess.lumWidth+15)/16*16 -
  729. pEncInst->preProcess.lumWidth;
  730. u32 fillBottom = (pEncInst->preProcess.lumHeight+15)/16*16 -
  731. pEncInst->preProcess.lumHeight;
  732. pEncInst->seqParameterSet.frameCropping = ENCHW_YES;
  733. pEncInst->seqParameterSet.frameCropLeftOffset = 0;
  734. pEncInst->seqParameterSet.frameCropRightOffset = 0;
  735. pEncInst->seqParameterSet.frameCropTopOffset = 0;
  736. pEncInst->seqParameterSet.frameCropBottomOffset = 0;
  737. if (pPreProcCfg->rotation == 0) { /* No rotation */
  738. pEncInst->seqParameterSet.frameCropRightOffset = fillRight/2;
  739. pEncInst->seqParameterSet.frameCropBottomOffset = fillBottom/2;
  740. } else if (pPreProcCfg->rotation == 1) { /* Rotate right */
  741. pEncInst->seqParameterSet.frameCropLeftOffset = fillRight/2;
  742. pEncInst->seqParameterSet.frameCropBottomOffset = fillBottom/2;
  743. } else { /* Rotate left */
  744. pEncInst->seqParameterSet.frameCropRightOffset = fillRight/2;
  745. pEncInst->seqParameterSet.frameCropTopOffset = fillBottom/2;
  746. }
  747. }
  748. if(pp_tmp.videoStab != 0)
  749. {
  750. u32 width = pp_tmp.lumWidth;
  751. u32 height = pp_tmp.lumHeight;
  752. if(pp_tmp.rotation)
  753. {
  754. u32 tmp;
  755. tmp = width;
  756. width = height;
  757. height = tmp;
  758. }
  759. if(VSCheckSize(pp_tmp.lumWidthSrc, pp_tmp.lumHeightSrc, width, height)
  760. != 0)
  761. {
  762. APITRACE
  763. ("H264EncSetPreProcessing: ERROR Invalid size for stabilization");
  764. return H264ENC_INVALID_ARGUMENT;
  765. }
  766. #ifdef VIDEOSTAB_ENABLED
  767. VSAlgInit(&pEncInst->vsSwData, pp_tmp.lumWidthSrc, pp_tmp.lumHeightSrc,
  768. width, height);
  769. VSAlgGetResult(&pEncInst->vsSwData, &pp_tmp.horOffsetSrc,
  770. &pp_tmp.verOffsetSrc);
  771. #endif
  772. }
  773. pp_tmp.colorConversionType = pPreProcCfg->colorConversion.type;
  774. pp_tmp.colorConversionCoeffA = pPreProcCfg->colorConversion.coeffA;
  775. pp_tmp.colorConversionCoeffB = pPreProcCfg->colorConversion.coeffB;
  776. pp_tmp.colorConversionCoeffC = pPreProcCfg->colorConversion.coeffC;
  777. pp_tmp.colorConversionCoeffE = pPreProcCfg->colorConversion.coeffE;
  778. pp_tmp.colorConversionCoeffF = pPreProcCfg->colorConversion.coeffF;
  779. EncSetColorConversion(&pp_tmp, &pEncInst->asic);
  780. {
  781. preProcess_s *pp = &pEncInst->preProcess;
  782. if(EWLmemcpy(pp, &pp_tmp, sizeof(preProcess_s)) != pp)
  783. {
  784. APITRACE("H264EncSetPreProcessing: memcpy failed");
  785. return H264ENC_SYSTEM_ERROR;
  786. }
  787. }
  788. APITRACE("H264EncSetPreProcessing: OK");
  789. return H264ENC_OK;
  790. }
  791. /*------------------------------------------------------------------------------
  792. Function name : H264EncGetPreProcessing
  793. Description : Returns current preprocessing parameters
  794. Return type : H264EncRet
  795. Argument : inst - encoder instance
  796. Argument : pPreProcCfg - place where the parameters are returned
  797. ------------------------------------------------------------------------------*/
  798. H264EncRet H264EncGetPreProcessing(H264EncInst inst,
  799. H264EncPreProcessingCfg * pPreProcCfg)
  800. {
  801. h264Instance_s *pEncInst = (h264Instance_s *) inst;
  802. preProcess_s *pPP;
  803. APITRACE("H264EncGetPreProcessing#");
  804. /* Check for illegal inputs */
  805. if((inst == NULL) || (pPreProcCfg == NULL))
  806. {
  807. APITRACE("H264EncGetPreProcessing: ERROR Null argument");
  808. return H264ENC_NULL_ARGUMENT;
  809. }
  810. /* Check for existing instance */
  811. if(pEncInst->inst != pEncInst)
  812. {
  813. APITRACE("H264EncGetPreProcessing: ERROR Invalid instance");
  814. return H264ENC_INSTANCE_ERROR;
  815. }
  816. pPP = &pEncInst->preProcess;
  817. pPreProcCfg->origHeight = pPP->lumHeightSrc;
  818. pPreProcCfg->origWidth = pPP->lumWidthSrc;
  819. pPreProcCfg->xOffset = pPP->horOffsetSrc;
  820. pPreProcCfg->yOffset = pPP->verOffsetSrc;
  821. pPreProcCfg->rotation = (H264EncPictureRotation) pPP->rotation;
  822. pPreProcCfg->inputType = (H264EncPictureType) pPP->inputFormat;
  823. pPreProcCfg->videoStabilization = pPP->videoStab;
  824. pPreProcCfg->colorConversion.type =
  825. (H264EncColorConversionType) pPP->colorConversionType;
  826. pPreProcCfg->colorConversion.coeffA = pPP->colorConversionCoeffA;
  827. pPreProcCfg->colorConversion.coeffB = pPP->colorConversionCoeffB;
  828. pPreProcCfg->colorConversion.coeffC = pPP->colorConversionCoeffC;
  829. pPreProcCfg->colorConversion.coeffE = pPP->colorConversionCoeffE;
  830. pPreProcCfg->colorConversion.coeffF = pPP->colorConversionCoeffF;
  831. APITRACE("H264EncGetPreProcessing: OK");
  832. return H264ENC_OK;
  833. }
  834. /*------------------------------------------------------------------------------
  835. Function name : H264EncSetSeiUserData
  836. Description : Sets user data SEI messages
  837. Return type : H264EncRet
  838. Argument : inst - the instance in use
  839. pUserData - pointer to userData, this is used by the
  840. encoder so it must not be released before
  841. disabling user data
  842. userDataSize - size of userData, minimum size 16,
  843. maximum size H264ENC_MAX_USER_DATA_SIZE
  844. not valid size disables userData sei messages
  845. ------------------------------------------------------------------------------*/
  846. H264EncRet H264EncSetSeiUserData(H264EncInst inst, const u8 * pUserData,
  847. u32 userDataSize)
  848. {
  849. h264Instance_s *pEncInst = (h264Instance_s *) inst;
  850. /* Check for illegal inputs */
  851. if((pEncInst == NULL) || (userDataSize != 0 && pUserData == NULL))
  852. {
  853. APITRACE("H264EncSetSeiUserData: ERROR Null argument");
  854. return H264ENC_NULL_ARGUMENT;
  855. }
  856. /* Check for existing instance */
  857. if(pEncInst->inst != pEncInst)
  858. {
  859. APITRACE("H264EncSetSeiUserData: ERROR Invalid instance");
  860. return H264ENC_INSTANCE_ERROR;
  861. }
  862. /* Disable user data */
  863. if((userDataSize < 16) || (userDataSize > H264ENC_MAX_USER_DATA_SIZE))
  864. {
  865. pEncInst->rateControl.sei.userDataEnabled = ENCHW_NO;
  866. pEncInst->rateControl.sei.pUserData = NULL;
  867. pEncInst->rateControl.sei.userDataSize = 0;
  868. }
  869. else
  870. {
  871. pEncInst->rateControl.sei.userDataEnabled = ENCHW_YES;
  872. pEncInst->rateControl.sei.pUserData = pUserData;
  873. pEncInst->rateControl.sei.userDataSize = userDataSize;
  874. }
  875. return H264ENC_OK;
  876. }
  877. /*------------------------------------------------------------------------------
  878. Function name : H264EncStrmStart
  879. Description : Starts a new stream
  880. Return type : H264EncRet
  881. Argument : inst - encoder instance
  882. Argument : pEncIn - user provided input parameters
  883. pEncOut - place where output info is returned
  884. ------------------------------------------------------------------------------*/
  885. H264EncRet H264EncStrmStart(H264EncInst inst, const H264EncIn * pEncIn,
  886. H264EncOut * pEncOut)
  887. {
  888. h264Instance_s *pEncInst = (h264Instance_s *) inst;
  889. h264RateControl_s *rc;
  890. u32 tmp;
  891. APITRACE("H264EncStrmStart#");
  892. /* Check for illegal inputs */
  893. if((pEncInst == NULL) || (pEncIn == NULL) || (pEncOut == NULL))
  894. {
  895. APITRACE("H264EncStrmStart: ERROR Null argument");
  896. return H264ENC_NULL_ARGUMENT;
  897. }
  898. /* Check for existing instance */
  899. if(pEncInst->inst != pEncInst)
  900. {
  901. APITRACE("H264EncStrmStart: ERROR Invalid instance");
  902. return H264ENC_INSTANCE_ERROR;
  903. }
  904. pEncOut->streamSize = 0;
  905. rc = &pEncInst->rateControl;
  906. /* Check status */
  907. if(pEncInst->encStatus != H264ENCSTAT_INIT)
  908. {
  909. APITRACE("H264EncStrmStart: ERROR Invalid status");
  910. return H264ENC_INVALID_STATUS;
  911. }
  912. /* Check for invalid input values */
  913. if((pEncIn->pOutBuf == NULL) ||
  914. (pEncIn->outBufSize < H264ENCSTRMSTART_MIN_BUF))
  915. {
  916. APITRACE("H264EncStrmStart: ERROR Invalid input. Stream buffer");
  917. return H264ENC_INVALID_ARGUMENT;
  918. }
  919. /* Set stream buffer, the size has been checked */
  920. (void) H264SetBuffer(&pEncInst->stream, (u8 *) pEncIn->pOutBuf,
  921. (u32) pEncIn->outBufSize);
  922. /* Set pointer to the beginning of NAL unit size buffer */
  923. pEncOut->pNaluSizeBuf = (u32 *) pEncInst->asic.sizeTbl.nal.virtualAddress;
  924. pEncOut->numNalus = 0;
  925. #ifdef INTERNAL_TEST
  926. /* Configure the encoder instance according to the test vector */
  927. H264ConfigureTestBeforeStream(pEncInst);
  928. #endif
  929. #ifdef TRACE_STREAM
  930. /* Open stream tracing */
  931. EncOpenStreamTrace("stream.trc");
  932. traceStream.frameNum = pEncInst->frameCnt;
  933. traceStream.id = 0; /* Stream generated by SW */
  934. traceStream.bitCnt = 0; /* New frame */
  935. #endif
  936. /* Set the profile to be used */
  937. pEncInst->seqParameterSet.profileIdc = 66; /* base profile */
  938. /* CABAC => main profile */
  939. if (pEncInst->picParameterSet.enableCabac >= 1)
  940. pEncInst->seqParameterSet.profileIdc = 77;
  941. /* 8x8 transform enabled => high profile */
  942. if (pEncInst->picParameterSet.transform8x8Mode == ENCHW_YES)
  943. pEncInst->seqParameterSet.profileIdc = 100;
  944. /* update VUI */
  945. if(rc->sei.enabled == ENCHW_YES)
  946. {
  947. H264SpsSetVuiPictStructPresentFlag(&pEncInst->seqParameterSet, 1);
  948. }
  949. if(rc->hrd == ENCHW_YES)
  950. {
  951. H264SpsSetVuiHrd(&pEncInst->seqParameterSet, 1);
  952. H264SpsSetVuiHrdBitRate(&pEncInst->seqParameterSet,
  953. rc->virtualBuffer.bitRate);
  954. H264SpsSetVuiHrdCpbSize(&pEncInst->seqParameterSet,
  955. rc->virtualBuffer.bufferSize);
  956. }
  957. /* Initialize cabac context tables for HW */
  958. if (pEncInst->picParameterSet.enableCabac >= 1)
  959. {
  960. if (H264CabacInit(pEncInst->asic.cabacCtx.virtualAddress,
  961. pEncInst->slice.cabacInitIdc) != 0)
  962. {
  963. APITRACE("H264EncStrmStart: ERROR in CABAC Context Init");
  964. return H264ENC_MEMORY_ERROR;
  965. }
  966. }
  967. /* Use the first frame QP in the PPS */
  968. pEncInst->picParameterSet.picInitQpMinus26 = (i32) (rc->qpHdr) - 26;
  969. /* Init SEI */
  970. H264InitSei(&rc->sei, pEncInst->seqParameterSet.byteStream,
  971. rc->hrd, rc->outRateNum, rc->outRateDenom);
  972. H264SeqParameterSet(&pEncInst->stream, &pEncInst->seqParameterSet, ENCHW_YES);
  973. H264AddNaluSize(pEncOut, pEncInst->stream.byteCnt);
  974. tmp = pEncInst->stream.byteCnt;
  975. /* Subset SPS for MVC */
  976. if (pEncInst->numViews > 1)
  977. {
  978. H264SubsetSeqParameterSet(&pEncInst->stream, &pEncInst->seqParameterSet);
  979. H264AddNaluSize(pEncOut, pEncInst->stream.byteCnt-tmp);
  980. tmp = pEncInst->stream.byteCnt;
  981. }
  982. H264PicParameterSet(&pEncInst->stream, &pEncInst->picParameterSet);
  983. H264AddNaluSize(pEncOut, pEncInst->stream.byteCnt-tmp);
  984. tmp = pEncInst->stream.byteCnt;
  985. /* In CABAC mode 2 we need two PPS: one with CAVLC (ppsId=0 for intra) and
  986. * one with CABAC (ppsId=1 for inter) */
  987. if (pEncInst->picParameterSet.enableCabac == 2)
  988. {
  989. pEncInst->picParameterSet.picParameterSetId = 1;
  990. pEncInst->picParameterSet.entropyCodingMode = ENCHW_YES;
  991. H264PicParameterSet(&pEncInst->stream, &pEncInst->picParameterSet);
  992. H264AddNaluSize(pEncOut, pEncInst->stream.byteCnt-tmp);
  993. tmp = pEncInst->stream.byteCnt;
  994. }
  995. if(pEncInst->stream.overflow == ENCHW_YES)
  996. {
  997. pEncOut->streamSize = 0;
  998. pEncOut->numNalus = 0;
  999. APITRACE("H264EncStrmStart: ERROR Output buffer too small");
  1000. return H264ENC_OUTPUT_BUFFER_OVERFLOW;
  1001. }
  1002. /* Bytes generated */
  1003. pEncOut->streamSize = pEncInst->stream.byteCnt;
  1004. /* Status == START_STREAM Stream started */
  1005. pEncInst->encStatus = H264ENCSTAT_START_STREAM;
  1006. pEncInst->slice.frameNum = 0;
  1007. pEncInst->rateControl.fillerIdx = (u32) (-1);
  1008. if(rc->hrd == ENCHW_YES)
  1009. {
  1010. /* Update HRD Parameters to RC if needed */
  1011. u32 bitrate = H264SpsGetVuiHrdBitRate(&pEncInst->seqParameterSet);
  1012. u32 cpbsize = H264SpsGetVuiHrdCpbSize(&pEncInst->seqParameterSet);
  1013. if ((rc->virtualBuffer.bitRate != (i32)bitrate) ||
  1014. (rc->virtualBuffer.bufferSize != (i32)cpbsize))
  1015. {
  1016. rc->virtualBuffer.bitRate = bitrate;
  1017. rc->virtualBuffer.bufferSize = cpbsize;
  1018. (void) H264InitRc(rc);
  1019. }
  1020. }
  1021. #ifdef VIDEOSTAB_ENABLED
  1022. /* new stream so reset the stabilization */
  1023. VSAlgReset(&pEncInst->vsSwData);
  1024. #endif
  1025. APITRACE("H264EncStrmStart: OK");
  1026. return H264ENC_OK;
  1027. }
  1028. /*------------------------------------------------------------------------------
  1029. Function name : H264EncStrmEncode
  1030. Description : Encodes a new picture
  1031. Return type : H264EncRet
  1032. Argument : inst - encoder instance
  1033. Argument : pEncIn - user provided input parameters
  1034. pEncOut - place where output info is returned
  1035. ------------------------------------------------------------------------------*/
  1036. H264EncRet H264EncStrmEncode(H264EncInst inst, const H264EncIn * pEncIn,
  1037. H264EncOut * pEncOut,
  1038. H264EncSliceReadyCallBackFunc sliceReadyCbFunc,
  1039. void * pAppData)
  1040. {
  1041. h264Instance_s *pEncInst = (h264Instance_s *) inst;
  1042. slice_s *pSlice;
  1043. regValues_s *regs;
  1044. h264EncodeFrame_e ret;
  1045. APITRACE("H264EncStrmEncode#");
  1046. /* Check for illegal inputs */
  1047. if((pEncInst == NULL) || (pEncIn == NULL) || (pEncOut == NULL))
  1048. {
  1049. APITRACE("H264EncStrmEncode: ERROR Null argument");
  1050. return H264ENC_NULL_ARGUMENT;
  1051. }
  1052. /* Check for existing instance */
  1053. if(pEncInst->inst != pEncInst)
  1054. {
  1055. APITRACE("H264EncStrmEncode: ERROR Invalid instance");
  1056. return H264ENC_INSTANCE_ERROR;
  1057. }
  1058. /* Clear the output structure */
  1059. pEncOut->codingType = H264ENC_NOTCODED_FRAME;
  1060. pEncOut->streamSize = 0;
  1061. /* Set pointer to the beginning of NAL unit size buffer */
  1062. pEncOut->pNaluSizeBuf = (u32 *) pEncInst->asic.sizeTbl.nal.virtualAddress;
  1063. pEncOut->numNalus = pEncInst->naluOffset = 0;
  1064. /* Clear the NAL unit size table */
  1065. if(pEncOut->pNaluSizeBuf != NULL)
  1066. pEncOut->pNaluSizeBuf[0] = 0;
  1067. #ifdef EVALUATION_LIMIT
  1068. /* Check for evaluation limit */
  1069. if(pEncInst->frameCnt >= EVALUATION_LIMIT)
  1070. {
  1071. APITRACE("H264EncStrmEncode: OK Evaluation limit exceeded");
  1072. return H264ENC_OK;
  1073. }
  1074. #endif
  1075. /* Check status, INIT and ERROR not allowed */
  1076. if((pEncInst->encStatus != H264ENCSTAT_START_STREAM) &&
  1077. (pEncInst->encStatus != H264ENCSTAT_START_FRAME))
  1078. {
  1079. APITRACE("H264EncStrmEncode: ERROR Invalid status");
  1080. return H264ENC_INVALID_STATUS;
  1081. }
  1082. /* Check for invalid input values */
  1083. if((!H264_BUS_ADDRESS_VALID(pEncIn->busOutBuf)) ||
  1084. (pEncIn->pOutBuf == NULL) ||
  1085. (pEncIn->outBufSize < H264ENCSTRMENCODE_MIN_BUF) ||
  1086. (pEncIn->codingType > H264ENC_PREDICTED_FRAME))
  1087. {
  1088. APITRACE("H264EncStrmEncode: ERROR Invalid input. Output buffer");
  1089. return H264ENC_INVALID_ARGUMENT;
  1090. }
  1091. switch (pEncInst->preProcess.inputFormat)
  1092. {
  1093. case H264ENC_YUV420_PLANAR:
  1094. if(!H264_BUS_ADDRESS_VALID(pEncIn->busChromaV))
  1095. {
  1096. APITRACE("H264EncStrmEncode: ERROR Invalid input busChromaU");
  1097. return H264ENC_INVALID_ARGUMENT;
  1098. }
  1099. /* fall through */
  1100. case H264ENC_YUV420_SEMIPLANAR:
  1101. if(!H264_BUS_ADDRESS_VALID(pEncIn->busChromaU))
  1102. {
  1103. APITRACE("H264EncStrmEncode: ERROR Invalid input busChromaU");
  1104. return H264ENC_INVALID_ARGUMENT;
  1105. }
  1106. /* fall through */
  1107. case H264ENC_YUV422_INTERLEAVED_YUYV:
  1108. case H264ENC_YUV422_INTERLEAVED_UYVY:
  1109. case H264ENC_RGB565:
  1110. case H264ENC_BGR565:
  1111. case H264ENC_RGB555:
  1112. case H264ENC_BGR555:
  1113. case H264ENC_RGB444:
  1114. case H264ENC_BGR444:
  1115. case H264ENC_RGB888:
  1116. case H264ENC_BGR888:
  1117. case H264ENC_RGB101010:
  1118. case H264ENC_BGR101010:
  1119. if(!H264_BUS_ADDRESS_VALID(pEncIn->busLuma))
  1120. {
  1121. APITRACE("H264EncStrmEncode: ERROR Invalid input busLuma");
  1122. return H264ENC_INVALID_ARGUMENT;
  1123. }
  1124. break;
  1125. default:
  1126. APITRACE("H264EncStrmEncode: ERROR Invalid input format");
  1127. return H264ENC_INVALID_ARGUMENT;
  1128. }
  1129. if(pEncInst->preProcess.videoStab)
  1130. {
  1131. if(!H264_BUS_ADDRESS_VALID(pEncIn->busLumaStab))
  1132. {
  1133. APITRACE("H264EncStrmEncode: ERROR Invalid input busLumaStab");
  1134. return H264ENC_INVALID_ARGUMENT;
  1135. }
  1136. }
  1137. /* some shortcuts */
  1138. pSlice = &pEncInst->slice;
  1139. regs = &pEncInst->asic.regs;
  1140. /* Set stream buffer, the size has been checked */
  1141. if(H264SetBuffer(&pEncInst->stream, (u8 *) pEncIn->pOutBuf,
  1142. (i32) pEncIn->outBufSize) == ENCHW_NOK)
  1143. {
  1144. APITRACE("H264EncStrmEncode: ERROR Invalid output buffer");
  1145. return H264ENC_INVALID_ARGUMENT;
  1146. }
  1147. /* Try to reserve the HW resource */
  1148. if(EWLReserveHw(pEncInst->asic.ewl) == EWL_ERROR)
  1149. {
  1150. APITRACE("H264EncStrmEncode: ERROR HW unavailable");
  1151. return H264ENC_HW_RESERVED;
  1152. }
  1153. /* update in/out buffers */
  1154. regs->inputLumBase = pEncIn->busLuma;
  1155. regs->inputCbBase = pEncIn->busChromaU;
  1156. regs->inputCrBase = pEncIn->busChromaV;
  1157. regs->outputStrmBase = pEncIn->busOutBuf;
  1158. regs->outputStrmSize = pEncIn->outBufSize;
  1159. pEncInst->sliceReadyCbFunc = sliceReadyCbFunc;
  1160. pEncInst->pOutBuf = pEncIn->pOutBuf;
  1161. pEncInst->pAppData = pAppData;
  1162. /* setup stabilization */
  1163. if(pEncInst->preProcess.videoStab)
  1164. {
  1165. regs->vsNextLumaBase = pEncIn->busLumaStab;
  1166. }
  1167. {
  1168. H264EncPictureCodingType ct = pEncIn->codingType;
  1169. /* Status may affect the frame coding type */
  1170. if(pEncInst->encStatus == H264ENCSTAT_START_STREAM)
  1171. {
  1172. ct = H264ENC_INTRA_FRAME;
  1173. }
  1174. #ifdef VIDEOSTAB_ENABLED
  1175. if(pEncInst->vsSwData.sceneChange)
  1176. {
  1177. pEncInst->vsSwData.sceneChange = 0;
  1178. ct = H264ENC_INTRA_FRAME;
  1179. }
  1180. #endif
  1181. pSlice->prevFrameNum = pSlice->frameNum;
  1182. /* MVC view frames are never intra. */
  1183. if ((pEncInst->numViews > 1) && ((pSlice->frameNum % 2) == 1))
  1184. ct = H264ENC_PREDICTED_FRAME;
  1185. /* Frame coding type defines the NAL unit type */
  1186. switch (ct)
  1187. {
  1188. case H264ENC_INTRA_FRAME:
  1189. /* IDR-slice */
  1190. pSlice->nalUnitType = IDR;
  1191. pSlice->sliceType = ISLICE;
  1192. pSlice->frameNum = 0;
  1193. H264MadInit(&pEncInst->mad, pEncInst->mbPerFrame);
  1194. break;
  1195. case H264ENC_PREDICTED_FRAME:
  1196. default:
  1197. /* non-IDR slice */
  1198. pSlice->nalUnitType = NONIDR;
  1199. pSlice->sliceType = PSLICE;
  1200. break;
  1201. }
  1202. }
  1203. /* Rate control */
  1204. H264BeforePicRc(&pEncInst->rateControl, pEncIn->timeIncrement,
  1205. pSlice->sliceType);
  1206. /* time stamp updated */
  1207. H264UpdateSeiTS(&pEncInst->rateControl.sei, pEncIn->timeIncrement);
  1208. /* Rate control may choose to skip the frame */
  1209. if(pEncInst->rateControl.frameCoded == ENCHW_NO)
  1210. {
  1211. APITRACE("H264EncStrmEncode: OK, frame skipped");
  1212. pSlice->frameNum = pSlice->prevFrameNum; /* restore frame_num */
  1213. #if 0
  1214. /* Write previous reconstructed frame when frame is skipped */
  1215. EncAsicRecycleInternalImage(&pEncInst->asic.regs);
  1216. EncDumpRecon(&pEncInst->asic);
  1217. EncAsicRecycleInternalImage(&pEncInst->asic.regs);
  1218. #endif
  1219. EWLReleaseHw(pEncInst->asic.ewl);
  1220. return H264ENC_FRAME_READY;
  1221. }
  1222. #ifdef TRACE_STREAM
  1223. traceStream.frameNum = pEncInst->frameCnt;
  1224. traceStream.id = 0; /* Stream generated by SW */
  1225. traceStream.bitCnt = 0; /* New frame */
  1226. #endif
  1227. #ifdef INTERNAL_TEST
  1228. /* Configure the encoder instance according to the test vector */
  1229. H264ConfigureTestBeforeFrame(pEncInst);
  1230. #endif
  1231. /* Determine the start offset for NALU size table.
  1232. * HW needs a 64-bit aligned address so we leave the first 32-bits unused
  1233. * if SW creates one leading NAL unit. Also the HW bus address needs to be
  1234. * offset in H264CodeFrame. */
  1235. {
  1236. i32 numLeadingNalus = 0;
  1237. sei_s *sei = &pEncInst->rateControl.sei;
  1238. if(sei->enabled == ENCHW_YES || sei->userDataEnabled == ENCHW_YES)
  1239. numLeadingNalus++;
  1240. if ((pEncInst->numViews > 1) && ((pSlice->frameNum % 2) == 0))
  1241. numLeadingNalus++;
  1242. pEncInst->numNalus = numLeadingNalus;
  1243. if(numLeadingNalus % 2)
  1244. {
  1245. pEncOut->pNaluSizeBuf++;
  1246. pEncInst->naluOffset++;
  1247. }
  1248. }
  1249. /* update any cropping/rotation/filling */
  1250. EncPreProcess(&pEncInst->asic, &pEncInst->preProcess);
  1251. /* SEI message */
  1252. {
  1253. sei_s *sei = &pEncInst->rateControl.sei;
  1254. if(sei->enabled == ENCHW_YES || sei->userDataEnabled == ENCHW_YES)
  1255. {
  1256. H264NalUnitHdr(&pEncInst->stream, 0, SEI, sei->byteStream);
  1257. if(sei->enabled == ENCHW_YES)
  1258. {
  1259. if(pSlice->nalUnitType == IDR)
  1260. {
  1261. H264BufferingSei(&pEncInst->stream, sei);
  1262. }
  1263. H264PicTimingSei(&pEncInst->stream, sei);
  1264. }
  1265. if(sei->userDataEnabled == ENCHW_YES)
  1266. {
  1267. H264UserDataUnregSei(&pEncInst->stream, sei);
  1268. }
  1269. H264RbspTrailingBits(&pEncInst->stream);
  1270. sei->nalUnitSize = pEncInst->stream.byteCnt;
  1271. H264AddNaluSize(pEncOut, pEncInst->stream.byteCnt);
  1272. }
  1273. }
  1274. /* For MVC stream insert prefix NALU before base view pictures */
  1275. if ((pEncInst->numViews > 1) && ((pSlice->frameNum % 2) == 0))
  1276. {
  1277. i32 byteCnt = pEncInst->stream.byteCnt;
  1278. H264PrefixNal(pEncInst);
  1279. H264AddNaluSize(pEncOut, pEncInst->stream.byteCnt-byteCnt);
  1280. }
  1281. else
  1282. {
  1283. pEncInst->mvc.anchorPicFlag = (pSlice->frameNum == 1);
  1284. pEncInst->mvc.viewId = 1;
  1285. pEncInst->mvc.interViewFlag = 0;
  1286. }
  1287. /* Code one frame */
  1288. ret = H264CodeFrame(pEncInst);
  1289. #ifdef TRACE_RECON
  1290. EncDumpRecon(&pEncInst->asic);
  1291. #endif
  1292. if(ret != H264ENCODE_OK)
  1293. {
  1294. /* Error has occured and the frame is invalid */
  1295. H264EncRet to_user;
  1296. switch (ret)
  1297. {
  1298. case H264ENCODE_TIMEOUT:
  1299. APITRACE("H264EncStrmEncode: ERROR HW timeout");
  1300. to_user = H264ENC_HW_TIMEOUT;
  1301. break;
  1302. case H264ENCODE_HW_RESET:
  1303. APITRACE("H264EncStrmEncode: ERROR HW reset detected");
  1304. to_user = H264ENC_HW_RESET;
  1305. break;
  1306. case H264ENCODE_HW_ERROR:
  1307. APITRACE("H264EncStrmEncode: ERROR HW bus access error");
  1308. to_user = H264ENC_HW_BUS_ERROR;
  1309. break;
  1310. case H264ENCODE_SYSTEM_ERROR:
  1311. default:
  1312. /* System error has occured, encoding can't continue */
  1313. pEncInst->encStatus = H264ENCSTAT_ERROR;
  1314. APITRACE("H264EncStrmEncode: ERROR Fatal system error");
  1315. to_user = H264ENC_SYSTEM_ERROR;
  1316. }
  1317. return to_user;
  1318. }
  1319. #ifdef VIDEOSTAB_ENABLED
  1320. /* Finalize video stabilization */
  1321. if(pEncInst->preProcess.videoStab)
  1322. {
  1323. u32 no_motion;
  1324. VSReadStabData(pEncInst->asic.regs.regMirror, &pEncInst->vsHwData);
  1325. no_motion = VSAlgStabilize(&pEncInst->vsSwData, &pEncInst->vsHwData);
  1326. if(no_motion)
  1327. {
  1328. VSAlgReset(&pEncInst->vsSwData);
  1329. }
  1330. /* update offset after stabilization */
  1331. VSAlgGetResult(&pEncInst->vsSwData, &pEncInst->preProcess.horOffsetSrc,
  1332. &pEncInst->preProcess.verOffsetSrc);
  1333. }
  1334. #endif
  1335. /* Update NALU table with the amount of slices created by the HW */
  1336. {
  1337. i32 numSlices;
  1338. if (pEncInst->slice.sliceSize)
  1339. numSlices = (pEncInst->mbPerFrame + pEncInst->slice.sliceSize - 1) /
  1340. pEncInst->slice.sliceSize;
  1341. else
  1342. numSlices = 1;
  1343. pEncOut->numNalus += numSlices;
  1344. pEncOut->pNaluSizeBuf[pEncOut->numNalus] = 0;
  1345. }
  1346. /* Filler data if needed */
  1347. {
  1348. u32 s = H264FillerRc(&pEncInst->rateControl, pEncInst->frameCnt);
  1349. if(s != 0)
  1350. {
  1351. s = H264FillerNALU(&pEncInst->stream,
  1352. (i32) s, pEncInst->seqParameterSet.byteStream);
  1353. }
  1354. pEncInst->fillerNalSize = s;
  1355. H264AddNaluSize(pEncOut, s);
  1356. }
  1357. pEncOut->motionVectors = (i8*)pEncInst->asic.mvOutput.virtualAddress;
  1358. /* After stream buffer overflow discard the coded frame */
  1359. if(pEncInst->stream.overflow == ENCHW_YES)
  1360. {
  1361. if ((pEncInst->numRefBuffsLum == 1) || (pEncInst->numViews == 2))
  1362. {
  1363. /* Only one reference frame buffer in use, so we can't use it
  1364. * as reference => we must encode next frame as intra */
  1365. pEncInst->encStatus = H264ENCSTAT_START_STREAM;
  1366. }
  1367. pEncOut->numNalus = 0;
  1368. pEncOut->pNaluSizeBuf[0] = 0;
  1369. APITRACE("H264EncStrmEncode: ERROR Output buffer too small");
  1370. return H264ENC_OUTPUT_BUFFER_OVERFLOW;
  1371. }
  1372. /* Rate control action after vop */
  1373. {
  1374. i32 stat;
  1375. stat = H264AfterPicRc(&pEncInst->rateControl, regs->rlcCount,
  1376. pEncInst->stream.byteCnt, regs->qpSum);
  1377. H264MadThreshold(&pEncInst->mad, regs->madCount);
  1378. /* After HRD overflow discard the coded frame and go back old time,
  1379. * just like not coded frame. But if only one reference frame
  1380. * buffer is in use we can't discard the frame unless the next frame
  1381. * is coded as intra. */
  1382. if((stat == H264RC_OVERFLOW) &&
  1383. (pEncInst->numRefBuffsLum > 1) &&
  1384. (pEncInst->numViews == 1))
  1385. {
  1386. pSlice->frameNum = pSlice->prevFrameNum; /* revert frame_num */
  1387. pEncOut->numNalus = 0;
  1388. pEncOut->pNaluSizeBuf[0] = 0;
  1389. APITRACE("H264EncStrmEncode: OK, Frame discarded (HRD overflow)");
  1390. return H264ENC_FRAME_READY;
  1391. }
  1392. }
  1393. /* Use the reconstructed frame as the reference for the next frame */
  1394. EncAsicRecycleInternalImage(&pEncInst->asic, pEncInst->numViews,
  1395. (pSlice->frameNum % 2), (pSlice->frameNum <= 1),
  1396. pEncInst->numRefBuffsLum, pEncInst->numRefBuffsChr);
  1397. /* Store the stream size and frame coding type in output structure */
  1398. pEncOut->streamSize = pEncInst->stream.byteCnt;
  1399. if(pSlice->nalUnitType == IDR)
  1400. {
  1401. pEncOut->codingType = H264ENC_INTRA_FRAME;
  1402. pSlice->idrPicId += 1;
  1403. if(pSlice->idrPicId == H264ENC_IDR_ID_MODULO)
  1404. pSlice->idrPicId = 0;
  1405. }
  1406. else
  1407. {
  1408. pEncOut->codingType = H264ENC_PREDICTED_FRAME;
  1409. }
  1410. /* Frame was encoded so increment frame number */
  1411. pEncInst->frameCnt++;
  1412. pSlice->frameNum++;
  1413. pSlice->frameNum %= (1U << pSlice->frameNumBits);
  1414. pEncInst->encStatus = H264ENCSTAT_START_FRAME;
  1415. APITRACE("H264EncStrmEncode: OK");
  1416. return H264ENC_FRAME_READY;
  1417. }
  1418. /*------------------------------------------------------------------------------
  1419. Function name : H264EncStrmEnd
  1420. Description : Ends a stream
  1421. Return type : H264EncRet
  1422. Argument : inst - encoder instance
  1423. Argument : pEncIn - user provided input parameters
  1424. pEncOut - place where output info is returned
  1425. ------------------------------------------------------------------------------*/
  1426. H264EncRet H264EncStrmEnd(H264EncInst inst, const H264EncIn * pEncIn,
  1427. H264EncOut * pEncOut)
  1428. {
  1429. h264Instance_s *pEncInst = (h264Instance_s *) inst;
  1430. APITRACE("H264EncStrmEnd#");
  1431. /* Check for illegal inputs */
  1432. if((pEncInst == NULL) || (pEncIn == NULL) || (pEncOut == NULL))
  1433. {
  1434. APITRACE("H264EncStrmEnd: ERROR Null argument");
  1435. return H264ENC_NULL_ARGUMENT;
  1436. }
  1437. /* Check for existing instance */
  1438. if(pEncInst->inst != pEncInst)
  1439. {
  1440. APITRACE("H264EncStrmEnd: ERROR Invalid instance");
  1441. return H264ENC_INSTANCE_ERROR;
  1442. }
  1443. /* Check status, this also makes sure that the instance is valid */
  1444. if((pEncInst->encStatus != H264ENCSTAT_START_FRAME) &&
  1445. (pEncInst->encStatus != H264ENCSTAT_START_STREAM))
  1446. {
  1447. APITRACE("H264EncStrmEnd: ERROR Invalid status");
  1448. return H264ENC_INVALID_STATUS;
  1449. }
  1450. pEncOut->streamSize = 0;
  1451. /* Set pointer to the beginning of NAL unit size buffer */
  1452. pEncOut->pNaluSizeBuf = (u32 *) pEncInst->asic.sizeTbl.nal.virtualAddress;
  1453. pEncOut->numNalus = 0;
  1454. /* Clear the NAL unit size table */
  1455. if(pEncOut->pNaluSizeBuf != NULL)
  1456. pEncOut->pNaluSizeBuf[0] = 0;
  1457. /* Check for invalid input values */
  1458. if(pEncIn->pOutBuf == NULL ||
  1459. (pEncIn->outBufSize < H264ENCSTRMSTART_MIN_BUF))
  1460. {
  1461. APITRACE("H264EncStrmEnd: ERROR Invalid input. Stream buffer");
  1462. return H264ENC_INVALID_ARGUMENT;
  1463. }
  1464. /* Set stream buffer and check the size */
  1465. if(H264SetBuffer(&pEncInst->stream, (u8 *) pEncIn->pOutBuf,
  1466. (u32) pEncIn->outBufSize) != ENCHW_OK)
  1467. {
  1468. APITRACE("H264EncStrmEnd: ERROR Output buffer too small");
  1469. return H264ENC_INVALID_ARGUMENT;
  1470. }
  1471. /* Write end-of-stream code */
  1472. H264EndOfSequence(&pEncInst->stream, &pEncInst->seqParameterSet);
  1473. /* Bytes generated */
  1474. pEncOut->streamSize = pEncInst->stream.byteCnt;
  1475. H264AddNaluSize(pEncOut, pEncInst->stream.byteCnt);
  1476. /* Status == INIT Stream ended, next stream can be started */
  1477. pEncInst->encStatus = H264ENCSTAT_INIT;
  1478. APITRACE("H264EncStrmEnd: OK");
  1479. return H264ENC_OK;
  1480. }
  1481. /*------------------------------------------------------------------------------
  1482. Function name : H264AddNaluSize
  1483. Description : Adds the size of a NAL unit into NAL size output buffer.
  1484. Return type : void
  1485. Argument : pEncOut - encoder output structure
  1486. Argument : naluSizeBytes - size of the NALU in bytes
  1487. ------------------------------------------------------------------------------*/
  1488. void H264AddNaluSize(H264EncOut * pEncOut, u32 naluSizeBytes)
  1489. {
  1490. if(pEncOut->pNaluSizeBuf != NULL)
  1491. {
  1492. pEncOut->pNaluSizeBuf[pEncOut->numNalus++] = naluSizeBytes;
  1493. pEncOut->pNaluSizeBuf[pEncOut->numNalus] = 0;
  1494. }
  1495. }
  1496. /*------------------------------------------------------------------------------
  1497. H264PrefixNal
  1498. ------------------------------------------------------------------------------*/
  1499. void H264PrefixNal(h264Instance_s *pEncInst)
  1500. {
  1501. H264NalUnitHdr(&pEncInst->stream, 1, PREFIX,
  1502. pEncInst->seqParameterSet.byteStream);
  1503. pEncInst->mvc.anchorPicFlag = (pEncInst->slice.nalUnitType == IDR);
  1504. pEncInst->mvc.priorityId = 0;
  1505. pEncInst->mvc.viewId = 0;
  1506. pEncInst->mvc.temporalId = 0;
  1507. pEncInst->mvc.interViewFlag = 1;
  1508. H264PutBits(&pEncInst->stream, 0, 1);
  1509. COMMENT("svc_extension_flag");
  1510. H264NalUnitHdrMvcExtension(&pEncInst->stream, &pEncInst->mvc);
  1511. }
  1512. /*------------------------------------------------------------------------------
  1513. Function name : H264EncSetTestId
  1514. Description : Sets the encoder configuration according to a test vector
  1515. Return type : H264EncRet
  1516. Argument : inst - encoder instance
  1517. Argument : testId - test vector ID
  1518. ------------------------------------------------------------------------------*/
  1519. H264EncRet H264EncSetTestId(H264EncInst inst, u32 testId)
  1520. {
  1521. h264Instance_s *pEncInst = (h264Instance_s *) inst;
  1522. (void) pEncInst;
  1523. (void) testId;
  1524. APITRACE("H264EncSetTestId#");
  1525. #ifdef INTERNAL_TEST
  1526. pEncInst->testId = testId;
  1527. APITRACE("H264EncSetTestId# OK");
  1528. return H264ENC_OK;
  1529. #else
  1530. /* Software compiled without testing support, return error always */
  1531. APITRACE("H264EncSetTestId# ERROR, testing disabled at compile time");
  1532. return H264ENC_ERROR;
  1533. #endif
  1534. }