1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843 |
- /*------------------------------------------------------------------------------
- -- --
- -- This software is confidential and proprietary and may be used --
- -- only as expressly authorized by a licensing agreement from --
- -- --
- -- Hantro Products Oy. --
- -- --
- -- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
- -- ALL RIGHTS RESERVED --
- -- --
- -- The entire notice above must be reproduced --
- -- on all copies and should not be removed. --
- -- --
- --------------------------------------------------------------------------------
- --
- -- Abstract : H264 Encoder API
- --
- ------------------------------------------------------------------------------*/
- /*------------------------------------------------------------------------------
- Version Information
- ------------------------------------------------------------------------------*/
- #define H264ENC_MAJOR_VERSION 1
- #define H264ENC_MINOR_VERSION 3
- #define H264ENC_BUILD_MAJOR 1
- #define H264ENC_BUILD_MINOR 14
- #define H264ENC_BUILD_REVISION 0
- #define H264ENC_SW_BUILD ((H264ENC_BUILD_MAJOR * 1000000) + \
- (H264ENC_BUILD_MINOR * 1000) + H264ENC_BUILD_REVISION)
- /*------------------------------------------------------------------------------
- 1. Include headers
- ------------------------------------------------------------------------------*/
- #include "h264encapi.h"
- #include "enccommon.h"
- #include "H264Instance.h"
- #include "H264Init.h"
- #include "H264PutBits.h"
- #include "H264CodeFrame.h"
- #include "H264Sei.h"
- #include "H264RateControl.h"
- #include "H264Cabac.h"
- #ifdef INTERNAL_TEST
- #include "H264TestId.h"
- #endif
- #ifdef VIDEOSTAB_ENABLED
- #include "vidstabcommon.h"
- #endif
- /*------------------------------------------------------------------------------
- 2. External compiler flags
- --------------------------------------------------------------------------------
- #define EVALUATION_LIMIT 300 max number of frames to encode
- --------------------------------------------------------------------------------
- 3. Module defines
- ------------------------------------------------------------------------------*/
- /* Parameter limits */
- #define H264ENCSTRMSTART_MIN_BUF 64
- #define H264ENCSTRMENCODE_MIN_BUF 4096
- #define H264ENC_MAX_PP_INPUT_WIDTH 8176
- #define H264ENC_MAX_PP_INPUT_HEIGHT 8176
- #define H264ENC_MAX_BITRATE (50000*1200) /* Level 4.1 limit */
- #define H264ENC_MAX_USER_DATA_SIZE 2048
- #define H264ENC_IDR_ID_MODULO 16
- #define H264_BUS_ADDRESS_VALID(bus_address) (((bus_address) != 0) && \
- ((bus_address & 0x07) == 0))
- /* HW ID check. H264EncInit() will fail if HW doesn't match. */
- #define HW_ID_MASK 0xFFFF0000
- #define HW_ID 0x82900000
- /* Tracing macro */
- #ifdef H264ENC_TRACE
- #define APITRACE(str) H264EncTrace(str)
- #else
- #define APITRACE(str)
- #endif
- /*------------------------------------------------------------------------------
- 4. Local function prototypes
- ------------------------------------------------------------------------------*/
- static void H264AddNaluSize(H264EncOut * pEncOut, u32 naluSizeBytes);
- static i32 VSCheckSize(u32 inputWidth, u32 inputHeight, u32 stabilizedWidth,
- u32 stabilizedHeight);
- static void H264PrefixNal(h264Instance_s *pEncInst);
- /*------------------------------------------------------------------------------
- Function name : H264EncGetApiVersion
- Description : Return the API version info
-
- Return type : H264EncApiVersion
- Argument : void
- ------------------------------------------------------------------------------*/
- H264EncApiVersion H264EncGetApiVersion(void)
- {
- H264EncApiVersion ver;
- ver.major = H264ENC_MAJOR_VERSION;
- ver.minor = H264ENC_MINOR_VERSION;
- APITRACE("H264EncGetApiVersion# OK");
- return ver;
- }
- /*------------------------------------------------------------------------------
- Function name : H264EncGetBuild
- Description : Return the SW and HW build information
-
- Return type : H264EncBuild
- Argument : void
- ------------------------------------------------------------------------------*/
- H264EncBuild H264EncGetBuild(void)
- {
- H264EncBuild ver;
- ver.swBuild = H264ENC_SW_BUILD;
- ver.hwBuild = EWLReadAsicID();
- APITRACE("H264EncGetBuild# OK");
- return (ver);
- }
- /*------------------------------------------------------------------------------
- Function name : H264EncInit
- Description : Initialize an encoder instance and returns it to application
-
- Return type : H264EncRet
- Argument : pEncCfg - initialization parameters
- instAddr - where to save the created instance
- ------------------------------------------------------------------------------*/
- H264EncRet H264EncInit(const H264EncConfig * pEncCfg, H264EncInst * instAddr)
- {
- H264EncRet ret;
- h264Instance_s *pEncInst = NULL;
- APITRACE("H264EncInit#");
- /* check that right shift on negative numbers is performed signed */
- /*lint -save -e* following check causes multiple lint messages */
- #if (((-1) >> 1) != (-1))
- #error Right bit-shifting (>>) does not preserve the sign
- #endif
- /*lint -restore */
- /* Check for illegal inputs */
- if(pEncCfg == NULL || instAddr == NULL)
- {
- APITRACE("H264EncInit: ERROR Null argument");
- return H264ENC_NULL_ARGUMENT;
- }
- /* Check for correct HW */
- if ((EWLReadAsicID() & HW_ID_MASK) != HW_ID)
- {
- APITRACE("H264EncInit: ERROR Invalid HW ID");
- return H264ENC_ERROR;
- }
- /* Check that configuration is valid */
- if(H264CheckCfg(pEncCfg) == ENCHW_NOK)
- {
- APITRACE("H264EncInit: ERROR Invalid configuration");
- return H264ENC_INVALID_ARGUMENT;
- }
- /* Initialize encoder instance and allocate memories */
- ret = H264Init(pEncCfg, &pEncInst);
- if(ret != H264ENC_OK)
- {
- APITRACE("H264EncInit: ERROR Initialization failed");
- return ret;
- }
- /* Status == INIT Initialization succesful */
- pEncInst->encStatus = H264ENCSTAT_INIT;
- pEncInst->inst = pEncInst; /* used as checksum */
- *instAddr = (H264EncInst) pEncInst;
- APITRACE("H264EncInit: OK");
- return H264ENC_OK;
- }
- /*------------------------------------------------------------------------------
- Function name : H264EncRelease
- Description : Releases encoder instance and all associated resource
-
- Return type : H264EncRet
- Argument : inst - the instance to be released
- ------------------------------------------------------------------------------*/
- H264EncRet H264EncRelease(H264EncInst inst)
- {
- h264Instance_s *pEncInst = (h264Instance_s *) inst;
- APITRACE("H264EncRelease#");
- /* Check for illegal inputs */
- if(pEncInst == NULL)
- {
- APITRACE("H264EncRelease: ERROR Null argument");
- return H264ENC_NULL_ARGUMENT;
- }
- /* Check for existing instance */
- if(pEncInst->inst != pEncInst)
- {
- APITRACE("H264EncRelease: ERROR Invalid instance");
- return H264ENC_INSTANCE_ERROR;
- }
- #ifdef TRACE_STREAM
- EncCloseStreamTrace();
- #endif
- H264Shutdown(pEncInst);
- APITRACE("H264EncRelease: OK");
- return H264ENC_OK;
- }
- /*------------------------------------------------------------------------------
- Function name : H264EncSetCodingCtrl
- Description : Sets encoding parameters
-
- Return type : H264EncRet
- Argument : inst - the instance in use
- pCodeParams - user provided parameters
- ------------------------------------------------------------------------------*/
- H264EncRet H264EncSetCodingCtrl(H264EncInst inst,
- const H264EncCodingCtrl * pCodeParams)
- {
- h264Instance_s *pEncInst = (h264Instance_s *) inst;
- regValues_s *regs = &pEncInst->asic.regs;
- APITRACE("H264EncSetCodingCtrl#");
- /* Check for illegal inputs */
- if((pEncInst == NULL) || (pCodeParams == NULL))
- {
- APITRACE("H264EncSetCodingCtrl: ERROR Null argument");
- return H264ENC_NULL_ARGUMENT;
- }
- /* Check for existing instance */
- if(pEncInst->inst != pEncInst)
- {
- APITRACE("H264EncSetCodingCtrl: ERROR Invalid instance");
- return H264ENC_INSTANCE_ERROR;
- }
- /* Check for invalid values */
- if(pCodeParams->sliceSize > pEncInst->mbPerCol)
- {
- APITRACE("H264EncSetCodingCtrl: ERROR Invalid sliceSize");
- return H264ENC_INVALID_ARGUMENT;
- }
- if(pCodeParams->cirStart > pEncInst->mbPerFrame ||
- pCodeParams->cirInterval > pEncInst->mbPerFrame)
- {
- APITRACE("H264EncSetCodingCtrl: ERROR Invalid CIR value");
- return H264ENC_INVALID_ARGUMENT;
- }
- if(pCodeParams->intraArea.enable) {
- if(!(pCodeParams->intraArea.top <= pCodeParams->intraArea.bottom &&
- pCodeParams->intraArea.bottom < pEncInst->mbPerCol &&
- pCodeParams->intraArea.left <= pCodeParams->intraArea.right &&
- pCodeParams->intraArea.right < pEncInst->mbPerRow))
- {
- APITRACE("H264EncSetCodingCtrl: ERROR Invalid intraArea");
- return H264ENC_INVALID_ARGUMENT;
- }
- }
- if(pCodeParams->roi1Area.enable) {
- if(!(pCodeParams->roi1Area.top <= pCodeParams->roi1Area.bottom &&
- pCodeParams->roi1Area.bottom < pEncInst->mbPerCol &&
- pCodeParams->roi1Area.left <= pCodeParams->roi1Area.right &&
- pCodeParams->roi1Area.right < pEncInst->mbPerRow))
- {
- APITRACE("H264EncSetCodingCtrl: ERROR Invalid roi1Area");
- return H264ENC_INVALID_ARGUMENT;
- }
- }
- if(pCodeParams->roi2Area.enable) {
- if(!(pCodeParams->roi2Area.top <= pCodeParams->roi2Area.bottom &&
- pCodeParams->roi2Area.bottom < pEncInst->mbPerCol &&
- pCodeParams->roi2Area.left <= pCodeParams->roi2Area.right &&
- pCodeParams->roi2Area.right < pEncInst->mbPerRow))
- {
- APITRACE("H264EncSetCodingCtrl: ERROR Invalid roi2Area");
- return H264ENC_INVALID_ARGUMENT;
- }
- }
- if(pCodeParams->roi1DeltaQp < -15 ||
- pCodeParams->roi1DeltaQp > 0 ||
- pCodeParams->roi2DeltaQp < -15 ||
- pCodeParams->roi2DeltaQp > 0)
- {
- APITRACE("H264EncSetCodingCtrl: ERROR Invalid ROI delta QP");
- return H264ENC_INVALID_ARGUMENT;
- }
- /* Check status, only slice size, CIR & ROI allowed to change after start */
- if(pEncInst->encStatus != H264ENCSTAT_INIT)
- {
- goto set_slice_size;
- }
- if(pCodeParams->constrainedIntraPrediction > 1 ||
- pCodeParams->disableDeblockingFilter > 2 ||
- pCodeParams->enableCabac > 2 ||
- pCodeParams->transform8x8Mode > 2 ||
- pCodeParams->quarterPixelMv > 2 ||
- pCodeParams->seiMessages > 1 || pCodeParams->videoFullRange > 1)
- {
- APITRACE("H264EncSetCodingCtrl: ERROR Invalid enable/disable");
- return H264ENC_INVALID_ARGUMENT;
- }
- if(pCodeParams->sampleAspectRatioWidth > 65535 ||
- pCodeParams->sampleAspectRatioHeight > 65535)
- {
- APITRACE("H264EncSetCodingCtrl: ERROR Invalid sampleAspectRatio");
- return H264ENC_INVALID_ARGUMENT;
- }
- if(pCodeParams->cabacInitIdc > 2)
- {
- APITRACE("H264EncSetCodingCtrl: ERROR Invalid cabacInitIdc");
- return H264ENC_INVALID_ARGUMENT;
- }
- /* Configure the values */
- if(pCodeParams->constrainedIntraPrediction == 0)
- pEncInst->picParameterSet.constIntraPred = ENCHW_NO;
- else
- pEncInst->picParameterSet.constIntraPred = ENCHW_YES;
- /* filter control header always present */
- pEncInst->picParameterSet.deblockingFilterControlPresent = ENCHW_YES;
- pEncInst->slice.disableDeblocking = pCodeParams->disableDeblockingFilter;
- pEncInst->picParameterSet.enableCabac = pCodeParams->enableCabac;
- pEncInst->slice.cabacInitIdc = pCodeParams->cabacInitIdc;
- if((pCodeParams->enableCabac == 0) || (pCodeParams->enableCabac == 2))
- pEncInst->picParameterSet.entropyCodingMode = ENCHW_NO;
- else
- pEncInst->picParameterSet.entropyCodingMode = ENCHW_YES;
- /* 8x8 mode: 2=enable, 1=adaptive (720p or bigger frame) */
- if ((pCodeParams->transform8x8Mode == 2) ||
- ((pCodeParams->transform8x8Mode == 1) &&
- (pEncInst->mbPerFrame >= 3600)))
- {
- pEncInst->picParameterSet.transform8x8Mode = ENCHW_YES;
- }
- H264SpsSetVuiAspectRatio(&pEncInst->seqParameterSet,
- pCodeParams->sampleAspectRatioWidth,
- pCodeParams->sampleAspectRatioHeight);
- H264SpsSetVuiVideoInfo(&pEncInst->seqParameterSet,
- pCodeParams->videoFullRange);
- /* SEI messages are written in the beginning of each frame */
- if(pCodeParams->seiMessages)
- pEncInst->rateControl.sei.enabled = ENCHW_YES;
- else
- pEncInst->rateControl.sei.enabled = ENCHW_NO;
- set_slice_size:
- /* Slice size is set in macroblock rows => convert to macroblocks */
- pEncInst->slice.sliceSize = pCodeParams->sliceSize * pEncInst->mbPerRow;
- pEncInst->slice.quarterPixelMv = pCodeParams->quarterPixelMv;
- /* Set CIR, intra forcing and ROI parameters */
- regs->cirStart = pCodeParams->cirStart;
- regs->cirInterval = pCodeParams->cirInterval;
- regs->intraSliceMap1 = pCodeParams->intraSliceMap1;
- regs->intraSliceMap2 = pCodeParams->intraSliceMap2;
- regs->intraSliceMap3 = pCodeParams->intraSliceMap3;
- if (pCodeParams->intraArea.enable) {
- regs->intraAreaTop = pCodeParams->intraArea.top;
- regs->intraAreaLeft = pCodeParams->intraArea.left;
- regs->intraAreaBottom = pCodeParams->intraArea.bottom;
- regs->intraAreaRight = pCodeParams->intraArea.right;
- }
- if (pCodeParams->roi1Area.enable) {
- regs->roi1Top = pCodeParams->roi1Area.top;
- regs->roi1Left = pCodeParams->roi1Area.left;
- regs->roi1Bottom = pCodeParams->roi1Area.bottom;
- regs->roi1Right = pCodeParams->roi1Area.right;
- }
- if (pCodeParams->roi2Area.enable) {
- regs->roi2Top = pCodeParams->roi2Area.top;
- regs->roi2Left = pCodeParams->roi2Area.left;
- regs->roi2Bottom = pCodeParams->roi2Area.bottom;
- regs->roi2Right = pCodeParams->roi2Area.right;
- }
- regs->roi1DeltaQp = -pCodeParams->roi1DeltaQp;
- regs->roi2DeltaQp = -pCodeParams->roi2DeltaQp;
- APITRACE("H264EncSetCodingCtrl: OK");
- return H264ENC_OK;
- }
- /*------------------------------------------------------------------------------
- Function name : H264EncGetCodingCtrl
- Description : Returns current encoding parameters
-
- Return type : H264EncRet
- Argument : inst - the instance in use
- pCodeParams - palce where parameters are returned
- ------------------------------------------------------------------------------*/
- H264EncRet H264EncGetCodingCtrl(H264EncInst inst,
- H264EncCodingCtrl * pCodeParams)
- {
- h264Instance_s *pEncInst = (h264Instance_s *) inst;
- regValues_s *regs = &pEncInst->asic.regs;
- APITRACE("H264EncGetCodingCtrl#");
- /* Check for illegal inputs */
- if((pEncInst == NULL) || (pCodeParams == NULL))
- {
- APITRACE("H264EncGetCodingCtrl: ERROR Null argument");
- return H264ENC_NULL_ARGUMENT;
- }
- /* Check for existing instance */
- if(pEncInst->inst != pEncInst)
- {
- APITRACE("H264EncGetCodingCtrl: ERROR Invalid instance");
- return H264ENC_INSTANCE_ERROR;
- }
- /* Get values */
- pCodeParams->constrainedIntraPrediction =
- (pEncInst->picParameterSet.constIntraPred == ENCHW_NO) ? 0 : 1;
- /* Slice size from macroblocks to macroblock rows */
- pCodeParams->sliceSize = pEncInst->slice.sliceSize / pEncInst->mbPerRow;
- pCodeParams->seiMessages =
- (pEncInst->rateControl.sei.enabled == ENCHW_YES) ? 1 : 0;
- pCodeParams->videoFullRange =
- (pEncInst->seqParameterSet.vui.videoFullRange == ENCHW_YES) ? 1 : 0;
- pCodeParams->sampleAspectRatioWidth =
- pEncInst->seqParameterSet.vui.sarWidth;
- pCodeParams->sampleAspectRatioHeight =
- pEncInst->seqParameterSet.vui.sarHeight;
- pCodeParams->disableDeblockingFilter = pEncInst->slice.disableDeblocking;
- pCodeParams->enableCabac = pEncInst->picParameterSet.enableCabac;
- pCodeParams->cabacInitIdc = pEncInst->slice.cabacInitIdc;
- pCodeParams->transform8x8Mode = pEncInst->picParameterSet.transform8x8Mode;
- pCodeParams->quarterPixelMv = pEncInst->slice.quarterPixelMv;
- pCodeParams->cirStart = regs->cirStart;
- pCodeParams->cirInterval = regs->cirInterval;
- pCodeParams->intraSliceMap1 = regs->intraSliceMap1;
- pCodeParams->intraSliceMap2 = regs->intraSliceMap2;
- pCodeParams->intraSliceMap3 = regs->intraSliceMap3;
- pCodeParams->intraArea.enable = regs->intraAreaTop < pEncInst->mbPerCol ? 1 : 0;
- pCodeParams->intraArea.top = regs->intraAreaTop;
- pCodeParams->intraArea.left = regs->intraAreaLeft;
- pCodeParams->intraArea.bottom = regs->intraAreaBottom;
- pCodeParams->intraArea.right = regs->intraAreaRight;
- pCodeParams->roi1Area.enable = regs->roi1Top < pEncInst->mbPerCol ? 1 : 0;
- pCodeParams->roi1Area.top = regs->roi1Top;
- pCodeParams->roi1Area.left = regs->roi1Left;
- pCodeParams->roi1Area.bottom = regs->roi1Bottom;
- pCodeParams->roi1Area.right = regs->roi1Right;
- pCodeParams->roi2Area.enable = regs->roi2Top < pEncInst->mbPerCol ? 1 : 0;
- pCodeParams->roi2Area.top = regs->roi2Top;
- pCodeParams->roi2Area.left = regs->roi2Left;
- pCodeParams->roi2Area.bottom = regs->roi2Bottom;
- pCodeParams->roi2Area.right = regs->roi2Right;
- pCodeParams->roi1DeltaQp = -regs->roi1DeltaQp;
- pCodeParams->roi2DeltaQp = -regs->roi2DeltaQp;
- APITRACE("H264EncGetCodingCtrl: OK");
- return H264ENC_OK;
- }
- /*------------------------------------------------------------------------------
- Function name : H264EncSetRateCtrl
- Description : Sets rate control parameters
-
- Return type : H264EncRet
- Argument : inst - the instance in use
- pRateCtrl - user provided parameters
- ------------------------------------------------------------------------------*/
- H264EncRet H264EncSetRateCtrl(H264EncInst inst,
- const H264EncRateCtrl * pRateCtrl)
- {
- h264Instance_s *pEncInst = (h264Instance_s *) inst;
- h264RateControl_s *rc;
- u32 i, tmp;
- APITRACE("H264EncSetRateCtrl#");
- /* Check for illegal inputs */
- if((pEncInst == NULL) || (pRateCtrl == NULL))
- {
- APITRACE("H264EncSetRateCtrl: ERROR Null argument");
- return H264ENC_NULL_ARGUMENT;
- }
- /* Check for existing instance */
- if(pEncInst->inst != pEncInst)
- {
- APITRACE("H264EncSetRateCtrl: ERROR Invalid instance");
- return H264ENC_INSTANCE_ERROR;
- }
- rc = &pEncInst->rateControl;
- /* after stream was started with HRD ON,
- * it is not allowed to change RC params */
- if(pEncInst->encStatus == H264ENCSTAT_START_FRAME && rc->hrd == ENCHW_YES)
- {
- APITRACE
- ("H264EncSetRateCtrl: ERROR Stream started with HRD ON. Not allowed to change any parameters");
- return H264ENC_INVALID_STATUS;
- }
- /* Check for invalid input values */
- if(pRateCtrl->pictureRc > 1 ||
- pRateCtrl->mbRc > 1 || pRateCtrl->pictureSkip > 1 || pRateCtrl->hrd > 1)
- {
- APITRACE("H264EncSetRateCtrl: ERROR Invalid enable/disable value");
- return H264ENC_INVALID_ARGUMENT;
- }
- if(pRateCtrl->qpHdr > 51 ||
- pRateCtrl->qpMin > 51 ||
- pRateCtrl->qpMax > 51 ||
- pRateCtrl->qpMax < pRateCtrl->qpMin)
- {
- APITRACE("H264EncSetRateCtrl: ERROR Invalid QP");
- return H264ENC_INVALID_ARGUMENT;
- }
- if((pRateCtrl->qpHdr != -1) &&
- (pRateCtrl->qpHdr < (i32)pRateCtrl->qpMin ||
- pRateCtrl->qpHdr > (i32)pRateCtrl->qpMax))
- {
- APITRACE("H264EncSetRateCtrl: ERROR QP out of range");
- return H264ENC_INVALID_ARGUMENT;
- }
- if((u32)(pRateCtrl->intraQpDelta + 12) > 24)
- {
- APITRACE("H264EncSetRateCtrl: ERROR intraQpDelta out of range");
- return H264ENC_INVALID_ARGUMENT;
- }
- if(pRateCtrl->fixedIntraQp > 51)
- {
- APITRACE("H264EncSetRateCtrl: ERROR fixedIntraQp out of range");
- return H264ENC_INVALID_ARGUMENT;
- }
- if(pRateCtrl->gopLen < 1 || pRateCtrl->gopLen > 300)
- {
- APITRACE("H264EncSetRateCtrl: ERROR Invalid GOP length");
- return H264ENC_INVALID_ARGUMENT;
- }
- /* Bitrate affects only when rate control is enabled */
- if((pRateCtrl->pictureRc || pRateCtrl->mbRc ||
- pRateCtrl->pictureSkip || pRateCtrl->hrd) &&
- (pRateCtrl->bitPerSecond < 10000 ||
- pRateCtrl->bitPerSecond > H264ENC_MAX_BITRATE))
- {
- APITRACE("H264EncSetRateCtrl: ERROR Invalid bitPerSecond");
- return H264ENC_INVALID_ARGUMENT;
- }
- {
- u32 cpbSize = pRateCtrl->hrdCpbSize;
- u32 bps = pRateCtrl->bitPerSecond;
- u32 level = pEncInst->seqParameterSet.levelIdx;
- /* Limit maximum bitrate based on resolution and frame rate */
- /* Saturates really high settings */
- /* bits per unpacked frame */
- tmp = 3 * 8 * pEncInst->mbPerFrame * 256 / 2;
- /* bits per second */
- tmp = H264Calculate(tmp, rc->outRateNum, rc->outRateDenom);
- if (bps > (tmp / 2))
- bps = tmp / 2;
- if(cpbSize == 0)
- cpbSize = H264MaxCPBS[level];
- else if(cpbSize == (u32) (-1))
- cpbSize = bps;
- /* Limit minimum CPB size based on average bits per frame */
- tmp = H264Calculate(bps, rc->outRateDenom, rc->outRateNum);
- cpbSize = MAX(cpbSize, tmp);
- /* cpbSize must be rounded so it is exactly the size written in stream */
- i = 0;
- tmp = cpbSize;
- while (4095 < (tmp >> (4 + i++)));
- cpbSize = (tmp >> (4 + i)) << (4 + i);
- /* if HRD is ON we have to obay all its limits */
- if(pRateCtrl->hrd != 0)
- {
- if(cpbSize > H264MaxCPBS[level])
- {
- APITRACE
- ("H264EncSetRateCtrl: ERROR. HRD is ON. hrdCpbSize higher than maximum allowed for stream level");
- return H264ENC_INVALID_ARGUMENT;
- }
- if(bps > H264MaxBR[level])
- {
- APITRACE
- ("H264EncSetRateCtrl: ERROR. HRD is ON. bitPerSecond higher than maximum allowed for stream level");
- return H264ENC_INVALID_ARGUMENT;
- }
- }
- rc->virtualBuffer.bufferSize = cpbSize;
- /* Set the parameters to rate control */
- if(pRateCtrl->pictureRc != 0)
- rc->picRc = ENCHW_YES;
- else
- rc->picRc = ENCHW_NO;
- if(pRateCtrl->mbRc != 0)
- rc->mbRc = ENCHW_YES;
- else
- rc->mbRc = ENCHW_NO;
- if(pRateCtrl->pictureSkip != 0)
- rc->picSkip = ENCHW_YES;
- else
- rc->picSkip = ENCHW_NO;
- if(pRateCtrl->hrd != 0)
- {
- rc->hrd = ENCHW_YES;
- rc->picRc = ENCHW_YES;
- }
- else
- rc->hrd = ENCHW_NO;
- rc->qpHdr = pRateCtrl->qpHdr;
- rc->qpMin = pRateCtrl->qpMin;
- rc->qpMax = pRateCtrl->qpMax;
- rc->virtualBuffer.bitRate = bps;
- rc->gopLen = pRateCtrl->gopLen;
- }
- rc->intraQpDelta = pRateCtrl->intraQpDelta;
- rc->fixedIntraQp = pRateCtrl->fixedIntraQp;
- rc->mbQpAdjustment = pRateCtrl->mbQpAdjustment;
- (void) H264InitRc(rc); /* new parameters checked already */
- APITRACE("H264EncSetRateCtrl: OK");
- return H264ENC_OK;
- }
- /*------------------------------------------------------------------------------
- Function name : H264EncGetRateCtrl
- Description : Return current rate control parameters
-
- Return type : H264EncRet
- Argument : inst - the instance in use
- pRateCtrl - place where parameters are returned
- ------------------------------------------------------------------------------*/
- H264EncRet H264EncGetRateCtrl(H264EncInst inst, H264EncRateCtrl * pRateCtrl)
- {
- h264Instance_s *pEncInst = (h264Instance_s *) inst;
- h264RateControl_s *rc;
- APITRACE("H264EncGetRateCtrl#");
- /* Check for illegal inputs */
- if((pEncInst == NULL) || (pRateCtrl == NULL))
- {
- APITRACE("H264EncGetRateCtrl: ERROR Null argument");
- return H264ENC_NULL_ARGUMENT;
- }
- /* Check for existing instance */
- if(pEncInst->inst != pEncInst)
- {
- APITRACE("H264EncGetRateCtrl: ERROR Invalid instance");
- return H264ENC_INSTANCE_ERROR;
- }
- /* Get the values */
- rc = &pEncInst->rateControl;
- pRateCtrl->pictureRc = rc->picRc == ENCHW_NO ? 0 : 1;
- pRateCtrl->mbRc = rc->mbRc == ENCHW_NO ? 0 : 1;
- pRateCtrl->pictureSkip = rc->picSkip == ENCHW_NO ? 0 : 1;
- pRateCtrl->qpHdr = rc->qpHdr;
- pRateCtrl->qpMin = rc->qpMin;
- pRateCtrl->qpMax = rc->qpMax;
- pRateCtrl->bitPerSecond = rc->virtualBuffer.bitRate;
- pRateCtrl->hrd = rc->hrd == ENCHW_NO ? 0 : 1;
- pRateCtrl->gopLen = rc->gopLen;
- pRateCtrl->hrdCpbSize = (u32) rc->virtualBuffer.bufferSize;
- pRateCtrl->intraQpDelta = rc->intraQpDelta;
- pRateCtrl->fixedIntraQp = rc->fixedIntraQp;
- APITRACE("H264EncGetRateCtrl: OK");
- return H264ENC_OK;
- }
- /*------------------------------------------------------------------------------
- Function name : VSCheckSize
- Description :
- Return type : i32
- Argument : u32 inputWidth
- Argument : u32 inputHeight
- Argument : u32 stabilizedWidth
- Argument : u32 stabilizedHeight
- ------------------------------------------------------------------------------*/
- i32 VSCheckSize(u32 inputWidth, u32 inputHeight, u32 stabilizedWidth,
- u32 stabilizedHeight)
- {
- /* Input picture minimum dimensions */
- if((inputWidth < 104) || (inputHeight < 104))
- return 1;
- /* Stabilized picture minimum values */
- if((stabilizedWidth < 96) || (stabilizedHeight < 96))
- return 1;
- /* Stabilized dimensions multiple of 4 */
- if(((stabilizedWidth & 3) != 0) || ((stabilizedHeight & 3) != 0))
- return 1;
- /* Edge >= 4 pixels, not checked because stabilization can be
- * used without cropping for scene detection
- if((inputWidth < (stabilizedWidth + 8)) ||
- (inputHeight < (stabilizedHeight + 8)))
- return 1; */
- return 0;
- }
- /*------------------------------------------------------------------------------
- Function name : H264EncSetPreProcessing
- Description : Sets the preprocessing parameters
- Return type : H264EncRet
- Argument : inst - encoder instance in use
- Argument : pPreProcCfg - user provided parameters
- ------------------------------------------------------------------------------*/
- H264EncRet H264EncSetPreProcessing(H264EncInst inst,
- const H264EncPreProcessingCfg * pPreProcCfg)
- {
- h264Instance_s *pEncInst = (h264Instance_s *) inst;
- preProcess_s pp_tmp;
- APITRACE("H264EncSetPreProcessing#");
- /* Check for illegal inputs */
- if((inst == NULL) || (pPreProcCfg == NULL))
- {
- APITRACE("H264EncSetPreProcessing: ERROR Null argument");
- return H264ENC_NULL_ARGUMENT;
- }
- /* Check for existing instance */
- if(pEncInst->inst != pEncInst)
- {
- APITRACE("H264EncSetPreProcessing: ERROR Invalid instance");
- return H264ENC_INSTANCE_ERROR;
- }
- /* check HW limitations */
- {
- EWLHwConfig_t cfg = EWLReadAsicConfig();
- /* is video stabilization supported? */
- if(cfg.vsEnabled == EWL_HW_CONFIG_NOT_SUPPORTED &&
- pPreProcCfg->videoStabilization != 0)
- {
- APITRACE("H264EncSetPreProcessing: ERROR Stabilization not supported");
- return H264ENC_INVALID_ARGUMENT;
- }
- if(cfg.rgbEnabled == EWL_HW_CONFIG_NOT_SUPPORTED &&
- pPreProcCfg->inputType >= H264ENC_RGB565 &&
- pPreProcCfg->inputType <= H264ENC_BGR101010)
- {
- APITRACE("H264EncSetPreProcessing: ERROR RGB input not supported");
- return H264ENC_INVALID_ARGUMENT;
- }
- }
- if(pPreProcCfg->origWidth > H264ENC_MAX_PP_INPUT_WIDTH ||
- pPreProcCfg->origHeight > H264ENC_MAX_PP_INPUT_HEIGHT)
- {
- APITRACE("H264EncSetPreProcessing: ERROR Too big input image");
- return H264ENC_INVALID_ARGUMENT;
- }
- if(pPreProcCfg->inputType > H264ENC_BGR101010)
- {
- APITRACE("H264EncSetPreProcessing: ERROR Invalid YUV type");
- return H264ENC_INVALID_ARGUMENT;
- }
- if(pPreProcCfg->rotation > H264ENC_ROTATE_90L)
- {
- APITRACE("H264EncSetPreProcessing: ERROR Invalid rotation");
- return H264ENC_INVALID_ARGUMENT;
- }
- pp_tmp.lumHeightSrc = pPreProcCfg->origHeight;
- pp_tmp.lumWidthSrc = pPreProcCfg->origWidth;
- if(pPreProcCfg->videoStabilization == 0)
- {
- pp_tmp.horOffsetSrc = pPreProcCfg->xOffset;
- pp_tmp.verOffsetSrc = pPreProcCfg->yOffset;
- }
- else
- {
- pp_tmp.horOffsetSrc = pp_tmp.verOffsetSrc = 0;
- }
- pp_tmp.lumWidth = pEncInst->preProcess.lumWidth;
- pp_tmp.lumHeight = pEncInst->preProcess.lumHeight;
- pp_tmp.rotation = pPreProcCfg->rotation;
- pp_tmp.inputFormat = pPreProcCfg->inputType;
- pp_tmp.videoStab = (pPreProcCfg->videoStabilization != 0) ? 1 : 0;
- /* Check for invalid values */
- if(EncPreProcessCheck(&pp_tmp) != ENCHW_OK)
- {
- APITRACE("H264EncSetPreProcessing: ERROR Invalid cropping values");
- return H264ENC_INVALID_ARGUMENT;
- }
- /* Set cropping parameters if required */
- if( pEncInst->preProcess.lumWidth%16 || pEncInst->preProcess.lumHeight%16 )
- {
- u32 fillRight = (pEncInst->preProcess.lumWidth+15)/16*16 -
- pEncInst->preProcess.lumWidth;
- u32 fillBottom = (pEncInst->preProcess.lumHeight+15)/16*16 -
- pEncInst->preProcess.lumHeight;
- pEncInst->seqParameterSet.frameCropping = ENCHW_YES;
- pEncInst->seqParameterSet.frameCropLeftOffset = 0;
- pEncInst->seqParameterSet.frameCropRightOffset = 0;
- pEncInst->seqParameterSet.frameCropTopOffset = 0;
- pEncInst->seqParameterSet.frameCropBottomOffset = 0;
- if (pPreProcCfg->rotation == 0) { /* No rotation */
- pEncInst->seqParameterSet.frameCropRightOffset = fillRight/2;
- pEncInst->seqParameterSet.frameCropBottomOffset = fillBottom/2;
- } else if (pPreProcCfg->rotation == 1) { /* Rotate right */
- pEncInst->seqParameterSet.frameCropLeftOffset = fillRight/2;
- pEncInst->seqParameterSet.frameCropBottomOffset = fillBottom/2;
- } else { /* Rotate left */
- pEncInst->seqParameterSet.frameCropRightOffset = fillRight/2;
- pEncInst->seqParameterSet.frameCropTopOffset = fillBottom/2;
- }
- }
- if(pp_tmp.videoStab != 0)
- {
- u32 width = pp_tmp.lumWidth;
- u32 height = pp_tmp.lumHeight;
- if(pp_tmp.rotation)
- {
- u32 tmp;
- tmp = width;
- width = height;
- height = tmp;
- }
- if(VSCheckSize(pp_tmp.lumWidthSrc, pp_tmp.lumHeightSrc, width, height)
- != 0)
- {
- APITRACE
- ("H264EncSetPreProcessing: ERROR Invalid size for stabilization");
- return H264ENC_INVALID_ARGUMENT;
- }
- #ifdef VIDEOSTAB_ENABLED
- VSAlgInit(&pEncInst->vsSwData, pp_tmp.lumWidthSrc, pp_tmp.lumHeightSrc,
- width, height);
- VSAlgGetResult(&pEncInst->vsSwData, &pp_tmp.horOffsetSrc,
- &pp_tmp.verOffsetSrc);
- #endif
- }
- pp_tmp.colorConversionType = pPreProcCfg->colorConversion.type;
- pp_tmp.colorConversionCoeffA = pPreProcCfg->colorConversion.coeffA;
- pp_tmp.colorConversionCoeffB = pPreProcCfg->colorConversion.coeffB;
- pp_tmp.colorConversionCoeffC = pPreProcCfg->colorConversion.coeffC;
- pp_tmp.colorConversionCoeffE = pPreProcCfg->colorConversion.coeffE;
- pp_tmp.colorConversionCoeffF = pPreProcCfg->colorConversion.coeffF;
- EncSetColorConversion(&pp_tmp, &pEncInst->asic);
- {
- preProcess_s *pp = &pEncInst->preProcess;
- if(EWLmemcpy(pp, &pp_tmp, sizeof(preProcess_s)) != pp)
- {
- APITRACE("H264EncSetPreProcessing: memcpy failed");
- return H264ENC_SYSTEM_ERROR;
- }
- }
- APITRACE("H264EncSetPreProcessing: OK");
- return H264ENC_OK;
- }
- /*------------------------------------------------------------------------------
- Function name : H264EncGetPreProcessing
- Description : Returns current preprocessing parameters
- Return type : H264EncRet
- Argument : inst - encoder instance
- Argument : pPreProcCfg - place where the parameters are returned
- ------------------------------------------------------------------------------*/
- H264EncRet H264EncGetPreProcessing(H264EncInst inst,
- H264EncPreProcessingCfg * pPreProcCfg)
- {
- h264Instance_s *pEncInst = (h264Instance_s *) inst;
- preProcess_s *pPP;
- APITRACE("H264EncGetPreProcessing#");
- /* Check for illegal inputs */
- if((inst == NULL) || (pPreProcCfg == NULL))
- {
- APITRACE("H264EncGetPreProcessing: ERROR Null argument");
- return H264ENC_NULL_ARGUMENT;
- }
- /* Check for existing instance */
- if(pEncInst->inst != pEncInst)
- {
- APITRACE("H264EncGetPreProcessing: ERROR Invalid instance");
- return H264ENC_INSTANCE_ERROR;
- }
- pPP = &pEncInst->preProcess;
- pPreProcCfg->origHeight = pPP->lumHeightSrc;
- pPreProcCfg->origWidth = pPP->lumWidthSrc;
- pPreProcCfg->xOffset = pPP->horOffsetSrc;
- pPreProcCfg->yOffset = pPP->verOffsetSrc;
- pPreProcCfg->rotation = (H264EncPictureRotation) pPP->rotation;
- pPreProcCfg->inputType = (H264EncPictureType) pPP->inputFormat;
- pPreProcCfg->videoStabilization = pPP->videoStab;
- pPreProcCfg->colorConversion.type =
- (H264EncColorConversionType) pPP->colorConversionType;
- pPreProcCfg->colorConversion.coeffA = pPP->colorConversionCoeffA;
- pPreProcCfg->colorConversion.coeffB = pPP->colorConversionCoeffB;
- pPreProcCfg->colorConversion.coeffC = pPP->colorConversionCoeffC;
- pPreProcCfg->colorConversion.coeffE = pPP->colorConversionCoeffE;
- pPreProcCfg->colorConversion.coeffF = pPP->colorConversionCoeffF;
- APITRACE("H264EncGetPreProcessing: OK");
- return H264ENC_OK;
- }
- /*------------------------------------------------------------------------------
- Function name : H264EncSetSeiUserData
- Description : Sets user data SEI messages
- Return type : H264EncRet
- Argument : inst - the instance in use
- pUserData - pointer to userData, this is used by the
- encoder so it must not be released before
- disabling user data
- userDataSize - size of userData, minimum size 16,
- maximum size H264ENC_MAX_USER_DATA_SIZE
- not valid size disables userData sei messages
- ------------------------------------------------------------------------------*/
- H264EncRet H264EncSetSeiUserData(H264EncInst inst, const u8 * pUserData,
- u32 userDataSize)
- {
- h264Instance_s *pEncInst = (h264Instance_s *) inst;
- /* Check for illegal inputs */
- if((pEncInst == NULL) || (userDataSize != 0 && pUserData == NULL))
- {
- APITRACE("H264EncSetSeiUserData: ERROR Null argument");
- return H264ENC_NULL_ARGUMENT;
- }
- /* Check for existing instance */
- if(pEncInst->inst != pEncInst)
- {
- APITRACE("H264EncSetSeiUserData: ERROR Invalid instance");
- return H264ENC_INSTANCE_ERROR;
- }
- /* Disable user data */
- if((userDataSize < 16) || (userDataSize > H264ENC_MAX_USER_DATA_SIZE))
- {
- pEncInst->rateControl.sei.userDataEnabled = ENCHW_NO;
- pEncInst->rateControl.sei.pUserData = NULL;
- pEncInst->rateControl.sei.userDataSize = 0;
- }
- else
- {
- pEncInst->rateControl.sei.userDataEnabled = ENCHW_YES;
- pEncInst->rateControl.sei.pUserData = pUserData;
- pEncInst->rateControl.sei.userDataSize = userDataSize;
- }
- return H264ENC_OK;
- }
- /*------------------------------------------------------------------------------
- Function name : H264EncStrmStart
- Description : Starts a new stream
- Return type : H264EncRet
- Argument : inst - encoder instance
- Argument : pEncIn - user provided input parameters
- pEncOut - place where output info is returned
- ------------------------------------------------------------------------------*/
- H264EncRet H264EncStrmStart(H264EncInst inst, const H264EncIn * pEncIn,
- H264EncOut * pEncOut)
- {
- h264Instance_s *pEncInst = (h264Instance_s *) inst;
- h264RateControl_s *rc;
- u32 tmp;
- APITRACE("H264EncStrmStart#");
- /* Check for illegal inputs */
- if((pEncInst == NULL) || (pEncIn == NULL) || (pEncOut == NULL))
- {
- APITRACE("H264EncStrmStart: ERROR Null argument");
- return H264ENC_NULL_ARGUMENT;
- }
- /* Check for existing instance */
- if(pEncInst->inst != pEncInst)
- {
- APITRACE("H264EncStrmStart: ERROR Invalid instance");
- return H264ENC_INSTANCE_ERROR;
- }
- pEncOut->streamSize = 0;
- rc = &pEncInst->rateControl;
- /* Check status */
- if(pEncInst->encStatus != H264ENCSTAT_INIT)
- {
- APITRACE("H264EncStrmStart: ERROR Invalid status");
- return H264ENC_INVALID_STATUS;
- }
- /* Check for invalid input values */
- if((pEncIn->pOutBuf == NULL) ||
- (pEncIn->outBufSize < H264ENCSTRMSTART_MIN_BUF))
- {
- APITRACE("H264EncStrmStart: ERROR Invalid input. Stream buffer");
- return H264ENC_INVALID_ARGUMENT;
- }
- /* Set stream buffer, the size has been checked */
- (void) H264SetBuffer(&pEncInst->stream, (u8 *) pEncIn->pOutBuf,
- (u32) pEncIn->outBufSize);
- /* Set pointer to the beginning of NAL unit size buffer */
- pEncOut->pNaluSizeBuf = (u32 *) pEncInst->asic.sizeTbl.nal.virtualAddress;
- pEncOut->numNalus = 0;
- #ifdef INTERNAL_TEST
- /* Configure the encoder instance according to the test vector */
- H264ConfigureTestBeforeStream(pEncInst);
- #endif
- #ifdef TRACE_STREAM
- /* Open stream tracing */
- EncOpenStreamTrace("stream.trc");
- traceStream.frameNum = pEncInst->frameCnt;
- traceStream.id = 0; /* Stream generated by SW */
- traceStream.bitCnt = 0; /* New frame */
- #endif
- /* Set the profile to be used */
- pEncInst->seqParameterSet.profileIdc = 66; /* base profile */
- /* CABAC => main profile */
- if (pEncInst->picParameterSet.enableCabac >= 1)
- pEncInst->seqParameterSet.profileIdc = 77;
- /* 8x8 transform enabled => high profile */
- if (pEncInst->picParameterSet.transform8x8Mode == ENCHW_YES)
- pEncInst->seqParameterSet.profileIdc = 100;
- /* update VUI */
- if(rc->sei.enabled == ENCHW_YES)
- {
- H264SpsSetVuiPictStructPresentFlag(&pEncInst->seqParameterSet, 1);
- }
- if(rc->hrd == ENCHW_YES)
- {
- H264SpsSetVuiHrd(&pEncInst->seqParameterSet, 1);
- H264SpsSetVuiHrdBitRate(&pEncInst->seqParameterSet,
- rc->virtualBuffer.bitRate);
- H264SpsSetVuiHrdCpbSize(&pEncInst->seqParameterSet,
- rc->virtualBuffer.bufferSize);
- }
- /* Initialize cabac context tables for HW */
- if (pEncInst->picParameterSet.enableCabac >= 1)
- {
- if (H264CabacInit(pEncInst->asic.cabacCtx.virtualAddress,
- pEncInst->slice.cabacInitIdc) != 0)
- {
- APITRACE("H264EncStrmStart: ERROR in CABAC Context Init");
- return H264ENC_MEMORY_ERROR;
- }
- }
- /* Use the first frame QP in the PPS */
- pEncInst->picParameterSet.picInitQpMinus26 = (i32) (rc->qpHdr) - 26;
- /* Init SEI */
- H264InitSei(&rc->sei, pEncInst->seqParameterSet.byteStream,
- rc->hrd, rc->outRateNum, rc->outRateDenom);
- H264SeqParameterSet(&pEncInst->stream, &pEncInst->seqParameterSet, ENCHW_YES);
- H264AddNaluSize(pEncOut, pEncInst->stream.byteCnt);
- tmp = pEncInst->stream.byteCnt;
- /* Subset SPS for MVC */
- if (pEncInst->numViews > 1)
- {
- H264SubsetSeqParameterSet(&pEncInst->stream, &pEncInst->seqParameterSet);
- H264AddNaluSize(pEncOut, pEncInst->stream.byteCnt-tmp);
- tmp = pEncInst->stream.byteCnt;
- }
- H264PicParameterSet(&pEncInst->stream, &pEncInst->picParameterSet);
- H264AddNaluSize(pEncOut, pEncInst->stream.byteCnt-tmp);
- tmp = pEncInst->stream.byteCnt;
- /* In CABAC mode 2 we need two PPS: one with CAVLC (ppsId=0 for intra) and
- * one with CABAC (ppsId=1 for inter) */
- if (pEncInst->picParameterSet.enableCabac == 2)
- {
- pEncInst->picParameterSet.picParameterSetId = 1;
- pEncInst->picParameterSet.entropyCodingMode = ENCHW_YES;
- H264PicParameterSet(&pEncInst->stream, &pEncInst->picParameterSet);
- H264AddNaluSize(pEncOut, pEncInst->stream.byteCnt-tmp);
- tmp = pEncInst->stream.byteCnt;
- }
- if(pEncInst->stream.overflow == ENCHW_YES)
- {
- pEncOut->streamSize = 0;
- pEncOut->numNalus = 0;
- APITRACE("H264EncStrmStart: ERROR Output buffer too small");
- return H264ENC_OUTPUT_BUFFER_OVERFLOW;
- }
- /* Bytes generated */
- pEncOut->streamSize = pEncInst->stream.byteCnt;
- /* Status == START_STREAM Stream started */
- pEncInst->encStatus = H264ENCSTAT_START_STREAM;
- pEncInst->slice.frameNum = 0;
- pEncInst->rateControl.fillerIdx = (u32) (-1);
- if(rc->hrd == ENCHW_YES)
- {
- /* Update HRD Parameters to RC if needed */
- u32 bitrate = H264SpsGetVuiHrdBitRate(&pEncInst->seqParameterSet);
- u32 cpbsize = H264SpsGetVuiHrdCpbSize(&pEncInst->seqParameterSet);
- if ((rc->virtualBuffer.bitRate != (i32)bitrate) ||
- (rc->virtualBuffer.bufferSize != (i32)cpbsize))
- {
- rc->virtualBuffer.bitRate = bitrate;
- rc->virtualBuffer.bufferSize = cpbsize;
- (void) H264InitRc(rc);
- }
- }
- #ifdef VIDEOSTAB_ENABLED
- /* new stream so reset the stabilization */
- VSAlgReset(&pEncInst->vsSwData);
- #endif
- APITRACE("H264EncStrmStart: OK");
- return H264ENC_OK;
- }
- /*------------------------------------------------------------------------------
- Function name : H264EncStrmEncode
- Description : Encodes a new picture
- Return type : H264EncRet
- Argument : inst - encoder instance
- Argument : pEncIn - user provided input parameters
- pEncOut - place where output info is returned
- ------------------------------------------------------------------------------*/
- H264EncRet H264EncStrmEncode(H264EncInst inst, const H264EncIn * pEncIn,
- H264EncOut * pEncOut,
- H264EncSliceReadyCallBackFunc sliceReadyCbFunc,
- void * pAppData)
- {
- h264Instance_s *pEncInst = (h264Instance_s *) inst;
- slice_s *pSlice;
- regValues_s *regs;
- h264EncodeFrame_e ret;
- APITRACE("H264EncStrmEncode#");
- /* Check for illegal inputs */
- if((pEncInst == NULL) || (pEncIn == NULL) || (pEncOut == NULL))
- {
- APITRACE("H264EncStrmEncode: ERROR Null argument");
- return H264ENC_NULL_ARGUMENT;
- }
- /* Check for existing instance */
- if(pEncInst->inst != pEncInst)
- {
- APITRACE("H264EncStrmEncode: ERROR Invalid instance");
- return H264ENC_INSTANCE_ERROR;
- }
- /* Clear the output structure */
- pEncOut->codingType = H264ENC_NOTCODED_FRAME;
- pEncOut->streamSize = 0;
- /* Set pointer to the beginning of NAL unit size buffer */
- pEncOut->pNaluSizeBuf = (u32 *) pEncInst->asic.sizeTbl.nal.virtualAddress;
- pEncOut->numNalus = pEncInst->naluOffset = 0;
- /* Clear the NAL unit size table */
- if(pEncOut->pNaluSizeBuf != NULL)
- pEncOut->pNaluSizeBuf[0] = 0;
- #ifdef EVALUATION_LIMIT
- /* Check for evaluation limit */
- if(pEncInst->frameCnt >= EVALUATION_LIMIT)
- {
- APITRACE("H264EncStrmEncode: OK Evaluation limit exceeded");
- return H264ENC_OK;
- }
- #endif
- /* Check status, INIT and ERROR not allowed */
- if((pEncInst->encStatus != H264ENCSTAT_START_STREAM) &&
- (pEncInst->encStatus != H264ENCSTAT_START_FRAME))
- {
- APITRACE("H264EncStrmEncode: ERROR Invalid status");
- return H264ENC_INVALID_STATUS;
- }
- /* Check for invalid input values */
- if((!H264_BUS_ADDRESS_VALID(pEncIn->busOutBuf)) ||
- (pEncIn->pOutBuf == NULL) ||
- (pEncIn->outBufSize < H264ENCSTRMENCODE_MIN_BUF) ||
- (pEncIn->codingType > H264ENC_PREDICTED_FRAME))
- {
- APITRACE("H264EncStrmEncode: ERROR Invalid input. Output buffer");
- return H264ENC_INVALID_ARGUMENT;
- }
- switch (pEncInst->preProcess.inputFormat)
- {
- case H264ENC_YUV420_PLANAR:
- if(!H264_BUS_ADDRESS_VALID(pEncIn->busChromaV))
- {
- APITRACE("H264EncStrmEncode: ERROR Invalid input busChromaU");
- return H264ENC_INVALID_ARGUMENT;
- }
- /* fall through */
- case H264ENC_YUV420_SEMIPLANAR:
- if(!H264_BUS_ADDRESS_VALID(pEncIn->busChromaU))
- {
- APITRACE("H264EncStrmEncode: ERROR Invalid input busChromaU");
- return H264ENC_INVALID_ARGUMENT;
- }
- /* fall through */
- case H264ENC_YUV422_INTERLEAVED_YUYV:
- case H264ENC_YUV422_INTERLEAVED_UYVY:
- case H264ENC_RGB565:
- case H264ENC_BGR565:
- case H264ENC_RGB555:
- case H264ENC_BGR555:
- case H264ENC_RGB444:
- case H264ENC_BGR444:
- case H264ENC_RGB888:
- case H264ENC_BGR888:
- case H264ENC_RGB101010:
- case H264ENC_BGR101010:
- if(!H264_BUS_ADDRESS_VALID(pEncIn->busLuma))
- {
- APITRACE("H264EncStrmEncode: ERROR Invalid input busLuma");
- return H264ENC_INVALID_ARGUMENT;
- }
- break;
- default:
- APITRACE("H264EncStrmEncode: ERROR Invalid input format");
- return H264ENC_INVALID_ARGUMENT;
- }
- if(pEncInst->preProcess.videoStab)
- {
- if(!H264_BUS_ADDRESS_VALID(pEncIn->busLumaStab))
- {
- APITRACE("H264EncStrmEncode: ERROR Invalid input busLumaStab");
- return H264ENC_INVALID_ARGUMENT;
- }
- }
- /* some shortcuts */
- pSlice = &pEncInst->slice;
- regs = &pEncInst->asic.regs;
- /* Set stream buffer, the size has been checked */
- if(H264SetBuffer(&pEncInst->stream, (u8 *) pEncIn->pOutBuf,
- (i32) pEncIn->outBufSize) == ENCHW_NOK)
- {
- APITRACE("H264EncStrmEncode: ERROR Invalid output buffer");
- return H264ENC_INVALID_ARGUMENT;
- }
- /* Try to reserve the HW resource */
- if(EWLReserveHw(pEncInst->asic.ewl) == EWL_ERROR)
- {
- APITRACE("H264EncStrmEncode: ERROR HW unavailable");
- return H264ENC_HW_RESERVED;
- }
- /* update in/out buffers */
- regs->inputLumBase = pEncIn->busLuma;
- regs->inputCbBase = pEncIn->busChromaU;
- regs->inputCrBase = pEncIn->busChromaV;
- regs->outputStrmBase = pEncIn->busOutBuf;
- regs->outputStrmSize = pEncIn->outBufSize;
- pEncInst->sliceReadyCbFunc = sliceReadyCbFunc;
- pEncInst->pOutBuf = pEncIn->pOutBuf;
- pEncInst->pAppData = pAppData;
- /* setup stabilization */
- if(pEncInst->preProcess.videoStab)
- {
- regs->vsNextLumaBase = pEncIn->busLumaStab;
- }
- {
- H264EncPictureCodingType ct = pEncIn->codingType;
- /* Status may affect the frame coding type */
- if(pEncInst->encStatus == H264ENCSTAT_START_STREAM)
- {
- ct = H264ENC_INTRA_FRAME;
- }
- #ifdef VIDEOSTAB_ENABLED
- if(pEncInst->vsSwData.sceneChange)
- {
- pEncInst->vsSwData.sceneChange = 0;
- ct = H264ENC_INTRA_FRAME;
- }
- #endif
- pSlice->prevFrameNum = pSlice->frameNum;
- /* MVC view frames are never intra. */
- if ((pEncInst->numViews > 1) && ((pSlice->frameNum % 2) == 1))
- ct = H264ENC_PREDICTED_FRAME;
- /* Frame coding type defines the NAL unit type */
- switch (ct)
- {
- case H264ENC_INTRA_FRAME:
- /* IDR-slice */
- pSlice->nalUnitType = IDR;
- pSlice->sliceType = ISLICE;
- pSlice->frameNum = 0;
- H264MadInit(&pEncInst->mad, pEncInst->mbPerFrame);
- break;
- case H264ENC_PREDICTED_FRAME:
- default:
- /* non-IDR slice */
- pSlice->nalUnitType = NONIDR;
- pSlice->sliceType = PSLICE;
- break;
- }
- }
- /* Rate control */
- H264BeforePicRc(&pEncInst->rateControl, pEncIn->timeIncrement,
- pSlice->sliceType);
- /* time stamp updated */
- H264UpdateSeiTS(&pEncInst->rateControl.sei, pEncIn->timeIncrement);
- /* Rate control may choose to skip the frame */
- if(pEncInst->rateControl.frameCoded == ENCHW_NO)
- {
- APITRACE("H264EncStrmEncode: OK, frame skipped");
- pSlice->frameNum = pSlice->prevFrameNum; /* restore frame_num */
- #if 0
- /* Write previous reconstructed frame when frame is skipped */
- EncAsicRecycleInternalImage(&pEncInst->asic.regs);
- EncDumpRecon(&pEncInst->asic);
- EncAsicRecycleInternalImage(&pEncInst->asic.regs);
- #endif
- EWLReleaseHw(pEncInst->asic.ewl);
- return H264ENC_FRAME_READY;
- }
- #ifdef TRACE_STREAM
- traceStream.frameNum = pEncInst->frameCnt;
- traceStream.id = 0; /* Stream generated by SW */
- traceStream.bitCnt = 0; /* New frame */
- #endif
- #ifdef INTERNAL_TEST
- /* Configure the encoder instance according to the test vector */
- H264ConfigureTestBeforeFrame(pEncInst);
- #endif
- /* Determine the start offset for NALU size table.
- * HW needs a 64-bit aligned address so we leave the first 32-bits unused
- * if SW creates one leading NAL unit. Also the HW bus address needs to be
- * offset in H264CodeFrame. */
- {
- i32 numLeadingNalus = 0;
- sei_s *sei = &pEncInst->rateControl.sei;
- if(sei->enabled == ENCHW_YES || sei->userDataEnabled == ENCHW_YES)
- numLeadingNalus++;
- if ((pEncInst->numViews > 1) && ((pSlice->frameNum % 2) == 0))
- numLeadingNalus++;
- pEncInst->numNalus = numLeadingNalus;
- if(numLeadingNalus % 2)
- {
- pEncOut->pNaluSizeBuf++;
- pEncInst->naluOffset++;
- }
- }
- /* update any cropping/rotation/filling */
- EncPreProcess(&pEncInst->asic, &pEncInst->preProcess);
- /* SEI message */
- {
- sei_s *sei = &pEncInst->rateControl.sei;
- if(sei->enabled == ENCHW_YES || sei->userDataEnabled == ENCHW_YES)
- {
- H264NalUnitHdr(&pEncInst->stream, 0, SEI, sei->byteStream);
- if(sei->enabled == ENCHW_YES)
- {
- if(pSlice->nalUnitType == IDR)
- {
- H264BufferingSei(&pEncInst->stream, sei);
- }
- H264PicTimingSei(&pEncInst->stream, sei);
- }
- if(sei->userDataEnabled == ENCHW_YES)
- {
- H264UserDataUnregSei(&pEncInst->stream, sei);
- }
- H264RbspTrailingBits(&pEncInst->stream);
- sei->nalUnitSize = pEncInst->stream.byteCnt;
- H264AddNaluSize(pEncOut, pEncInst->stream.byteCnt);
- }
- }
- /* For MVC stream insert prefix NALU before base view pictures */
- if ((pEncInst->numViews > 1) && ((pSlice->frameNum % 2) == 0))
- {
- i32 byteCnt = pEncInst->stream.byteCnt;
- H264PrefixNal(pEncInst);
- H264AddNaluSize(pEncOut, pEncInst->stream.byteCnt-byteCnt);
- }
- else
- {
- pEncInst->mvc.anchorPicFlag = (pSlice->frameNum == 1);
- pEncInst->mvc.viewId = 1;
- pEncInst->mvc.interViewFlag = 0;
- }
- /* Code one frame */
- ret = H264CodeFrame(pEncInst);
- #ifdef TRACE_RECON
- EncDumpRecon(&pEncInst->asic);
- #endif
- if(ret != H264ENCODE_OK)
- {
- /* Error has occured and the frame is invalid */
- H264EncRet to_user;
- switch (ret)
- {
- case H264ENCODE_TIMEOUT:
- APITRACE("H264EncStrmEncode: ERROR HW timeout");
- to_user = H264ENC_HW_TIMEOUT;
- break;
- case H264ENCODE_HW_RESET:
- APITRACE("H264EncStrmEncode: ERROR HW reset detected");
- to_user = H264ENC_HW_RESET;
- break;
- case H264ENCODE_HW_ERROR:
- APITRACE("H264EncStrmEncode: ERROR HW bus access error");
- to_user = H264ENC_HW_BUS_ERROR;
- break;
- case H264ENCODE_SYSTEM_ERROR:
- default:
- /* System error has occured, encoding can't continue */
- pEncInst->encStatus = H264ENCSTAT_ERROR;
- APITRACE("H264EncStrmEncode: ERROR Fatal system error");
- to_user = H264ENC_SYSTEM_ERROR;
- }
- return to_user;
- }
- #ifdef VIDEOSTAB_ENABLED
- /* Finalize video stabilization */
- if(pEncInst->preProcess.videoStab)
- {
- u32 no_motion;
- VSReadStabData(pEncInst->asic.regs.regMirror, &pEncInst->vsHwData);
- no_motion = VSAlgStabilize(&pEncInst->vsSwData, &pEncInst->vsHwData);
- if(no_motion)
- {
- VSAlgReset(&pEncInst->vsSwData);
- }
- /* update offset after stabilization */
- VSAlgGetResult(&pEncInst->vsSwData, &pEncInst->preProcess.horOffsetSrc,
- &pEncInst->preProcess.verOffsetSrc);
- }
- #endif
- /* Update NALU table with the amount of slices created by the HW */
- {
- i32 numSlices;
- if (pEncInst->slice.sliceSize)
- numSlices = (pEncInst->mbPerFrame + pEncInst->slice.sliceSize - 1) /
- pEncInst->slice.sliceSize;
- else
- numSlices = 1;
- pEncOut->numNalus += numSlices;
- pEncOut->pNaluSizeBuf[pEncOut->numNalus] = 0;
- }
- /* Filler data if needed */
- {
- u32 s = H264FillerRc(&pEncInst->rateControl, pEncInst->frameCnt);
- if(s != 0)
- {
- s = H264FillerNALU(&pEncInst->stream,
- (i32) s, pEncInst->seqParameterSet.byteStream);
- }
- pEncInst->fillerNalSize = s;
- H264AddNaluSize(pEncOut, s);
- }
- pEncOut->motionVectors = (i8*)pEncInst->asic.mvOutput.virtualAddress;
- /* After stream buffer overflow discard the coded frame */
- if(pEncInst->stream.overflow == ENCHW_YES)
- {
- if ((pEncInst->numRefBuffsLum == 1) || (pEncInst->numViews == 2))
- {
- /* Only one reference frame buffer in use, so we can't use it
- * as reference => we must encode next frame as intra */
- pEncInst->encStatus = H264ENCSTAT_START_STREAM;
- }
- pEncOut->numNalus = 0;
- pEncOut->pNaluSizeBuf[0] = 0;
- APITRACE("H264EncStrmEncode: ERROR Output buffer too small");
- return H264ENC_OUTPUT_BUFFER_OVERFLOW;
- }
- /* Rate control action after vop */
- {
- i32 stat;
- stat = H264AfterPicRc(&pEncInst->rateControl, regs->rlcCount,
- pEncInst->stream.byteCnt, regs->qpSum);
- H264MadThreshold(&pEncInst->mad, regs->madCount);
- /* After HRD overflow discard the coded frame and go back old time,
- * just like not coded frame. But if only one reference frame
- * buffer is in use we can't discard the frame unless the next frame
- * is coded as intra. */
- if((stat == H264RC_OVERFLOW) &&
- (pEncInst->numRefBuffsLum > 1) &&
- (pEncInst->numViews == 1))
- {
- pSlice->frameNum = pSlice->prevFrameNum; /* revert frame_num */
- pEncOut->numNalus = 0;
- pEncOut->pNaluSizeBuf[0] = 0;
- APITRACE("H264EncStrmEncode: OK, Frame discarded (HRD overflow)");
- return H264ENC_FRAME_READY;
- }
- }
- /* Use the reconstructed frame as the reference for the next frame */
- EncAsicRecycleInternalImage(&pEncInst->asic, pEncInst->numViews,
- (pSlice->frameNum % 2), (pSlice->frameNum <= 1),
- pEncInst->numRefBuffsLum, pEncInst->numRefBuffsChr);
- /* Store the stream size and frame coding type in output structure */
- pEncOut->streamSize = pEncInst->stream.byteCnt;
- if(pSlice->nalUnitType == IDR)
- {
- pEncOut->codingType = H264ENC_INTRA_FRAME;
- pSlice->idrPicId += 1;
- if(pSlice->idrPicId == H264ENC_IDR_ID_MODULO)
- pSlice->idrPicId = 0;
- }
- else
- {
- pEncOut->codingType = H264ENC_PREDICTED_FRAME;
- }
- /* Frame was encoded so increment frame number */
- pEncInst->frameCnt++;
- pSlice->frameNum++;
- pSlice->frameNum %= (1U << pSlice->frameNumBits);
- pEncInst->encStatus = H264ENCSTAT_START_FRAME;
- APITRACE("H264EncStrmEncode: OK");
- return H264ENC_FRAME_READY;
- }
- /*------------------------------------------------------------------------------
- Function name : H264EncStrmEnd
- Description : Ends a stream
- Return type : H264EncRet
- Argument : inst - encoder instance
- Argument : pEncIn - user provided input parameters
- pEncOut - place where output info is returned
- ------------------------------------------------------------------------------*/
- H264EncRet H264EncStrmEnd(H264EncInst inst, const H264EncIn * pEncIn,
- H264EncOut * pEncOut)
- {
- h264Instance_s *pEncInst = (h264Instance_s *) inst;
- APITRACE("H264EncStrmEnd#");
- /* Check for illegal inputs */
- if((pEncInst == NULL) || (pEncIn == NULL) || (pEncOut == NULL))
- {
- APITRACE("H264EncStrmEnd: ERROR Null argument");
- return H264ENC_NULL_ARGUMENT;
- }
- /* Check for existing instance */
- if(pEncInst->inst != pEncInst)
- {
- APITRACE("H264EncStrmEnd: ERROR Invalid instance");
- return H264ENC_INSTANCE_ERROR;
- }
- /* Check status, this also makes sure that the instance is valid */
- if((pEncInst->encStatus != H264ENCSTAT_START_FRAME) &&
- (pEncInst->encStatus != H264ENCSTAT_START_STREAM))
- {
- APITRACE("H264EncStrmEnd: ERROR Invalid status");
- return H264ENC_INVALID_STATUS;
- }
- pEncOut->streamSize = 0;
- /* Set pointer to the beginning of NAL unit size buffer */
- pEncOut->pNaluSizeBuf = (u32 *) pEncInst->asic.sizeTbl.nal.virtualAddress;
- pEncOut->numNalus = 0;
- /* Clear the NAL unit size table */
- if(pEncOut->pNaluSizeBuf != NULL)
- pEncOut->pNaluSizeBuf[0] = 0;
- /* Check for invalid input values */
- if(pEncIn->pOutBuf == NULL ||
- (pEncIn->outBufSize < H264ENCSTRMSTART_MIN_BUF))
- {
- APITRACE("H264EncStrmEnd: ERROR Invalid input. Stream buffer");
- return H264ENC_INVALID_ARGUMENT;
- }
- /* Set stream buffer and check the size */
- if(H264SetBuffer(&pEncInst->stream, (u8 *) pEncIn->pOutBuf,
- (u32) pEncIn->outBufSize) != ENCHW_OK)
- {
- APITRACE("H264EncStrmEnd: ERROR Output buffer too small");
- return H264ENC_INVALID_ARGUMENT;
- }
- /* Write end-of-stream code */
- H264EndOfSequence(&pEncInst->stream, &pEncInst->seqParameterSet);
- /* Bytes generated */
- pEncOut->streamSize = pEncInst->stream.byteCnt;
- H264AddNaluSize(pEncOut, pEncInst->stream.byteCnt);
- /* Status == INIT Stream ended, next stream can be started */
- pEncInst->encStatus = H264ENCSTAT_INIT;
- APITRACE("H264EncStrmEnd: OK");
- return H264ENC_OK;
- }
- /*------------------------------------------------------------------------------
- Function name : H264AddNaluSize
- Description : Adds the size of a NAL unit into NAL size output buffer.
- Return type : void
- Argument : pEncOut - encoder output structure
- Argument : naluSizeBytes - size of the NALU in bytes
- ------------------------------------------------------------------------------*/
- void H264AddNaluSize(H264EncOut * pEncOut, u32 naluSizeBytes)
- {
- if(pEncOut->pNaluSizeBuf != NULL)
- {
- pEncOut->pNaluSizeBuf[pEncOut->numNalus++] = naluSizeBytes;
- pEncOut->pNaluSizeBuf[pEncOut->numNalus] = 0;
- }
- }
- /*------------------------------------------------------------------------------
- H264PrefixNal
- ------------------------------------------------------------------------------*/
- void H264PrefixNal(h264Instance_s *pEncInst)
- {
- H264NalUnitHdr(&pEncInst->stream, 1, PREFIX,
- pEncInst->seqParameterSet.byteStream);
- pEncInst->mvc.anchorPicFlag = (pEncInst->slice.nalUnitType == IDR);
- pEncInst->mvc.priorityId = 0;
- pEncInst->mvc.viewId = 0;
- pEncInst->mvc.temporalId = 0;
- pEncInst->mvc.interViewFlag = 1;
- H264PutBits(&pEncInst->stream, 0, 1);
- COMMENT("svc_extension_flag");
- H264NalUnitHdrMvcExtension(&pEncInst->stream, &pEncInst->mvc);
- }
- /*------------------------------------------------------------------------------
- Function name : H264EncSetTestId
- Description : Sets the encoder configuration according to a test vector
- Return type : H264EncRet
- Argument : inst - encoder instance
- Argument : testId - test vector ID
- ------------------------------------------------------------------------------*/
- H264EncRet H264EncSetTestId(H264EncInst inst, u32 testId)
- {
- h264Instance_s *pEncInst = (h264Instance_s *) inst;
- (void) pEncInst;
- (void) testId;
- APITRACE("H264EncSetTestId#");
- #ifdef INTERNAL_TEST
- pEncInst->testId = testId;
-
- APITRACE("H264EncSetTestId# OK");
- return H264ENC_OK;
- #else
- /* Software compiled without testing support, return error always */
- APITRACE("H264EncSetTestId# ERROR, testing disabled at compile time");
- return H264ENC_ERROR;
- #endif
- }
|