H264TestBench.c 87 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566
  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 testbench for linux
  17. --
  18. ------------------------------------------------------------------------------*/
  19. /*------------------------------------------------------------------------------
  20. 1. Include headers
  21. ------------------------------------------------------------------------------*/
  22. /* For command line structure */
  23. #include "H264TestBench.h"
  24. /* For parameter parsing */
  25. #include "EncGetOption.h"
  26. /* For SW/HW shared memory allocation */
  27. #include "ewl.h"
  28. /* For accessing the EWL instance inside the encoder */
  29. #include "H264Instance.h"
  30. /* For compiler flags, test data, debug and tracing */
  31. #include "enccommon.h"
  32. /* For Hantro H.264 encoder */
  33. #include "h264encapi.h"
  34. #ifdef INTERNAL_TEST
  35. #include "h264encapi_ext.h"
  36. #endif
  37. /* For printing and file IO */
  38. #include <stdio.h>
  39. /* For dynamic memory allocation */
  40. #include <stdlib.h>
  41. /* For memset, strcpy and strlen */
  42. #include <string.h>
  43. /* For sleep */
  44. #include <unistd.h>
  45. #ifdef USE_EFENCE
  46. #include "efence.h"
  47. #endif
  48. /*------------------------------------------------------------------------------
  49. 2. External compiler flags
  50. --------------------------------------------------------------------------------
  51. NO_OUTPUT_WRITE: Output stream is not written to file. This should be used
  52. when running performance simulations.
  53. NO_INPUT_READ: Input frames are not read from file. This should be used
  54. when running performance simulations.
  55. PSNR: Enable PSNR calculation with --psnr option, only works with
  56. system model
  57. --------------------------------------------------------------------------------
  58. 3. Module defines
  59. ------------------------------------------------------------------------------*/
  60. #define H264ERR_OUTPUT stdout
  61. #define MAX_GOP_LEN 300
  62. /* The maximum amount of frames for bitrate moving average calculation */
  63. #define MOVING_AVERAGE_FRAMES 30
  64. #ifdef PSNR
  65. float log10f(float x);
  66. float roundf(float x);
  67. #endif
  68. /* Global variables */
  69. static char input[] = "input.yuv";
  70. static char output[] = "stream.h264";
  71. static char nal_sizes_file[] = "nal_sizes.txt";
  72. static char *streamType[2] = { "BYTE_STREAM", "NAL_UNITS" };
  73. static char *viewMode[4] = { "H264_DOUBLE_BUFFER", "H264_SINGLE_BUFFER",
  74. "MVC_INTER_VIEW_PRED", "MVC_INTER_PRED"};
  75. static option_s option[] = {
  76. {"help", 'H'},
  77. {"firstPic", 'a', 1},
  78. {"lastPic", 'b', 1},
  79. {"width", 'x', 1},
  80. {"height", 'y', 1},
  81. {"lumWidthSrc", 'w', 1},
  82. {"lumHeightSrc", 'h', 1},
  83. {"horOffsetSrc", 'X', 1},
  84. {"verOffsetSrc", 'Y', 1},
  85. {"outputRateNumer", 'f', 1},
  86. {"outputRateDenom", 'F', 1},
  87. {"inputRateNumer", 'j', 1},
  88. {"inputRateDenom", 'J', 1},
  89. {"inputFormat", 'l', 1}, /* Input image format */
  90. {"colorConversion", 'O', 1}, /* RGB to YCbCr conversion type */
  91. {"inputMvc", '9', 1},
  92. {"input", 'i', 1}, /* "input" must be after "inputFormat" */
  93. {"output", 'o', 1},
  94. {"videoRange", 'k', 1},
  95. {"rotation", 'r', 1}, /* Input image rotation */
  96. {"intraPicRate", 'I', 1},
  97. {"constIntraPred", 'T', 1},
  98. {"disableDeblocking", 'D', 1},
  99. {"filterOffsetA", 'W', 1},
  100. {"filterOffsetB", 'E', 1},
  101. {"trans8x8", '8', 1}, /* adaptive 4x4/8x8 transform */
  102. {"enableCabac", 'K', 1},
  103. {"cabacInitIdc", 'p', 1},
  104. {"mbRowPerSlice", 'V', 1},
  105. {"bitPerSecond", 'B', 1},
  106. {"picRc", 'U', 1},
  107. {"mbRc", 'u', 1},
  108. {"picSkip", 's', 1}, /* Frame skipping */
  109. {"gopLength", 'g', 1}, /* group of pictures length */
  110. {"qpMin", 'n', 1}, /* Minimum frame header qp */
  111. {"qpMax", 'm', 1}, /* Maximum frame header qp */
  112. {"qpHdr", 'q', 1}, /* Defaul qp */
  113. {"chromaQpOffset", 'Q', 1}, /* Chroma qp index offset */
  114. {"hrdConformance", 'C', 1}, /* HDR Conformance (ANNEX C) */
  115. {"cpbSize", 'c', 1}, /* Coded Picture Buffer Size */
  116. {"intraQpDelta", 'A', 1}, /* QP adjustment for intra frames */
  117. {"fixedIntraQp", 'G', 1}, /* Fixed QP for all intra frames */
  118. {"userData", 'z', 1}, /* SEI User data file */
  119. {"level", 'L', 1}, /* Level * 10 (ANNEX A) */
  120. {"byteStream", 'R', 1}, /* Byte stream format (ANNEX B) */
  121. {"sei", 'S', 1}, /* SEI messages */
  122. {"videoStab", 'Z', 1}, /* video stabilization */
  123. {"bpsAdjust", '1', 1}, /* Setting bitrate on the fly */
  124. {"mbQpAdjustment", '2', 1}, /* MAD based MB QP adjustment */
  125. {"mvOutput", '3', 1}, /* MV output in mv.txt */
  126. {"testId", 'e', 1},
  127. {"burstSize", 'N', 1},
  128. {"burstType", 't', 1},
  129. {"quarterPixelMv", 'M', 1},
  130. {"trigger", 'P', 1},
  131. {"psnr", 'd', 0},
  132. {"testParam", 'v', 1},
  133. /* Only long option can be used for all the following parameters because
  134. * we have no more letters to use. All shortOpt=0 will be identified by
  135. * long option. */
  136. {"cir", '0', 1},
  137. {"intraSliceMap1", '0', 1},
  138. {"intraSliceMap2", '0', 1},
  139. {"intraSliceMap3", '0', 1},
  140. {"intraArea", '0', 1},
  141. {"roi1Area", '0', 1},
  142. {"roi2Area", '0', 1},
  143. {"roi1DeltaQp", '0', 1},
  144. {"roi2DeltaQp", '0', 1},
  145. {"viewMode", '0', 1},
  146. {0, 0, 0} /* End of options */
  147. };
  148. typedef struct {
  149. i32 frame[MOVING_AVERAGE_FRAMES];
  150. i32 length;
  151. i32 count;
  152. i32 pos;
  153. i32 frameRateNumer;
  154. i32 frameRateDenom;
  155. } ma_s;
  156. /* SW/HW shared memories for input/output buffers */
  157. static EWLLinearMem_t pictureMem;
  158. static EWLLinearMem_t pictureStabMem;
  159. static EWLLinearMem_t outbufMem;
  160. static FILE *yuvFile = NULL;
  161. static char *yuvFileName = NULL;
  162. static FILE *yuvFileMvc = NULL;
  163. static off_t file_size;
  164. #ifdef MULTIFILEINPUT
  165. /* Try to read input from input.yuv, input.yuv1, input.yuv2, etc.. */
  166. static i32 fileNumber=0;
  167. char inputFilename[256];
  168. i32 inputFilenameLength;
  169. #endif
  170. i32 trigger_point = -1; /* Logic Analyzer trigger point */
  171. /*------------------------------------------------------------------------------
  172. 4. Local function prototypes
  173. ------------------------------------------------------------------------------*/
  174. static int AllocRes(commandLine_s * cmdl, H264EncInst enc);
  175. static void FreeRes(H264EncInst enc);
  176. static int OpenEncoder(commandLine_s * cml, H264EncInst * encoder);
  177. static i32 Encode(i32 argc, char **argv, H264EncInst inst, commandLine_s * cml);
  178. static void CloseEncoder(H264EncInst encoder);
  179. static i32 NextPic(i32 inputRateNumer, i32 inputRateDenom, i32 outputRateNumer,
  180. i32 outputRateDenom, i32 frameCnt, i32 firstPic);
  181. static int ReadPic(u8 * image, i32 size, i32 nro, char *name, i32 width,
  182. i32 height, i32 format);
  183. static u8* ReadUserData(H264EncInst encoder, char *name);
  184. static int Parameter(i32 argc, char **argv, commandLine_s * ep);
  185. static void Help(void);
  186. static void WriteStrm(FILE * fout, u32 * outbuf, u32 size, u32 endian);
  187. static int ChangeInput(i32 argc, char **argv, char **name, option_s * option);
  188. static void PrintNalSizes(const u32 *pNaluSizeBuf, const u8 *pOutBuf,
  189. u32 strmSize, i32 byteStream);
  190. static void WriteNalSizesToFile(const char *file, const u32 * pNaluSizeBuf,
  191. u32 buffSize);
  192. static void WriteMotionVectors(FILE *file, i8 *mvs, i32 frame,
  193. i32 width, i32 height);
  194. static void PrintErrorValue(const char *errorDesc, u32 retVal);
  195. static u32 PrintPSNR(u8 *a, u8 *b, i32 scanline, i32 wdh, i32 hgt, i32 rotation);
  196. static u32 GetResolution(char *filename, i32 *pWidth, i32 *pHeight);
  197. static void MaAddFrame(ma_s *ma, i32 frameSizeBits);
  198. static i32 Ma(ma_s *ma);
  199. void H264SliceReady(H264EncSliceReady *slice);
  200. /*------------------------------------------------------------------------------
  201. main
  202. ------------------------------------------------------------------------------*/
  203. int main(int argc, char *argv[])
  204. {
  205. H264EncInst encoder;
  206. commandLine_s cmdl;
  207. H264EncApiVersion apiVer;
  208. H264EncBuild encBuild;
  209. i32 ret;
  210. apiVer = H264EncGetApiVersion();
  211. encBuild = H264EncGetBuild();
  212. fprintf(stdout, "H.264 Encoder API version %d.%d\n", apiVer.major,
  213. apiVer.minor);
  214. fprintf(stdout, "HW ID: 0x%08x\t SW Build: %u.%u.%u\n\n",
  215. encBuild.hwBuild, encBuild.swBuild / 1000000,
  216. (encBuild.swBuild / 1000) % 1000, encBuild.swBuild % 1000);
  217. #ifdef EVALUATION_LIMIT
  218. fprintf(stdout, "Evaluation version with %d frame limit.\n\n", EVALUATION_LIMIT);
  219. #endif
  220. if(argc < 2)
  221. {
  222. Help();
  223. exit(0);
  224. }
  225. remove(nal_sizes_file);
  226. remove("stream.trc");
  227. /* Parse command line parameters */
  228. if(Parameter(argc, argv, &cmdl) != 0)
  229. {
  230. fprintf(H264ERR_OUTPUT, "Input parameter error\n");
  231. return -1;
  232. }
  233. /* Check that input file exists */
  234. yuvFile = fopen(cmdl.input, "rb");
  235. if(yuvFile == NULL)
  236. {
  237. fprintf(H264ERR_OUTPUT, "Unable to open input file: %s\n", cmdl.input);
  238. return -1;
  239. }
  240. else
  241. {
  242. fclose(yuvFile);
  243. yuvFile = NULL;
  244. }
  245. /* Check that MVC input file exists */
  246. if (cmdl.inputMvc)
  247. {
  248. yuvFile = fopen(cmdl.inputMvc, "rb");
  249. if(yuvFile == NULL)
  250. {
  251. fprintf(H264ERR_OUTPUT, "Unable to open input file: %s\n", cmdl.input);
  252. return -1;
  253. }
  254. else
  255. {
  256. fclose(yuvFile);
  257. yuvFile = NULL;
  258. }
  259. if (cmdl.viewMode < H264ENC_MVC_STEREO_INTER_VIEW_PRED)
  260. fprintf(H264ERR_OUTPUT,
  261. "Warning: MVC input with H.264 view mode! Check --viewMode!\n");
  262. }
  263. /* Encoder initialization */
  264. if(OpenEncoder(&cmdl, &encoder) != 0)
  265. {
  266. return -1;
  267. }
  268. /* Set the test ID for internal testing,
  269. * the SW must be compiled with testing flags */
  270. H264EncSetTestId(encoder, cmdl.testId);
  271. /* Allocate input and output buffers */
  272. if(AllocRes(&cmdl, encoder) != 0)
  273. {
  274. fprintf(H264ERR_OUTPUT, "Failed to allocate the external resources!\n");
  275. FreeRes(encoder);
  276. CloseEncoder(encoder);
  277. return 1;
  278. }
  279. ret = Encode(argc, argv, encoder, &cmdl);
  280. FreeRes(encoder);
  281. CloseEncoder(encoder);
  282. return ret;
  283. }
  284. /*------------------------------------------------------------------------------
  285. Encode
  286. Do the encoding.
  287. Params:
  288. argc - number of arguments to the application
  289. argv - argument list as provided to the application
  290. encoder - encoder instance
  291. cml - processed comand line options
  292. Return:
  293. 0 - for success
  294. -1 - error
  295. ------------------------------------------------------------------------------*/
  296. i32 Encode(i32 argc, char **argv, H264EncInst encoder, commandLine_s * cml)
  297. {
  298. H264EncIn encIn;
  299. H264EncOut encOut;
  300. H264EncRet ret;
  301. H264EncRateCtrl rc;
  302. int intraPeriodCnt = 0, codedFrameCnt = 0, next = 0, src_img_size;
  303. u32 frameCnt = 0;
  304. u32 streamSize = 0;
  305. u32 bitrate = 0;
  306. u32 psnrSum = 0;
  307. u32 psnrCnt = 0;
  308. u32 psnr = 0;
  309. ma_s ma;
  310. i32 i;
  311. FILE *fout = NULL;
  312. FILE *fmv = NULL;
  313. u8 *pUserData;
  314. /* Set the window length for bitrate moving average calculation */
  315. ma.pos = ma.count = 0;
  316. ma.frameRateNumer = cml->outputRateNumer;
  317. ma.frameRateDenom = cml->outputRateDenom;
  318. if (cml->outputRateDenom)
  319. ma.length = MAX(1, MIN(cml->outputRateNumer / cml->outputRateDenom,
  320. MOVING_AVERAGE_FRAMES));
  321. else
  322. ma.length = MOVING_AVERAGE_FRAMES;
  323. encIn.pOutBuf = outbufMem.virtualAddress;
  324. encIn.busOutBuf = outbufMem.busAddress;
  325. encIn.outBufSize = outbufMem.size;
  326. /* Source Image Size */
  327. if(cml->inputFormat <= 1)
  328. {
  329. src_img_size = cml->lumWidthSrc * cml->lumHeightSrc +
  330. 2 * (((cml->lumWidthSrc + 1) >> 1) *
  331. ((cml->lumHeightSrc + 1) >> 1));
  332. }
  333. else if((cml->inputFormat <= 9))
  334. {
  335. /* 422 YUV or 16-bit RGB */
  336. src_img_size = cml->lumWidthSrc * cml->lumHeightSrc * 2;
  337. }
  338. else
  339. {
  340. /* 32-bit RGB */
  341. src_img_size = cml->lumWidthSrc * cml->lumHeightSrc * 4;
  342. }
  343. printf("Reading input from file <%s>, frame size %d bytes.\n",
  344. cml->input, src_img_size);
  345. if (cml->inputMvc)
  346. printf("Reading second view input from file <%s>, frame size %d bytes.\n",
  347. cml->inputMvc, src_img_size);
  348. /* Start stream */
  349. ret = H264EncStrmStart(encoder, &encIn, &encOut);
  350. if(ret != H264ENC_OK)
  351. {
  352. PrintErrorValue("H264EncStrmStart() failed.", ret);
  353. return -1;
  354. }
  355. fout = fopen(cml->output, "wb");
  356. if(fout == NULL)
  357. {
  358. fprintf(H264ERR_OUTPUT, "Failed to create the output file.\n");
  359. return -1;
  360. }
  361. if (cml->mvOutput)
  362. {
  363. fmv = fopen("mv.txt", "wb");
  364. if(fmv == NULL)
  365. {
  366. fprintf(H264ERR_OUTPUT, "Failed to create mv.txt output file.\n");
  367. return -1;
  368. }
  369. }
  370. WriteStrm(fout, outbufMem.virtualAddress, encOut.streamSize, 0);
  371. if(cml->byteStream == 0)
  372. {
  373. WriteNalSizesToFile(nal_sizes_file, encOut.pNaluSizeBuf,
  374. encOut.numNalus);
  375. }
  376. streamSize += encOut.streamSize;
  377. H264EncGetRateCtrl(encoder, &rc);
  378. /* Allocate a buffer for user data and read data from file */
  379. pUserData = ReadUserData(encoder, cml->userData);
  380. printf("\nInput | Pic | QP | Type | BR avg MA(%3d) | ByteCnt (inst) |",
  381. ma.length);
  382. if (cml->psnr)
  383. printf(" PSNR | NALU sizes\n");
  384. else
  385. printf(" NALU sizes\n");
  386. printf("--------------------------------------------------------------------------------\n");
  387. printf(" | | %2d | HDR | | %7i %6i | ",
  388. rc.qpHdr, streamSize, encOut.streamSize);
  389. if (cml->psnr)
  390. printf(" | ");
  391. PrintNalSizes(encOut.pNaluSizeBuf, (u8 *) outbufMem.virtualAddress,
  392. encOut.streamSize, cml->byteStream);
  393. printf("\n");
  394. /* Setup encoder input */
  395. {
  396. u32 w = (cml->lumWidthSrc + 15) & (~0x0f);
  397. encIn.busLuma = pictureMem.busAddress;
  398. encIn.busChromaU = encIn.busLuma + (w * cml->lumHeightSrc);
  399. encIn.busChromaV = encIn.busChromaU +
  400. (((w + 1) >> 1) * ((cml->lumHeightSrc + 1) >> 1));
  401. }
  402. /* First frame is always intra with time increment = 0 */
  403. encIn.codingType = H264ENC_INTRA_FRAME;
  404. encIn.timeIncrement = 0;
  405. encIn.busLumaStab = pictureStabMem.busAddress;
  406. intraPeriodCnt = cml->intraPicRate;
  407. /* Main encoding loop */
  408. nextinput:
  409. while((next = NextPic(cml->inputRateNumer, cml->inputRateDenom,
  410. cml->outputRateNumer, cml->outputRateDenom,
  411. (cml->inputMvc) ? frameCnt/2 : frameCnt,
  412. cml->firstPic)) <= cml->lastPic)
  413. {
  414. #ifdef EVALUATION_LIMIT
  415. if(frameCnt >= EVALUATION_LIMIT)
  416. break;
  417. #endif
  418. #ifndef NO_INPUT_READ
  419. /* Read next frame */
  420. if(ReadPic((u8 *) pictureMem.virtualAddress,
  421. src_img_size, next,
  422. (cml->inputMvc && (frameCnt%2)) ? cml->inputMvc : cml->input,
  423. cml->lumWidthSrc, cml->lumHeightSrc, cml->inputFormat) != 0)
  424. break;
  425. if(cml->videoStab > 0)
  426. {
  427. /* Stabilize the frame after current frame */
  428. i32 nextStab = NextPic(cml->inputRateNumer, cml->inputRateDenom,
  429. cml->outputRateNumer, cml->outputRateDenom, frameCnt+1,
  430. cml->firstPic);
  431. if(ReadPic((u8 *) pictureStabMem.virtualAddress,
  432. src_img_size, nextStab, cml->input,
  433. cml->lumWidthSrc, cml->lumHeightSrc,
  434. cml->inputFormat) != 0)
  435. break;
  436. }
  437. #endif
  438. for (i = 0; i < MAX_BPS_ADJUST; i++)
  439. if (cml->bpsAdjustFrame[i] &&
  440. (codedFrameCnt == cml->bpsAdjustFrame[i]))
  441. {
  442. rc.bitPerSecond = cml->bpsAdjustBitrate[i];
  443. printf("Adjusting bitrate target: %d\n", rc.bitPerSecond);
  444. if((ret = H264EncSetRateCtrl(encoder, &rc)) != H264ENC_OK)
  445. {
  446. PrintErrorValue("H264EncSetRateCtrl() failed.", ret);
  447. }
  448. }
  449. /* Select frame type */
  450. if((cml->intraPicRate != 0) && (intraPeriodCnt >= cml->intraPicRate))
  451. encIn.codingType = H264ENC_INTRA_FRAME;
  452. else
  453. encIn.codingType = H264ENC_PREDICTED_FRAME;
  454. ret = H264EncStrmEncode(encoder, &encIn, &encOut, &H264SliceReady, NULL);
  455. H264EncGetRateCtrl(encoder, &rc);
  456. streamSize += encOut.streamSize;
  457. MaAddFrame(&ma, encOut.streamSize*8);
  458. if((frameCnt+1) && cml->outputRateDenom)
  459. {
  460. /* Using 64-bits to avoid overflow */
  461. unsigned long long tmp = streamSize / (frameCnt+1);
  462. tmp *= (u32) cml->outputRateNumer;
  463. bitrate = (u32) (8 * (tmp / (u32) cml->outputRateDenom));
  464. }
  465. switch (ret)
  466. {
  467. case H264ENC_FRAME_READY:
  468. printf("%5i | %3i | %2i | %s | %9u %9u | %7i %6i | ",
  469. next, frameCnt, rc.qpHdr,
  470. encOut.codingType == H264ENC_INTRA_FRAME ? " I " :
  471. encOut.codingType == H264ENC_PREDICTED_FRAME ? " P " : "skip",
  472. bitrate, Ma(&ma), streamSize, encOut.streamSize);
  473. if (cml->psnr)
  474. psnr = PrintPSNR((u8 *)
  475. (((h264Instance_s *)encoder)->asic.regs.inputLumBase +
  476. ((h264Instance_s *)encoder)->asic.regs.inputLumaBaseOffset),
  477. (u8 *)
  478. (((h264Instance_s *)encoder)->asic.regs.internalImageLumBaseR),
  479. cml->lumWidthSrc, cml->width, cml->height, cml->rotation);
  480. if (psnr) {
  481. psnrSum += psnr;
  482. psnrCnt++;
  483. }
  484. PrintNalSizes(encOut.pNaluSizeBuf, (u8 *) outbufMem.virtualAddress,
  485. encOut.streamSize, cml->byteStream);
  486. printf("\n");
  487. WriteStrm(fout, outbufMem.virtualAddress, encOut.streamSize, 0);
  488. if(cml->byteStream == 0)
  489. WriteNalSizesToFile(nal_sizes_file, encOut.pNaluSizeBuf,
  490. encOut.numNalus);
  491. WriteMotionVectors(fmv, encOut.motionVectors, frameCnt,
  492. cml->width, cml->height);
  493. if (pUserData)
  494. {
  495. /* We want the user data to be written only once so
  496. * we disable the user data and free the memory after
  497. * first frame has been encoded. */
  498. H264EncSetSeiUserData(encoder, NULL, 0);
  499. free(pUserData);
  500. pUserData = NULL;
  501. }
  502. break;
  503. case H264ENC_OUTPUT_BUFFER_OVERFLOW:
  504. printf("%5i | %3i | %2i | %s | %9u %9u | %7i %6i | \n",
  505. next, frameCnt, rc.qpHdr, "lost",
  506. bitrate, Ma(&ma), streamSize, encOut.streamSize);
  507. break;
  508. default:
  509. PrintErrorValue("H264EncStrmEncode() failed.", ret);
  510. /* For debugging, can be removed */
  511. WriteStrm(fout, outbufMem.virtualAddress, encOut.streamSize, 0);
  512. /* We try to continue encoding the next frame */
  513. break;
  514. }
  515. encIn.timeIncrement = cml->outputRateDenom;
  516. frameCnt++;
  517. if (encOut.codingType == H264ENC_INTRA_FRAME)
  518. intraPeriodCnt = 0;
  519. if (encOut.codingType != H264ENC_NOTCODED_FRAME) {
  520. intraPeriodCnt++; codedFrameCnt++;
  521. }
  522. } /* End of main encoding loop */
  523. /* Change next input sequence */
  524. if(ChangeInput(argc, argv, &cml->input, option))
  525. {
  526. if(yuvFile != NULL)
  527. {
  528. fclose(yuvFile);
  529. yuvFile = NULL;
  530. }
  531. frameCnt = 0;
  532. goto nextinput;
  533. }
  534. /* End stream */
  535. ret = H264EncStrmEnd(encoder, &encIn, &encOut);
  536. if(ret != H264ENC_OK)
  537. {
  538. PrintErrorValue("H264EncStrmEnd() failed.", ret);
  539. }
  540. else
  541. {
  542. streamSize += encOut.streamSize;
  543. printf(" | | | END | | %7i %6i | ",
  544. streamSize, encOut.streamSize);
  545. if (cml->psnr)
  546. printf(" | ");
  547. PrintNalSizes(encOut.pNaluSizeBuf, (u8 *) outbufMem.virtualAddress,
  548. encOut.streamSize, cml->byteStream);
  549. printf("\n");
  550. WriteStrm(fout, outbufMem.virtualAddress, encOut.streamSize, 0);
  551. if(cml->byteStream == 0)
  552. {
  553. WriteNalSizesToFile(nal_sizes_file, encOut.pNaluSizeBuf,
  554. encOut.numNalus);
  555. }
  556. }
  557. printf("\nBitrate target %d bps, actual %d bps (%d%%).\n",
  558. rc.bitPerSecond, bitrate,
  559. (rc.bitPerSecond) ? bitrate*100/rc.bitPerSecond : 0);
  560. printf("Total of %d frames processed, %d frames encoded, %d bytes.\n",
  561. frameCnt, codedFrameCnt, streamSize);
  562. if (psnrCnt)
  563. printf("Average PSNR %d.%02d\n",
  564. (psnrSum/psnrCnt)/100, (psnrSum/psnrCnt)%100);
  565. /* Free all resources */
  566. if(fout != NULL)
  567. fclose(fout);
  568. if(fmv != NULL)
  569. fclose(fmv);
  570. if(yuvFile != NULL)
  571. fclose(yuvFile);
  572. if(yuvFileMvc != NULL)
  573. fclose(yuvFileMvc);
  574. return 0;
  575. }
  576. /*------------------------------------------------------------------------------
  577. AllocRes
  578. Allocation of the physical memories used by both SW and HW:
  579. the input pictures and the output stream buffer.
  580. NOTE! The implementation uses the EWL instance from the encoder
  581. for OS independence. This is not recommended in final environment
  582. because the encoder will release the EWL instance in case of error.
  583. Instead, the memories should be allocated from the OS the same way
  584. as inside EWLMallocLinear().
  585. ------------------------------------------------------------------------------*/
  586. int AllocRes(commandLine_s * cmdl, H264EncInst enc)
  587. {
  588. i32 ret;
  589. u32 pictureSize;
  590. u32 outbufSize;
  591. if(cmdl->inputFormat <= 1)
  592. {
  593. /* Input picture in planar YUV 4:2:0 format */
  594. pictureSize =
  595. ((cmdl->lumWidthSrc + 15) & (~15)) * cmdl->lumHeightSrc * 3 / 2;
  596. }
  597. else if((cmdl->inputFormat <= 9))
  598. {
  599. /* Input picture in YUYV 4:2:2 or 16-bit RGB format */
  600. pictureSize =
  601. ((cmdl->lumWidthSrc + 15) & (~15)) * cmdl->lumHeightSrc * 2;
  602. }
  603. else
  604. {
  605. /* Input picture in 32-bit RGB format */
  606. pictureSize =
  607. ((cmdl->lumWidthSrc + 15) & (~15)) * cmdl->lumHeightSrc * 4;
  608. }
  609. printf("Input %dx%d encoding at %dx%d\n", cmdl->lumWidthSrc,
  610. cmdl->lumHeightSrc, cmdl->width, cmdl->height);
  611. pictureMem.virtualAddress = NULL;
  612. outbufMem.virtualAddress = NULL;
  613. pictureStabMem.virtualAddress = NULL;
  614. /* Here we use the EWL instance directly from the encoder
  615. * because it is the easiest way to allocate the linear memories */
  616. ret = EWLMallocLinear(((h264Instance_s *)enc)->asic.ewl, pictureSize,
  617. &pictureMem);
  618. if (ret != EWL_OK)
  619. {
  620. fprintf(H264ERR_OUTPUT, "Failed to allocate input picture!\n");
  621. pictureMem.virtualAddress = NULL;
  622. return 1;
  623. }
  624. if(cmdl->videoStab > 0)
  625. {
  626. ret = EWLMallocLinear(((h264Instance_s *)enc)->asic.ewl, pictureSize,
  627. &pictureStabMem);
  628. if (ret != EWL_OK)
  629. {
  630. fprintf(H264ERR_OUTPUT, "Failed to allocate stab input picture!\n");
  631. pictureStabMem.virtualAddress = NULL;
  632. return 1;
  633. }
  634. }
  635. outbufSize = 4 * pictureMem.size < (1024 * 1024 * 8) ?
  636. 4 * pictureMem.size : (1024 * 1024 * 8);
  637. ret = EWLMallocLinear(((h264Instance_s *)enc)->asic.ewl, outbufSize,
  638. &outbufMem);
  639. if (ret != EWL_OK)
  640. {
  641. fprintf(H264ERR_OUTPUT, "Failed to allocate output buffer!\n");
  642. outbufMem.virtualAddress = NULL;
  643. return 1;
  644. }
  645. printf("Input buffer size: %d bytes\n", pictureMem.size);
  646. printf("Input buffer bus address: 0x%08x\n", pictureMem.busAddress);
  647. printf("Input buffer user address: 0x%08x\n", (u32) pictureMem.virtualAddress);
  648. printf("Output buffer size: %d bytes\n", outbufMem.size);
  649. printf("Output buffer bus address: 0x%08x\n", outbufMem.busAddress);
  650. printf("Output buffer user address: 0x%08x\n", (u32) outbufMem.virtualAddress);
  651. return 0;
  652. }
  653. /*------------------------------------------------------------------------------
  654. FreeRes
  655. Release all resources allcoated byt AllocRes()
  656. ------------------------------------------------------------------------------*/
  657. void FreeRes(H264EncInst enc)
  658. {
  659. if(pictureMem.virtualAddress != NULL)
  660. EWLFreeLinear(((h264Instance_s *)enc)->asic.ewl, &pictureMem);
  661. if(pictureStabMem.virtualAddress != NULL)
  662. EWLFreeLinear(((h264Instance_s *)enc)->asic.ewl, &pictureStabMem);
  663. if(outbufMem.virtualAddress != NULL)
  664. EWLFreeLinear(((h264Instance_s *)enc)->asic.ewl, &outbufMem);
  665. }
  666. /*------------------------------------------------------------------------------
  667. OpenEncoder
  668. Create and configure an encoder instance.
  669. Params:
  670. cml - processed comand line options
  671. pEnc - place where to save the new encoder instance
  672. Return:
  673. 0 - for success
  674. -1 - error
  675. ------------------------------------------------------------------------------*/
  676. int OpenEncoder(commandLine_s * cml, H264EncInst * pEnc)
  677. {
  678. H264EncRet ret;
  679. H264EncConfig cfg;
  680. H264EncCodingCtrl codingCfg;
  681. H264EncRateCtrl rcCfg;
  682. H264EncPreProcessingCfg preProcCfg;
  683. H264EncInst encoder;
  684. /* Default resolution, try parsing input file name */
  685. if(cml->lumWidthSrc == DEFAULT || cml->lumHeightSrc == DEFAULT)
  686. {
  687. if (GetResolution(cml->input, &cml->lumWidthSrc, &cml->lumHeightSrc))
  688. {
  689. /* No dimensions found in filename, using default QCIF */
  690. cml->lumWidthSrc = 176;
  691. cml->lumHeightSrc = 144;
  692. }
  693. }
  694. /* Encoder initialization */
  695. if(cml->width == DEFAULT)
  696. cml->width = cml->lumWidthSrc;
  697. if(cml->height == DEFAULT)
  698. cml->height = cml->lumHeightSrc;
  699. /* outputRateNumer */
  700. if(cml->outputRateNumer == DEFAULT)
  701. {
  702. cml->outputRateNumer = cml->inputRateNumer;
  703. }
  704. /* outputRateDenom */
  705. if(cml->outputRateDenom == DEFAULT)
  706. {
  707. cml->outputRateDenom = cml->inputRateDenom;
  708. }
  709. if(cml->rotation)
  710. {
  711. cfg.width = cml->height;
  712. cfg.height = cml->width;
  713. }
  714. else
  715. {
  716. cfg.width = cml->width;
  717. cfg.height = cml->height;
  718. }
  719. cfg.frameRateDenom = cml->outputRateDenom;
  720. cfg.frameRateNum = cml->outputRateNumer;
  721. cfg.viewMode = H264ENC_BASE_VIEW_DOUBLE_BUFFER; /* Two buffers by default */
  722. if(cml->viewMode != DEFAULT)
  723. cfg.viewMode = cml->viewMode;
  724. if(cml->byteStream)
  725. cfg.streamType = H264ENC_BYTE_STREAM;
  726. else
  727. cfg.streamType = H264ENC_NAL_UNIT_STREAM;
  728. cfg.level = H264ENC_LEVEL_4;
  729. if(cml->level != DEFAULT && cml->level != 0)
  730. cfg.level = (H264EncLevel)cml->level;
  731. printf
  732. ("Init config: size %dx%d %d/%d fps %s %s P&L %d\n",
  733. cfg.width, cfg.height, cfg.frameRateNum,
  734. cfg.frameRateDenom, streamType[cfg.streamType],
  735. viewMode[cfg.viewMode], cfg.level);
  736. if((ret = H264EncInit(&cfg, pEnc)) != H264ENC_OK)
  737. {
  738. PrintErrorValue("H264EncInit() failed.", ret);
  739. return -1;
  740. }
  741. encoder = *pEnc;
  742. /* Encoder setup: rate control */
  743. if((ret = H264EncGetRateCtrl(encoder, &rcCfg)) != H264ENC_OK)
  744. {
  745. PrintErrorValue("H264EncGetRateCtrl() failed.", ret);
  746. CloseEncoder(encoder);
  747. return -1;
  748. }
  749. else
  750. {
  751. printf("Get rate control: qp %2d [%2d, %2d] %8d bps "
  752. "pic %d mb %d skip %d hrd %d\n cpbSize %d gopLen %d "
  753. "intraQpDelta %2d\n",
  754. rcCfg.qpHdr, rcCfg.qpMin, rcCfg.qpMax, rcCfg.bitPerSecond,
  755. rcCfg.pictureRc, rcCfg.mbRc, rcCfg.pictureSkip, rcCfg.hrd,
  756. rcCfg.hrdCpbSize, rcCfg.gopLen, rcCfg.intraQpDelta);
  757. if(cml->qpHdr != DEFAULT)
  758. rcCfg.qpHdr = cml->qpHdr;
  759. if(cml->qpMin != DEFAULT)
  760. rcCfg.qpMin = cml->qpMin;
  761. if(cml->qpMax != DEFAULT)
  762. rcCfg.qpMax = cml->qpMax;
  763. if(cml->picSkip != DEFAULT)
  764. rcCfg.pictureSkip = cml->picSkip;
  765. if(cml->picRc != DEFAULT)
  766. rcCfg.pictureRc = cml->picRc;
  767. if(cml->mbRc != DEFAULT)
  768. rcCfg.mbRc = cml->mbRc != 0 ? 1 : 0;
  769. if(cml->bitPerSecond != DEFAULT)
  770. rcCfg.bitPerSecond = cml->bitPerSecond;
  771. if(cml->hrdConformance != DEFAULT)
  772. rcCfg.hrd = cml->hrdConformance;
  773. if(cml->cpbSize != DEFAULT)
  774. rcCfg.hrdCpbSize = cml->cpbSize;
  775. if(cml->intraPicRate != 0)
  776. rcCfg.gopLen = MIN(cml->intraPicRate, MAX_GOP_LEN);
  777. if(cml->gopLength != DEFAULT)
  778. rcCfg.gopLen = cml->gopLength;
  779. if(cml->intraQpDelta != DEFAULT)
  780. rcCfg.intraQpDelta = cml->intraQpDelta;
  781. rcCfg.fixedIntraQp = cml->fixedIntraQp;
  782. rcCfg.mbQpAdjustment = cml->mbQpAdjustment;
  783. printf("Set rate control: qp %2d [%2d, %2d] %8d bps "
  784. "pic %d mb %d skip %d hrd %d\n"
  785. " cpbSize %d gopLen %d intraQpDelta %2d "
  786. "fixedIntraQp %2d mbQpAdjustment %d\n",
  787. rcCfg.qpHdr, rcCfg.qpMin, rcCfg.qpMax, rcCfg.bitPerSecond,
  788. rcCfg.pictureRc, rcCfg.mbRc, rcCfg.pictureSkip, rcCfg.hrd,
  789. rcCfg.hrdCpbSize, rcCfg.gopLen, rcCfg.intraQpDelta,
  790. rcCfg.fixedIntraQp, rcCfg.mbQpAdjustment);
  791. if((ret = H264EncSetRateCtrl(encoder, &rcCfg)) != H264ENC_OK)
  792. {
  793. PrintErrorValue("H264EncSetRateCtrl() failed.", ret);
  794. CloseEncoder(encoder);
  795. return -1;
  796. }
  797. }
  798. /* Encoder setup: coding control */
  799. if((ret = H264EncGetCodingCtrl(encoder, &codingCfg)) != H264ENC_OK)
  800. {
  801. PrintErrorValue("H264EncGetCodingCtrl() failed.", ret);
  802. CloseEncoder(encoder);
  803. return -1;
  804. }
  805. else
  806. {
  807. if(cml->mbRowPerSlice != DEFAULT)
  808. {
  809. codingCfg.sliceSize = cml->mbRowPerSlice;
  810. }
  811. if(cml->constIntraPred != DEFAULT)
  812. {
  813. if(cml->constIntraPred != 0)
  814. codingCfg.constrainedIntraPrediction = 1;
  815. else
  816. codingCfg.constrainedIntraPrediction = 0;
  817. }
  818. if(cml->disableDeblocking != 0)
  819. codingCfg.disableDeblockingFilter = 1;
  820. else
  821. codingCfg.disableDeblockingFilter = 0;
  822. if((cml->disableDeblocking != 1) &&
  823. ((cml->filterOffsetA != 0) || (cml->filterOffsetB != 0)))
  824. codingCfg.disableDeblockingFilter = 1;
  825. if(cml->enableCabac != DEFAULT)
  826. {
  827. codingCfg.enableCabac = cml->enableCabac;
  828. if (cml->cabacInitIdc != DEFAULT)
  829. codingCfg.cabacInitIdc = cml->cabacInitIdc;
  830. }
  831. codingCfg.transform8x8Mode = cml->trans8x8;
  832. if(cml->quarterPixelMv != DEFAULT)
  833. codingCfg.quarterPixelMv = cml->quarterPixelMv;
  834. if(cml->videoRange != DEFAULT)
  835. {
  836. if(cml->videoRange != 0)
  837. codingCfg.videoFullRange = 1;
  838. else
  839. codingCfg.videoFullRange = 0;
  840. }
  841. if(cml->sei)
  842. codingCfg.seiMessages = 1;
  843. else
  844. codingCfg.seiMessages = 0;
  845. codingCfg.cirStart = cml->cirStart;
  846. codingCfg.cirInterval = cml->cirInterval;
  847. codingCfg.intraSliceMap1 = cml->intraSliceMap1;
  848. codingCfg.intraSliceMap2 = cml->intraSliceMap2;
  849. codingCfg.intraSliceMap3 = cml->intraSliceMap3;
  850. codingCfg.intraArea.enable = cml->intraAreaEnable;
  851. codingCfg.intraArea.top = cml->intraAreaTop;
  852. codingCfg.intraArea.left = cml->intraAreaLeft;
  853. codingCfg.intraArea.bottom = cml->intraAreaBottom;
  854. codingCfg.intraArea.right = cml->intraAreaRight;
  855. codingCfg.roi1Area.enable = cml->roi1AreaEnable;
  856. codingCfg.roi1Area.top = cml->roi1AreaTop;
  857. codingCfg.roi1Area.left = cml->roi1AreaLeft;
  858. codingCfg.roi1Area.bottom = cml->roi1AreaBottom;
  859. codingCfg.roi1Area.right = cml->roi1AreaRight;
  860. codingCfg.roi2Area.enable = cml->roi2AreaEnable;
  861. codingCfg.roi2Area.top = cml->roi2AreaTop;
  862. codingCfg.roi2Area.left = cml->roi2AreaLeft;
  863. codingCfg.roi2Area.bottom = cml->roi2AreaBottom;
  864. codingCfg.roi2Area.right = cml->roi2AreaRight;
  865. codingCfg.roi1DeltaQp = cml->roi1DeltaQp;
  866. codingCfg.roi2DeltaQp = cml->roi2DeltaQp;
  867. printf
  868. ("Set coding control: SEI %d Slice %5d deblocking %d "
  869. "constrained intra %d video range %d\n"
  870. " cabac %d cabac initial idc %d Adaptive 8x8 transform %d"
  871. " quarter-pixel MV %d\n",
  872. codingCfg.seiMessages, codingCfg.sliceSize,
  873. codingCfg.disableDeblockingFilter,
  874. codingCfg.constrainedIntraPrediction, codingCfg.videoFullRange,
  875. codingCfg.enableCabac,
  876. codingCfg.cabacInitIdc, codingCfg.transform8x8Mode,
  877. codingCfg.quarterPixelMv );
  878. if (codingCfg.cirInterval)
  879. printf(" CIR: %d %d\n",
  880. codingCfg.cirStart, codingCfg.cirInterval);
  881. if (codingCfg.intraSliceMap1 || codingCfg.intraSliceMap2 ||
  882. codingCfg.intraSliceMap3)
  883. printf(" IntraSliceMap: 0x%0x 0x%0x 0x%0x\n",
  884. codingCfg.intraSliceMap1, codingCfg.intraSliceMap2,
  885. codingCfg.intraSliceMap3);
  886. if (codingCfg.intraArea.enable)
  887. printf(" IntraArea: %dx%d-%dx%d\n",
  888. codingCfg.intraArea.left, codingCfg.intraArea.top,
  889. codingCfg.intraArea.right, codingCfg.intraArea.bottom);
  890. if (codingCfg.roi1Area.enable)
  891. printf(" ROI 1: %d %dx%d-%dx%d\n", codingCfg.roi1DeltaQp,
  892. codingCfg.roi1Area.left, codingCfg.roi1Area.top,
  893. codingCfg.roi1Area.right, codingCfg.roi1Area.bottom);
  894. if (codingCfg.roi2Area.enable)
  895. printf(" ROI 2: %d %dx%d-%dx%d\n", codingCfg.roi2DeltaQp,
  896. codingCfg.roi2Area.left, codingCfg.roi2Area.top,
  897. codingCfg.roi2Area.right, codingCfg.roi2Area.bottom);
  898. if((ret = H264EncSetCodingCtrl(encoder, &codingCfg)) != H264ENC_OK)
  899. {
  900. PrintErrorValue("H264EncSetCodingCtrl() failed.", ret);
  901. CloseEncoder(encoder);
  902. return -1;
  903. }
  904. #ifdef INTERNAL_TEST
  905. /* Set some values outside the product API for internal
  906. * testing purposes */
  907. H264EncSetChromaQpIndexOffset(encoder, cml->chromaQpOffset);
  908. printf("Set ChromaQpIndexOffset: %d\n", cml->chromaQpOffset);
  909. H264EncSetHwBurstSize(encoder, cml->burst);
  910. printf("Set HW Burst Size: %d\n", cml->burst);
  911. H264EncSetHwBurstType(encoder, cml->bursttype);
  912. printf("Set HW Burst Type: %d\n", cml->bursttype);
  913. if(codingCfg.disableDeblockingFilter == 1)
  914. {
  915. H264EncFilter advCoding;
  916. H264EncGetFilter(encoder, &advCoding);
  917. advCoding.disableDeblocking = cml->disableDeblocking;
  918. advCoding.filterOffsetA = cml->filterOffsetA * 2;
  919. advCoding.filterOffsetB = cml->filterOffsetB * 2;
  920. printf
  921. ("Set filter params: disableDeblocking %d filterOffsetA = %i filterOffsetB = %i\n",
  922. advCoding.disableDeblocking, advCoding.filterOffsetA,
  923. advCoding.filterOffsetB);
  924. ret = H264EncSetFilter(encoder, &advCoding);
  925. if(ret != H264ENC_OK)
  926. {
  927. PrintErrorValue("H264EncSetFilter() failed.", ret);
  928. CloseEncoder(encoder);
  929. return -1;
  930. }
  931. }
  932. #endif
  933. }
  934. /* PreP setup */
  935. if((ret = H264EncGetPreProcessing(encoder, &preProcCfg)) != H264ENC_OK)
  936. {
  937. PrintErrorValue("H264EncGetPreProcessing() failed.", ret);
  938. CloseEncoder(encoder);
  939. return -1;
  940. }
  941. printf
  942. ("Get PreP: input %4dx%d : offset %4dx%d : format %d : rotation %d "
  943. ": stab %d : cc %d\n",
  944. preProcCfg.origWidth, preProcCfg.origHeight, preProcCfg.xOffset,
  945. preProcCfg.yOffset, preProcCfg.inputType, preProcCfg.rotation,
  946. preProcCfg.videoStabilization, preProcCfg.colorConversion.type);
  947. preProcCfg.inputType = (H264EncPictureType)cml->inputFormat;
  948. preProcCfg.rotation = (H264EncPictureRotation)cml->rotation;
  949. preProcCfg.origWidth =
  950. cml->lumWidthSrc /*(cml->lumWidthSrc + 15) & (~0x0F) */ ;
  951. preProcCfg.origHeight = cml->lumHeightSrc;
  952. if(cml->horOffsetSrc != DEFAULT)
  953. preProcCfg.xOffset = cml->horOffsetSrc;
  954. if(cml->verOffsetSrc != DEFAULT)
  955. preProcCfg.yOffset = cml->verOffsetSrc;
  956. if(cml->videoStab != DEFAULT)
  957. preProcCfg.videoStabilization = cml->videoStab;
  958. if(cml->colorConversion != DEFAULT)
  959. preProcCfg.colorConversion.type =
  960. (H264EncColorConversionType)cml->colorConversion;
  961. if(preProcCfg.colorConversion.type == H264ENC_RGBTOYUV_USER_DEFINED)
  962. {
  963. preProcCfg.colorConversion.coeffA = 20000;
  964. preProcCfg.colorConversion.coeffB = 44000;
  965. preProcCfg.colorConversion.coeffC = 5000;
  966. preProcCfg.colorConversion.coeffE = 35000;
  967. preProcCfg.colorConversion.coeffF = 38000;
  968. }
  969. printf
  970. ("Set PreP: input %4dx%d : offset %4dx%d : format %d : rotation %d "
  971. ": stab %d : cc %d\n",
  972. preProcCfg.origWidth, preProcCfg.origHeight, preProcCfg.xOffset,
  973. preProcCfg.yOffset, preProcCfg.inputType, preProcCfg.rotation,
  974. preProcCfg.videoStabilization, preProcCfg.colorConversion.type);
  975. if((ret = H264EncSetPreProcessing(encoder, &preProcCfg)) != H264ENC_OK)
  976. {
  977. PrintErrorValue("H264EncSetPreProcessing() failed.", ret);
  978. CloseEncoder(encoder);
  979. return -1;
  980. }
  981. return 0;
  982. }
  983. /*------------------------------------------------------------------------------
  984. CloseEncoder
  985. Release an encoder insatnce.
  986. Params:
  987. encoder - the instance to be released
  988. ------------------------------------------------------------------------------*/
  989. void CloseEncoder(H264EncInst encoder)
  990. {
  991. H264EncRet ret;
  992. if((ret = H264EncRelease(encoder)) != H264ENC_OK)
  993. {
  994. PrintErrorValue("H264EncRelease() failed.", ret);
  995. }
  996. }
  997. /*------------------------------------------------------------------------------
  998. ------------------------------------------------------------------------------*/
  999. int ParseDelim(char *optArg, char delim)
  1000. {
  1001. i32 i;
  1002. for (i = 0; i < (i32)strlen(optArg); i++)
  1003. if (optArg[i] == delim)
  1004. {
  1005. optArg[i] = 0;
  1006. return i;
  1007. }
  1008. return -1;
  1009. }
  1010. /*------------------------------------------------------------------------------
  1011. Parameter
  1012. Process the testbench calling arguments.
  1013. Params:
  1014. argc - number of arguments to the application
  1015. argv - argument list as provided to the application
  1016. cml - processed comand line options
  1017. Return:
  1018. 0 - for success
  1019. -1 - error
  1020. ------------------------------------------------------------------------------*/
  1021. int Parameter(i32 argc, char **argv, commandLine_s * cml)
  1022. {
  1023. i32 ret, i;
  1024. char *optArg;
  1025. argument_s argument;
  1026. i32 status = 0;
  1027. i32 bpsAdjustCount = 0;
  1028. memset(cml, 0, sizeof(commandLine_s));
  1029. cml->width = DEFAULT;
  1030. cml->height = DEFAULT;
  1031. cml->outputRateNumer = DEFAULT;
  1032. cml->outputRateDenom = DEFAULT;
  1033. cml->qpHdr = DEFAULT;
  1034. cml->qpMin = DEFAULT;
  1035. cml->qpMax = DEFAULT;
  1036. cml->picRc = DEFAULT;
  1037. cml->mbRc = DEFAULT;
  1038. cml->cpbSize = DEFAULT;
  1039. cml->constIntraPred = DEFAULT;
  1040. cml->horOffsetSrc = DEFAULT;
  1041. cml->verOffsetSrc = DEFAULT;
  1042. cml->videoStab = DEFAULT;
  1043. cml->gopLength = DEFAULT;
  1044. cml->input = input;
  1045. cml->output = output;
  1046. cml->firstPic = 0;
  1047. cml->lastPic = 100;
  1048. cml->inputRateNumer = 30;
  1049. cml->inputRateDenom = 1;
  1050. cml->lumWidthSrc = DEFAULT;
  1051. cml->lumHeightSrc = DEFAULT;
  1052. cml->rotation = 0;
  1053. cml->inputFormat = 0;
  1054. cml->bitPerSecond = 1000000;
  1055. cml->intraQpDelta = DEFAULT;
  1056. cml->fixedIntraQp=0;
  1057. cml->chromaQpOffset = 2;
  1058. cml->disableDeblocking = 0;
  1059. cml->filterOffsetA = 0;
  1060. cml->filterOffsetB = 0;
  1061. cml->enableCabac = DEFAULT;
  1062. cml->cabacInitIdc = DEFAULT;
  1063. cml->trans8x8 = 0;
  1064. cml->burst = 16;
  1065. cml->bursttype = 0;
  1066. cml->quarterPixelMv = DEFAULT;
  1067. cml->testId = 0;
  1068. cml->viewMode = DEFAULT;
  1069. cml->sei = 0;
  1070. cml->byteStream = 1;
  1071. cml->hrdConformance = 0;
  1072. cml->videoRange = 0;
  1073. cml->picSkip = 0;
  1074. cml->psnr = 0;
  1075. cml->testParam = 0;
  1076. argument.optCnt = 1;
  1077. while((ret = EncGetOption(argc, argv, option, &argument)) != -1)
  1078. {
  1079. if(ret == -2)
  1080. {
  1081. status = 1;
  1082. }
  1083. optArg = argument.optArg;
  1084. switch (argument.shortOpt)
  1085. {
  1086. case 'i':
  1087. cml->input = optArg;
  1088. break;
  1089. case '9':
  1090. cml->inputMvc = optArg;
  1091. break;
  1092. case 'o':
  1093. cml->output = optArg;
  1094. break;
  1095. case 'z':
  1096. cml->userData = optArg;
  1097. break;
  1098. case 'a':
  1099. cml->firstPic = atoi(optArg);
  1100. break;
  1101. case 'b':
  1102. cml->lastPic = atoi(optArg);
  1103. break;
  1104. case 'x':
  1105. cml->width = atoi(optArg);
  1106. break;
  1107. case 'y':
  1108. cml->height = atoi(optArg);
  1109. break;
  1110. case 'w':
  1111. cml->lumWidthSrc = atoi(optArg);
  1112. break;
  1113. case 'h':
  1114. cml->lumHeightSrc = atoi(optArg);
  1115. break;
  1116. case 'X':
  1117. cml->horOffsetSrc = atoi(optArg);
  1118. break;
  1119. case 'Y':
  1120. cml->verOffsetSrc = atoi(optArg);
  1121. break;
  1122. case 'f':
  1123. cml->outputRateNumer = atoi(optArg);
  1124. break;
  1125. case 'F':
  1126. cml->outputRateDenom = atoi(optArg);
  1127. break;
  1128. case 'j':
  1129. cml->inputRateNumer = atoi(optArg);
  1130. break;
  1131. case 'J':
  1132. cml->inputRateDenom = atoi(optArg);
  1133. break;
  1134. case 'T':
  1135. cml->constIntraPred = atoi(optArg);
  1136. break;
  1137. case 'D':
  1138. cml->disableDeblocking = atoi(optArg);
  1139. break;
  1140. case 'W':
  1141. cml->filterOffsetA = atoi(optArg);
  1142. break;
  1143. case 'E':
  1144. cml->filterOffsetB = atoi(optArg);
  1145. break;
  1146. case '8':
  1147. cml->trans8x8 = atoi(optArg);
  1148. break;
  1149. case 'K':
  1150. cml->enableCabac = atoi(optArg);
  1151. break;
  1152. case 'p':
  1153. cml->cabacInitIdc = atoi(optArg);
  1154. break;
  1155. case 'I':
  1156. cml->intraPicRate = atoi(optArg);
  1157. break;
  1158. case 'N':
  1159. cml->burst = atoi(optArg);
  1160. break;
  1161. case 't':
  1162. cml->bursttype = atoi(optArg);
  1163. break;
  1164. case 'q':
  1165. cml->qpHdr = atoi(optArg);
  1166. break;
  1167. case 'n':
  1168. cml->qpMin = atoi(optArg);
  1169. break;
  1170. case 'm':
  1171. cml->qpMax = atoi(optArg);
  1172. break;
  1173. case 'B':
  1174. cml->bitPerSecond = atoi(optArg);
  1175. break;
  1176. case 'U':
  1177. cml->picRc = atoi(optArg);
  1178. break;
  1179. case 'u':
  1180. cml->mbRc = atoi(optArg);
  1181. break;
  1182. case 's':
  1183. cml->picSkip = atoi(optArg);
  1184. break;
  1185. case 'r':
  1186. cml->rotation = atoi(optArg);
  1187. break;
  1188. case 'l':
  1189. cml->inputFormat = atoi(optArg);
  1190. break;
  1191. case 'O':
  1192. cml->colorConversion = atoi(optArg);
  1193. break;
  1194. case 'Q':
  1195. cml->chromaQpOffset = atoi(optArg);
  1196. break;
  1197. case 'V':
  1198. cml->mbRowPerSlice = atoi(optArg);
  1199. break;
  1200. case 'k':
  1201. cml->videoRange = atoi(optArg);
  1202. break;
  1203. case 'L':
  1204. cml->level = atoi(optArg);
  1205. break;
  1206. case 'C':
  1207. cml->hrdConformance = atoi(optArg);
  1208. break;
  1209. case 'c':
  1210. cml->cpbSize = atoi(optArg);
  1211. break;
  1212. case 'e':
  1213. cml->testId = atoi(optArg);
  1214. break;
  1215. case 'S':
  1216. cml->sei = atoi(optArg);
  1217. break;
  1218. case 'M':
  1219. cml->quarterPixelMv = atoi(optArg);
  1220. break;
  1221. case 'P':
  1222. trigger_point = atoi(optArg);
  1223. break;
  1224. case 'R':
  1225. cml->byteStream = atoi(optArg);
  1226. break;
  1227. case 'Z':
  1228. cml->videoStab = atoi(optArg);
  1229. break;
  1230. case 'g':
  1231. cml->gopLength = atoi(optArg);
  1232. break;
  1233. case 'A':
  1234. cml->intraQpDelta = atoi(optArg);
  1235. break;
  1236. case 'G':
  1237. cml->fixedIntraQp = atoi(optArg);
  1238. break;
  1239. case '1':
  1240. if (bpsAdjustCount == MAX_BPS_ADJUST)
  1241. break;
  1242. /* Argument must be "xx:yy", replace ':' with 0 */
  1243. if ((i = ParseDelim(optArg, ':')) == -1) break;
  1244. /* xx is frame number */
  1245. cml->bpsAdjustFrame[bpsAdjustCount] = atoi(optArg);
  1246. /* yy is new target bitrate */
  1247. cml->bpsAdjustBitrate[bpsAdjustCount] = atoi(optArg+i+1);
  1248. bpsAdjustCount++;
  1249. break;
  1250. case '2':
  1251. cml->mbQpAdjustment = atoi(optArg);
  1252. break;
  1253. case 'v':
  1254. cml->testParam = atoi(optArg);
  1255. break;
  1256. case 'd':
  1257. cml->psnr = 1;
  1258. break;
  1259. case '3':
  1260. cml->mvOutput = atoi(optArg);
  1261. break;
  1262. case '0':
  1263. /* Check long option */
  1264. if (strcmp(argument.longOpt, "intraSliceMap1") == 0)
  1265. cml->intraSliceMap1 = strtoul(optArg, NULL, 16);
  1266. if (strcmp(argument.longOpt, "intraSliceMap2") == 0)
  1267. cml->intraSliceMap2 = strtoul(optArg, NULL, 16);
  1268. if (strcmp(argument.longOpt, "intraSliceMap3") == 0)
  1269. cml->intraSliceMap3 = strtoul(optArg, NULL, 16);
  1270. if (strcmp(argument.longOpt, "roi1DeltaQp") == 0)
  1271. cml->roi1AreaEnable = cml->roi1DeltaQp = atoi(optArg);
  1272. if (strcmp(argument.longOpt, "roi2DeltaQp") == 0)
  1273. cml->roi2AreaEnable = cml->roi2DeltaQp = atoi(optArg);
  1274. if (strcmp(argument.longOpt, "viewMode") == 0)
  1275. cml->viewMode = atoi(optArg);
  1276. if (strcmp(argument.longOpt, "cir") == 0)
  1277. {
  1278. /* Argument must be "xx:yy", replace ':' with 0 */
  1279. if ((i = ParseDelim(optArg, ':')) == -1) break;
  1280. /* xx is cir start */
  1281. cml->cirStart = atoi(optArg);
  1282. /* yy is cir interval */
  1283. cml->cirInterval = atoi(optArg+i+1);
  1284. }
  1285. if (strcmp(argument.longOpt, "intraArea") == 0)
  1286. {
  1287. /* Argument must be "xx:yy:XX:YY".
  1288. * xx is left coordinate, replace first ':' with 0 */
  1289. if ((i = ParseDelim(optArg, ':')) == -1) break;
  1290. cml->intraAreaLeft = atoi(optArg);
  1291. /* yy is top coordinate */
  1292. optArg += i+1;
  1293. if ((i = ParseDelim(optArg, ':')) == -1) break;
  1294. cml->intraAreaTop = atoi(optArg);
  1295. /* XX is right coordinate */
  1296. optArg += i+1;
  1297. if ((i = ParseDelim(optArg, ':')) == -1) break;
  1298. cml->intraAreaRight = atoi(optArg);
  1299. /* YY is bottom coordinate */
  1300. optArg += i+1;
  1301. cml->intraAreaBottom = atoi(optArg);
  1302. cml->intraAreaEnable = 1;
  1303. }
  1304. if (strcmp(argument.longOpt, "roi1Area") == 0)
  1305. {
  1306. /* Argument must be "xx:yy:XX:YY".
  1307. * xx is left coordinate, replace first ':' with 0 */
  1308. if ((i = ParseDelim(optArg, ':')) == -1) break;
  1309. cml->roi1AreaLeft = atoi(optArg);
  1310. /* yy is top coordinate */
  1311. optArg += i+1;
  1312. if ((i = ParseDelim(optArg, ':')) == -1) break;
  1313. cml->roi1AreaTop = atoi(optArg);
  1314. /* XX is right coordinate */
  1315. optArg += i+1;
  1316. if ((i = ParseDelim(optArg, ':')) == -1) break;
  1317. cml->roi1AreaRight = atoi(optArg);
  1318. /* YY is bottom coordinate */
  1319. optArg += i+1;
  1320. cml->roi1AreaBottom = atoi(optArg);
  1321. cml->roi1AreaEnable = 1;
  1322. }
  1323. if (strcmp(argument.longOpt, "roi2Area") == 0)
  1324. {
  1325. /* Argument must be "xx:yy:XX:YY".
  1326. * xx is left coordinate, replace first ':' with 0 */
  1327. if ((i = ParseDelim(optArg, ':')) == -1) break;
  1328. cml->roi2AreaLeft = atoi(optArg);
  1329. /* yy is top coordinate */
  1330. optArg += i+1;
  1331. if ((i = ParseDelim(optArg, ':')) == -1) break;
  1332. cml->roi2AreaTop = atoi(optArg);
  1333. /* XX is right coordinate */
  1334. optArg += i+1;
  1335. if ((i = ParseDelim(optArg, ':')) == -1) break;
  1336. cml->roi2AreaRight = atoi(optArg);
  1337. /* YY is bottom coordinate */
  1338. optArg += i+1;
  1339. cml->roi2AreaBottom = atoi(optArg);
  1340. cml->roi2AreaEnable = 1;
  1341. }
  1342. break;
  1343. default:
  1344. break;
  1345. }
  1346. }
  1347. return status;
  1348. }
  1349. /*------------------------------------------------------------------------------
  1350. ReadPic
  1351. Read raw YUV 4:2:0 or 4:2:2 image data from file
  1352. Params:
  1353. image - buffer where the image will be saved
  1354. size - amount of image data to be read
  1355. nro - picture number to be read
  1356. name - name of the file to read
  1357. width - image width in pixels
  1358. height - image height in pixels
  1359. format - image format (YUV 420/422/RGB16/RGB32)
  1360. Returns:
  1361. 0 - for success
  1362. non-zero error code
  1363. ------------------------------------------------------------------------------*/
  1364. int ReadPic(u8 * image, i32 size, i32 nro, char *name, i32 width, i32 height,
  1365. i32 format)
  1366. {
  1367. int ret = 0;
  1368. FILE *readFile = NULL;
  1369. if(yuvFile == NULL)
  1370. {
  1371. yuvFile = fopen(name, "rb");
  1372. yuvFileName = name;
  1373. if(yuvFile == NULL)
  1374. {
  1375. fprintf(H264ERR_OUTPUT, "\nUnable to open YUV file: %s\n", name);
  1376. ret = -1;
  1377. goto end;
  1378. }
  1379. fseeko(yuvFile, 0, SEEK_END);
  1380. file_size = ftello(yuvFile);
  1381. }
  1382. if((name != yuvFileName) && (yuvFileMvc == NULL))
  1383. {
  1384. yuvFileMvc = fopen(name, "rb");
  1385. if(yuvFileMvc == NULL)
  1386. {
  1387. fprintf(H264ERR_OUTPUT, "\nUnable to open YUV file: %s\n", name);
  1388. ret = -1;
  1389. goto end;
  1390. }
  1391. fseeko(yuvFileMvc, 0, SEEK_END);
  1392. file_size = ftello(yuvFileMvc);
  1393. }
  1394. if(name == yuvFileName)
  1395. readFile = yuvFile;
  1396. else
  1397. readFile = yuvFileMvc;
  1398. /* Stop if over last frame of the file */
  1399. if((off_t)size * (nro + 1) > file_size)
  1400. {
  1401. printf("\nCan't read frame, EOF\n");
  1402. ret = -1;
  1403. goto end;
  1404. }
  1405. if(fseeko(readFile, (off_t)size * nro, SEEK_SET) != 0)
  1406. {
  1407. fprintf(H264ERR_OUTPUT, "\nI can't seek frame no: %i from file: %s\n",
  1408. nro, name);
  1409. ret = -1;
  1410. goto end;
  1411. }
  1412. if((width & 0x0f) == 0)
  1413. fread(image, 1, size, readFile);
  1414. else
  1415. {
  1416. i32 i;
  1417. u8 *buf = image;
  1418. i32 scan = (width + 15) & (~0x0f);
  1419. /* Read the frame so that scan (=stride) is multiple of 16 pixels */
  1420. if(format == 0) /* YUV 4:2:0 planar */
  1421. {
  1422. /* Y */
  1423. for(i = 0; i < height; i++)
  1424. {
  1425. fread(buf, 1, width, readFile);
  1426. buf += scan;
  1427. }
  1428. /* Cb */
  1429. for(i = 0; i < (height / 2); i++)
  1430. {
  1431. fread(buf, 1, width / 2, readFile);
  1432. buf += scan / 2;
  1433. }
  1434. /* Cr */
  1435. for(i = 0; i < (height / 2); i++)
  1436. {
  1437. fread(buf, 1, width / 2, readFile);
  1438. buf += scan / 2;
  1439. }
  1440. }
  1441. else if(format == 1) /* YUV 4:2:0 semiplanar */
  1442. {
  1443. /* Y */
  1444. for(i = 0; i < height; i++)
  1445. {
  1446. fread(buf, 1, width, readFile);
  1447. buf += scan;
  1448. }
  1449. /* CbCr */
  1450. for(i = 0; i < (height / 2); i++)
  1451. {
  1452. fread(buf, 1, width, readFile);
  1453. buf += scan;
  1454. }
  1455. }
  1456. else if(format <= 9) /* YUV 4:2:2 interleaved or 16-bit RGB */
  1457. {
  1458. for(i = 0; i < height; i++)
  1459. {
  1460. fread(buf, 1, width * 2, readFile);
  1461. buf += scan * 2;
  1462. }
  1463. }
  1464. else /* 32-bit RGB */
  1465. {
  1466. for(i = 0; i < height; i++)
  1467. {
  1468. fread(buf, 1, width * 4, readFile);
  1469. buf += scan * 4;
  1470. }
  1471. }
  1472. }
  1473. end:
  1474. return ret;
  1475. }
  1476. /*------------------------------------------------------------------------------
  1477. ReadUserData
  1478. Read user data from file and pass to encoder
  1479. Params:
  1480. name - name of file in which user data is located
  1481. Returns:
  1482. NULL - when user data reading failed
  1483. pointer - allocated buffer containing user data
  1484. ------------------------------------------------------------------------------*/
  1485. u8* ReadUserData(H264EncInst encoder, char *name)
  1486. {
  1487. FILE *file = NULL;
  1488. i32 byteCnt;
  1489. u8 *data;
  1490. if(name == NULL)
  1491. return NULL;
  1492. if(strcmp("0", name) == 0)
  1493. return NULL;
  1494. /* Get user data length from file */
  1495. file = fopen(name, "rb");
  1496. if(file == NULL)
  1497. {
  1498. fprintf(H264ERR_OUTPUT, "Unable to open User Data file: %s\n", name);
  1499. return NULL;
  1500. }
  1501. fseek(file, 0L, SEEK_END);
  1502. byteCnt = ftell(file);
  1503. rewind(file);
  1504. /* Minimum size of user data */
  1505. if (byteCnt < 16)
  1506. byteCnt = 16;
  1507. /* Maximum size of user data */
  1508. if (byteCnt > 2048)
  1509. byteCnt = 2048;
  1510. /* Allocate memory for user data */
  1511. if((data = (u8 *) malloc(sizeof(u8) * byteCnt)) == NULL)
  1512. {
  1513. fclose(file);
  1514. fprintf(H264ERR_OUTPUT, "Unable to alloc User Data memory\n");
  1515. return NULL;
  1516. }
  1517. /* Read user data from file */
  1518. fread(data, sizeof(u8), byteCnt, file);
  1519. fclose(file);
  1520. printf("User data: %d bytes [%d %d %d %d ...]\n",
  1521. byteCnt, data[0], data[1], data[2], data[3]);
  1522. /* Pass the data buffer to encoder
  1523. * The encoder reads the buffer during following H264EncStrmEncode() calls.
  1524. * User data writing must be disabled (with SetSeiUserData(enc, 0, 0)) */
  1525. H264EncSetSeiUserData(encoder, data, byteCnt);
  1526. return data;
  1527. }
  1528. /*------------------------------------------------------------------------------
  1529. Help
  1530. Print out some instructions about usage.
  1531. ------------------------------------------------------------------------------*/
  1532. void Help(void)
  1533. {
  1534. fprintf(stdout, "Usage: %s [options] -i inputfile\n\n", "h264_testenc");
  1535. fprintf(stdout, "Default parameters are marked inside []. More detailed description of\n"
  1536. "H.264 API parameters can be found from H.264 API Manual.\n\n");
  1537. fprintf(stdout,
  1538. " Parameters affecting which input frames are encoded:\n"
  1539. " -i[s] --input Read input video sequence from file. [input.yuv]\n"
  1540. " -9[s] --inputMvc Read MVC second view input video sequence from file. []\n"
  1541. " -o[s] --output Write output H.264 stream to file. [stream.h264]\n"
  1542. " -a[n] --firstPic First picture of input file to encode. [0]\n"
  1543. " -b[n] --lastPic Last picture of input file to encode. [100]\n"
  1544. " -f[n] --outputRateNumer 1..1048575 Output picture rate numerator. [30]\n"
  1545. " -F[n] --outputRateDenom 1..1048575 Output picture rate denominator. [1]\n"
  1546. " Encoded frame rate will be\n"
  1547. " outputRateNumer/outputRateDenom fps\n"
  1548. " -j[n] --inputRateNumer 1..1048575 Input picture rate numerator. [30]\n"
  1549. " -J[n] --inputRateDenom 1..1048575 Input picture rate denominator. [1]\n\n");
  1550. fprintf(stdout,
  1551. " Parameters affecting input frame and encoded frame resolutions and cropping:\n"
  1552. " -w[n] --lumWidthSrc Width of source image. [176]\n"
  1553. " -h[n] --lumHeightSrc Height of source image. [144]\n");
  1554. fprintf(stdout,
  1555. " -x[n] --width Width of encoded output image. [--lumWidthSrc]\n"
  1556. " -y[n] --height Height of encoded output image. [--lumHeightSrc]\n"
  1557. " -X[n] --horOffsetSrc Output image horizontal cropping offset. [0]\n"
  1558. " -Y[n] --verOffsetSrc Output image vertical cropping offset. [0]\n\n");
  1559. fprintf(stdout,
  1560. " Parameters for pre-processing frames before encoding:\n"
  1561. " -l[n] --inputFormat Input YUV format. [0]\n"
  1562. " 0 - YUV420 planar\n"
  1563. " 1 - YUV420 semiplanar\n"
  1564. " 2 - YUYV422 interleaved\n"
  1565. " 3 - UYVY422 interleaved\n"
  1566. " 4 - RGB565 16bpp\n"
  1567. " 5 - BGR565 16bpp\n"
  1568. " 6 - RGB555 16bpp\n"
  1569. " 7 - BGR555 16bpp\n"
  1570. " 8 - RGB444 16bpp\n"
  1571. " 9 - BGR444 16bpp\n"
  1572. " 10 - RGB888 32bpp\n"
  1573. " 11 - BGR888 32bpp\n"
  1574. " 12 - RGB101010 32bpp\n"
  1575. " 13 - BGR101010 32bpp\n"
  1576. " -O[n] --colorConversion RGB to YCbCr color conversion type. [0]\n"
  1577. " 0 - BT.601\n"
  1578. " 1 - BT.709\n"
  1579. " 2 - User defined, coeffs defined in testbench.\n");
  1580. fprintf(stdout,
  1581. " -r[n] --rotation Rotate input image. [0]\n"
  1582. " 0 - disabled\n"
  1583. " 1 - 90 degrees right\n"
  1584. " 2 - 90 degrees left\n"
  1585. " -Z[n] --videoStab Enable video stabilization or scene change detection. [0]\n"
  1586. " Stabilization works by adjusting cropping offset for\n"
  1587. " every frame. Scene change detection encodes scene\n"
  1588. " changes as intra frames, it is enabled when\n"
  1589. " input resolution == encoded resolution.\n\n");
  1590. fprintf(stdout,
  1591. " Parameters affecting the output stream and encoding tools:\n"
  1592. " -L[n] --level 10..51, H264 Level. 40=Level 4.0 [40]\n"
  1593. " Each level has resolution and bitrate limitations:\n"
  1594. " 10 - QCIF (176x144) 75kbits\n"
  1595. " 20 - CIF (352x288) 2.4Mbits\n"
  1596. " 30 - SD (720x576) 12Mbits\n"
  1597. " 40 - 1080p (1920x1080) 24Mbits\n"
  1598. " -R[n] --byteStream Stream type. [1]\n"
  1599. " 0 - NAL units. Nal sizes returned in <nal_sizes.txt>\n"
  1600. " 1 - byte stream according to H.264 Standard Annex B.\n");
  1601. fprintf(stdout,
  1602. " -S[n] --sei Enable SEI messages (buffering period + picture timing) [0]\n"
  1603. " Writes Supplemental Enhancement Information messages\n"
  1604. " containing information about picture time stamps\n"
  1605. " and picture buffering into stream.\n");
  1606. fprintf(stdout,
  1607. " -8[n] --trans8x8 0=OFF, 1=Adaptive, 2=ON [0]\n"
  1608. " Adaptive setting enables 8x8 transform for >= 720p.\n"
  1609. " Enabling 8x8 transform makes the stream High Profile.\n"
  1610. " -M[n] --quarterPixelMv 0=OFF, 1=Adaptive, 2=ON [1]\n"
  1611. " Adaptive setting disables 1/4p MVs for > 720p.\n"
  1612. " -K[n] --enableCabac 0=OFF (CAVLC), 1=ON (CABAC),\n"
  1613. " 2=ON for Inter frames (intra=CAVLC, inter=CABAC) [0]\n"
  1614. " Enabling CABAC makes the stream Main Profile.\n"
  1615. " -p[n] --cabacInitIdc 0..2 Initialization value for CABAC. [0]\n"
  1616. " -k[n] --videoRange 0..1 Video signal sample range value in H.264 stream. [0]\n"
  1617. " 0 - Y range in [16..235] Cb,Cr in [16..240]\n"
  1618. " 1 - Y,Cb,Cr range in [0..255]\n");
  1619. fprintf(stdout,
  1620. " -T[n] --constIntraPred 0=OFF, 1=ON Constrained intra prediction flag [0]\n"
  1621. " Improves stream error recovery by not allowing\n"
  1622. " intra MBs to predict from neighboring inter MBs.\n"
  1623. " -D[n] --disableDeblocking 0..2 Value of disable_deblocking_filter_idc [0]\n"
  1624. " 0 = Inloop deblocking filter enabled (best quality)\n"
  1625. " 1 = Inloop deblocking filter disabled\n"
  1626. " 2 = Inloop deblocking filter disabled on slice edges\n"
  1627. " -I[n] --intraPicRate Intra picture rate in frames. [0]\n"
  1628. " Forces every Nth frame to be encoded as intra frame.\n"
  1629. " -V[n] --mbRowPerSlice Slice size in macroblock rows. [0]\n\n");
  1630. fprintf(stdout,
  1631. " Parameters affecting the rate control and output stream bitrate:\n"
  1632. " -B[n] --bitPerSecond 10000..levelMax, target bitrate for rate control [1000000]\n"
  1633. " -U[n] --picRc 0=OFF, 1=ON Picture rate control. [1]\n"
  1634. " Calculates new target QP for every frame.\n"
  1635. " -u[n] --mbRc 0=OFF, 1=ON Macroblock rate control (Check point rc). [1]\n"
  1636. " Updates target QP inside frame.\n"
  1637. " -C[n] --hrdConformance 0=OFF, 1=ON HRD conformance. [0]\n"
  1638. " Uses standard defined model to limit bitrate variance.\n"
  1639. " -c[n] --cpbSize HRD Coded Picture Buffer size in bits. [0]\n"
  1640. " Buffer size used by the HRD model.\n"
  1641. " -g[n] --gopLength Group Of Pictures length in frames, 1..300 [intraPicRate]\n"
  1642. " Rate control allocates bits for one GOP and tries to\n"
  1643. " match the target bitrate at the end of each GOP.\n"
  1644. " Typically GOP begins with an intra frame, but this\n"
  1645. " is not mandatory.\n");
  1646. fprintf(stdout,
  1647. " -s[n] --picSkip 0=OFF, 1=ON Picture skip rate control. [0]\n"
  1648. " Allows rate control to skip frames if needed.\n"
  1649. " -q[n] --qpHdr -1..51, Initial target QP. [26]\n"
  1650. " -1 = Encoder calculates initial QP. NOTE: use -q-1\n"
  1651. " The initial QP used in the beginning of stream.\n"
  1652. " -n[n] --qpMin 0..51, Minimum frame header QP. [10]\n"
  1653. " -m[n] --qpMax 0..51, Maximum frame header QP. [51]\n"
  1654. " -A[n] --intraQpDelta -12..12, Intra QP delta. [-3]\n"
  1655. " QP difference between target QP and intra frame QP.\n"
  1656. " -G[n] --fixedIntraQp 0..51, Fixed Intra QP, 0 = disabled. [0]\n"
  1657. " Use fixed QP value for every intra frame in stream.\n"
  1658. " -2[n] --mbQpAdjustment -8..7, MAD based MB QP adjustment, 0 = disabled. [0]\n"
  1659. " Improves quality of macroblocks based on MAD value.\n"
  1660. " -1[n]:[n] --bpsAdjust Frame:bitrate for adjusting bitrate on the fly.\n"
  1661. " Sets new target bitrate at specific frame.\n\n");
  1662. fprintf(stdout,
  1663. " Other parameters for coding and reporting:\n"
  1664. " -z[n] --userData SEI User data file name. File is read and inserted\n"
  1665. " as SEI message before first frame.\n"
  1666. " -d --psnr Enables PSNR calculation for each frame.\n"
  1667. " -3[n] --mvOutput Enable MV writing in <mv.txt> [0]\n\n");
  1668. fprintf(stdout,
  1669. " --cir start:interval for Cyclic Intra Refresh.\n"
  1670. " Forces macroblocks in intra mode. [0:0]\n"
  1671. " --intraSliceMap1 32b hex bitmap for forcing slices 0..31\n"
  1672. " coding as intra. LSB=slice0 [0]\n"
  1673. " --intraSliceMap2 32b hex bitmap for forcing slices 32..63\n"
  1674. " coding as intra. LSB=slice32 [0]\n"
  1675. " --intraSliceMap3 32b hex bitmap for forcing slices 64..95\n"
  1676. " coding as intra. LSB=slice64 [0]\n"
  1677. " --intraArea left:top:right:bottom macroblock coordinates\n"
  1678. " specifying rectangular area of MBs to\n"
  1679. " force encoding in intra mode.\n"
  1680. " --roi1Area left:top:right:bottom macroblock coordinates\n"
  1681. " --roi2Area left:top:right:bottom macroblock coordinates\n"
  1682. " specifying rectangular area of MBs as\n"
  1683. " Region Of Interest with lower QP.\n"
  1684. " --roi1DeltaQp -15..0, QP delta value for ROI 1 MBs. [0]\n"
  1685. " --roi2DeltaQp -15..0, QP delta value for ROI 2 MBs. [0]\n"
  1686. " --viewMode Mode for encoder view prediction and buffering [0]\n"
  1687. " 0 = Base view stream with two frame buffers\n"
  1688. " 1 = Base view stream with one frame buffer\n"
  1689. " 2 = Multiview stream with one frame buffer\n"
  1690. " 3 = Multiview stream with two frame buffers\n");
  1691. fprintf(stdout,
  1692. "\nTesting parameters that are not supported for end-user:\n"
  1693. " -Q[n] --chromaQpOffset -12..12 Chroma QP offset. [2]\n"
  1694. " -W[n] --filterOffsetA -6..6 Deblocking filter offset A. [0]\n"
  1695. " -E[n] --filterOffsetB -6..6 Deblocking filter offset B. [0]\n"
  1696. " -N[n] --burstSize 0..63 HW bus burst size. [16]\n"
  1697. " -t[n] --burstType 0=SINGLE, 1=INCR HW bus burst type. [0]\n"
  1698. " -e[n] --testId Internal test ID. [0]\n"
  1699. " -P[n] --trigger Logic Analyzer trigger at picture <n>. [-1]\n"
  1700. "\n");
  1701. ;
  1702. }
  1703. /*------------------------------------------------------------------------------
  1704. WriteStrm
  1705. Write encoded stream to file
  1706. Params:
  1707. fout - file to write
  1708. strbuf - data to be written
  1709. size - amount of data to write
  1710. endian - data endianess, big or little
  1711. ------------------------------------------------------------------------------*/
  1712. void WriteStrm(FILE * fout, u32 * strmbuf, u32 size, u32 endian)
  1713. {
  1714. #ifdef NO_OUTPUT_WRITE
  1715. return;
  1716. #endif
  1717. /* Swap the stream endianess before writing to file if needed */
  1718. if(endian == 1)
  1719. {
  1720. u32 i = 0, words = (size + 3) / 4;
  1721. while(words)
  1722. {
  1723. u32 val = strmbuf[i];
  1724. u32 tmp = 0;
  1725. tmp |= (val & 0xFF) << 24;
  1726. tmp |= (val & 0xFF00) << 8;
  1727. tmp |= (val & 0xFF0000) >> 8;
  1728. tmp |= (val & 0xFF000000) >> 24;
  1729. strmbuf[i] = tmp;
  1730. words--;
  1731. i++;
  1732. }
  1733. }
  1734. /* Write the stream to file */
  1735. fwrite(strmbuf, 1, size, fout);
  1736. }
  1737. /*------------------------------------------------------------------------------
  1738. NextPic
  1739. Function calculates next input picture depending input and output frame
  1740. rates.
  1741. Input inputRateNumer (input.yuv) frame rate numerator.
  1742. inputRateDenom (input.yuv) frame rate denominator
  1743. outputRateNumer (stream.mpeg4) frame rate numerator.
  1744. outputRateDenom (stream.mpeg4) frame rate denominator.
  1745. frameCnt Frame counter.
  1746. firstPic The first picture of input.yuv sequence.
  1747. Return next The next picture of input.yuv sequence.
  1748. ------------------------------------------------------------------------------*/
  1749. i32 NextPic(i32 inputRateNumer, i32 inputRateDenom, i32 outputRateNumer,
  1750. i32 outputRateDenom, i32 frameCnt, i32 firstPic)
  1751. {
  1752. u32 sift;
  1753. u32 skip;
  1754. u32 numer;
  1755. u32 denom;
  1756. u32 next;
  1757. numer = (u32) inputRateNumer *(u32) outputRateDenom;
  1758. denom = (u32) inputRateDenom *(u32) outputRateNumer;
  1759. if(numer >= denom)
  1760. {
  1761. sift = 9;
  1762. do
  1763. {
  1764. sift--;
  1765. }
  1766. while(((numer << sift) >> sift) != numer);
  1767. }
  1768. else
  1769. {
  1770. sift = 17;
  1771. do
  1772. {
  1773. sift--;
  1774. }
  1775. while(((numer << sift) >> sift) != numer);
  1776. }
  1777. skip = (numer << sift) / denom;
  1778. next = (((u32) frameCnt * skip) >> sift) + (u32) firstPic;
  1779. return (i32) next;
  1780. }
  1781. /*------------------------------------------------------------------------------
  1782. ChangeInput
  1783. Change input file.
  1784. Params:
  1785. argc - number of arguments to the application
  1786. argv - argument list as provided to the application
  1787. option - list of accepted cmdline options
  1788. Returns:
  1789. 1 - for success
  1790. ------------------------------------------------------------------------------*/
  1791. int ChangeInput(i32 argc, char **argv, char **name, option_s * option)
  1792. {
  1793. i32 ret;
  1794. argument_s argument;
  1795. i32 enable = 0;
  1796. #ifdef MULTIFILEINPUT
  1797. /* End when can't open next file */
  1798. if (!yuvFile)
  1799. return 0;
  1800. /* Use the first file name as base: input.yuv */
  1801. if (fileNumber == 0)
  1802. {
  1803. strcpy(inputFilename, *name);
  1804. inputFilenameLength = strlen(inputFilename);
  1805. }
  1806. /* Remove the previous input file, decoder will create next file. */
  1807. remove(inputFilename);
  1808. /* First check and wait until the decoder has created next file */
  1809. {
  1810. FILE * fp = NULL;
  1811. sprintf(inputFilename+inputFilenameLength, "%d", fileNumber+2);
  1812. printf("\nWaiting for file: %s\n", inputFilename);
  1813. while (!fp)
  1814. {
  1815. sleep(1);
  1816. fp = fopen(inputFilename, "r");
  1817. /* End when a file named EOF exists */
  1818. if (!fp)
  1819. fp = fopen("EOF", "r");
  1820. }
  1821. fclose(fp);
  1822. }
  1823. /* The next file should be named: input.yuv1, input.yuv2, etc.. */
  1824. sprintf(inputFilename+inputFilenameLength, "%d", ++fileNumber);
  1825. *name = inputFilename;
  1826. printf("\nNext file: %s\n", *name);
  1827. return 1;
  1828. #endif
  1829. argument.optCnt = 1;
  1830. while((ret = EncGetOption(argc, argv, option, &argument)) != -1)
  1831. {
  1832. if((ret == 1) && (enable))
  1833. {
  1834. *name = argument.optArg;
  1835. printf("\nNext file: %s\n", *name);
  1836. return 1;
  1837. }
  1838. if(argument.optArg == *name)
  1839. {
  1840. enable = 1;
  1841. }
  1842. }
  1843. return 0;
  1844. }
  1845. /*------------------------------------------------------------------------------
  1846. API tracing
  1847. TRacing as defined by the API.
  1848. Params:
  1849. msg - null terminated tracing message
  1850. ------------------------------------------------------------------------------*/
  1851. void H264EncTrace(const char *msg)
  1852. {
  1853. static FILE *fp = NULL;
  1854. if(fp == NULL)
  1855. fp = fopen("api.trc", "wt");
  1856. if(fp)
  1857. fprintf(fp, "%s\n", msg);
  1858. }
  1859. /*------------------------------------------------------------------------------
  1860. Get out pure NAL units from byte stream format (one picture data)
  1861. This is an example!
  1862. Params:
  1863. pNaluSizeBuf - buffer where the individual NAL size are (return by API)
  1864. pStream- buffre containign the whole picture data
  1865. ------------------------------------------------------------------------------*/
  1866. void NalUnitsFromByteStream(const u32 * pNaluSizeBuf, const u8 * pStream)
  1867. {
  1868. u32 nalSize, nal;
  1869. const u8 *pNalBase;
  1870. nal = 0;
  1871. pNalBase = pStream + 4; /* skip the 4-byte startcode */
  1872. while(pNaluSizeBuf[nal] != 0) /* after the last NAL unit size we have a zero */
  1873. {
  1874. nalSize = pNaluSizeBuf[nal] - 4;
  1875. /* now we have the pure NAL unit, do something with it */
  1876. /* DoSomethingWithThisNAL(pNalBase, nalSize); */
  1877. pNalBase += pNaluSizeBuf[nal]; /* next NAL data base address */
  1878. nal++; /* next NAL unit */
  1879. }
  1880. }
  1881. /*------------------------------------------------------------------------------
  1882. ------------------------------------------------------------------------------*/
  1883. void PrintNalSizes(const u32 *pNaluSizeBuf, const u8 *pOutBuf, u32 strmSize,
  1884. i32 byteStream)
  1885. {
  1886. u32 nalu = 0, naluSum = 0;
  1887. /* Step through the NALU size buffer */
  1888. while(pNaluSizeBuf && pNaluSizeBuf[nalu] != 0)
  1889. {
  1890. #ifdef INTERNAL_TEST
  1891. /* In byte stream format each NAL must start with
  1892. * start code: any number of leading zeros + 0x000001 */
  1893. if (byteStream) {
  1894. int zero_count = 0;
  1895. const u8 *pTmp = pOutBuf + naluSum;
  1896. /* count zeros, shall be at least 2 */
  1897. while(*pTmp++ == 0x00)
  1898. zero_count++;
  1899. if(zero_count < 2 || pTmp[-1] != 0x01)
  1900. printf
  1901. ("Error: NAL unit %d at %d doesn't start with '00 00 01' ",
  1902. nalu, naluSum);
  1903. }
  1904. #endif
  1905. naluSum += pNaluSizeBuf[nalu];
  1906. printf("%d ", pNaluSizeBuf[nalu++]);
  1907. }
  1908. #ifdef INTERNAL_TEST
  1909. /* NAL sum must be the same as the whole frame stream size */
  1910. if (naluSum && naluSum != strmSize)
  1911. printf("Error: NAL size sum (%d) does not match stream size",
  1912. naluSum);
  1913. #endif
  1914. }
  1915. /*------------------------------------------------------------------------------
  1916. WriteNalSizesToFile
  1917. Dump NAL size to a file
  1918. Params:
  1919. file - file name where toi dump
  1920. pNaluSizeBuf - buffer where the individual NAL size are (return by API)
  1921. buffSize - size in bytes of the above buffer
  1922. ------------------------------------------------------------------------------*/
  1923. void WriteNalSizesToFile(const char *file, const u32 * pNaluSizeBuf,
  1924. u32 buffSize)
  1925. {
  1926. FILE *fo;
  1927. u32 offset = 0;
  1928. fo = fopen(file, "at");
  1929. if(fo == NULL)
  1930. {
  1931. printf("FAILED to open NAL size tracing file <%s>\n", file);
  1932. return;
  1933. }
  1934. while(offset < buffSize && *pNaluSizeBuf != 0)
  1935. {
  1936. fprintf(fo, "%d\n", *pNaluSizeBuf++);
  1937. offset += sizeof(u32);
  1938. }
  1939. fclose(fo);
  1940. }
  1941. /*------------------------------------------------------------------------------
  1942. WriteMotionVectors
  1943. Write motion vectors into a file
  1944. ------------------------------------------------------------------------------*/
  1945. void WriteMotionVectors(FILE *file, i8 *mvs, i32 frame, i32 width, i32 height)
  1946. {
  1947. i32 i;
  1948. i32 mbPerRow = (width+15)/16;
  1949. i32 mbPerCol = (height+15)/16;
  1950. i32 mbPerFrame = mbPerRow * mbPerCol;
  1951. u8 *sads = (u8 *)mvs;
  1952. if (!file || !mvs)
  1953. return;
  1954. fprintf(file,
  1955. "\nFrame=%d motion vector X,Y for %d macroblocks (%dx%d)\n",
  1956. frame, mbPerFrame, mbPerRow, mbPerCol);
  1957. for (i = 0; i < mbPerFrame; i++)
  1958. {
  1959. fprintf(file, " %3d,%3d", mvs[i*4], mvs[i*4+1]);
  1960. if ((i % mbPerRow) == mbPerRow-1)
  1961. fprintf(file, "\n");
  1962. }
  1963. fprintf(file,
  1964. "\nFrame=%d SAD\n", frame);
  1965. for (i = 0; i < mbPerFrame; i++)
  1966. {
  1967. fprintf(file, " %5d", (u32)(sads[i*4+2] << 8) | sads[i*4+3]);
  1968. if ((i % mbPerRow) == mbPerRow-1)
  1969. fprintf(file, "\n");
  1970. }
  1971. }
  1972. /*------------------------------------------------------------------------------
  1973. PrintErrorValue
  1974. Print return error value
  1975. ------------------------------------------------------------------------------*/
  1976. void PrintErrorValue(const char *errorDesc, u32 retVal)
  1977. {
  1978. char * str;
  1979. switch (retVal)
  1980. {
  1981. case H264ENC_ERROR: str = "H264ENC_ERROR"; break;
  1982. case H264ENC_NULL_ARGUMENT: str = "H264ENC_NULL_ARGUMENT"; break;
  1983. case H264ENC_INVALID_ARGUMENT: str = "H264ENC_INVALID_ARGUMENT"; break;
  1984. case H264ENC_MEMORY_ERROR: str = "H264ENC_MEMORY_ERROR"; break;
  1985. case H264ENC_EWL_ERROR: str = "H264ENC_EWL_ERROR"; break;
  1986. case H264ENC_EWL_MEMORY_ERROR: str = "H264ENC_EWL_MEMORY_ERROR"; break;
  1987. case H264ENC_INVALID_STATUS: str = "H264ENC_INVALID_STATUS"; break;
  1988. case H264ENC_OUTPUT_BUFFER_OVERFLOW: str = "H264ENC_OUTPUT_BUFFER_OVERFLOW"; break;
  1989. case H264ENC_HW_BUS_ERROR: str = "H264ENC_HW_BUS_ERROR"; break;
  1990. case H264ENC_HW_DATA_ERROR: str = "H264ENC_HW_DATA_ERROR"; break;
  1991. case H264ENC_HW_TIMEOUT: str = "H264ENC_HW_TIMEOUT"; break;
  1992. case H264ENC_HW_RESERVED: str = "H264ENC_HW_RESERVED"; break;
  1993. case H264ENC_SYSTEM_ERROR: str = "H264ENC_SYSTEM_ERROR"; break;
  1994. case H264ENC_INSTANCE_ERROR: str = "H264ENC_INSTANCE_ERROR"; break;
  1995. case H264ENC_HRD_ERROR: str = "H264ENC_HRD_ERROR"; break;
  1996. case H264ENC_HW_RESET: str = "H264ENC_HW_RESET"; break;
  1997. default: str = "UNDEFINED";
  1998. }
  1999. fprintf(H264ERR_OUTPUT, "%s Return value: %s\n", errorDesc, str);
  2000. }
  2001. /*------------------------------------------------------------------------------
  2002. PrintPSNR
  2003. Calculate and print frame PSNR
  2004. ------------------------------------------------------------------------------*/
  2005. u32 PrintPSNR(u8 *a, u8 *b, i32 scanline, i32 wdh, i32 hgt, i32 rotation)
  2006. {
  2007. #ifdef PSNR
  2008. float mse = 0.0;
  2009. u32 tmp, i, j;
  2010. if (!rotation)
  2011. {
  2012. for (j = 0 ; j < hgt; j++) {
  2013. for (i = 0; i < wdh; i++) {
  2014. tmp = a[i] - b[i];
  2015. tmp *= tmp;
  2016. mse += tmp;
  2017. }
  2018. a += scanline;
  2019. b += wdh;
  2020. }
  2021. mse /= wdh * hgt;
  2022. }
  2023. if (mse == 0.0) {
  2024. printf("--.-- | ");
  2025. } else {
  2026. mse = 10.0 * log10f(65025.0 / mse);
  2027. printf("%5.2f | ", mse);
  2028. }
  2029. return (u32)roundf(mse*100);
  2030. #else
  2031. printf("xx.xx | ");
  2032. return 0;
  2033. #endif
  2034. }
  2035. /*------------------------------------------------------------------------------
  2036. GetResolution
  2037. Parse image resolution from file name
  2038. ------------------------------------------------------------------------------*/
  2039. u32 GetResolution(char *filename, i32 *pWidth, i32 *pHeight)
  2040. {
  2041. i32 i;
  2042. u32 w, h;
  2043. i32 len = strlen(filename);
  2044. i32 filenameBegin = 0;
  2045. /* Find last '/' in the file name, it marks the beginning of file name */
  2046. for (i = len-1; i; --i)
  2047. if (filename[i] == '/') {
  2048. filenameBegin = i+1;
  2049. break;
  2050. }
  2051. /* If '/' found, it separates trailing path from file name */
  2052. for (i = filenameBegin; i <= len-3; ++i)
  2053. {
  2054. if ((strncmp(filename+i, "subqcif", 7) == 0) ||
  2055. (strncmp(filename+i, "sqcif", 5) == 0))
  2056. {
  2057. *pWidth = 128;
  2058. *pHeight = 96;
  2059. printf("Detected resolution SubQCIF (128x96) from file name.\n");
  2060. return 0;
  2061. }
  2062. if (strncmp(filename+i, "qcif", 4) == 0)
  2063. {
  2064. *pWidth = 176;
  2065. *pHeight = 144;
  2066. printf("Detected resolution QCIF (176x144) from file name.\n");
  2067. return 0;
  2068. }
  2069. if (strncmp(filename+i, "4cif", 4) == 0)
  2070. {
  2071. *pWidth = 704;
  2072. *pHeight = 576;
  2073. printf("Detected resolution 4CIF (704x576) from file name.\n");
  2074. return 0;
  2075. }
  2076. if (strncmp(filename+i, "cif", 3) == 0)
  2077. {
  2078. *pWidth = 352;
  2079. *pHeight = 288;
  2080. printf("Detected resolution CIF (352x288) from file name.\n");
  2081. return 0;
  2082. }
  2083. if (strncmp(filename+i, "qqvga", 5) == 0)
  2084. {
  2085. *pWidth = 160;
  2086. *pHeight = 120;
  2087. printf("Detected resolution QQVGA (160x120) from file name.\n");
  2088. return 0;
  2089. }
  2090. if (strncmp(filename+i, "qvga", 4) == 0)
  2091. {
  2092. *pWidth = 320;
  2093. *pHeight = 240;
  2094. printf("Detected resolution QVGA (320x240) from file name.\n");
  2095. return 0;
  2096. }
  2097. if (strncmp(filename+i, "vga", 3) == 0)
  2098. {
  2099. *pWidth = 640;
  2100. *pHeight = 480;
  2101. printf("Detected resolution VGA (640x480) from file name.\n");
  2102. return 0;
  2103. }
  2104. if (strncmp(filename+i, "720p", 4) == 0)
  2105. {
  2106. *pWidth = 1280;
  2107. *pHeight = 720;
  2108. printf("Detected resolution 720p (1280x720) from file name.\n");
  2109. return 0;
  2110. }
  2111. if (strncmp(filename+i, "1080p", 5) == 0)
  2112. {
  2113. *pWidth = 1920;
  2114. *pHeight = 1080;
  2115. printf("Detected resolution 1080p (1920x1080) from file name.\n");
  2116. return 0;
  2117. }
  2118. if (filename[i] == 'x')
  2119. {
  2120. if (sscanf(filename+i-4, "%ux%u", &w, &h) == 2)
  2121. {
  2122. *pWidth = w;
  2123. *pHeight = h;
  2124. printf("Detected resolution %dx%d from file name.\n", w, h);
  2125. return 0;
  2126. }
  2127. else if (sscanf(filename+i-3, "%ux%u", &w, &h) == 2)
  2128. {
  2129. *pWidth = w;
  2130. *pHeight = h;
  2131. printf("Detected resolution %dx%d from file name.\n", w, h);
  2132. return 0;
  2133. }
  2134. else if (sscanf(filename+i-2, "%ux%u", &w, &h) == 2)
  2135. {
  2136. *pWidth = w;
  2137. *pHeight = h;
  2138. printf("Detected resolution %dx%d from file name.\n", w, h);
  2139. return 0;
  2140. }
  2141. }
  2142. if (filename[i] == 'w')
  2143. {
  2144. if (sscanf(filename+i, "w%uh%u", &w, &h) == 2)
  2145. {
  2146. *pWidth = w;
  2147. *pHeight = h;
  2148. printf("Detected resolution %dx%d from file name.\n", w, h);
  2149. return 0;
  2150. }
  2151. }
  2152. }
  2153. return 1; /* Error - no resolution found */
  2154. }
  2155. /*------------------------------------------------------------------------------
  2156. Add new frame bits for moving average bitrate calculation
  2157. ------------------------------------------------------------------------------*/
  2158. void MaAddFrame(ma_s *ma, i32 frameSizeBits)
  2159. {
  2160. ma->frame[ma->pos++] = frameSizeBits;
  2161. if (ma->pos == ma->length)
  2162. ma->pos = 0;
  2163. if (ma->count < ma->length)
  2164. ma->count++;
  2165. }
  2166. /*------------------------------------------------------------------------------
  2167. Calculate average bitrate of moving window
  2168. ------------------------------------------------------------------------------*/
  2169. i32 Ma(ma_s *ma)
  2170. {
  2171. i32 i;
  2172. unsigned long long sum = 0; /* Using 64-bits to avoid overflow */
  2173. for (i = 0; i < ma->count; i++)
  2174. sum += ma->frame[i];
  2175. if (!ma->frameRateDenom)
  2176. return 0;
  2177. sum = sum / ma->length;
  2178. return sum * ma->frameRateNumer / ma->frameRateDenom;
  2179. }
  2180. /*------------------------------------------------------------------------------
  2181. Callback function called by the encoder SW after "slice ready"
  2182. interrupt from HW. Note that this function is not necessarily called
  2183. after every slice i.e. it is possible that two or more slices are
  2184. completed between callbacks. The callback is not called for the last slice.
  2185. ------------------------------------------------------------------------------*/
  2186. void H264SliceReady(H264EncSliceReady *slice)
  2187. {
  2188. /* Here is possible to implement low-latency streaming by
  2189. * sending the complete slices before the whole frame is completed. */
  2190. #if 0
  2191. /* This is an example how to access the slices, but it will mess up prints */
  2192. {
  2193. i32 i;
  2194. u8 *strmPtr;
  2195. if (slice->slicesReadyPrev == 0) /* New frame */
  2196. strmPtr = (u8*)slice->pOutBuf; /* Pointer to beginning of frame */
  2197. else
  2198. strmPtr = (u8*)slice->pAppData; /* Here we store the slice pointer */
  2199. for (i = slice->slicesReadyPrev; i < slice->slicesReady; i++)
  2200. {
  2201. printf("#%d:%p:%d\n", i, strmPtr, slice->sliceSizes[i]);
  2202. strmPtr += slice->sliceSizes[i];
  2203. }
  2204. /* Store the slice pointer for next callback */
  2205. slice->pAppData = strmPtr;
  2206. }
  2207. #endif
  2208. }