diff --git a/codec/build/iOS/enc/welsenc/welsenc.xcodeproj/project.pbxproj b/codec/build/iOS/enc/welsenc/welsenc.xcodeproj/project.pbxproj index 592deead..9015ca06 100644 --- a/codec/build/iOS/enc/welsenc/welsenc.xcodeproj/project.pbxproj +++ b/codec/build/iOS/enc/welsenc/welsenc.xcodeproj/project.pbxproj @@ -51,6 +51,9 @@ 9AED66661946A2B3009A3567 /* utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AED66651946A2B3009A3567 /* utils.cpp */; }; F5617A50196A833A006E2B20 /* reconstruct_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F5617A4F196A833A006E2B20 /* reconstruct_aarch64_neon.S */; }; F5BE8005196B913200ED02ED /* memory_aarch64_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F5BE8004196B913200ED02ED /* memory_aarch64_neon.S */; }; + F7E9994519EBD1E9009B1021 /* svc_set_mb_syn_cabac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F7E9994419EBD1E9009B1021 /* svc_set_mb_syn_cabac.cpp */; }; + F7E9994719EBD1EF009B1021 /* cabac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F7E9994619EBD1EF009B1021 /* cabac.cpp */; }; + F7E9994919EBD1F8009B1021 /* set_mb_syn_cabac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F7E9994819EBD1F8009B1021 /* set_mb_syn_cabac.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -164,6 +167,11 @@ 9AED66671946A2C4009A3567 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = utils.h; path = ../../../common/inc/utils.h; sourceTree = ""; }; F5617A4F196A833A006E2B20 /* reconstruct_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = reconstruct_aarch64_neon.S; path = arm64/reconstruct_aarch64_neon.S; sourceTree = ""; }; F5BE8004196B913200ED02ED /* memory_aarch64_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = memory_aarch64_neon.S; path = arm64/memory_aarch64_neon.S; sourceTree = ""; }; + F7E9994419EBD1E9009B1021 /* svc_set_mb_syn_cabac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = svc_set_mb_syn_cabac.cpp; sourceTree = ""; }; + F7E9994619EBD1EF009B1021 /* cabac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cabac.cpp; sourceTree = ""; }; + F7E9994819EBD1F8009B1021 /* set_mb_syn_cabac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = set_mb_syn_cabac.cpp; sourceTree = ""; }; + F7E9997E19EBD3C6009B1021 /* set_mb_syn_cabac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = set_mb_syn_cabac.h; sourceTree = ""; }; + F7E9997F19EBD3CE009B1021 /* svc_set_mb_syn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = svc_set_mb_syn.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -254,6 +262,8 @@ 4CE446A918BC605C0017DF25 /* inc */ = { isa = PBXGroup; children = ( + F7E9997F19EBD3CE009B1021 /* svc_set_mb_syn.h */, + F7E9997E19EBD3C6009B1021 /* set_mb_syn_cabac.h */, 9AED66671946A2C4009A3567 /* utils.h */, 4CDBFB9D18E5068D0025A767 /* wels_transpose_matrix.h */, 4CE446AA18BC605C0017DF25 /* as264_common.h */, @@ -309,6 +319,9 @@ 4CE446DC18BC605C0017DF25 /* src */ = { isa = PBXGroup; children = ( + F7E9994819EBD1F8009B1021 /* set_mb_syn_cabac.cpp */, + F7E9994619EBD1EF009B1021 /* cabac.cpp */, + F7E9994419EBD1E9009B1021 /* svc_set_mb_syn_cabac.cpp */, 9AED66651946A2B3009A3567 /* utils.cpp */, 4CE446DD18BC605C0017DF25 /* au_set.cpp */, 4CE446DE18BC605C0017DF25 /* deblocking.cpp */, @@ -438,6 +451,7 @@ 4C34067018C57D0400DFA14A /* memory_neon.S in Sources */, 4CE4470F18BC605C0017DF25 /* deblocking.cpp in Sources */, 4CE4472518BC605C0017DF25 /* svc_encode_mb.cpp in Sources */, + F7E9994719EBD1EF009B1021 /* cabac.cpp in Sources */, 4CE4471A18BC605C0017DF25 /* mv_pred.cpp in Sources */, 4C34066E18C57D0400DFA14A /* intra_pred_sad_3_opt_neon.S in Sources */, 4C23BC60195A77E0003B81FC /* intra_pred_sad_3_opt_aarch64_neon.S in Sources */, @@ -446,6 +460,7 @@ F5BE8005196B913200ED02ED /* memory_aarch64_neon.S in Sources */, 4CBC1B83194ACBB400214D9E /* intra_pred_aarch64_neon.S in Sources */, 4CE4471718BC605C0017DF25 /* mc.cpp in Sources */, + F7E9994519EBD1E9009B1021 /* svc_set_mb_syn_cabac.cpp in Sources */, F5617A50196A833A006E2B20 /* reconstruct_aarch64_neon.S in Sources */, 4CE4472918BC605C0017DF25 /* svc_set_mb_syn_cavlc.cpp in Sources */, 4CE4471818BC605C0017DF25 /* md.cpp in Sources */, @@ -465,6 +480,7 @@ 6CA38DA51991D31A003EAAE0 /* svc_motion_estimation_aarch64_neon.S in Sources */, 4CE4471418BC605C0017DF25 /* encoder_ext.cpp in Sources */, 4C34067218C57D0400DFA14A /* reconstruct_neon.S in Sources */, + F7E9994919EBD1F8009B1021 /* set_mb_syn_cabac.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/codec/build/win32/enc/WelsEncCore.vcproj b/codec/build/win32/enc/WelsEncCore.vcproj index 26c20a35..652f9643 100644 --- a/codec/build/win32/enc/WelsEncCore.vcproj +++ b/codec/build/win32/enc/WelsEncCore.vcproj @@ -329,6 +329,10 @@ RelativePath="..\..\..\encoder\core\src\au_set.cpp" > + + @@ -429,6 +433,10 @@ RelativePath="..\..\..\encoder\core\src\sample.cpp" > + + @@ -461,6 +469,10 @@ RelativePath="..\..\..\encoder\core\src\svc_motion_estimate.cpp" > + + @@ -626,6 +638,10 @@ RelativePath="..\..\..\encoder\core\inc\sample.h" > + + @@ -678,6 +694,10 @@ RelativePath="..\..\..\encoder\core\inc\svc_motion_estimate.h" > + + @@ -731,7 +751,7 @@ > @@ -740,7 +760,7 @@ > @@ -749,7 +769,7 @@ > @@ -758,7 +778,7 @@ > @@ -771,7 +791,7 @@ > @@ -780,7 +800,7 @@ > @@ -789,7 +809,7 @@ > @@ -798,7 +818,7 @@ > @@ -811,7 +831,7 @@ > @@ -820,7 +840,7 @@ > @@ -829,7 +849,7 @@ > @@ -838,7 +858,7 @@ > @@ -851,7 +871,7 @@ > @@ -860,7 +880,7 @@ > @@ -869,7 +889,7 @@ > @@ -878,7 +898,7 @@ > @@ -891,7 +911,7 @@ > @@ -900,7 +920,7 @@ > @@ -909,7 +929,7 @@ > @@ -918,7 +938,7 @@ > @@ -931,7 +951,7 @@ > @@ -940,7 +960,7 @@ > @@ -949,7 +969,7 @@ > @@ -958,7 +978,7 @@ > @@ -971,7 +991,7 @@ > @@ -980,7 +1000,7 @@ > @@ -989,7 +1009,7 @@ > @@ -998,7 +1018,7 @@ > @@ -1011,7 +1031,7 @@ > @@ -1020,7 +1040,7 @@ > @@ -1029,7 +1049,7 @@ > @@ -1038,7 +1058,7 @@ > @@ -1051,7 +1071,7 @@ > @@ -1060,7 +1080,7 @@ > @@ -1069,7 +1089,7 @@ > @@ -1078,7 +1098,7 @@ > @@ -1091,7 +1111,7 @@ > @@ -1100,7 +1120,7 @@ > @@ -1109,7 +1129,7 @@ > @@ -1118,7 +1138,7 @@ > @@ -1131,7 +1151,7 @@ > @@ -1140,7 +1160,7 @@ > @@ -1149,7 +1169,7 @@ > @@ -1158,7 +1178,7 @@ > @@ -1171,7 +1191,7 @@ > @@ -1180,7 +1200,7 @@ > @@ -1189,7 +1209,7 @@ > @@ -1198,7 +1218,7 @@ > @@ -1211,7 +1231,7 @@ > @@ -1220,7 +1240,7 @@ > @@ -1229,7 +1249,7 @@ > @@ -1238,7 +1258,7 @@ > @@ -1251,7 +1271,7 @@ > @@ -1260,7 +1280,7 @@ > @@ -1269,7 +1289,7 @@ > @@ -1278,7 +1298,7 @@ > @@ -1291,7 +1311,7 @@ > @@ -1300,7 +1320,7 @@ > @@ -1309,7 +1329,7 @@ > @@ -1318,7 +1338,7 @@ > @@ -1331,7 +1351,7 @@ > @@ -1340,7 +1360,7 @@ > @@ -1349,7 +1369,7 @@ > @@ -1358,7 +1378,7 @@ > @@ -1371,7 +1391,7 @@ > @@ -1380,7 +1400,7 @@ > @@ -1389,7 +1409,7 @@ > @@ -1398,7 +1418,7 @@ > diff --git a/codec/console/enc/src/welsenc.cpp b/codec/console/enc/src/welsenc.cpp index 26a310c2..8ac9081e 100644 --- a/codec/console/enc/src/welsenc.cpp +++ b/codec/console/enc/src/welsenc.cpp @@ -238,6 +238,8 @@ int ParseConfig (CReadConfig& cRdCfg, SSourcePicture* pSrcPic, SEncParamExt& pSv pSvcParam.bEnableSSEI = atoi (strTag[1].c_str()) ? true : false; } else if (strTag[0].compare ("EnableFrameCropping") == 0) { pSvcParam.bEnableFrameCroppingFlag = (atoi (strTag[1].c_str()) != 0); + } else if (strTag[0].compare ("EntropyCodingModeFlag") == 0) { + pSvcParam.iEntropyCodingModeFlag = (atoi (strTag[1].c_str()) != 0); } else if (strTag[0].compare ("LoopFilterDisableIDC") == 0) { pSvcParam.iLoopFilterDisableIdc = (int8_t)atoi (strTag[1].c_str()); if (pSvcParam.iLoopFilterDisableIdc > 6 || pSvcParam.iLoopFilterDisableIdc < 0) { @@ -354,6 +356,7 @@ void PrintHelp() { printf (" -iper Intra period (default: -1) : must be a power of 2 of GOP size (or -1)\n"); printf (" -nalsize the Maximum NAL size. which should be larger than the each layer slicesize when slice mode equals to SM_DYN_SLICE\n"); printf (" -spsid Enable id adding in SPS/PPS per IDR \n"); + printf (" -cabac Entropy coding mode(0:cavlc 1:cabac \n"); printf (" -denois Control denoising (default: 0)\n"); printf (" -scene Control scene change detection (default: 0)\n"); printf (" -bgd Control background detection (default: 0)\n"); @@ -420,6 +423,9 @@ int ParseCommandLine (int argc, char** argv, SSourcePicture* pSrcPic, SEncParamE else if (!strcmp (pCommand, "-spsid") && (n < argc)) pSvcParam.bEnableSpsPpsIdAddition = atoi (argv[n++]) ? true : false; + else if (!strcmp (pCommand, "-cabac") && (n < argc)) + pSvcParam.iEntropyCodingModeFlag = atoi (argv[n++]); + else if (!strcmp (pCommand, "-denois") && (n < argc)) pSvcParam.bEnableDenoise = atoi (argv[n++]) ? true : false; diff --git a/codec/encoder/core/inc/au_set.h b/codec/encoder/core/inc/au_set.h index c6fc27bb..786ff6b1 100644 --- a/codec/encoder/core/inc/au_set.h +++ b/codec/encoder/core/inc/au_set.h @@ -138,7 +138,8 @@ int32_t WelsInitPps (SWelsPPS* pPps, SSubsetSps* pSubsetSps, const uint32_t kuiPpsId, const bool kbDeblockingFilterPresentFlag, - const bool kbUsingSubsetSps); + const bool kbUsingSubsetSps, + const bool kbEntropyCodingModeFlag); int32_t WelsCheckRefFrameLimitation (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam); } #endif//WELS_ACCESS_UNIT_PARSER_H__ diff --git a/codec/encoder/core/inc/encoder.h b/codec/encoder/core/inc/encoder.h index dc013bed..2179e996 100644 --- a/codec/encoder/core/inc/encoder.h +++ b/codec/encoder/core/inc/encoder.h @@ -70,7 +70,7 @@ int32_t AllocateBsOutputBuffer (CMemoryAlign* pMa, const int32_t iNeededLen, int * \param pEncCtx sWelsEncCtx* * \return successful - 0; otherwise none 0 for failed */ -int32_t InitFunctionPointers (SWelsFuncPtrList* pFuncList, SWelsSvcCodingParam* _param, uint32_t uiCpuFlag); +int32_t InitFunctionPointers (sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* _param, uint32_t uiCpuFlag); ///*! // * \brief decide frame type (IDR/P frame) diff --git a/codec/encoder/core/inc/encoder_context.h b/codec/encoder/core/inc/encoder_context.h index e21a26e6..3bf1e2d1 100644 --- a/codec/encoder/core/inc/encoder_context.h +++ b/codec/encoder/core/inc/encoder_context.h @@ -225,7 +225,7 @@ typedef struct TagWelsEncCtx { int32_t iEncoderError; WELS_MUTEX mutexEncoderError; bool bDeliveryFlag; - + SStateCtx sWelsCabacContexts[4][WELS_QP_MAX + 1][WELS_CONTEXT_COUNT]; #ifdef ENABLE_FRAME_DUMP bool bDependencyRecFlag[MAX_DEPENDENCY_LAYER]; bool bRecFlag; diff --git a/codec/encoder/core/inc/param_svc.h b/codec/encoder/core/inc/param_svc.h index 18f76fa2..f7121c76 100644 --- a/codec/encoder/core/inc/param_svc.h +++ b/codec/encoder/core/inc/param_svc.h @@ -157,7 +157,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt { /* Rate Control */ param.iRCMode = RC_QUALITY_MODE; param.iPaddingFlag = 0; - + param.iEntropyCodingModeFlag = 0; param.bEnableDenoise = false; // denoise control param.bEnableSceneChangeDetect = true; // scene change detection control param.bEnableBackgroundDetection = true; // background detection control @@ -240,7 +240,8 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt { int8_t iIdxSpatial = 0; EProfileIdc uiProfileIdc = PRO_BASELINE; - + if (iEntropyCodingModeFlag) + uiProfileIdc = PRO_MAIN; SSpatialLayerInternal* pDlp = &sDependencyLayers[0]; while (iIdxSpatial < iSpatialLayerNum) { @@ -298,7 +299,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt { iLoopFilterDisableIdc = pCodingParam.iLoopFilterDisableIdc; // 0: on, 1: off, 2: on except for slice boundaries, iLoopFilterAlphaC0Offset = pCodingParam.iLoopFilterAlphaC0Offset; // AlphaOffset: valid range [-6, 6], default 0 iLoopFilterBetaOffset = pCodingParam.iLoopFilterBetaOffset; // BetaOffset: valid range [-6, 6], default 0 - + iEntropyCodingModeFlag = pCodingParam.iEntropyCodingModeFlag; bEnableFrameCroppingFlag = pCodingParam.bEnableFrameCroppingFlag; /* Rate Control */ @@ -459,7 +460,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt { const uint8_t* pTemporalIdList = &g_kuiTemporalIdListTable[iDecStages][0]; SSpatialLayerInternal* pDlp = &sDependencyLayers[0]; SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0]; - EProfileIdc uiProfileIdc = PRO_BASELINE; + EProfileIdc uiProfileIdc = iEntropyCodingModeFlag ? PRO_MAIN : PRO_BASELINE; int8_t i = 0; while (i < iSpatialLayerNum) { @@ -492,7 +493,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt { return ENC_RETURN_INVALIDINPUT; } - uiProfileIdc = PRO_SCALABLE_BASELINE; + uiProfileIdc = iEntropyCodingModeFlag ? PRO_SCALABLE_HIGH : PRO_SCALABLE_BASELINE; ++ pDlp; ++ pSpatialLayer; ++ i; diff --git a/codec/encoder/core/inc/parameter_sets.h b/codec/encoder/core/inc/parameter_sets.h index 67e3aa64..d0a1570d 100644 --- a/codec/encoder/core/inc/parameter_sets.h +++ b/codec/encoder/core/inc/parameter_sets.h @@ -147,7 +147,7 @@ uint8_t uiChromaQpIndexOffset; // /* potential application for High profile */ // bool bPicOrderPresentFlag; - +bool bEntropyCodingModeFlag; bool bDeblockingFilterControlPresentFlag; // bool bConstainedIntraPredFlag; diff --git a/codec/encoder/core/inc/set_mb_syn_cabac.h b/codec/encoder/core/inc/set_mb_syn_cabac.h new file mode 100644 index 00000000..83f0c073 --- /dev/null +++ b/codec/encoder/core/inc/set_mb_syn_cabac.h @@ -0,0 +1,89 @@ +/*! + * \copy + * Copyright (c) 2009-2013, Cisco Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * \file set_mb_syn_cabac.h + * + * \brief Seting all syntax elements of mb and encoding residual with cabac + * + * \date 09/27/2014 Created + * + ************************************************************************************* + */ + +#ifndef SET_MB_SYN_CABAC_H_ +#define SET_MB_SYN_CABAC_H_ + +#include "typedefs.h" +#include "bit_stream.h" + +namespace WelsEnc { + +#define WELS_QP_MAX 51 +#define WELS_CONTEXT_COUNT 460 +#define CTX_NA 0 + +typedef struct TagStateCtx { + uint8_t m_uiState; + uint8_t m_uiValMps; +} SStateCtx; +typedef struct TagCabacCtx { + uint32_t m_uiLow; + uint32_t m_uiRange; + SStateCtx m_sStateCtx[WELS_CONTEXT_COUNT]; + uint8_t* m_pBufStart; + uint8_t* m_pBufEnd; + uint8_t* m_pBufCur; + uint8_t m_iBitsOutstanding; + uint32_t m_uData; + uint32_t m_uiBitsUsed; + uint32_t m_iFirstFlag; + uint32_t m_uiBinCountsInNalUnits; +} SCabacCtx; + + +extern const uint8_t g_kuiCabacRangeLps[64][4]; +extern const int8_t g_kiCabacGlobalContextIdx[WELS_CONTEXT_COUNT][4][2]; +extern const uint8_t g_kuiStateTransTable[64][2]; + +void WelsCabacContextInit (void* pCtx,SCabacCtx* pCbCtx,int32_t iModel); +void WelsCabacEncodeInit (SCabacCtx* pCbCtx, uint8_t* pBuf, uint8_t* pEnd); +void WelsCabacEncodeDecision (SCabacCtx* pCbCtx, int32_t iCtx, uint32_t uiBin); +void WelsCabacEncodeBypassOne (SCabacCtx* pCbCtx, uint32_t uiBin); +void WelsCabacEncodeTerminate (SCabacCtx* pCbCtx, uint32_t uiBin); +void WelsCabacEncodeUeBypass (SCabacCtx* pCbCtx, int32_t iExpBits, uint32_t uiVal); +void WelsCabacEncodeFlush (SCabacCtx* pCbCtx); +uint8_t* WelsCabacEncodeGetPtr (SCabacCtx* pCbCtx); +int32_t WriteBlockResidualCabac (void* pEncCtx, int16_t* pCoffLevel, int32_t iEndIdx, + int32_t iCalRunLevelFlag, + int32_t iResidualProperty, int8_t iNC, SBitStringAux* pBs); + +} +#endif diff --git a/codec/encoder/core/inc/set_mb_syn_cavlc.h b/codec/encoder/core/inc/set_mb_syn_cavlc.h index 25968d8c..e6066782 100644 --- a/codec/encoder/core/inc/set_mb_syn_cavlc.h +++ b/codec/encoder/core/inc/set_mb_syn_cavlc.h @@ -48,30 +48,30 @@ namespace WelsEnc { - -enum EResidualProperty { -LUMA_DC = 0, -LUMA_AC = 1, -LUMA_4x4 = 2, -CHROMA_DC = 3, -CHROMA_AC = 4 +enum ECtxBlockCat { + LUMA_DC = 0, + LUMA_AC = 1, + LUMA_4x4 = 2, + CHROMA_DC = 3, + CHROMA_AC = 4 }; #define LUMA_DC_AC 0x04 typedef struct TagCavlcTableItem { -uint16_t uiBits; -uint8_t uiLen; -uint8_t uiSuffixLength; + uint16_t uiBits; + uint8_t uiLen; + uint8_t uiSuffixLength; } SCavlcTableItem; -void InitCoeffFunc (SWelsFuncPtrList* pFuncList, const uint32_t uiCpuFlag); +void InitCoeffFunc (SWelsFuncPtrList* pFuncList, const uint32_t uiCpuFlag,int32_t iEntropyCodingModeFlag); int32_t WriteBlockResidualCavlc (SWelsFuncPtrList* pFuncList, int16_t* pCoffLevel, int32_t iEndIdx, int32_t iCalRunLevelFlag, int32_t iResidualProperty, int8_t iNC, SBitStringAux* pBs); + #if defined(__cplusplus) extern "C" { #endif//__cplusplus diff --git a/codec/encoder/core/inc/slice.h b/codec/encoder/core/inc/slice.h index 27ef769f..bf442193 100644 --- a/codec/encoder/core/inc/slice.h +++ b/codec/encoder/core/inc/slice.h @@ -42,7 +42,7 @@ #include "parameter_sets.h" #include "svc_enc_slice_segment.h" #include "bit_stream.h" - +#include "set_mb_syn_cabac.h" namespace WelsEnc { @@ -178,6 +178,10 @@ uint8_t uiAssumeLog2BytePerMb; uint32_t uiSliceFMECostDown;//TODO: for FME switch under MT, to opt after ME final? uint8_t uiReservedFillByte; // reserved to meet 4 bytes alignment + +SCabacCtx sCabacCtx; +int32_t iCabacInitIdc; +int32_t iMbSkipRun; } SSlice, *PSlice; } diff --git a/codec/encoder/core/inc/svc_enc_golomb.h b/codec/encoder/core/inc/svc_enc_golomb.h index 11c422fc..92867c9c 100644 --- a/codec/encoder/core/inc/svc_enc_golomb.h +++ b/codec/encoder/core/inc/svc_enc_golomb.h @@ -171,7 +171,6 @@ pBs->pBufPtr += 4 - pBs->iLeftBits / 8; pBs->iLeftBits = 32; pBs->uiCurBits = 0; // for future writing safe, 5/19/2010 } - /* * Write unsigned exp golomb codes */ @@ -246,5 +245,15 @@ static inline int32_t BsGetBitsPos (SBitStringAux* pBs) { return (int32_t) (((pBs->pBufPtr - pBs->pBuf) << 3) + 32 - pBs->iLeftBits); } +static inline void BsAlign( SBitStringAux* pBs ) +{ + if( pBs->iLeftBits&7 ) + { + pBs->uiCurBits <<= pBs->iLeftBits&7; + pBs->uiCurBits |= (1 << (pBs->iLeftBits&7)) - 1; + pBs->iLeftBits &= ~7; + } + BsFlush(pBs ); +} } #endif//WELS_EXPONENTIAL_GOLOMB_ENTROPY_CODING_H__ diff --git a/codec/encoder/core/inc/svc_enc_macroblock.h b/codec/encoder/core/inc/svc_enc_macroblock.h index 4f024f6b..0b697fa3 100644 --- a/codec/encoder/core/inc/svc_enc_macroblock.h +++ b/codec/encoder/core/inc/svc_enc_macroblock.h @@ -69,6 +69,10 @@ SMVUnitXY sP16x16Mv; uint8_t uiLumaQp; // uiLumaQp: pPps->iInitialQp + sSliceHeader->delta_qp + mb->dquant. uint8_t uiChromaQp; uint8_t uiSliceIdc; // AVC: pFirstMbInSlice?; SVC: (pFirstMbInSlice << 7) | ((uiDependencyId << 4) | uiQualityId); +uint32_t uiChromPredMode; +int32_t iLumaDQp; +SMVUnitXY sMvd[4]; +int32_t iCbpDc; uint8_t reserved_filling_bytes[1]; // filling bytes reserved to make structure aligned with 4 bytes, higher cache hit on less structure size by 2 cache lines( 2 * 64 bytes) once hit } SMB, *PMb; diff --git a/codec/encoder/core/inc/svc_enc_slice_segment.h b/codec/encoder/core/inc/svc_enc_slice_segment.h index 45985ba1..6b725098 100644 --- a/codec/encoder/core/inc/svc_enc_slice_segment.h +++ b/codec/encoder/core/inc/svc_enc_slice_segment.h @@ -46,6 +46,8 @@ #include "memory_align.h" #include "codec_app_def.h" +#include "set_mb_syn_cabac.h" + namespace WelsEnc { @@ -90,10 +92,11 @@ typedef struct TagDynamicSlicingStack { int32_t iStartPos; int32_t iCurrentPos; -uint8_t* pBsStackBufPtr; // current writing position +uint8_t* pBsStackBufPtr; // current writing position uint32_t uiBsStackCurBits; int32_t iBsStackLeftBits; +SCabacCtx sStoredCabac; int32_t iMbSkipRunStack; uint8_t uiLastMbQp; } SDynamicSlicingStack; diff --git a/codec/encoder/core/inc/svc_set_mb_syn.h b/codec/encoder/core/inc/svc_set_mb_syn.h new file mode 100644 index 00000000..2a82c3bd --- /dev/null +++ b/codec/encoder/core/inc/svc_set_mb_syn.h @@ -0,0 +1,68 @@ +/*! + * \copy + * Copyright (c) 2009-2013, Cisco Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * \file svc_set_mb_syn.h + * + * \brief Seting all syntax elements of mb and encoding residual with cavlc and cabac + * + * \date 2009.8.12 Created + * + ************************************************************************************* + */ + +#ifndef SVC_SET_MB_SYN_H_ +#define SVC_SET_MB_SYN_H_ + +#include "typedefs.h" +#include "wels_common_basis.h" +#include "encoder_context.h" +#include "md.h" +#include "slice.h" +#include "set_mb_syn_cavlc.h" +#include "set_mb_syn_cabac.h" + +namespace WelsEnc { + + + +int32_t WelsWriteMbResidual (SWelsFuncPtrList* pFuncList, SMbCache* sMbCacheInfo, SMB* pCurMb, SBitStringAux* pBs); + +void WelsSpatialWriteSubMbPred (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb); + +void WelsSpatialWriteMbPred (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb); +void WelsInitSliceCabac(sWelsEncCtx* pEncCtx,SSlice* pSlice); +void WelsCabacInit(void *pCtx); +void WelsWriteSliceEndSyn(SSlice *pSlice,bool bEntropyCodingModeFlag); +//for Base Layer CAVLC writing +int32_t WelsSpatialWriteMbSyn (void* Ctx, SSlice* pSlice, SMB* pCurMb); +int32_t WelsSpatialWriteMbSynCabac (void* pCtx, SSlice* pSlice, SMB* pCurMb); +} +#endif diff --git a/codec/encoder/core/inc/svc_set_mb_syn_cavlc.h b/codec/encoder/core/inc/svc_set_mb_syn_cavlc.h index f1d133b9..f4dae19f 100644 --- a/codec/encoder/core/inc/svc_set_mb_syn_cavlc.h +++ b/codec/encoder/core/inc/svc_set_mb_syn_cavlc.h @@ -37,7 +37,6 @@ * ************************************************************************************* */ - #ifndef SVC_SET_MB_SYN_CAVLC_H_ #define SVC_SET_MB_SYN_CAVLC_H_ @@ -45,19 +44,24 @@ #include "wels_common_basis.h" #include "encoder_context.h" #include "md.h" - +#include "slice.h" #include "set_mb_syn_cavlc.h" +#include "set_mb_syn_cabac.h" namespace WelsEnc { + + int32_t WelsWriteMbResidual (SWelsFuncPtrList* pFuncList, SMbCache* sMbCacheInfo, SMB* pCurMb, SBitStringAux* pBs); void WelsSpatialWriteSubMbPred (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb); void WelsSpatialWriteMbPred (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb); - +void WelsInitSliceCabac(sWelsEncCtx* pEncCtx,SSlice* pSlice); +void WelsWriteSliceEndSyn(SSlice *pSlice,bool bEntropyCodingModeFlag); //for Base Layer CAVLC writing -int32_t WelsSpatialWriteMbSyn (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb); +int32_t WelsSpatialWriteMbSyn (void* Ctx, SSlice* pSlice, SMB* pCurMb); +int32_t WelsSpatialWriteMbSynCabac (void* pCtx, SSlice* pSlice, SMB* pCurMb); } #endif diff --git a/codec/encoder/core/inc/wels_common_basis.h b/codec/encoder/core/inc/wels_common_basis.h index 643bdbe6..2880e1e3 100644 --- a/codec/encoder/core/inc/wels_common_basis.h +++ b/codec/encoder/core/inc/wels_common_basis.h @@ -47,40 +47,45 @@ namespace WelsEnc { struct SMVUnitXY { // each 4 Bytes -int16_t iMvX; -int16_t iMvY; + int16_t iMvX; + int16_t iMvY; public: -SMVUnitXY& sDeltaMv (const SMVUnitXY& _v0, const SMVUnitXY& _v1) { - iMvX = _v0.iMvX - _v1.iMvX; - iMvY = _v0.iMvY - _v1.iMvY; - return (*this); -} + SMVUnitXY& sDeltaMv (const SMVUnitXY& _v0, const SMVUnitXY& _v1) { + iMvX = _v0.iMvX - _v1.iMvX; + iMvY = _v0.iMvY - _v1.iMvY; + return (*this); + }; + SMVUnitXY& sAssginMv (const SMVUnitXY& _v0) { + iMvX = _v0.iMvX; + iMvY = _v0.iMvY; + return (*this); + }; }; typedef struct TagMVComponentUnit { // each LIST_0/LIST_1 -SMVUnitXY sMotionVectorCache[5 * 6 - 1]; // Luma only: 5 x 6 - 1 = 29 D-Words -int8_t iRefIndexCache[5 * 6]; // Luma only: 5 x 6 = 30 bytes + SMVUnitXY sMotionVectorCache[5 * 6 - 1]; // Luma only: 5 x 6 - 1 = 29 D-Words + int8_t iRefIndexCache[5 * 6]; // Luma only: 5 x 6 = 30 bytes } SMVComponentUnit, *PMVComponentUnit; typedef struct TagParaSetOffsetVariable { -int32_t iParaSetIdDelta[MAX_DQ_LAYER_NUM/*+1*/]; //mark delta between SPS_ID_in_bs and sps_id_in_encoder, can be minus, for each dq-layer + int32_t iParaSetIdDelta[MAX_DQ_LAYER_NUM/*+1*/]; //mark delta between SPS_ID_in_bs and sps_id_in_encoder, can be minus, for each dq-layer //need not extra +1 due no MGS and FMO case so far -bool bUsedParaSetIdInBs[MAX_PPS_COUNT]; //mark the used SPS_ID with 1 -uint32_t uiNextParaSetIdToUseInBs; //mark the next SPS_ID_in_bs, for all layers + bool bUsedParaSetIdInBs[MAX_PPS_COUNT]; //mark the used SPS_ID with 1 + uint32_t uiNextParaSetIdToUseInBs; //mark the next SPS_ID_in_bs, for all layers } SParaSetOffsetVariable; typedef struct TagParaSetOffset { //in PS0 design, "sParaSetOffsetVariable" record the previous paras before current IDR, AND NEED to be stacked and recover across IDR -SParaSetOffsetVariable -sParaSetOffsetVariable[PARA_SET_TYPE]; //PARA_SET_TYPE=3; paraset_type = 0: AVC_SPS; =1: Subset_SPS; =2: PPS + SParaSetOffsetVariable + sParaSetOffsetVariable[PARA_SET_TYPE]; //PARA_SET_TYPE=3; paraset_type = 0: AVC_SPS; =1: Subset_SPS; =2: PPS //in PSO design, "bPpsIdMappingIntoSubsetsps" uses the current para of current IDR period -bool -bPpsIdMappingIntoSubsetsps[MAX_DQ_LAYER_NUM/*+1*/]; // need not extra +1 due no MGS and FMO case so far -uint16_t -uiIdrPicId; // IDR picture id: [0, 65535], this one is used for LTR!! Can we just NOT put this into the SParaSetOffset structure?!! + bool + bPpsIdMappingIntoSubsetsps[MAX_DQ_LAYER_NUM/*+1*/]; // need not extra +1 due no MGS and FMO case so far + uint16_t + uiIdrPicId; // IDR picture id: [0, 65535], this one is used for LTR!! Can we just NOT put this into the SParaSetOffset structure?!! #if _DEBUG -bool bEnableSpsPpsIdAddition; + bool bEnableSpsPpsIdAddition; #endif } SParaSetOffset; @@ -88,32 +93,32 @@ bool bEnableSpsPpsIdAddition; /* Position Offset structure */ typedef struct TagCropOffset { -int16_t iCropLeft; -int16_t iCropRight; -int16_t iCropTop; -int16_t iCropBottom; + int16_t iCropLeft; + int16_t iCropRight; + int16_t iCropTop; + int16_t iCropBottom; } SCropOffset; /* Transform Type */ enum ETransType { -T_4x4 = 0, -T_8x8 = 1, -T_16x16 = 2, -T_PCM = 3 + T_4x4 = 0, + T_8x8 = 1, + T_16x16 = 2, + T_PCM = 3 }; enum EMbPosition { -LEFT_MB_POS = 0x01, // A -TOP_MB_POS = 0x02, // B -TOPRIGHT_MB_POS = 0x04, // C -TOPLEFT_MB_POS = 0x08, // D, -RIGHT_MB_POS = 0x10, // add followed four case to reuse when intra up-sample -BOTTOM_MB_POS = 0x20, // -BOTTOMRIGHT_MB_POS = 0x40, // -BOTTOMLEFT_MB_POS = 0x80, // -MB_POS_A = 0x100 + LEFT_MB_POS = 0x01, // A + TOP_MB_POS = 0x02, // B + TOPRIGHT_MB_POS = 0x04, // C + TOPLEFT_MB_POS = 0x08, // D, + RIGHT_MB_POS = 0x10, // add followed four case to reuse when intra up-sample + BOTTOM_MB_POS = 0x20, // + BOTTOMRIGHT_MB_POS = 0x40, // + BOTTOMLEFT_MB_POS = 0x80, // + MB_POS_A = 0x100 }; #define MB_ON_PIC_BOUNDRY (RIGHT_MB_POS|BOTTOM_MB_POS|LEFT_MB_POS|TOP_MB_POS) @@ -180,13 +185,13 @@ typedef uint32_t Mb_Type; enum { -Intra4x4 = 0, -Intra16x16 = 1, -Inter16x16 = 2, -Inter16x8 = 3, -Inter8x16 = 4, -Inter8x8 = 5, -PSkip = 6 + Intra4x4 = 0, + Intra16x16 = 1, + Inter16x16 = 2, + Inter16x8 = 3, + Inter8x16 = 4, + Inter8x8 = 5, + PSkip = 6 }; diff --git a/codec/encoder/core/inc/wels_func_ptr_def.h b/codec/encoder/core/inc/wels_func_ptr_def.h index fd341fb0..afe6f829 100644 --- a/codec/encoder/core/inc/wels_func_ptr_def.h +++ b/codec/encoder/core/inc/wels_func_ptr_def.h @@ -160,9 +160,10 @@ typedef void (*PLineFullSearchFunc) (SWelsFuncPtrList* pFuncList, SWelsME* pMe, const int16_t kiMinMv, const int16_t kiMaxMv, const bool bVerticalSearch); typedef void (*PInitializeHashforFeatureFunc) (uint32_t* pTimesOfFeatureValue, uint16_t* pBuf, const int32_t kiListSize, - uint16_t** pLocationOfFeature, uint16_t** pFeatureValuePointerList); -typedef void (*PFillQpelLocationByFeatureValueFunc) (uint16_t* pFeatureOfBlock, const int32_t kiWidth, const int32_t kiHeight, - uint16_t** pFeatureValuePointerList); + uint16_t** pLocationOfFeature, uint16_t** pFeatureValuePointerList); +typedef void (*PFillQpelLocationByFeatureValueFunc) (uint16_t* pFeatureOfBlock, const int32_t kiWidth, + const int32_t kiHeight, + uint16_t** pFeatureValuePointerList); typedef void (*PCalculateBlockFeatureOfFrame) (uint8_t* pRef, const int32_t kiWidth, const int32_t kiHeight, const int32_t kiRefStride, uint16_t* pFeatureOfBlock, uint32_t pTimesOfFeatureValue[]); @@ -200,6 +201,9 @@ typedef void (*PAfterBuildRefListFunc) (void* pCtx); typedef int32_t (*PCavlcParamCalFunc) (int16_t* pCoff, uint8_t* pRun, int16_t* pLevel, int32_t* pTotalCoeffs, int32_t iEndIdx); +typedef int32_t (*PWelsSpatialWriteMbSyn) (void* pCtx, SSlice* pSlice, SMB* pCurMb); +typedef void (*PStashMBStatus) (SDynamicSlicingStack* pDss, void* pBuffer, SSlice* pSlice, int32_t iMbSkipRun); +typedef int32_t (*PStashPopMBStatus) (SDynamicSlicingStack* pDss, void* pBuffer, SSlice* pSlice); struct TagWelsFuncPointerList { SExpandPicFunc sExpandPicFunc; @@ -297,6 +301,9 @@ struct TagWelsFuncPointerList { PAfterBuildRefListFunc pAfterBuildRefList; PCavlcParamCalFunc pfCavlcParamCal; + PWelsSpatialWriteMbSyn pfWelsSpatialWriteMbSyn; + PStashMBStatus pfStashMBStatus; + PStashPopMBStatus pfStashPopMBStatus; }; } //end of namespace WelsEnc { diff --git a/codec/encoder/core/src/au_set.cpp b/codec/encoder/core/src/au_set.cpp index 67afd879..b2be247d 100644 --- a/codec/encoder/core/src/au_set.cpp +++ b/codec/encoder/core/src/au_set.cpp @@ -266,7 +266,7 @@ int32_t WelsWritePpsSyntax (SWelsPPS* pPps, SBitStringAux* pBitStringAux, SParaS } #endif - BsWriteOneBit (pLocalBitStringAux, false/*pPps->entropy_coding_mode_flag*/); + BsWriteOneBit (pLocalBitStringAux, pPps->bEntropyCodingModeFlag); BsWriteOneBit (pLocalBitStringAux, false/*pPps->bPicOrderPresentFlag*/); #ifdef DISABLE_FMO_FEATURE @@ -414,7 +414,8 @@ int32_t WelsInitPps (SWelsPPS* pPps, SSubsetSps* pSubsetSps, const uint32_t kuiPpsId, const bool kbDeblockingFilterPresentFlag, - const bool kbUsingSubsetSps) { + const bool kbUsingSubsetSps, + const bool kbEntropyCodingModeFlag) { SWelsSPS* pUsedSps = NULL; if (pPps == NULL || (pSps == NULL && pSubsetSps == NULL)) return 1; @@ -433,6 +434,7 @@ int32_t WelsInitPps (SWelsPPS* pPps, /* fill picture parameter set syntax */ pPps->iPpsId = kuiPpsId; pPps->iSpsId = pUsedSps->uiSpsId; + pPps->bEntropyCodingModeFlag = kbEntropyCodingModeFlag; #if !defined(DISABLE_FMO_FEATURE) pPps->uiNumSliceGroups = 1; //param->qos_param.sliceGroupCount; if (pPps->uiNumSliceGroups > 1) { diff --git a/codec/encoder/core/src/cabac.cpp b/codec/encoder/core/src/cabac.cpp new file mode 100644 index 00000000..e3ee9664 --- /dev/null +++ b/codec/encoder/core/src/cabac.cpp @@ -0,0 +1,557 @@ +/*! + * \copy + * Copyright (c) 2009-2013, Cisco Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * \file cabac.cpp + * + * \brief cabac table + * + * \date 10/11/2014 Created + * + ************************************************************************************* + */ +#include "typedefs.h" +#include "set_mb_syn_cabac.h" + + +namespace WelsEnc { + +/* this table is from Table9-12 to Table 9-24 */ + +const int8_t g_kiCabacGlobalContextIdx[WELS_CONTEXT_COUNT][4][2] = { + //0-10 Table 9-12 + {{20, -15}, {20, -15}, {20, -15}, {20, -15}}, + {{2, 54}, {2, 54}, {2, 54}, {2, 54}}, + {{3, 74}, {3, 74}, {3, 74}, {3, 74}}, + {{20, -15}, {20, -15}, {20, -15}, {20, -15}}, + {{2, 54}, {2, 54}, {2, 54}, {2, 54}}, + {{3, 74}, {3, 74}, {3, 74}, {3, 74}}, + {{ -28, 127}, { -28, 127}, { -28, 127}, { -28, 127}}, + {{ -23, 104}, { -23, 104}, { -23, 104}, { -23, 104}}, + {{ -6, 53}, { -6, 53}, { -6, 53}, { -6, 53}}, + {{ -1, 54}, { -1, 54}, { -1, 54}, { -1, 54}}, + {{7, 51}, {7, 51}, {7, 51}, {7, 51}}, + //11-23 Table 9-13 + {{CTX_NA, CTX_NA}, {23, 33}, {22, 25}, {29, 16}}, + {{CTX_NA, CTX_NA}, {23, 2}, {34, 0}, {25, 0}}, + {{CTX_NA, CTX_NA}, {21, 0}, {16, 0}, {14, 0}}, + {{CTX_NA, CTX_NA}, {1, 9}, { -2, 9}, { -10, 51}}, + {{CTX_NA, CTX_NA}, {0, 49}, {4, 41}, { -3, 62}}, + {{CTX_NA, CTX_NA}, { -37, 118}, { -29, 118}, { -27, 99}}, + {{CTX_NA, CTX_NA}, {5, 57}, {2, 65}, {26, 16}}, + {{CTX_NA, CTX_NA}, { -13, 78}, { -6, 71}, { -4, 85}}, + {{CTX_NA, CTX_NA}, { -11, 65}, { -13, 79}, { -24, 102}}, + {{CTX_NA, CTX_NA}, {1, 62}, {5, 52}, {5, 57}}, + {{CTX_NA, CTX_NA}, {12, 49}, {9, 50}, {6, 57}}, + {{CTX_NA, CTX_NA}, { -4, 73}, { -3, 70}, { -17, 73}}, + {{CTX_NA, CTX_NA}, {17, 50}, {10, 54}, {14, 57}}, + //24-39 Table9-14 + {{CTX_NA, CTX_NA}, {18, 64}, {26, 34}, {20, 40}}, + {{CTX_NA, CTX_NA}, {9, 43}, {19, 22}, {20, 10}}, + {{CTX_NA, CTX_NA}, {29, 0}, {40, 0}, {29, 0}}, + {{CTX_NA, CTX_NA}, {26, 67}, {57, 2}, {54, 0}}, + {{CTX_NA, CTX_NA}, {16, 90}, {41, 36}, {37, 42}}, + {{CTX_NA, CTX_NA}, {9, 104}, {26, 69}, {12, 97}}, + {{CTX_NA, CTX_NA}, { -46, 127}, { -45, 127}, { -32, 127}}, + {{CTX_NA, CTX_NA}, { -20, 104}, { -15, 101}, { -22, 117}}, + {{CTX_NA, CTX_NA}, {1, 67}, { -4, 76}, { -2, 74}}, + {{CTX_NA, CTX_NA}, { -13, 78}, { -6, 71}, { -4, 85}}, + {{CTX_NA, CTX_NA}, { -11, 65}, { -13, 79}, { -24, 102}}, + {{CTX_NA, CTX_NA}, {1, 62}, {5, 52}, {5, 57}}, + {{CTX_NA, CTX_NA}, { -6, 86}, {6, 69}, { -6, 93}}, + {{CTX_NA, CTX_NA}, { -17, 95}, { -13, 90}, { -14, 88}}, + {{CTX_NA, CTX_NA}, { -6, 61}, {0, 52}, { -6, 44}}, + {{CTX_NA, CTX_NA}, {9, 45}, {8, 43}, {4, 55}}, + //40-53 Table 9-15 + {{CTX_NA, CTX_NA}, { -3, 69}, { -2, 69}, { -11, 89}}, + {{CTX_NA, CTX_NA}, { -6, 81}, { -5, 82}, { -15, 103}}, + {{CTX_NA, CTX_NA}, { -11, 96}, { -10, 96}, { -21, 116}}, + {{CTX_NA, CTX_NA}, {6, 55}, {2, 59}, {19, 57}}, + {{CTX_NA, CTX_NA}, {7, 67}, {2, 75}, {20, 58}}, + {{CTX_NA, CTX_NA}, { -5, 86}, { -3, 87}, {4, 84}}, + {{CTX_NA, CTX_NA}, {2, 88}, { -3, 100}, {6, 96}}, + {{CTX_NA, CTX_NA}, {0, 58}, {1, 56}, {1, 63}}, + {{CTX_NA, CTX_NA}, { -3, 76}, { -3, 74}, { -5, 85}}, + {{CTX_NA, CTX_NA}, { -10, 94}, { -6, 85}, { -13, 106}}, + {{CTX_NA, CTX_NA}, {5, 54}, {0, 59}, {5, 63}}, + {{CTX_NA, CTX_NA}, {4, 69}, { -3, 81}, {6, 75}}, + {{CTX_NA, CTX_NA}, { -3, 81}, { -7, 86}, { -3, 90}}, + {{CTX_NA, CTX_NA}, {0, 88}, { -5, 95}, { -1, 101}}, + //54-59 Table 9-16 + {{CTX_NA, CTX_NA}, { -7, 67}, { -1, 66}, {3, 55}}, + {{CTX_NA, CTX_NA}, { -5, 74}, { -1, 77}, { -4, 79}}, + {{CTX_NA, CTX_NA}, { -4, 74}, {1, 70}, { -2, 75}}, + {{CTX_NA, CTX_NA}, { -5, 80}, { -2, 86}, { -12, 97}}, + {{CTX_NA, CTX_NA}, { -7, 72}, { -5, 72}, { -7, 50}}, + {{CTX_NA, CTX_NA}, {1, 58}, {0, 61}, {1, 60}}, + //60-69 Table 9-17 + {{0, 41}, {0, 41}, {0, 41}, {0, 41}}, + {{0, 63}, {0, 63}, {0, 63}, {0, 63}}, + {{0, 63}, {0, 63}, {0, 63}, {0, 63}}, + {{0, 63}, {0, 63}, {0, 63}, {0, 63}}, + {{ -9, 83}, { -9, 83}, { -9, 83}, { -9, 83}}, + {{4, 86}, {4, 86}, {4, 86}, {4, 86}}, + {{0, 97}, {0, 97}, {0, 97}, {0, 97}}, + {{ -7, 72}, { -7, 72}, { -7, 72}, { -7, 72}}, + {{13, 41}, {13, 41}, {13, 41}, {13, 41}}, + {{3, 62}, {3, 62}, {3, 62}, {3, 62}}, + //70-104 Table 9-18 + {{0, 11}, {0, 45}, {13, 15}, {7, 34}}, + {{1, 55}, { -4, 78}, {7, 51}, { -9, 88}}, + {{0, 69}, { -3, 96}, {2, 80}, { -20, 127}}, + {{ -17, 127}, { -27, 126}, { -39, 127}, { -36, 127}}, + {{ -13, 102}, { -28, 98}, { -18, 91}, { -17, 91}}, + {{0, 82}, { -25, 101}, { -17, 96}, { -14, 95}}, + {{ -7, 74}, { -23, 67}, { -26, 81}, { -25, 84}}, + {{ -21, 107}, { -28, 82}, { -35, 98}, { -25, 86}}, + {{ -27, 127}, { -20, 94}, { -24, 102}, { -12, 89}}, + {{ -31, 127}, { -16, 83}, { -23, 97}, { -17, 91}}, + {{ -24, 127}, { -22, 110}, { -27, 119}, { -31, 127}}, + {{ -18, 95}, { -21, 91}, { -24, 99}, { -14, 76}}, + {{ -27, 127}, { -18, 102}, { -21, 110}, { -18, 103}}, + {{ -21, 114}, { -13, 93}, { -18, 102}, { -13, 90}}, + {{ -30, 127}, { -29, 127}, { -36, 127}, { -37, 127}}, + {{ -17, 123}, { -7, 92}, {0, 80}, {11, 80}}, + {{ -12, 115}, { -5, 89}, { -5, 89}, {5, 76}}, + {{ -16, 122}, { -7, 96}, { -7, 94}, {2, 84}}, + {{ -11, 115}, { -13, 108}, { -4, 92}, {5, 78}}, + {{ -12, 63}, { -3, 46}, {0, 39}, { -6, 55}}, + {{ -2, 68}, { -1, 65}, {0, 65}, {4, 61}}, + {{ -15, 84}, { -1, 57}, { -15, 84}, { -14, 83}}, + {{ -13, 104}, { -9, 93}, { -35, 127}, { -37, 127}}, + {{ -3, 70}, { -3, 74}, { -2, 73}, { -5, 79}}, + {{ -8, 93}, { -9, 92}, { -12, 104}, { -11, 104}}, + {{ -10, 90}, { -8, 87}, { -9, 91}, { -11, 91}}, + {{ -30, 127}, { -23, 126}, { -31, 127}, { -30, 127}}, + {{ -1, 74}, {5, 54}, {3, 55}, {0, 65}}, + {{ -6, 97}, {6, 60}, {7, 56}, { -2, 79}}, + {{ -7, 91}, {6, 59}, {7, 55}, {0, 72}}, + {{ -20, 127}, {6, 69}, {8, 61}, { -4, 92}}, + {{ -4, 56}, { -1, 48}, { -3, 53}, { -6, 56}}, + {{ -5, 82}, {0, 68}, {0, 68}, {3, 68}}, + {{ -7, 76}, { -4, 69}, { -7, 74}, { -8, 71}}, + {{ -22, 125}, { -8, 88}, { -9, 88}, { -13, 98}}, + //105-165 Table 9-19 + {{ -7, 93}, { -2, 85}, { -13, 103}, { -4, 86}}, + {{ -11, 87}, { -6, 78}, { -13, 91}, { -12, 88}}, + {{ -3, 77}, { -1, 75}, { -9, 89}, { -5, 82}}, + {{ -5, 71}, { -7, 77}, { -14, 92}, { -3, 72}}, + {{ -4, 63}, {2, 54}, { -8, 76}, { -4, 67}}, + {{ -4, 68}, {5, 50}, { -12, 87}, { -8, 72}}, + {{ -12, 84}, { -3, 68}, { -23, 110}, { -16, 89}}, + {{ -7, 62}, {1, 50}, { -24, 105}, { -9, 69}}, + {{ -7, 65}, {6, 42}, { -10, 78}, { -1, 59}}, + {{8, 61}, { -4, 81}, { -20, 112}, {5, 66}}, + {{5, 56}, {1, 63}, { -17, 99}, {4, 57}}, + {{ -2, 66}, { -4, 70}, { -78, 127}, { -4, 71}}, + {{1, 64}, {0, 67}, { -70, 127}, { -2, 71}}, + {{0, 61}, {2, 57}, { -50, 127}, {2, 58}}, + {{ -2, 78}, { -2, 76}, { -46, 127}, { -1, 74}}, + {{1, 50}, {11, 35}, { -4, 66}, { -4, 44}}, + {{7, 52}, {4, 64}, { -5, 78}, { -1, 69}}, + {{10, 35}, {1, 61}, { -4, 71}, {0, 62}}, + {{0, 44}, {11, 35}, { -8, 72}, { -7, 51}}, + {{11, 38}, {18, 25}, {2, 59}, { -4, 47}}, + {{1, 45}, {12, 24}, { -1, 55}, { -6, 42}}, + {{0, 46}, {13, 29}, { -7, 70}, { -3, 41}}, + {{5, 44}, {13, 36}, { -6, 75}, { -6, 53}}, + {{31, 17}, { -10, 93}, { -8, 89}, {8, 76}}, + {{1, 51}, { -7, 73}, { -34, 119}, { -9, 78}}, + {{7, 50}, { -2, 73}, { -3, 75}, { -11, 83}}, + {{28, 19}, {13, 46}, {32, 20}, {9, 52}}, + {{16, 33}, {9, 49}, {30, 22}, {0, 67}}, + {{14, 62}, { -7, 100}, { -44, 127}, { -5, 90}}, + {{ -13, 108}, {9, 53}, {0, 54}, {1, 67}}, + {{ -15, 100}, {2, 53}, { -5, 61}, { -15, 72}}, + {{ -13, 101}, {5, 53}, {0, 58}, { -5, 75}}, + {{ -13, 91}, { -2, 61}, { -1, 60}, { -8, 80}}, + {{ -12, 94}, {0, 56}, { -3, 61}, { -21, 83}}, + {{ -10, 88}, {0, 56}, { -8, 67}, { -21, 64}}, + {{ -16, 84}, { -13, 63}, { -25, 84}, { -13, 31}}, + {{ -10, 86}, { -5, 60}, { -14, 74}, { -25, 64}}, + {{ -7, 83}, { -1, 62}, { -5, 65}, { -29, 94}}, + {{ -13, 87}, {4, 57}, {5, 52}, {9, 75}}, + {{ -19, 94}, { -6, 69}, {2, 57}, {17, 63}}, + {{1, 70}, {4, 57}, {0, 61}, { -8, 74}}, + {{0, 72}, {14, 39}, { -9, 69}, { -5, 35}}, + {{ -5, 74}, {4, 51}, { -11, 70}, { -2, 27}}, + {{18, 59}, {13, 68}, {18, 55}, {13, 91}}, + {{ -8, 102}, {3, 64}, { -4, 71}, {3, 65}}, + {{ -15, 100}, {1, 61}, {0, 58}, { -7, 69}}, + {{0, 95}, {9, 63}, {7, 61}, {8, 77}}, + {{ -4, 75}, {7, 50}, {9, 41}, { -10, 66}}, + {{2, 72}, {16, 39}, {18, 25}, {3, 62}}, + {{ -11, 75}, {5, 44}, {9, 32}, { -3, 68}}, + {{ -3, 71}, {4, 52}, {5, 43}, { -20, 81}}, + {{15, 46}, {11, 48}, {9, 47}, {0, 30}}, + {{ -13, 69}, { -5, 60}, {0, 44}, {1, 7}}, + {{0, 62}, { -1, 59}, {0, 51}, { -3, 23}}, + {{0, 65}, {0, 59}, {2, 46}, { -21, 74}}, + {{21, 37}, {22, 33}, {19, 38}, {16, 66}}, + {{ -15, 72}, {5, 44}, { -4, 66}, { -23, 124}}, + {{9, 57}, {14, 43}, {15, 38}, {17, 37}}, + {{16, 54}, { -1, 78}, {12, 42}, {44, -18}}, + {{0, 62}, {0, 60}, {9, 34}, {50, -34}}, + {{12, 72}, {9, 69}, {0, 89}, { -22, 127}}, + //166-226 Table 9-20 + {{24, 0}, {11, 28}, {4, 45}, {4, 39}}, + {{15, 9}, {2, 40}, {10, 28}, {0, 42}}, + {{8, 25}, {3, 44}, {10, 31}, {7, 34}}, + {{13, 18}, {0, 49}, {33, -11}, {11, 29}}, + {{15, 9}, {0, 46}, {52, -43}, {8, 31}}, + {{13, 19}, {2, 44}, {18, 15}, {6, 37}}, + {{10, 37}, {2, 51}, {28, 0}, {7, 42}}, + {{12, 18}, {0, 47}, {35, -22}, {3, 40}}, + {{6, 29}, {4, 39}, {38, -25}, {8, 33}}, + {{20, 33}, {2, 62}, {34, 0}, {13, 43}}, + {{15, 30}, {6, 46}, {39, -18}, {13, 36}}, + {{4, 45}, {0, 54}, {32, -12}, {4, 47}}, + {{1, 58}, {3, 54}, {102, -94}, {3, 55}}, + {{0, 62}, {2, 58}, {0, 0}, {2, 58}}, + {{7, 61}, {4, 63}, {56, -15}, {6, 60}}, + {{12, 38}, {6, 51}, {33, -4}, {8, 44}}, + {{11, 45}, {6, 57}, {29, 10}, {11, 44}}, + {{15, 39}, {7, 53}, {37, -5}, {14, 42}}, + {{11, 42}, {6, 52}, {51, -29}, {7, 48}}, + {{13, 44}, {6, 55}, {39, -9}, {4, 56}}, + {{16, 45}, {11, 45}, {52, -34}, {4, 52}}, + {{12, 41}, {14, 36}, {69, -58}, {13, 37}}, + {{10, 49}, {8, 53}, {67, -63}, {9, 49}}, + {{30, 34}, { -1, 82}, {44, -5}, {19, 58}}, + {{18, 42}, {7, 55}, {32, 7}, {10, 48}}, + {{10, 55}, { -3, 78}, {55, -29}, {12, 45}}, + {{17, 51}, {15, 46}, {32, 1}, {0, 69}}, + {{17, 46}, {22, 31}, {0, 0}, {20, 33}}, + {{0, 89}, { -1, 84}, {27, 36}, {8, 63}}, + {{26, -19}, {25, 7}, {33, -25}, {35, -18}}, + {{22, -17}, {30, -7}, {34, -30}, {33, -25}}, + {{26, -17}, {28, 3}, {36, -28}, {28, -3}}, + {{30, -25}, {28, 4}, {38, -28}, {24, 10}}, + {{28, -20}, {32, 0}, {38, -27}, {27, 0}}, + {{33, -23}, {34, -1}, {34, -18}, {34, -14}}, + {{37, -27}, {30, 6}, {35, -16}, {52, -44}}, + {{33, -23}, {30, 6}, {34, -14}, {39, -24}}, + {{40, -28}, {32, 9}, {32, -8}, {19, 17}}, + {{38, -17}, {31, 19}, {37, -6}, {31, 25}}, + {{33, -11}, {26, 27}, {35, 0}, {36, 29}}, + {{40, -15}, {26, 30}, {30, 10}, {24, 33}}, + {{41, -6}, {37, 20}, {28, 18}, {34, 15}}, + {{38, 1}, {28, 34}, {26, 25}, {30, 20}}, + {{41, 17}, {17, 70}, {29, 41}, {22, 73}}, + {{30, -6}, {1, 67}, {0, 75}, {20, 34}}, + {{27, 3}, {5, 59}, {2, 72}, {19, 31}}, + {{26, 22}, {9, 67}, {8, 77}, {27, 44}}, + {{37, -16}, {16, 30}, {14, 35}, {19, 16}}, + {{35, -4}, {18, 32}, {18, 31}, {15, 36}}, + {{38, -8}, {18, 35}, {17, 35}, {15, 36}}, + {{38, -3}, {22, 29}, {21, 30}, {21, 28}}, + {{37, 3}, {24, 31}, {17, 45}, {25, 21}}, + {{38, 5}, {23, 38}, {20, 42}, {30, 20}}, + {{42, 0}, {18, 43}, {18, 45}, {31, 12}}, + {{35, 16}, {20, 41}, {27, 26}, {27, 16}}, + {{39, 22}, {11, 63}, {16, 54}, {24, 42}}, + {{14, 48}, {9, 59}, {7, 66}, {0, 93}}, + {{27, 37}, {9, 64}, {16, 56}, {14, 56}}, + {{21, 60}, { -1, 94}, {11, 73}, {15, 57}}, + {{12, 68}, { -2, 89}, {10, 67}, {26, 38}}, + {{2, 97}, { -9, 108}, { -10, 116}, { -24, 127}}, + //227-275 Table 9-21 + {{ -3, 71}, { -6, 76}, { -23, 112}, { -24, 115}}, + {{ -6, 42}, { -2, 44}, { -15, 71}, { -22, 82}}, + {{ -5, 50}, {0, 45}, { -7, 61}, { -9, 62}}, + {{ -3, 54}, {0, 52}, {0, 53}, {0, 53}}, + {{ -2, 62}, { -3, 64}, { -5, 66}, {0, 59}}, + {{0, 58}, { -2, 59}, { -11, 77}, { -14, 85}}, + {{1, 63}, { -4, 70}, { -9, 80}, { -13, 89}}, + {{ -2, 72}, { -4, 75}, { -9, 84}, { -13, 94}}, + {{ -1, 74}, { -8, 82}, { -10, 87}, { -11, 92}}, + {{ -9, 91}, { -17, 102}, { -34, 127}, { -29, 127}}, + {{ -5, 67}, { -9, 77}, { -21, 101}, { -21, 100}}, + {{ -5, 27}, {3, 24}, { -3, 39}, { -14, 57}}, + {{ -3, 39}, {0, 42}, { -5, 53}, { -12, 67}}, + {{ -2, 44}, {0, 48}, { -7, 61}, { -11, 71}}, + {{0, 46}, {0, 55}, { -11, 75}, { -10, 77}}, + {{ -16, 64}, { -6, 59}, { -15, 77}, { -21, 85}}, + {{ -8, 68}, { -7, 71}, { -17, 91}, { -16, 88}}, + {{ -10, 78}, { -12, 83}, { -25, 107}, { -23, 104}}, + {{ -6, 77}, { -11, 87}, { -25, 111}, { -15, 98}}, + {{ -10, 86}, { -30, 119}, { -28, 122}, { -37, 127}}, + {{ -12, 92}, {1, 58}, { -11, 76}, { -10, 82}}, + {{ -15, 55}, { -3, 29}, { -10, 44}, { -8, 48}}, + {{ -10, 60}, { -1, 36}, { -10, 52}, { -8, 61}}, + {{ -6, 62}, {1, 38}, { -10, 57}, { -8, 66}}, + {{ -4, 65}, {2, 43}, { -9, 58}, { -7, 70}}, + {{ -12, 73}, { -6, 55}, { -16, 72}, { -14, 75}}, + {{ -8, 76}, {0, 58}, { -7, 69}, { -10, 79}}, + {{ -7, 80}, {0, 64}, { -4, 69}, { -9, 83}}, + {{ -9, 88}, { -3, 74}, { -5, 74}, { -12, 92}}, + {{ -17, 110}, { -10, 90}, { -9, 86}, { -18, 108}}, + {{ -11, 97}, {0, 70}, {2, 66}, { -4, 79}}, + {{ -20, 84}, { -4, 29}, { -9, 34}, { -22, 69}}, + {{ -11, 79}, {5, 31}, {1, 32}, { -16, 75}}, + {{ -6, 73}, {7, 42}, {11, 31}, { -2, 58}}, + {{ -4, 74}, {1, 59}, {5, 52}, {1, 58}}, + {{ -13, 86}, { -2, 58}, { -2, 55}, { -13, 78}}, + {{ -13, 96}, { -3, 72}, { -2, 67}, { -9, 83}}, + {{ -11, 97}, { -3, 81}, {0, 73}, { -4, 81}}, + {{ -19, 117}, { -11, 97}, { -8, 89}, { -13, 99}}, + {{ -8, 78}, {0, 58}, {3, 52}, { -13, 81}}, + {{ -5, 33}, {8, 5}, {7, 4}, { -6, 38}}, + {{ -4, 48}, {10, 14}, {10, 8}, { -13, 62}}, + {{ -2, 53}, {14, 18}, {17, 8}, { -6, 58}}, + {{ -3, 62}, {13, 27}, {16, 19}, { -2, 59}}, + {{ -13, 71}, {2, 40}, {3, 37}, { -16, 73}}, + {{ -10, 79}, {0, 58}, { -1, 61}, { -10, 76}}, + {{ -12, 86}, { -3, 70}, { -5, 73}, { -13, 86}}, + {{ -13, 90}, { -6, 79}, { -1, 70}, { -9, 83}}, + {{ -14, 97}, { -8, 85}, { -4, 78}, { -10, 87}}, + //276 no use + {{CTX_NA, CTX_NA}, {CTX_NA, CTX_NA}, {CTX_NA, CTX_NA}, {CTX_NA, CTX_NA}}, + //277-337 Table 9-22 + {{ -6, 93}, { -13, 106}, { -21, 126}, { -22, 127}}, + {{ -6, 84}, { -16, 106}, { -23, 124}, { -25, 127}}, + {{ -8, 79}, { -10, 87}, { -20, 110}, { -25, 120}}, + {{0, 66}, { -21, 114}, { -26, 126}, { -27, 127}}, + {{ -1, 71}, { -18, 110}, { -25, 124}, { -19, 114}}, + {{0, 62}, { -14, 98}, { -17, 105}, { -23, 117}}, + {{ -2, 60}, { -22, 110}, { -27, 121}, { -25, 118}}, + {{ -2, 59}, { -21, 106}, { -27, 117}, { -26, 117}}, + {{ -5, 75}, { -18, 103}, { -17, 102}, { -24, 113}}, + {{ -3, 62}, { -21, 107}, { -26, 117}, { -28, 118}}, + {{ -4, 58}, { -23, 108}, { -27, 116}, { -31, 120}}, + {{ -9, 66}, { -26, 112}, { -33, 122}, { -37, 124}}, + {{ -1, 79}, { -10, 96}, { -10, 95}, { -10, 94}}, + {{0, 71}, { -12, 95}, { -14, 100}, { -15, 102}}, + {{3, 68}, { -5, 91}, { -8, 95}, { -10, 99}}, + {{10, 44}, { -9, 93}, { -17, 111}, { -13, 106}}, + {{ -7, 62}, { -22, 94}, { -28, 114}, { -50, 127}}, + {{15, 36}, { -5, 86}, { -6, 89}, { -5, 92}}, + {{14, 40}, {9, 67}, { -2, 80}, {17, 57}}, + {{16, 27}, { -4, 80}, { -4, 82}, { -5, 86}}, + {{12, 29}, { -10, 85}, { -9, 85}, { -13, 94}}, + {{1, 44}, { -1, 70}, { -8, 81}, { -12, 91}}, + {{20, 36}, {7, 60}, { -1, 72}, { -2, 77}}, + {{18, 32}, {9, 58}, {5, 64}, {0, 71}}, + {{5, 42}, {5, 61}, {1, 67}, { -1, 73}}, + {{1, 48}, {12, 50}, {9, 56}, {4, 64}}, + {{10, 62}, {15, 50}, {0, 69}, { -7, 81}}, + {{17, 46}, {18, 49}, {1, 69}, {5, 64}}, + {{9, 64}, {17, 54}, {7, 69}, {15, 57}}, + {{ -12, 104}, {10, 41}, { -7, 69}, {1, 67}}, + {{ -11, 97}, {7, 46}, { -6, 67}, {0, 68}}, + {{ -16, 96}, { -1, 51}, { -16, 77}, { -10, 67}}, + {{ -7, 88}, {7, 49}, { -2, 64}, {1, 68}}, + {{ -8, 85}, {8, 52}, {2, 61}, {0, 77}}, + {{ -7, 85}, {9, 41}, { -6, 67}, {2, 64}}, + {{ -9, 85}, {6, 47}, { -3, 64}, {0, 68}}, + {{ -13, 88}, {2, 55}, {2, 57}, { -5, 78}}, + {{4, 66}, {13, 41}, { -3, 65}, {7, 55}}, + {{ -3, 77}, {10, 44}, { -3, 66}, {5, 59}}, + {{ -3, 76}, {6, 50}, {0, 62}, {2, 65}}, + {{ -6, 76}, {5, 53}, {9, 51}, {14, 54}}, + {{10, 58}, {13, 49}, { -1, 66}, {15, 44}}, + {{ -1, 76}, {4, 63}, { -2, 71}, {5, 60}}, + {{ -1, 83}, {6, 64}, { -2, 75}, {2, 70}}, + {{ -7, 99}, { -2, 69}, { -1, 70}, { -2, 76}}, + {{ -14, 95}, { -2, 59}, { -9, 72}, { -18, 86}}, + {{2, 95}, {6, 70}, {14, 60}, {12, 70}}, + {{0, 76}, {10, 44}, {16, 37}, {5, 64}}, + {{ -5, 74}, {9, 31}, {0, 47}, { -12, 70}}, + {{0, 70}, {12, 43}, {18, 35}, {11, 55}}, + {{ -11, 75}, {3, 53}, {11, 37}, {5, 56}}, + {{1, 68}, {14, 34}, {12, 41}, {0, 69}}, + {{0, 65}, {10, 38}, {10, 41}, {2, 65}}, + {{ -14, 73}, { -3, 52}, {2, 48}, { -6, 74}}, + {{3, 62}, {13, 40}, {12, 41}, {5, 54}}, + {{4, 62}, {17, 32}, {13, 41}, {7, 54}}, + {{ -1, 68}, {7, 44}, {0, 59}, { -6, 76}}, + {{ -13, 75}, {7, 38}, {3, 50}, { -11, 82}}, + {{11, 55}, {13, 50}, {19, 40}, { -2, 77}}, + {{5, 64}, {10, 57}, {3, 66}, { -2, 77}}, + {{12, 70}, {26, 43}, {18, 50}, {25, 42}}, + //338-398 Table9-23 + {{15, 6}, {14, 11}, {19, -6}, {17, -13}}, + {{6, 19}, {11, 14}, {18, -6}, {16, -9}}, + {{7, 16}, {9, 11}, {14, 0}, {17, -12}}, + {{12, 14}, {18, 11}, {26, -12}, {27, -21}}, + {{18, 13}, {21, 9}, {31, -16}, {37, -30}}, + {{13, 11}, {23, -2}, {33, -25}, {41, -40}}, + {{13, 15}, {32, -15}, {33, -22}, {42, -41}}, + {{15, 16}, {32, -15}, {37, -28}, {48, -47}}, + {{12, 23}, {34, -21}, {39, -30}, {39, -32}}, + {{13, 23}, {39, -23}, {42, -30}, {46, -40}}, + {{15, 20}, {42, -33}, {47, -42}, {52, -51}}, + {{14, 26}, {41, -31}, {45, -36}, {46, -41}}, + {{14, 44}, {46, -28}, {49, -34}, {52, -39}}, + {{17, 40}, {38, -12}, {41, -17}, {43, -19}}, + {{17, 47}, {21, 29}, {32, 9}, {32, 11}}, + {{24, 17}, {45, -24}, {69, -71}, {61, -55}}, + {{21, 21}, {53, -45}, {63, -63}, {56, -46}}, + {{25, 22}, {48, -26}, {66, -64}, {62, -50}}, + {{31, 27}, {65, -43}, {77, -74}, {81, -67}}, + {{22, 29}, {43, -19}, {54, -39}, {45, -20}}, + {{19, 35}, {39, -10}, {52, -35}, {35, -2}}, + {{14, 50}, {30, 9}, {41, -10}, {28, 15}}, + {{10, 57}, {18, 26}, {36, 0}, {34, 1}}, + {{7, 63}, {20, 27}, {40, -1}, {39, 1}}, + {{ -2, 77}, {0, 57}, {30, 14}, {30, 17}}, + {{ -4, 82}, { -14, 82}, {28, 26}, {20, 38}}, + {{ -3, 94}, { -5, 75}, {23, 37}, {18, 45}}, + {{9, 69}, { -19, 97}, {12, 55}, {15, 54}}, + {{ -12, 109}, { -35, 125}, {11, 65}, {0, 79}}, + {{36, -35}, {27, 0}, {37, -33}, {36, -16}}, + {{36, -34}, {28, 0}, {39, -36}, {37, -14}}, + {{32, -26}, {31, -4}, {40, -37}, {37, -17}}, + {{37, -30}, {27, 6}, {38, -30}, {32, 1}}, + {{44, -32}, {34, 8}, {46, -33}, {34, 15}}, + {{34, -18}, {30, 10}, {42, -30}, {29, 15}}, + {{34, -15}, {24, 22}, {40, -24}, {24, 25}}, + {{40, -15}, {33, 19}, {49, -29}, {34, 22}}, + {{33, -7}, {22, 32}, {38, -12}, {31, 16}}, + {{35, -5}, {26, 31}, {40, -10}, {35, 18}}, + {{33, 0}, {21, 41}, {38, -3}, {31, 28}}, + {{38, 2}, {26, 44}, {46, -5}, {33, 41}}, + {{33, 13}, {23, 47}, {31, 20}, {36, 28}}, + {{23, 35}, {16, 65}, {29, 30}, {27, 47}}, + {{13, 58}, {14, 71}, {25, 44}, {21, 62}}, + {{29, -3}, {8, 60}, {12, 48}, {18, 31}}, + {{26, 0}, {6, 63}, {11, 49}, {19, 26}}, + {{22, 30}, {17, 65}, {26, 45}, {36, 24}}, + {{31, -7}, {21, 24}, {22, 22}, {24, 23}}, + {{35, -15}, {23, 20}, {23, 22}, {27, 16}}, + {{34, -3}, {26, 23}, {27, 21}, {24, 30}}, + {{34, 3}, {27, 32}, {33, 20}, {31, 29}}, + {{36, -1}, {28, 23}, {26, 28}, {22, 41}}, + {{34, 5}, {28, 24}, {30, 24}, {22, 42}}, + {{32, 11}, {23, 40}, {27, 34}, {16, 60}}, + {{35, 5}, {24, 32}, {18, 42}, {15, 52}}, + {{34, 12}, {28, 29}, {25, 39}, {14, 60}}, + {{39, 11}, {23, 42}, {18, 50}, {3, 78}}, + {{30, 29}, {19, 57}, {12, 70}, { -16, 123}}, + {{34, 26}, {22, 53}, {21, 54}, {21, 53}}, + {{29, 39}, {22, 61}, {14, 71}, {22, 56}}, + {{19, 66}, {11, 86}, {11, 83}, {25, 61}}, + {{31, 21}, {12, 40}, {25, 32}, {21, 33}}, + {{31, 31}, {11, 51}, {21, 49}, {19, 50}}, + {{25, 50}, {14, 59}, {21, 54}, {17, 61}}, + //402-459 Table 9-24 + {{ -17, 120}, { -4, 79}, { -5, 85}, { -3, 78}}, + {{ -20, 112}, { -7, 71}, { -6, 81}, { -8, 74}}, + {{ -18, 114}, { -5, 69}, { -10, 77}, { -9, 72}}, + {{ -11, 85}, { -9, 70}, { -7, 81}, { -10, 72}}, + {{ -15, 92}, { -8, 66}, { -17, 80}, { -18, 75}}, + {{ -14, 89}, { -10, 68}, { -18, 73}, { -12, 71}}, + {{ -26, 71}, { -19, 73}, { -4, 74}, { -11, 63}}, + {{ -15, 81}, { -12, 69}, { -10, 83}, { -5, 70}}, + {{ -14, 80}, { -16, 70}, { -9, 71}, { -17, 75}}, + {{0, 68}, { -15, 67}, { -9, 67}, { -14, 72}}, + {{ -14, 70}, { -20, 62}, { -1, 61}, { -16, 67}}, + {{ -24, 56}, { -19, 70}, { -8, 66}, { -8, 53}}, + {{ -23, 68}, { -16, 66}, { -14, 66}, { -14, 59}}, + {{ -24, 50}, { -22, 65}, {0, 59}, { -9, 52}}, + {{ -11, 74}, { -20, 63}, {2, 59}, { -11, 68}}, + {{23, -13}, {9, -2}, {17, -10}, {9, -2}}, + {{26, -13}, {26, -9}, {32, -13}, {30, -10}}, + {{40, -15}, {33, -9}, {42, -9}, {31, -4}}, + {{49, -14}, {39, -7}, {49, -5}, {33, -1}}, + {{44, 3}, {41, -2}, {53, 0}, {33, 7}}, + {{45, 6}, {45, 3}, {64, 3}, {31, 12}}, + {{44, 34}, {49, 9}, {68, 10}, {37, 23}}, + {{33, 54}, {45, 27}, {66, 27}, {31, 38}}, + {{19, 82}, {36, 59}, {47, 57}, {20, 64}}, + {{ -3, 75}, { -6, 66}, { -5, 71}, { -9, 71}}, + {{ -1, 23}, { -7, 35}, {0, 24}, { -7, 37}}, + {{1, 34}, { -7, 42}, { -1, 36}, { -8, 44}}, + {{1, 43}, { -8, 45}, { -2, 42}, { -11, 49}}, + {{0, 54}, { -5, 48}, { -2, 52}, { -10, 56}}, + {{ -2, 55}, { -12, 56}, { -9, 57}, { -12, 59}}, + {{0, 61}, { -6, 60}, { -6, 63}, { -8, 63}}, + {{1, 64}, { -5, 62}, { -4, 65}, { -9, 67}}, + {{0, 68}, { -8, 66}, { -4, 67}, { -6, 68}}, + {{ -9, 92}, { -8, 76}, { -7, 82}, { -10, 79}}, + {{ -14, 106}, { -5, 85}, { -3, 81}, { -3, 78}}, + {{ -13, 97}, { -6, 81}, { -3, 76}, { -8, 74}}, + {{ -15, 90}, { -10, 77}, { -7, 72}, { -9, 72}}, + {{ -12, 90}, { -7, 81}, { -6, 78}, { -10, 72}}, + {{ -18, 88}, { -17, 80}, { -12, 72}, { -18, 75}}, + {{ -10, 73}, { -18, 73}, { -14, 68}, { -12, 71}}, + {{ -9, 79}, { -4, 74}, { -3, 70}, { -11, 63}}, + {{ -14, 86}, { -10, 83}, { -6, 76}, { -5, 70}}, + {{ -10, 73}, { -9, 71}, { -5, 66}, { -17, 75}}, + {{ -10, 70}, { -9, 67}, { -5, 62}, { -14, 72}}, + {{ -10, 69}, { -1, 61}, {0, 57}, { -16, 67}}, + {{ -5, 66}, { -8, 66}, { -4, 61}, { -8, 53}}, + {{ -9, 64}, { -14, 66}, { -9, 60}, { -14, 59}}, + {{ -5, 58}, {0, 59}, {1, 54}, { -9, 52}}, + {{2, 59}, {2, 59}, {2, 58}, { -11, 68}}, + {{21, -10}, {21, -13}, {17, -10}, {9, -2}}, + {{24, -11}, {33, -14}, {32, -13}, {30, -10}}, + {{28, -8}, {39, -7}, {42, -9}, {31, -4}}, + {{28, -1}, {46, -2}, {49, -5}, {33, -1}}, + {{29, 3}, {51, 2}, {53, 0}, {33, 7}}, + {{29, 9}, {60, 6}, {64, 3}, {31, 12}}, + {{35, 20}, {61, 17}, {68, 10}, {37, 23}}, + {{29, 36}, {55, 34}, {66, 27}, {31, 38}}, + {{14, 67}, {42, 62}, {47, 57}, {20, 64}}, +}; + +/*Table 9-44 – Specification of rangeTabLPS depending on pStateIdx and qCodIRangeIdx */ + +const uint8_t g_kuiCabacRangeLps[64][4] = { + { 128, 176, 208, 240}, { 128, 167, 197, 227}, { 128, 158, 187, 216}, { 123, 150, 178, 205}, { 116, 142, 169, 195}, { 111, 135, 160, 185}, { 105, 128, 152, 175}, { 100, 122, 144, 166}, + { 95, 116, 137, 158}, { 90, 110, 130, 150}, { 85, 104, 123, 142}, { 81, 99, 117, 135}, { 77, 94, 111, 128}, { 73, 89, 105, 122}, { 69, 85, 100, 116}, { 66, 80, 95, 110}, + { 62, 76, 90, 104}, { 59, 72, 86, 99}, { 56, 69, 81, 94}, { 53, 65, 77, 89}, { 51, 62, 73, 85}, { 48, 59, 69, 80}, { 46, 56, 66, 76}, { 43, 53, 63, 72}, + { 41, 50, 59, 69}, { 39, 48, 56, 65}, { 37, 45, 54, 62}, { 35, 43, 51, 59}, { 33, 41, 48, 56}, { 32, 39, 46, 53}, { 30, 37, 43, 50}, { 29, 35, 41, 48}, + { 27, 33, 39, 45}, { 26, 31, 37, 43}, { 24, 30, 35, 41}, { 23, 28, 33, 39}, { 22, 27, 32, 37}, { 21, 26, 30, 35}, { 20, 24, 29, 33}, { 19, 23, 27, 31}, + { 18, 22, 26, 30}, { 17, 21, 25, 28}, { 16, 20, 23, 27}, { 15, 19, 22, 25}, { 14, 18, 21, 24}, { 14, 17, 20, 23}, { 13, 16, 19, 22}, { 12, 15, 18, 21}, + { 12, 14, 17, 20}, { 11, 14, 16, 19}, { 11, 13, 15, 18}, { 10, 12, 15, 17}, { 10, 12, 14, 16}, { 9, 11, 13, 15}, { 9, 11, 12, 14}, { 8, 10, 12, 14}, + { 8, 9, 11, 13}, { 7, 9, 11, 12}, { 7, 9, 10, 12}, { 7, 8, 10, 11}, { 6, 8, 9, 11}, { 6, 7, 9, 10}, { 6, 7, 8, 9}, { 2, 2, 2, 2} +}; + +/*Table 9-45 – State transition table*/ + +const uint8_t g_kuiStateTransTable[64][2] = { + + {0, 1}, {0, 2}, {1, 3}, {2, 4}, {2, 5}, {4, 6}, {4, 7}, {5, 8}, {6, 9}, {7, 10}, + + {8, 11}, {9, 12}, {9, 13}, {11, 14}, {11, 15}, {12, 16}, {13, 17}, {13, 18}, {15, 19}, {15, 20}, + + {16, 21}, {16, 22}, {18, 23}, {18, 24}, {19, 25}, {19, 26}, {21, 27}, {21, 28}, {22, 29}, {22, 30}, + + {23, 31}, {24, 32}, {24, 33}, {25, 34}, {26, 35}, {26, 36}, {27, 37}, {27, 38}, {28, 39}, {29, 40}, + + {29, 41}, {30, 42}, {30, 43}, {30, 44}, {31, 45}, {32, 46}, {32, 47}, {33, 48}, {33, 49}, {33, 50}, + + {34, 51}, {34, 52}, {35, 53}, {35, 54}, {35, 55}, {36, 56}, {36, 57}, {36, 58}, {37, 59}, {37, 60}, + + {37, 61}, {38, 62}, {38, 62}, {63, 63} + +}; +}//end of namespace \ No newline at end of file diff --git a/codec/encoder/core/src/encoder.cpp b/codec/encoder/core/src/encoder.cpp index df6790bb..5d7982bb 100644 --- a/codec/encoder/core/src/encoder.cpp +++ b/codec/encoder/core/src/encoder.cpp @@ -152,8 +152,9 @@ void WelsInitBGDFunc (SWelsFuncPtrList* pFuncList, const bool kbEnableBackground * \param pEncCtx sWelsEncCtx* * \return successful - 0; otherwise none 0 for failed */ -int32_t InitFunctionPointers (SWelsFuncPtrList* pFuncList, SWelsSvcCodingParam* pParam, uint32_t uiCpuFlag) { +int32_t InitFunctionPointers (sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* pParam, uint32_t uiCpuFlag) { int32_t iReturn = ENC_RETURN_SUCCESS; + SWelsFuncPtrList* pFuncList = pEncCtx->pFuncList; bool bScreenContent = (SCREEN_CONTENT_REAL_TIME == pParam->iUsageType); /* Functionality utilization of CPU instructions dependency */ @@ -209,7 +210,7 @@ int32_t InitFunctionPointers (SWelsFuncPtrList* pFuncList, SWelsSvcCodingParam* /*init pixel average function*/ /*get one column or row pixel when refinement*/ WelsInitMcFuncs (pFuncList, uiCpuFlag); - InitCoeffFunc (pFuncList, uiCpuFlag); + InitCoeffFunc (pFuncList,uiCpuFlag,pParam->iEntropyCodingModeFlag); WelsInitEncodingFuncs (pFuncList, uiCpuFlag); WelsInitReconstructionFuncs (pFuncList, uiCpuFlag); diff --git a/codec/encoder/core/src/encoder_ext.cpp b/codec/encoder/core/src/encoder_ext.cpp index 5c744f7c..3f6f58df 100644 --- a/codec/encoder/core/src/encoder_ext.cpp +++ b/codec/encoder/core/src/encoder_ext.cpp @@ -54,6 +54,7 @@ #include "crt_util_safe_x.h" // Safe CRT routines like utils for cross platforms #include "slice_multi_threading.h" #include "measure_time.h" +#include "svc_set_mb_syn.h" namespace WelsEnc { @@ -947,7 +948,7 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) { } // initialize pPps - WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps); + WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps,pParam->iEntropyCodingModeFlag); // Not using FMO in SVC coding so far, come back if need FMO { @@ -2053,7 +2054,7 @@ int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPar FreeMemorySvc (&pCtx); return 1; } - InitFunctionPointers (pCtx->pFuncList, pCtx->pSvcParam, uiCpuFeatureFlags); + InitFunctionPointers (pCtx, pCtx->pSvcParam, uiCpuFeatureFlags); pCtx->iActiveThreadsNum = pCodingParam->iCountThreadsNum; pCtx->iMaxSliceCount = iSliceNum; @@ -2067,6 +2068,8 @@ int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPar if (pCodingParam->iMultipleThreadIdc > 1) iRet = CreateSliceThreads (pCtx); + if(pCodingParam->iEntropyCodingModeFlag) + WelsCabacInit (pCtx); WelsRcInitModule (pCtx, pCtx->pSvcParam->iRCMode); pCtx->pVpp = new CWelsPreProcess (pCtx); diff --git a/codec/encoder/core/src/set_mb_syn_cabac.cpp b/codec/encoder/core/src/set_mb_syn_cabac.cpp new file mode 100644 index 00000000..eae2c063 --- /dev/null +++ b/codec/encoder/core/src/set_mb_syn_cabac.cpp @@ -0,0 +1,240 @@ +/*! + * \copy + * Copyright (c) 2009-2013, Cisco Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * \file set_mb_syn_cabac.cpp + * + * \brief cabac coding engine + * + * \date 10/11/2014 Created + * + ************************************************************************************* + */ +#include +#include "typedefs.h" +#include "macros.h" +#include "wels_common_defs.h" +#include "set_mb_syn_cabac.h" +#include "encoder.h" + +namespace WelsEnc { + + +void WelsCabacInit (void* pCtx) { + sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; + for (int32_t iModel = 0; iModel < 4; iModel++) { + for (int32_t iQp = 0; iQp <= WELS_QP_MAX; iQp++) + for (int32_t iIdx = 0; iIdx < WELS_CONTEXT_COUNT; iIdx++) { + int32_t m = g_kiCabacGlobalContextIdx[iIdx][iModel][0]; + int32_t n = g_kiCabacGlobalContextIdx[iIdx][iModel][1]; + int32_t iPreCtxState = WELS_CLIP3 ((((m * iQp) >> 4) + n), 1, 126); + uint8_t uiValMps = 0; + uint8_t uiStateIdx = 0; + if (iPreCtxState <= 63) { + uiStateIdx = 63 - iPreCtxState; + uiValMps = 0; + } else { + uiStateIdx = iPreCtxState - 64; + uiValMps = 1; + } + pEncCtx->sWelsCabacContexts[iModel][iQp][iIdx].m_uiState = uiStateIdx; + pEncCtx->sWelsCabacContexts[iModel][iQp][iIdx].m_uiValMps = uiValMps; + } + } +} + +void WelsCabacContextInit (void* pCtx, SCabacCtx* pCbCtx, int32_t iModel) { + sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; + int32_t iIdx = pEncCtx->eSliceType == WelsCommon::I_SLICE ? 0 : iModel + 1; + int32_t iQp = pEncCtx->iGlobalQp; + memcpy (pCbCtx->m_sStateCtx, pEncCtx->sWelsCabacContexts[iIdx][iQp], + WELS_CONTEXT_COUNT * sizeof (SStateCtx)); +} + +void WelsCabacEncodeInit (SCabacCtx* pCbCtx, uint8_t* pBuf, uint8_t* pEnd) { + pCbCtx->m_uiLow = 0; + pCbCtx->m_uiRange = 510; + pCbCtx->m_iBitsOutstanding = 0; + pCbCtx->m_uData = 0; + pCbCtx->m_uiBitsUsed = 0; + pCbCtx->m_iFirstFlag = 1; + pCbCtx->m_pBufStart = pBuf; + pCbCtx->m_pBufEnd = pEnd; + pCbCtx->m_pBufCur = pBuf; + pCbCtx->m_uiBinCountsInNalUnits = 0; +} + +void WelsCabacPutBit (SCabacCtx* pCbCtx, uint32_t iValue) { + if (pCbCtx->m_iFirstFlag != 0) { + pCbCtx->m_iFirstFlag = 0; + } else { + pCbCtx->m_uData = (pCbCtx->m_uData << 1) | iValue; + pCbCtx->m_uiBitsUsed++; + } + if (pCbCtx->m_iBitsOutstanding == 0) { + while (pCbCtx->m_uiBitsUsed >= 8) { + pCbCtx->m_uiBitsUsed -= 8; + uint32_t uiByte = pCbCtx->m_uData >> (pCbCtx->m_uiBitsUsed); + if (pCbCtx->m_uiBitsUsed == 0) + pCbCtx->m_uData = 0; + else + pCbCtx->m_uData &= (uint32_t) ((0xFFFFFFFF) >> (32 - pCbCtx->m_uiBitsUsed)); + *pCbCtx->m_pBufCur ++ = uiByte; + } + } else { + + while (pCbCtx->m_iBitsOutstanding > 0) { + pCbCtx->m_uData = (pCbCtx->m_uData << 1) | (1 - iValue); + pCbCtx->m_iBitsOutstanding--; + pCbCtx->m_uiBitsUsed++; + while (pCbCtx->m_uiBitsUsed >= 8) { + pCbCtx->m_uiBitsUsed -= 8; + uint32_t uiByte = pCbCtx->m_uData >> (pCbCtx->m_uiBitsUsed); + if (pCbCtx->m_uiBitsUsed == 0) + pCbCtx->m_uData = 0; + else + pCbCtx->m_uData &= (uint32_t) ((0xFFFFFFFF) >> (32 - pCbCtx->m_uiBitsUsed)); + *pCbCtx->m_pBufCur ++ = uiByte; + } + } + } +} +void WelsCabacEncodeRenorm (SCabacCtx* pCbCtx) { + while (pCbCtx->m_uiRange < 256) { + if (pCbCtx->m_uiLow < 256) { + WelsCabacPutBit (pCbCtx, 0); + } else { + if (pCbCtx->m_uiLow >= 512) { + pCbCtx->m_uiLow -= 512; + WelsCabacPutBit (pCbCtx, 1); + } else { + pCbCtx->m_uiLow -= 256; + pCbCtx->m_iBitsOutstanding++; + } + } + pCbCtx->m_uiRange <<= 1; + pCbCtx->m_uiLow <<= 1; + } +} +void WelsCabacEncodeDecision (SCabacCtx* pCbCtx, int32_t iCtx, uint32_t uiBin) { + uint8_t uiState = pCbCtx->m_sStateCtx[iCtx].m_uiState; + uint8_t uiValMps = pCbCtx->m_sStateCtx[iCtx].m_uiValMps; + uint32_t uiRangeLps = g_kuiCabacRangeLps[uiState][ (pCbCtx->m_uiRange >> 6) & 3]; + + pCbCtx->m_uiRange -= uiRangeLps; + if (uiBin != uiValMps) { //LPS + pCbCtx->m_uiLow += pCbCtx->m_uiRange; + pCbCtx->m_uiRange = uiRangeLps; + if (uiState == 0) + uiValMps = 1 - uiValMps; + pCbCtx->m_sStateCtx[iCtx].m_uiState = g_kuiStateTransTable[uiState][0]; + pCbCtx->m_sStateCtx[iCtx].m_uiValMps = uiValMps; + } else { + pCbCtx->m_sStateCtx[iCtx].m_uiState = g_kuiStateTransTable[uiState][1]; + } + WelsCabacEncodeRenorm (pCbCtx); + pCbCtx->m_uiBinCountsInNalUnits++; +} + +void WelsCabacEncodeBypassOne (SCabacCtx* pCbCtx, uint32_t uiBin) { + pCbCtx->m_uiLow <<= 1; + if (uiBin) { + pCbCtx->m_uiLow += pCbCtx->m_uiRange; + } + if (pCbCtx->m_uiLow >= 1024) { + WelsCabacPutBit (pCbCtx, 1); + pCbCtx->m_uiLow -= 1024; + } else { + if (pCbCtx->m_uiLow < 512) + WelsCabacPutBit (pCbCtx, 0); + else { + pCbCtx->m_uiLow -= 512; + pCbCtx->m_iBitsOutstanding++; + } + } + pCbCtx->m_uiBinCountsInNalUnits++; +} +void WelsCabacEncodeTerminate (SCabacCtx* pCbCtx, uint32_t uiBin) { + pCbCtx->m_uiRange -= 2; + if (uiBin) { + pCbCtx->m_uiLow += pCbCtx->m_uiRange; + pCbCtx->m_uiRange = 2; + WelsCabacEncodeRenorm (pCbCtx); + WelsCabacPutBit (pCbCtx, ((pCbCtx->m_uiLow >> 9) & 1)); + int32_t iLastTwoBits = (((pCbCtx->m_uiLow >> 7) & 3) | 1); + pCbCtx->m_uData = (pCbCtx->m_uData << 2) | iLastTwoBits; + pCbCtx->m_uiBitsUsed += 2; + } else { + WelsCabacEncodeRenorm (pCbCtx); + } + pCbCtx->m_uiBinCountsInNalUnits++; +} +void WelsCabacEncodeUeBypass (SCabacCtx* pCbCtx, int32_t iExpBits, uint32_t uiVal) { + int32_t iSufS = uiVal; + int32_t iStopLoop = 0; + int32_t k = iExpBits; + do { + if (iSufS >= (1 << k)) { + WelsCabacEncodeBypassOne (pCbCtx, 1); + iSufS = iSufS - (1 << k); + k++; + } else { + WelsCabacEncodeBypassOne (pCbCtx, 0); + while (k--) + WelsCabacEncodeBypassOne (pCbCtx, (iSufS >> k) & 1); + iStopLoop = 1; + } + } while (!iStopLoop); +} + +void WelsCabacEncodeFlush (SCabacCtx* pCbCtx) { + WelsCabacEncodeTerminate (pCbCtx, 1); + while (pCbCtx->m_uiBitsUsed > 0) { + if (pCbCtx->m_uiBitsUsed > 8) { + pCbCtx->m_uiBitsUsed -= 8; + uint32_t uiByte = pCbCtx->m_uData >> (pCbCtx->m_uiBitsUsed); + pCbCtx->m_uData &= (uint32_t) ((0xFFFFFFFF) >> (32 - pCbCtx->m_uiBitsUsed)); + *pCbCtx->m_pBufCur ++ = uiByte; + } else { + if (pCbCtx->m_uiBitsUsed == 8) { + *pCbCtx->m_pBufCur ++ = pCbCtx->m_uData & 0xff; + } else { + *pCbCtx->m_pBufCur ++ = (pCbCtx->m_uData << (8 - pCbCtx->m_uiBitsUsed)); + } + pCbCtx->m_uiBitsUsed = 0; + } + } + +} + +uint8_t* WelsCabacEncodeGetPtr (SCabacCtx* pCbCtx) { + return pCbCtx->m_pBufCur; +} +} diff --git a/codec/encoder/core/src/set_mb_syn_cavlc.cpp b/codec/encoder/core/src/set_mb_syn_cavlc.cpp index 8d0e010f..b9d4a1c8 100644 --- a/codec/encoder/core/src/set_mb_syn_cavlc.cpp +++ b/codec/encoder/core/src/set_mb_syn_cavlc.cpp @@ -38,7 +38,7 @@ ************************************************************************************* */ -#include "set_mb_syn_cavlc.h" +#include "svc_set_mb_syn.h" #include "vlc_encoder.h" #include "cpu_core.h" #include "wels_const.h" @@ -199,8 +199,47 @@ int32_t WriteBlockResidualCavlc (SWelsFuncPtrList* pFuncList, int16_t* pCoffLev return ENC_RETURN_SUCCESS; } +void StashMBStatusCavlc (SDynamicSlicingStack* pDss, void* pBuffer, SSlice* pSlice, int32_t iMbSkipRun) { + SBitStringAux* pBs = (SBitStringAux*)pBuffer; + pDss->pBsStackBufPtr = pBs->pBufPtr; + pDss->uiBsStackCurBits = pBs->uiCurBits; + pDss->iBsStackLeftBits = pBs->iLeftBits; + pDss->uiLastMbQp = pSlice->uiLastMbQp; + pDss->iMbSkipRunStack = iMbSkipRun; +} +int32_t StashPopMBStatusCavlc (SDynamicSlicingStack* pDss, void* pBuffer, SSlice* pSlice) { + SBitStringAux* pBs = (SBitStringAux*)pBuffer; + pBs->pBufPtr = pDss->pBsStackBufPtr; + pBs->uiCurBits = pDss->uiBsStackCurBits; + pBs->iLeftBits = pDss->iBsStackLeftBits; + pSlice->uiLastMbQp = pDss->uiLastMbQp; + return pDss->iMbSkipRunStack; +} +void StashMBStatusCabac (SDynamicSlicingStack* pDss, void* pBuffer, SSlice* pSlice, int32_t iMbSkipRun) { + SCabacCtx* pCtx = (SCabacCtx*)pBuffer; + memcpy (&pDss->sStoredCabac, pCtx, sizeof (SCabacCtx)); + pDss->uiLastMbQp = pSlice->uiLastMbQp; + pDss->iMbSkipRunStack = iMbSkipRun; +} +int32_t StashPopMBStatusCabac (SDynamicSlicingStack* pDss, void* pBuffer, SSlice* pSlice) { + SCabacCtx* pCtx = (SCabacCtx*)pBuffer; + memcpy (pCtx, &pDss->sStoredCabac, sizeof (SCabacCtx)); + pSlice->uiLastMbQp = pDss->uiLastMbQp; + return pDss->iMbSkipRunStack; +} -void InitCoeffFunc (SWelsFuncPtrList* pFuncList, const uint32_t uiCpuFlag) { +void WelsWriteSliceEndSyn (SSlice* pSlice, bool bEntropyCodingModeFlag) { + SBitStringAux* pBs = pSlice->pSliceBsa; + if (bEntropyCodingModeFlag) { + WelsCabacEncodeFlush (&pSlice->sCabacCtx); + pBs->pBufPtr = WelsCabacEncodeGetPtr (&pSlice->sCabacCtx); + + } else { + BsRbspTrailingBits (pBs); + BsFlush (pBs); + } +} +void InitCoeffFunc (SWelsFuncPtrList* pFuncList, const uint32_t uiCpuFlag,int32_t iEntropyCodingModeFlag) { pFuncList->pfCavlcParamCal = CavlcParamCal_c; #if defined(X86_ASM) @@ -208,6 +247,17 @@ void InitCoeffFunc (SWelsFuncPtrList* pFuncList, const uint32_t uiCpuFlag) { // pFuncList->pfCavlcParamCal = CavlcParamCal_sse2; } #endif + if (iEntropyCodingModeFlag) { + pFuncList->pfStashMBStatus = StashMBStatusCabac; + pFuncList->pfStashPopMBStatus = StashPopMBStatusCabac; + pFuncList->pfWelsSpatialWriteMbSyn = WelsSpatialWriteMbSynCabac; + } else { + pFuncList->pfStashMBStatus = StashMBStatusCavlc; + pFuncList->pfStashPopMBStatus = StashPopMBStatusCavlc; + pFuncList->pfWelsSpatialWriteMbSyn = WelsSpatialWriteMbSyn; + + } } + } // namespace WelsEnc diff --git a/codec/encoder/core/src/svc_base_layer_md.cpp b/codec/encoder/core/src/svc_base_layer_md.cpp index a8daaf10..10fdd3b5 100644 --- a/codec/encoder/core/src/svc_base_layer_md.cpp +++ b/codec/encoder/core/src/svc_base_layer_md.cpp @@ -1617,7 +1617,7 @@ bool WelsMdFirstIntraMode (void* pEnc, void* pMd, SMB* pCurMb, SMbCache* pMbCach //chroma pWelsMd->iCostChroma = WelsMdIntraChroma (pFunc, pEncCtx->pCurDqLayer, pMbCache, pWelsMd->iLambda); WelsIMbChromaEncode (pEncCtx, pCurMb, pMbCache); //add pEnc&rec to MD--2010.3.15 - + pCurMb->uiChromPredMode = pMbCache->uiChmaI8x8Mode; pCurMb->pSadCost[0] = 0; return true; //intra_mb_type is best } @@ -1806,6 +1806,7 @@ void WelsMdIntraSecondaryModesEnc (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB* //chroma pWelsMd->iCostChroma = WelsMdIntraChroma (pFunc, pEncCtx->pCurDqLayer, pMbCache, pWelsMd->iLambda); WelsIMbChromaEncode (pEncCtx, pCurMb, pMbCache); //add pEnc&rec to MD--2010.3.15 + pCurMb->uiChromPredMode = pMbCache->uiChmaI8x8Mode; pCurMb->pSadCost[0] = 0; } diff --git a/codec/encoder/core/src/svc_encode_slice.cpp b/codec/encoder/core/src/svc_encode_slice.cpp index 7c7d362f..5fb34c0a 100644 --- a/codec/encoder/core/src/svc_encode_slice.cpp +++ b/codec/encoder/core/src/svc_encode_slice.cpp @@ -43,7 +43,7 @@ #include "svc_enc_golomb.h" #include "svc_base_layer_md.h" #include "svc_encode_mb.h" -#include "svc_set_mb_syn_cavlc.h" +#include "svc_set_mb_syn.h" #include "decode_mb_aux.h" #include "svc_mode_decision.h" @@ -270,6 +270,9 @@ void WelsSliceHeaderWrite (SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSli WriteRefPicMarking (pBs, pSliceHeader, pNalHead); } + if (pPps->bEntropyCodingModeFlag && pSliceHeader->eSliceType != I_SLICE) { + BsWriteUE (pBs, pSlice->iCabacInitIdc); + } BsWriteSE (pBs, pSliceHeader->iSliceQpDelta); /* pSlice qp delta */ if (pPps->bDeblockingFilterControlPresentFlag) { @@ -338,6 +341,11 @@ void WelsSliceHeaderExtWrite (SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* p } // } + + if (pPps->bEntropyCodingModeFlag && pSliceHeader->eSliceType != I_SLICE) { + BsWriteUE (pBs, pSlice->iCabacInitIdc); + } + BsWriteSE (pBs, pSliceHeader->iSliceQpDelta); /* pSlice qp delta */ if (pPps->bDeblockingFilterControlPresentFlag) { @@ -460,21 +468,7 @@ void OutputPMbWithoutConstructCsRsNoCopy (sWelsEncCtx* pCtx, SDqLayer* pDq, SSli pfIdctFour4x4 (pDecV, kiDecStrideChroma, pDecV, kiDecStrideChroma, pScaledTcoeff + 320); } } -inline void StashMBStatus (SDynamicSlicingStack* pDss, SBitStringAux* pBs, SSlice* pSlice, int32_t iMbSkipRun = 0) { - pDss->pBsStackBufPtr = pBs->pBufPtr; - pDss->uiBsStackCurBits = pBs->uiCurBits; - pDss->iBsStackLeftBits = pBs->iLeftBits; - pDss->uiLastMbQp = pSlice->uiLastMbQp; - pDss->iMbSkipRunStack = iMbSkipRun; -} -void StashPopMBStatus (SDynamicSlicingStack* pDss, SBitStringAux* pBs, SSlice* pSlice, int32_t* pMbSkipRun = 0) { - pBs->pBufPtr = pDss->pBsStackBufPtr; - pBs->uiCurBits = pDss->uiBsStackCurBits; - pBs->iLeftBits = pDss->iBsStackLeftBits; - pSlice->uiLastMbQp = pDss->uiLastMbQp; - if (pMbSkipRun) - *pMbSkipRun = pDss->iMbSkipRunStack; -} + void UpdateQpForOverflow (SMB* pCurMb, uint8_t kuiChromaQpIndexOffset) { pCurMb->uiLumaQp += DELTA_QP; pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + kuiChromaQpIndexOffset)]; @@ -501,8 +495,11 @@ int32_t WelsISliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice) { //pMd + encodin int32_t iEncReturn = ENC_RETURN_SUCCESS; SBitStringAux* pBs = pSlice->pSliceBsa; SDynamicSlicingStack sDss; + if (pEncCtx->pSvcParam->iEntropyCodingModeFlag) { + WelsInitSliceCabac (pEncCtx, pSlice); + } for (; ;) { - StashMBStatus (&sDss, pBs, pSlice); + pEncCtx->pFuncList->pfStashMBStatus (&sDss, pBs, pSlice, 0); iCurMbIdx = iNextMbIdx; pCurMb = &pMbList[ iCurMbIdx ]; @@ -514,9 +511,10 @@ TRY_REENCODING: WelsMdIntraMb (pEncCtx, &sMd, pCurMb, pMbCache); UpdateNonZeroCountCache (pCurMb, pMbCache); - iEncReturn = WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb); + + iEncReturn = pEncCtx->pFuncList->pfWelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb); if (iEncReturn == ENC_RETURN_VLCOVERFLOWFOUND) { - StashPopMBStatus (&sDss, pBs, pSlice); + pEncCtx->pFuncList->pfStashPopMBStatus (&sDss, pBs, pSlice); UpdateQpForOverflow (pCurMb, kuiChromaQpIndexOffset); goto TRY_REENCODING; } @@ -562,12 +560,14 @@ int32_t WelsISliceMdEncDynamic (sWelsEncCtx* pEncCtx, SSlice* pSlice) { //pMd + SWelsMD sMd; SDynamicSlicingStack sDss; sDss.iStartPos = BsGetBitsPos (pBs); - + if (pEncCtx->pSvcParam->iEntropyCodingModeFlag) { + WelsInitSliceCabac (pEncCtx, pSlice); + } for (; ;) { iCurMbIdx = iNextMbIdx; pCurMb = &pMbList[ iCurMbIdx ]; - StashMBStatus (&sDss, pBs, pSlice); + pEncCtx->pFuncList->pfStashMBStatus (&sDss, pBs, pSlice, 0); pEncCtx->pFuncList->pfRc.pfWelsRcMbInit (pEncCtx, pCurMb, pSlice); // if already reaches the largest number of slices, set QPs to the upper bound if (pSlice->bDynamicSlicingSliceSizeCtrlFlag) { @@ -581,9 +581,9 @@ TRY_REENCODING: WelsMdIntraMb (pEncCtx, &sMd, pCurMb, pMbCache); UpdateNonZeroCountCache (pCurMb, pMbCache); - iEncReturn = WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb); + iEncReturn = pEncCtx->pFuncList->pfWelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb); if (iEncReturn == ENC_RETURN_VLCOVERFLOWFOUND) { - StashPopMBStatus (&sDss, pBs, pSlice); + pEncCtx->pFuncList->pfStashPopMBStatus (&sDss, pBs, pSlice); UpdateQpForOverflow (pCurMb, kuiChromaQpIndexOffset); goto TRY_REENCODING; } @@ -593,7 +593,7 @@ TRY_REENCODING: sDss.iCurrentPos = BsGetBitsPos (pBs); if (DynSlcJudgeSliceBoundaryStepBack (pEncCtx, pSlice, pSliceCtx, pCurMb, &sDss)) { //islice - StashPopMBStatus (&sDss, pBs, pSlice); + pEncCtx->pFuncList->pfStashPopMBStatus (&sDss, pBs, pSlice); pCurLayer->pLastCodedMbIdxOfPartition[kiPartitionId] = iCurMbIdx - 1; // update pLastCodedMbIdxOfPartition, need to -1 due to stepping back ++ pCurLayer->pNumSliceCodedOfPartition[kiPartitionId]; @@ -749,7 +749,7 @@ int32_t WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const if (ENC_RETURN_SUCCESS != iEncReturn) return iEncReturn; - BsRbspTrailingBits (pBs); + WelsWriteSliceEndSyn (pCurSlice, pEncCtx->pSvcParam->iEntropyCodingModeFlag); return ENC_RETURN_SUCCESS; } @@ -942,7 +942,6 @@ int32_t WelsMdInterMbLoop (sWelsEncCtx* pEncCtx, SSlice* pSlice, void* pWelsMd, int32_t iNumMbCoded = 0; int32_t iNextMbIdx = kiSliceFirstMbXY; int32_t iCurMbIdx = -1; - int32_t iMbSkipRun = 0; const int32_t kiTotalNumMb = pCurLayer->iMbWidth * pCurLayer->iMbHeight; const int32_t kiMvdInterTableStride = pEncCtx->iMvdCostTableStride; uint16_t* pMvdCostTable = &pEncCtx->pMvdCostTable[pEncCtx->iMvdCostTableSize]; @@ -950,8 +949,12 @@ int32_t WelsMdInterMbLoop (sWelsEncCtx* pEncCtx, SSlice* pSlice, void* pWelsMd, const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset; int32_t iEncReturn = ENC_RETURN_SUCCESS; SDynamicSlicingStack sDss; + if (pEncCtx->pSvcParam->iEntropyCodingModeFlag) { + WelsInitSliceCabac (pEncCtx, pSlice); + } + pSlice->iMbSkipRun = 0; for (;;) { - StashMBStatus (&sDss, pBs, pSlice, iMbSkipRun); + pEncCtx->pFuncList->pfStashMBStatus (&sDss, pBs, pSlice, pSlice->iMbSkipRun); //point to current pMb iCurMbIdx = iNextMbIdx; pCurMb = &pMbList[ iCurMbIdx ]; @@ -979,23 +982,16 @@ TRY_REENCODING: UpdateNonZeroCountCache (pCurMb, pMbCache); //step (6): begin to write bit stream; if the pSlice size is controlled, the writing may be skipped - if (IS_SKIP (pCurMb->uiMbType)) { - pCurMb->uiLumaQp = pSlice->uiLastMbQp; - pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + kuiChromaQpIndexOffset)]; - iMbSkipRun++; - } else { - BsWriteUE (pBs, iMbSkipRun); - iMbSkipRun = 0; - iEncReturn = WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb); - if (iEncReturn == ENC_RETURN_VLCOVERFLOWFOUND) { - StashPopMBStatus (&sDss, pBs, pSlice, &iMbSkipRun); - UpdateQpForOverflow (pCurMb, kuiChromaQpIndexOffset); - goto TRY_REENCODING; - } - if (ENC_RETURN_SUCCESS != iEncReturn) - return iEncReturn; + iEncReturn = pEncCtx->pFuncList->pfWelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb); + if (iEncReturn == ENC_RETURN_VLCOVERFLOWFOUND) { + pSlice->iMbSkipRun = pEncCtx->pFuncList->pfStashPopMBStatus (&sDss, pBs, pSlice); + UpdateQpForOverflow (pCurMb, kuiChromaQpIndexOffset); + goto TRY_REENCODING; } + if (ENC_RETURN_SUCCESS != iEncReturn) + return iEncReturn; + //step (7): reconstruct current MB pCurMb->uiSliceIdc = kiSliceIdx; @@ -1017,8 +1013,8 @@ TRY_REENCODING: } } - if (iMbSkipRun) { - BsWriteUE (pBs, iMbSkipRun); + if (pSlice->iMbSkipRun) { + BsWriteUE (pBs, pSlice->iMbSkipRun); } return iEncReturn; @@ -1038,7 +1034,6 @@ int32_t WelsMdInterMbLoopOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice, const int32_t kiTotalNumMb = pCurLayer->iMbWidth * pCurLayer->iMbHeight; int32_t iNextMbIdx = kiSliceFirstMbXY; int32_t iCurMbIdx = -1; - int32_t iMbSkipRun = 0; const int32_t kiMvdInterTableStride = pEncCtx->iMvdCostTableStride; uint16_t* pMvdCostTable = &pEncCtx->pMvdCostTable[pEncCtx->iMvdCostTableSize]; const int32_t kiSliceIdx = pSlice->uiSliceIdx; @@ -1048,10 +1043,14 @@ int32_t WelsMdInterMbLoopOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice, SDynamicSlicingStack sDss; sDss.iStartPos = BsGetBitsPos (pBs); + if (pEncCtx->pSvcParam->iEntropyCodingModeFlag) { + WelsInitSliceCabac (pEncCtx, pSlice); + } + pSlice->iMbSkipRun = 0; for (;;) { //DYNAMIC_SLICING_ONE_THREAD - MultiD //stack pBs pointer - StashMBStatus (&sDss, pBs, pSlice, iMbSkipRun); + pEncCtx->pFuncList->pfStashMBStatus (&sDss, pBs, pSlice, pSlice->iMbSkipRun); //point to current pMb iCurMbIdx = iNextMbIdx; @@ -1088,28 +1087,22 @@ TRY_REENCODING: //step (6): begin to write bit stream; if the pSlice size is controlled, the writing may be skipped - if (IS_SKIP (pCurMb->uiMbType)) { - pCurMb->uiLumaQp = pSlice->uiLastMbQp; - pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + kuiChromaQpIndexOffset)]; - iMbSkipRun++; - } else { - BsWriteUE (pBs, iMbSkipRun); - iMbSkipRun = 0; - iEncReturn = WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb); - if (iEncReturn == ENC_RETURN_VLCOVERFLOWFOUND) { - StashPopMBStatus (&sDss, pBs, pSlice, &iMbSkipRun); - UpdateQpForOverflow (pCurMb, kuiChromaQpIndexOffset); - goto TRY_REENCODING; - } - if (ENC_RETURN_SUCCESS != iEncReturn) - return iEncReturn; + + iEncReturn = pEncCtx->pFuncList->pfWelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb); + if (iEncReturn == ENC_RETURN_VLCOVERFLOWFOUND) { + pSlice->iMbSkipRun = pEncCtx->pFuncList->pfStashPopMBStatus (&sDss, pBs, pSlice); + UpdateQpForOverflow (pCurMb, kuiChromaQpIndexOffset); + goto TRY_REENCODING; } + if (ENC_RETURN_SUCCESS != iEncReturn) + return iEncReturn; + //DYNAMIC_SLICING_ONE_THREAD - MultiD sDss.iCurrentPos = BsGetBitsPos (pBs); if (DynSlcJudgeSliceBoundaryStepBack (pEncCtx, pSlice, pSliceCtx, pCurMb, &sDss)) { - StashPopMBStatus (&sDss, pBs, pSlice, &iMbSkipRun); + pSlice->iMbSkipRun = pEncCtx->pFuncList->pfStashPopMBStatus (&sDss, pBs, pSlice); pCurLayer->pLastCodedMbIdxOfPartition[kiPartitionId] = iCurMbIdx - 1; // update pLastCodedMbIdxOfPartition, need to -1 due to stepping back ++ pCurLayer->pNumSliceCodedOfPartition[kiPartitionId]; @@ -1139,8 +1132,8 @@ TRY_REENCODING: } } - if (iMbSkipRun) { - BsWriteUE (pBs, iMbSkipRun); + if (pSlice->iMbSkipRun) { + BsWriteUE (pBs, pSlice->iMbSkipRun); } return iEncReturn; diff --git a/codec/encoder/core/src/svc_set_mb_syn_cabac.cpp b/codec/encoder/core/src/svc_set_mb_syn_cabac.cpp new file mode 100644 index 00000000..38d75866 --- /dev/null +++ b/codec/encoder/core/src/svc_set_mb_syn_cabac.cpp @@ -0,0 +1,691 @@ +/*! + * \copy + * Copyright (c) 2009-2013, Cisco Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * \file svc_set_mb_syn_cabac.cpp + * + * \brief wrtie cabac syntax + * + * \date 9/28/2014 Created + * + ************************************************************************************* + */ +#include "svc_set_mb_syn.h" +#include "set_mb_syn_cabac.h" +#include "svc_enc_golomb.h" + +namespace WelsEnc { + +static const uint16_t uiSignificantCoeffFlagOffset[5] = {0, 15, 29, 44, 47}; +static const uint16_t uiLastCoeffFlagOffset[5] = {0, 15, 29, 44, 47}; +static const uint16_t uiCoeffAbsLevelMinus1Offset[5] = {0, 10, 20, 30, 39}; +static const uint16_t uiCodecBlockFlagOffset[5] = {0, 4, 8, 12, 16}; + + +static void WelsCabacMbType (SCabacCtx* pCabacCtx, SMB* pCurMb, SMbCache* pMbCache, int32_t iMbWidth, + EWelsSliceType eSliceType) { + + if (eSliceType == I_SLICE) { + uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail; + SMB* pLeftMb = pCurMb - 1 ; + SMB* pTopMb = pCurMb - iMbWidth; + int32_t iCtx = 3; + if ((uiNeighborAvail & LEFT_MB_POS) && !IS_INTRA4x4 (pLeftMb->uiMbType)) + iCtx++; + if ((uiNeighborAvail & TOP_MB_POS) && !IS_INTRA4x4 (pTopMb->uiMbType)) //TOP MB + iCtx++; + + if (pCurMb->uiMbType == MB_TYPE_INTRA4x4) { + WelsCabacEncodeDecision (pCabacCtx, iCtx, 0); + } else { + int32_t iCbpChroma = pCurMb->uiCbp >> 4; + int32_t iCbpLuma = pCurMb->uiCbp & 15; + int32_t iPredMode = g_kiMapModeI16x16[pMbCache->uiLumaI16x16Mode]; + + WelsCabacEncodeDecision (pCabacCtx, iCtx, 1); + WelsCabacEncodeTerminate (pCabacCtx, 0); + if (iCbpLuma) + WelsCabacEncodeDecision (pCabacCtx, 6, 1); + else + WelsCabacEncodeDecision (pCabacCtx, 6, 0); + + if (iCbpChroma == 0) + WelsCabacEncodeDecision (pCabacCtx, 7, 0); + else { + WelsCabacEncodeDecision (pCabacCtx, 7, 1); + WelsCabacEncodeDecision (pCabacCtx, 8, iCbpChroma >> 1); + } + WelsCabacEncodeDecision (pCabacCtx, 9, iPredMode >> 1); + WelsCabacEncodeDecision (pCabacCtx, 10, iPredMode & 1); + } + } else if (eSliceType == P_SLICE) { + uint32_t uiMbType = pCurMb->uiMbType; + if (uiMbType == MB_TYPE_16x16) { + WelsCabacEncodeDecision (pCabacCtx, 14, 0); + WelsCabacEncodeDecision (pCabacCtx, 15, 0); + WelsCabacEncodeDecision (pCabacCtx, 16, 0); + } else if ((uiMbType == MB_TYPE_16x8) || (uiMbType == MB_TYPE_8x16)) { + + WelsCabacEncodeDecision (pCabacCtx, 14, 0); + WelsCabacEncodeDecision (pCabacCtx, 15, 1); + WelsCabacEncodeDecision (pCabacCtx, 17, pCurMb->uiMbType == MB_TYPE_16x8); + + } else if ((uiMbType == MB_TYPE_8x8) || (uiMbType == MB_TYPE_8x8_REF0)) { + WelsCabacEncodeDecision (pCabacCtx, 14, 0); + WelsCabacEncodeDecision (pCabacCtx, 15, 0); + WelsCabacEncodeDecision (pCabacCtx, 16, 1); + } else if (pCurMb->uiMbType == MB_TYPE_INTRA4x4) { + WelsCabacEncodeDecision (pCabacCtx, 14, 1); + WelsCabacEncodeDecision (pCabacCtx, 17, 0); + } else { + + int32_t iCbpChroma = pCurMb->uiCbp >> 4; + int32_t iCbpLuma = pCurMb->uiCbp & 15; + int32_t iPredMode = g_kiMapModeI16x16[pMbCache->uiLumaI16x16Mode]; + //prefix + WelsCabacEncodeDecision (pCabacCtx, 14, 1); + + //suffix + WelsCabacEncodeDecision (pCabacCtx, 17, 1); + WelsCabacEncodeTerminate (pCabacCtx, 0); + if (iCbpLuma) + WelsCabacEncodeDecision (pCabacCtx, 18, 1); + else + WelsCabacEncodeDecision (pCabacCtx, 18, 0); + if (iCbpChroma == 0) + WelsCabacEncodeDecision (pCabacCtx, 19, 0); + else { + WelsCabacEncodeDecision (pCabacCtx, 19, 1); + WelsCabacEncodeDecision (pCabacCtx, 19, iCbpChroma >> 1); + } + WelsCabacEncodeDecision (pCabacCtx, 20, iPredMode >> 1); + WelsCabacEncodeDecision (pCabacCtx, 20, iPredMode & 1); + + } + } + +} +void WelsCabacMbIntra4x4PredMode (SCabacCtx* pCabacCtx, SMbCache* pMbCache) { + + for (int32_t iMode = 0; iMode < 16; iMode++) { + + bool bPredFlag = pMbCache->pPrevIntra4x4PredModeFlag[iMode]; + int8_t iRemMode = pMbCache->pRemIntra4x4PredModeFlag[iMode]; + + if (bPredFlag) + WelsCabacEncodeDecision (pCabacCtx, 68, 1); + else { + WelsCabacEncodeDecision (pCabacCtx, 68, 0); + + WelsCabacEncodeDecision (pCabacCtx, 69, iRemMode & 0x01); + WelsCabacEncodeDecision (pCabacCtx, 69, (iRemMode >> 1) & 0x01); + WelsCabacEncodeDecision (pCabacCtx, 69, (iRemMode >> 2)); + } + } +} + +void WelsCabacMbIntraChromaPredMode (SCabacCtx* pCabacCtx, SMB* pCurMb, SMbCache* pMbCache, int32_t iMbWidth) { + uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail; + SMB* pLeftMb = pCurMb - 1 ; + SMB* pTopMb = pCurMb - iMbWidth; + + int32_t iPredMode = g_kiMapModeIntraChroma[pMbCache->uiChmaI8x8Mode]; + int32_t iCtx = 64; + if ((uiNeighborAvail & LEFT_MB_POS) && g_kiMapModeIntraChroma[pLeftMb->uiChromPredMode] != 0) + iCtx++; + if ((uiNeighborAvail & TOP_MB_POS) && g_kiMapModeIntraChroma[pTopMb->uiChromPredMode] != 0) + iCtx++; + + if (iPredMode == 0) { + WelsCabacEncodeDecision (pCabacCtx, iCtx, 0); + } else if (iPredMode == 1) { + WelsCabacEncodeDecision (pCabacCtx, iCtx, 1); + WelsCabacEncodeDecision (pCabacCtx, 67, 0); + } else if (iPredMode == 2) { + WelsCabacEncodeDecision (pCabacCtx, iCtx, 1); + WelsCabacEncodeDecision (pCabacCtx, 67, 1); + WelsCabacEncodeDecision (pCabacCtx, 67, 0); + } else { + WelsCabacEncodeDecision (pCabacCtx, iCtx, 1); + WelsCabacEncodeDecision (pCabacCtx, 67, 1); + WelsCabacEncodeDecision (pCabacCtx, 67, 1); + } +} + +void WelsCabacMbCbp (SMB* pCurMb, int32_t iMbWidth, SCabacCtx* pCabacCtx) { + int32_t iCbpBlockLuma[4] = { (pCurMb->uiCbp) & 1, (pCurMb->uiCbp >> 1) & 1, (pCurMb->uiCbp >> 2) & 1, (pCurMb->uiCbp >> 3) & 1}; + int32_t iCbpChroma = pCurMb->uiCbp >> 4; + int32_t iCbpBlockLeft[4] = {0, 0, 0, 0}; + int32_t iCbpBlockTop[4] = {0, 0, 0, 0}; + int32_t iCbpLeftChroma = 0; + int32_t iCbpTopChroma = 0; + int32_t iCbp = 0; + int32_t iCtx = 0; + uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail; + if (uiNeighborAvail & LEFT_MB_POS) { + iCbp = (pCurMb - 1)->uiCbp; + iCbpBlockLeft[0] = ! (iCbp & 1); + iCbpBlockLeft[1] = ! ((iCbp >> 1) & 1); + iCbpBlockLeft[2] = ! ((iCbp >> 2) & 1); + iCbpBlockLeft[3] = ! ((iCbp >> 3) & 1); + iCbpLeftChroma = iCbp >> 4; + if (iCbpLeftChroma) + iCtx += 1; + } + if (uiNeighborAvail & TOP_MB_POS) { + iCbp = (pCurMb - iMbWidth)->uiCbp; + iCbpBlockTop[0] = ! (iCbp & 1); + iCbpBlockTop[1] = ! ((iCbp >> 1) & 1); + iCbpBlockTop[2] = ! ((iCbp >> 2) & 1); + iCbpBlockTop[3] = ! ((iCbp >> 3) & 1); + iCbpTopChroma = iCbp >> 4; + if (iCbpTopChroma) + iCtx += 2; + } + WelsCabacEncodeDecision (pCabacCtx, 73 + iCbpBlockLeft[1] + iCbpBlockTop[2] * 2, iCbpBlockLuma[0]); + WelsCabacEncodeDecision (pCabacCtx, 73 + !iCbpBlockLuma[0] + iCbpBlockTop[3] * 2, iCbpBlockLuma[1]); + WelsCabacEncodeDecision (pCabacCtx, 73 + iCbpBlockLeft[3] + (!iCbpBlockLuma[0]) * 2 , iCbpBlockLuma[2]); + WelsCabacEncodeDecision (pCabacCtx, 73 + !iCbpBlockLuma[2] + (!iCbpBlockLuma[1]) * 2, iCbpBlockLuma[3]); + + + //chroma + if (iCbpChroma) { + WelsCabacEncodeDecision (pCabacCtx, 77 + iCtx, 1); + WelsCabacEncodeDecision (pCabacCtx, 81 + (iCbpLeftChroma >> 1) + ((iCbpTopChroma >> 1) * 2), iCbpChroma > 1); + } else { + WelsCabacEncodeDecision (pCabacCtx, 77 + iCtx, 0); + } +} + +void WelsCabacMbDeltaQp (SMB* pCurMb, SCabacCtx* pCabacCtx) { + SMB* pPrevMb = NULL; + int32_t iCtx = 0; + uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail; + + if ((uiNeighborAvail & LEFT_MB_POS) || (uiNeighborAvail & TOP_MB_POS)) { + pPrevMb = pCurMb - 1; + pCurMb->iLumaDQp = pCurMb->uiLumaQp - pPrevMb->uiLumaQp; + + if (IS_SKIP (pPrevMb->uiMbType) || ((pPrevMb->uiMbType != MB_TYPE_INTRA16x16) && (!pPrevMb->uiCbp)) + || (!pPrevMb->iLumaDQp)) + iCtx = 0; + else + iCtx = 1; + } + + if (pCurMb->iLumaDQp) { + int32_t iValue = pCurMb->iLumaDQp < 0 ? (-2 * pCurMb->iLumaDQp) : (2 * pCurMb->iLumaDQp - 1); + WelsCabacEncodeDecision (pCabacCtx, 60 + iCtx, 1); + if (iValue == 1) { + WelsCabacEncodeDecision (pCabacCtx, 60 + 2, 0); + } else { + WelsCabacEncodeDecision (pCabacCtx, 60 + 2, 1); + iValue--; + while ((--iValue) > 0) + WelsCabacEncodeDecision (pCabacCtx, 60 + 3, 1); + WelsCabacEncodeDecision (pCabacCtx, 60 + 3, 0); + } + } else { + WelsCabacEncodeDecision (pCabacCtx, 60 + iCtx, 0); + } +} + +void WelsMbSkipCabac (SCabacCtx* pCabacCtx, SMB* pCurMb, int32_t iMbWidth, EWelsSliceType eSliceType, + int16_t bSkipFlag) { + int32_t iCtx = (eSliceType == P_SLICE) ? 11 : 24; + uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail; + if (uiNeighborAvail & LEFT_MB_POS) { //LEFT MB + if (!IS_SKIP ((pCurMb - 1)->uiMbType)) + iCtx++; + } + if (uiNeighborAvail & TOP_MB_POS) { //TOP MB + if (!IS_SKIP ((pCurMb - iMbWidth)->uiMbType)) + iCtx++; + } + WelsCabacEncodeDecision (pCabacCtx, iCtx, bSkipFlag); + + if (bSkipFlag) { + for (int i = 0; i < 4; i++) { + + pCurMb->sMvd[i].iMvX = 0; + pCurMb->sMvd[i].iMvY = 0; + } + pCurMb->uiCbp = pCurMb->iCbpDc = 0; + } +} + +void WelsCabacMbRef (SCabacCtx* pCabacCtx, SMB* pCurMb, SMbCache* pMbCache, int16_t iIdx) { + SMVComponentUnit* pMvComp = &pMbCache->sMvComponents; + const int16_t iRefIdxA = pMvComp->iRefIndexCache[iIdx + 6]; + const int16_t iRefIdxB = pMvComp->iRefIndexCache[iIdx + 1]; + int16_t iRefIdx = pMvComp->iRefIndexCache[iIdx + 7]; + int16_t iCtx = 0; + + if ((iRefIdxA > 0) && (!pMbCache->bMbTypeSkip[3])) + iCtx++; + if ((iRefIdxB > 0) && (!pMbCache->bMbTypeSkip[1])) + iCtx += 2; + + while (iRefIdx > 0) { + WelsCabacEncodeDecision (pCabacCtx, 54 + iCtx, 1); + iCtx = (iCtx >> 2) + 4; + iRefIdx--; + } + WelsCabacEncodeDecision (pCabacCtx, 54 + iCtx, 0); +} + +inline void WelsCabacMbMvdLx (SCabacCtx* pCabacCtx, int32_t sMvd, int32_t iCtx, int32_t iPredMvd) { + const int32_t iAbsMvd = WELS_ABS (sMvd); + int32_t iCtxInc = 0; + int32_t iPrefix = WELS_MIN (iAbsMvd, 9); + int32_t i = 0; + + if (iPredMvd > 32) + iCtxInc += 2; + else if (iPredMvd > 2) + iCtxInc += 1; + + if (iPrefix) { + if (iPrefix < 9) { + WelsCabacEncodeDecision (pCabacCtx, iCtx + iCtxInc, 1); + iCtxInc = 3; + for (i = 0; i < iPrefix - 1; i++) { + WelsCabacEncodeDecision (pCabacCtx, iCtx + iCtxInc, 1); + if (i < 3) + iCtxInc++; + } + WelsCabacEncodeDecision (pCabacCtx, iCtx + iCtxInc, 0); + WelsCabacEncodeBypassOne (pCabacCtx, sMvd < 0); + } else { + WelsCabacEncodeDecision (pCabacCtx, iCtx + iCtxInc, 1); + iCtxInc = 3; + for (i = 0; i < (9 - 1); i++) { + WelsCabacEncodeDecision (pCabacCtx, iCtx + iCtxInc, 1); + if (i < 3) + iCtxInc++; + } + WelsCabacEncodeUeBypass (pCabacCtx, 3, iAbsMvd - 9); + WelsCabacEncodeBypassOne (pCabacCtx, sMvd < 0); + } + } else { + WelsCabacEncodeDecision (pCabacCtx, iCtx + iCtxInc, 0); + } +} +SMVUnitXY WelsCabacMbMvd (SCabacCtx* pCabacCtx, SMB* pCurMb, uint32_t iMbWidth, + SMVUnitXY sCurMv, SMVUnitXY sPredMv, int16_t iBlockIdx) { + uint32_t iAbsMvd0, iAbsMvd1; + uint8_t uiNeighborAvail = pCurMb->uiNeighborAvail; + SMVUnitXY sMvd; + SMVUnitXY sMvdLeft; + SMVUnitXY sMvdTop; + + sMvdLeft.iMvX = sMvdLeft.iMvY = sMvdTop.iMvX = sMvdTop.iMvY = 0; + sMvd.sDeltaMv (sCurMv, sPredMv); + + if (((iBlockIdx == 0) || (iBlockIdx == 1)) && (uiNeighborAvail & TOP_MB_POS)) { + sMvdTop.sAssginMv ((pCurMb - iMbWidth)->sMvd[iBlockIdx + 2]); + } + if ((iBlockIdx == 2) || (iBlockIdx == 3)) { + sMvdTop.sAssginMv (pCurMb->sMvd[iBlockIdx - 2]); + } + if (((iBlockIdx == 0) || (iBlockIdx == 2)) && (uiNeighborAvail & LEFT_MB_POS)) { + sMvdLeft.sAssginMv ((pCurMb - 1)->sMvd[iBlockIdx + 1]); + } + if ((iBlockIdx == 1) || (iBlockIdx == 3)) { + sMvdLeft.sAssginMv (pCurMb->sMvd[iBlockIdx - 1]); + } + + iAbsMvd0 = WELS_ABS (sMvdLeft.iMvX) + WELS_ABS (sMvdTop.iMvX); + iAbsMvd1 = WELS_ABS (sMvdLeft.iMvY) + WELS_ABS (sMvdTop.iMvY); + + WelsCabacMbMvdLx (pCabacCtx, sMvd.iMvX, 40, iAbsMvd0); + WelsCabacMbMvdLx (pCabacCtx, sMvd.iMvY, 47, iAbsMvd1); + return sMvd; +} + +int16_t WelsGetMbCtxCabac (SMbCache* pMbCache, SMB* pCurMb, uint32_t iMbWidth, ECtxBlockCat eCtxBlockCat, + int16_t iIdx) { + int16_t iNzA = -1, iNzB = -1; + int8_t* pNonZeroCoeffCount = pMbCache->iNonZeroCoeffCount; + int32_t bIntra = IS_INTRA (pCurMb->uiMbType); + int32_t iCtxInc = 0; + switch (eCtxBlockCat) { + case LUMA_AC: + case CHROMA_AC: + case LUMA_4x4: + iNzA = pNonZeroCoeffCount[iIdx - 1]; + iNzB = pNonZeroCoeffCount[iIdx - 8]; + break; + case LUMA_DC: + case CHROMA_DC: + if (pCurMb->uiNeighborAvail & LEFT_MB_POS) + iNzA = (pCurMb - 1)->iCbpDc & (1 << iIdx); + if (pCurMb->uiNeighborAvail & TOP_MB_POS) + iNzB = (pCurMb - iMbWidth)->iCbpDc & (1 << iIdx); + break; + default: + break; + } + if (((iNzA == -1) && bIntra) || (iNzA > 0)) + iCtxInc += 1; + if (((iNzB == -1) && bIntra) || (iNzB > 0)) + iCtxInc += 2; + return 85 + uiCodecBlockFlagOffset[eCtxBlockCat] + iCtxInc; +} + +void WelsWriteBlockResidualCabac (SMbCache* pMbCache, SMB* pCurMb, uint32_t iMbWidth, SCabacCtx* pCabacCtx, + ECtxBlockCat eCtxBlockCat, int16_t iIdx, int16_t iNonZeroCount, int16_t* pBlock, int16_t iEndIdx) { + int32_t iCtx = WelsGetMbCtxCabac (pMbCache, pCurMb, iMbWidth, eCtxBlockCat, iIdx); + if (iNonZeroCount) { + ENFORCE_STACK_ALIGN_1D (int16_t, iAbsLevel, 16, 16); + ENFORCE_STACK_ALIGN_1D (int16_t, iSignLevel, 16, 16); + const int32_t iCtxSig = 105 + uiSignificantCoeffFlagOffset[eCtxBlockCat]; + const int32_t iCtxLast = 166 + uiLastCoeffFlagOffset[eCtxBlockCat]; + const int32_t iCtxLevel = 227 + uiCoeffAbsLevelMinus1Offset[eCtxBlockCat]; + int32_t iNonZeroIdx = 0; + int32_t i = 0; + int32_t iNumAbsLevelEq1 = 0; + int32_t iNumAbsLevelGt1 = 0; + + WelsCabacEncodeDecision (pCabacCtx, iCtx, 1); + while (1) { + if (pBlock[i]) { + iSignLevel[iNonZeroIdx] = pBlock[i] < 0; + iAbsLevel[iNonZeroIdx] = WELS_ABS (pBlock[i]) - 1; + + iNonZeroIdx++; + WelsCabacEncodeDecision (pCabacCtx, iCtxSig + i, 1); + if (iNonZeroIdx != iNonZeroCount) + WelsCabacEncodeDecision (pCabacCtx, iCtxLast + i, 0); + else { + WelsCabacEncodeDecision (pCabacCtx, iCtxLast + i, 1); + break; + } + } else + WelsCabacEncodeDecision (pCabacCtx, iCtxSig + i, 0); + i++; + if (i == iEndIdx) { + iSignLevel[iNonZeroIdx] = pBlock[i] < 0; + iAbsLevel[iNonZeroIdx] = WELS_ABS (pBlock[i]) - 1; + iNonZeroIdx++; + break; + } + } + do { + int32_t iPrefix = 0; + iNonZeroIdx--; + iPrefix = WELS_MIN (iAbsLevel[iNonZeroIdx], 14); + if (iPrefix) { + iCtx = iCtxLevel + ((iNumAbsLevelGt1 != 0) ? 0 : WELS_MIN (4, 1 + iNumAbsLevelEq1)); + WelsCabacEncodeDecision (pCabacCtx, iCtx, 1); + iCtx = iCtxLevel + 5 + WELS_MIN (4 - (eCtxBlockCat == CHROMA_DC), iNumAbsLevelGt1); + for (i = 0; i < iPrefix - 1; i++) + WelsCabacEncodeDecision (pCabacCtx, iCtx, 1); + if (iPrefix < 14) + WelsCabacEncodeDecision (pCabacCtx, iCtx, 0); + else + WelsCabacEncodeUeBypass (pCabacCtx, 0, iAbsLevel[iNonZeroIdx] - 14); + iNumAbsLevelGt1++; + } else { + iCtx = iCtxLevel + ((iNumAbsLevelGt1 != 0) ? 0 : WELS_MIN (4, 1 + iNumAbsLevelEq1)); + WelsCabacEncodeDecision (pCabacCtx, iCtx, 0); + iNumAbsLevelEq1++; + } + WelsCabacEncodeBypassOne (pCabacCtx, iSignLevel[iNonZeroIdx]); + } while (iNonZeroIdx > 0); + + } else { + WelsCabacEncodeDecision (pCabacCtx, iCtx, 0); + } + + +} +int32_t WelsCalNonZeroCount (int16_t* pBlock, int16_t iNum) { + int32_t iCount = 0; + for (int16_t i = 0; i < iNum; i++) { + if (pBlock[i]) + iCount++; + } + return iCount; +} +int32_t WelsWriteMbResidualCabac (SSlice* pSlice, SMbCache* sMbCacheInfo, SMB* pCurMb, SCabacCtx* pCabacCtx, + int16_t iMbWidth, uint32_t uiChromaQpIndexOffset) { + + const uint16_t uiMbType = pCurMb->uiMbType; + SMbCache* pMbCache = &pSlice->sMbCacheInfo; + int16_t i = 0; + int8_t* pNonZeroCoeffCount = pMbCache->iNonZeroCoeffCount; + + + pCurMb->iCbpDc = 0; + pCurMb->iLumaDQp = 0; + + if ((pCurMb->uiCbp > 0) || (uiMbType == MB_TYPE_INTRA16x16)) { + int32_t iCbpChroma = pCurMb->uiCbp >> 4; + int32_t iCbpLuma = pCurMb->uiCbp & 15; + + pCurMb->iLumaDQp = pCurMb->uiLumaQp - pSlice->uiLastMbQp; + WelsCabacMbDeltaQp (pCurMb, pCabacCtx); + pSlice->uiLastMbQp = pCurMb->uiLumaQp; + + if (uiMbType == MB_TYPE_INTRA16x16) { + //Luma DC + int iNonZeroCount = WelsCalNonZeroCount (pMbCache->pDct->iLumaI16x16Dc, 16); + WelsWriteBlockResidualCabac (pMbCache, pCurMb, iMbWidth, pCabacCtx, LUMA_DC, 0, iNonZeroCount, + pMbCache->pDct->iLumaI16x16Dc, 15); + if (iNonZeroCount) + pCurMb->iCbpDc |= 1; + //Luma AC + + if (iCbpLuma) { + for (i = 0; i < 16; i++) { + int32_t iIdx = g_kuiCache48CountScan4Idx[i]; + WelsWriteBlockResidualCabac (pMbCache, pCurMb, iMbWidth, pCabacCtx, LUMA_AC, iIdx, + pNonZeroCoeffCount[iIdx], pMbCache->pDct->iLumaBlock[i], 14); + } + } + } else { + //Luma AC + for (i = 0; i < 16; i++) { + if (iCbpLuma & (1 << (i >> 2))) { + int32_t iIdx = g_kuiCache48CountScan4Idx[i]; + WelsWriteBlockResidualCabac (pMbCache, pCurMb, iMbWidth, pCabacCtx, LUMA_4x4, iIdx, + pNonZeroCoeffCount[iIdx], pMbCache->pDct->iLumaBlock[i], 15); + } + + } + } + + if (iCbpChroma) { + int32_t iNonZeroCount = 0; + //chroma DC + iNonZeroCount = WelsCalNonZeroCount (pMbCache->pDct->iChromaDc[0], 4); + if (iNonZeroCount) + pCurMb->iCbpDc |= 0x2; + WelsWriteBlockResidualCabac (pMbCache, pCurMb, iMbWidth, pCabacCtx, CHROMA_DC, 1, iNonZeroCount, + pMbCache->pDct->iChromaDc[0], 3); + + iNonZeroCount = WelsCalNonZeroCount (pMbCache->pDct->iChromaDc[1], 4); + if (iNonZeroCount) + pCurMb->iCbpDc |= 0x4; + WelsWriteBlockResidualCabac (pMbCache, pCurMb, iMbWidth, pCabacCtx, CHROMA_DC, 2, iNonZeroCount, + pMbCache->pDct->iChromaDc[1], 3); + if (iCbpChroma & 0x02) { + const uint8_t* g_kuiCache48CountScan4Idx_16base = &g_kuiCache48CountScan4Idx[16]; + //Cb AC + for (i = 0; i < 4; i++) { + int32_t iIdx = g_kuiCache48CountScan4Idx_16base[i]; + WelsWriteBlockResidualCabac (pMbCache, pCurMb, iMbWidth, pCabacCtx, CHROMA_AC, iIdx, + pNonZeroCoeffCount[iIdx], pMbCache->pDct->iChromaBlock[i], 14); + + } + + //Cr AC + + for (i = 0; i < 4; i++) { + int32_t iIdx = 24 + g_kuiCache48CountScan4Idx_16base[i]; + WelsWriteBlockResidualCabac (pMbCache, pCurMb, iMbWidth, pCabacCtx, CHROMA_AC, iIdx, + pNonZeroCoeffCount[iIdx], pMbCache->pDct->iChromaBlock[4 + i], 14); + } + } + } + } else { + pCurMb->uiLumaQp = pSlice->uiLastMbQp; + pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + uiChromaQpIndexOffset)]; + } + return 0; +} + +void WelsInitSliceCabac (sWelsEncCtx* pEncCtx, SSlice* pSlice) { + /* alignment needed */ + SBitStringAux* pBs = pSlice->pSliceBsa; + BsAlign (pBs); + + /* init cabac */ + WelsCabacContextInit (pEncCtx, &pSlice->sCabacCtx, pSlice->iCabacInitIdc); + WelsCabacEncodeInit (&pSlice->sCabacCtx, pBs->pBufPtr, pBs->pBufEnd); +} + +int32_t WelsSpatialWriteMbSynCabac (void* pCtx, SSlice* pSlice, SMB* pCurMb) { + sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; + SCabacCtx* pCabacCtx = &pSlice->sCabacCtx; + SMbCache* pMbCache = &pSlice->sMbCacheInfo; + const uint16_t uiMbType = pCurMb->uiMbType; + SSliceHeaderExt* pSliceHeadExt = &pSlice->sSliceHeaderExt; + uint32_t uiNumRefIdxL0Active = pSliceHeadExt->sSliceHeader.uiNumRefIdxL0Active - 1; + const int32_t iSliceFirstMbXY = pSliceHeadExt->sSliceHeader.iFirstMbInSlice; + int16_t i = 0; + int16_t iMbWidth = pEncCtx->pCurDqLayer->iMbWidth; + uint32_t uiChromaQpIndexOffset = pEncCtx->pCurDqLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset; + SMVUnitXY sMvd; + int32_t iRet = 0; + if (pCurMb->iMbXY > iSliceFirstMbXY) + WelsCabacEncodeTerminate (&pSlice->sCabacCtx, 0); + + if (IS_SKIP (pCurMb->uiMbType)) { + pCurMb->uiLumaQp = pSlice->uiLastMbQp; + pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + uiChromaQpIndexOffset)]; + WelsMbSkipCabac (&pSlice->sCabacCtx, pCurMb, iMbWidth, pEncCtx->eSliceType, 1); + + } else { + //skip flag + if (pEncCtx->eSliceType != I_SLICE) + WelsMbSkipCabac (&pSlice->sCabacCtx, pCurMb, iMbWidth, pEncCtx->eSliceType, 0); + + //write mb type + WelsCabacMbType (pCabacCtx, pCurMb, pMbCache, iMbWidth, pEncCtx->eSliceType); + + if (IS_INTRA (uiMbType)) { + if (uiMbType == MB_TYPE_INTRA4x4) { + WelsCabacMbIntra4x4PredMode (pCabacCtx, pMbCache); + } + WelsCabacMbIntraChromaPredMode (pCabacCtx, pCurMb, pMbCache, iMbWidth); + sMvd.iMvX = sMvd.iMvY = 0; + pCurMb->sMvd[0].sAssginMv (sMvd); + pCurMb->sMvd[1].sAssginMv (sMvd); + pCurMb->sMvd[2].sAssginMv (sMvd); + pCurMb->sMvd[3].sAssginMv (sMvd); + + } else if (uiMbType == MB_TYPE_16x16) { + + if (uiNumRefIdxL0Active > 0) { + WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 0); + } + sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, iMbWidth, pCurMb->sMv[0], pMbCache->sMbMvp[0], 0); + + pCurMb->sMvd[0].sAssginMv (sMvd); + pCurMb->sMvd[1].sAssginMv (sMvd); + pCurMb->sMvd[2].sAssginMv (sMvd); + pCurMb->sMvd[3].sAssginMv (sMvd); + + } else if (uiMbType == MB_TYPE_16x8) { + if (uiNumRefIdxL0Active > 0) { + WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 0); + WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 12); + } + sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, iMbWidth , pCurMb->sMv[0], pMbCache->sMbMvp[0], 0); + pCurMb->sMvd[0].sAssginMv (sMvd); + pCurMb->sMvd[1].sAssginMv (sMvd); + + + sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, iMbWidth, pCurMb->sMv[8], pMbCache->sMbMvp[1], 2); + pCurMb->sMvd[2].sAssginMv (sMvd); + pCurMb->sMvd[3].sAssginMv (sMvd); + + } else if (uiMbType == MB_TYPE_8x16) { + if (uiNumRefIdxL0Active > 0) { + WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 0); + WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 2); + } + sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, iMbWidth, pCurMb->sMv[0], pMbCache->sMbMvp[0], 0); + pCurMb->sMvd[0].sAssginMv (sMvd); + pCurMb->sMvd[2].sAssginMv (sMvd); + + sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, iMbWidth, pCurMb->sMv[2], pMbCache->sMbMvp[1], 1); + pCurMb->sMvd[1].sAssginMv (sMvd); + pCurMb->sMvd[3].sAssginMv (sMvd); + + } else if ((uiMbType == MB_TYPE_8x8) || (uiMbType == MB_TYPE_8x8_REF0)) { + for (i = 0; i < 4; i++) + WelsCabacEncodeDecision (pCabacCtx, 21, 1); + + if (uiNumRefIdxL0Active > 0) { + WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 0); + WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 2); + WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 12); + WelsCabacMbRef (pCabacCtx, pCurMb, pMbCache, 14); + } + + + sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, iMbWidth, pCurMb->sMv[0], pMbCache->sMbMvp[0], 0); + pCurMb->sMvd[0].sAssginMv (sMvd); + + sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, iMbWidth, pCurMb->sMv[2], pMbCache->sMbMvp[1], 1); + pCurMb->sMvd[1].sAssginMv (sMvd); + + sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, iMbWidth, pCurMb->sMv[8], pMbCache->sMbMvp[2], 2); + pCurMb->sMvd[2].sAssginMv (sMvd); + + sMvd = WelsCabacMbMvd (pCabacCtx, pCurMb, iMbWidth, pCurMb->sMv[10], pMbCache->sMbMvp[3], 3); + pCurMb->sMvd[3].sAssginMv (sMvd); + } + if (uiMbType != MB_TYPE_INTRA16x16) { + WelsCabacMbCbp (pCurMb, iMbWidth, pCabacCtx); + } + iRet = WelsWriteMbResidualCabac (pSlice, pMbCache, pCurMb, pCabacCtx, iMbWidth, uiChromaQpIndexOffset); + } + if (!IS_INTRA (pCurMb->uiMbType)) + pCurMb->uiChromPredMode = 0; + + return iRet; +} + + +} diff --git a/codec/encoder/core/src/svc_set_mb_syn_cavlc.cpp b/codec/encoder/core/src/svc_set_mb_syn_cavlc.cpp index e3b50180..bc36aa2b 100644 --- a/codec/encoder/core/src/svc_set_mb_syn_cavlc.cpp +++ b/codec/encoder/core/src/svc_set_mb_syn_cavlc.cpp @@ -40,7 +40,7 @@ #include "vlc_encoder.h" #include "ls_defines.h" -#include "svc_set_mb_syn_cavlc.h" +#include "svc_set_mb_syn.h" namespace WelsEnc { const uint32_t g_kuiIntra4x4CbpMap[48] = { @@ -220,40 +220,54 @@ int32_t CheckBitstreamBuffer (const uint32_t kuiSliceIdx, sWelsEncCtx* pEncCtx, } //============================Base Layer CAVLC Writing=============================== -int32_t WelsSpatialWriteMbSyn (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb) { +int32_t WelsSpatialWriteMbSyn (void* pCtx, SSlice* pSlice, SMB* pCurMb) { + sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; SBitStringAux* pBs = pSlice->pSliceBsa; SMbCache* pMbCache = &pSlice->sMbCacheInfo; + const uint8_t kuiChromaQpIndexOffset = pEncCtx->pCurDqLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset; - /* Step 1: write mb type and pred */ - if (IS_Inter_8x8 (pCurMb->uiMbType)) { - WelsSpatialWriteSubMbPred (pEncCtx, pSlice, pCurMb); + if (IS_SKIP (pCurMb->uiMbType)) { + pCurMb->uiLumaQp = pSlice->uiLastMbQp; + pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + kuiChromaQpIndexOffset)]; + + pSlice->iMbSkipRun++; + return ENC_RETURN_SUCCESS; } else { - WelsSpatialWriteMbPred (pEncCtx, pSlice, pCurMb); + if (pEncCtx->eSliceType != I_SLICE) { + BsWriteUE (pBs, pSlice->iMbSkipRun); + pSlice->iMbSkipRun = 0; + } + /* Step 1: write mb type and pred */ + if (IS_Inter_8x8 (pCurMb->uiMbType)) { + WelsSpatialWriteSubMbPred (pEncCtx, pSlice, pCurMb); + } else { + WelsSpatialWriteMbPred (pEncCtx, pSlice, pCurMb); + } + + /* Step 2: write coded block patern */ + if (IS_INTRA4x4 (pCurMb->uiMbType)) { + BsWriteUE (pBs, g_kuiIntra4x4CbpMap[pCurMb->uiCbp]); + } else if (!IS_INTRA16x16 (pCurMb->uiMbType)) { + BsWriteUE (pBs, g_kuiInterCbpMap[pCurMb->uiCbp]); + } + + /* Step 3: write QP and residual */ + if (pCurMb->uiCbp > 0 || IS_INTRA16x16 (pCurMb->uiMbType)) { + const int32_t kiDeltaQp = pCurMb->uiLumaQp - pSlice->uiLastMbQp; + pSlice->uiLastMbQp = pCurMb->uiLumaQp; + + BsWriteSE (pBs, kiDeltaQp); + if (WelsWriteMbResidual (pEncCtx->pFuncList, pMbCache, pCurMb, pBs)) + return ENC_RETURN_VLCOVERFLOWFOUND; + } else { + pCurMb->uiLumaQp = pSlice->uiLastMbQp; + pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + + pEncCtx->pCurDqLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset)]; + } + + /* Step 4: Check the left buffer */ + return CheckBitstreamBuffer (pSlice->uiSliceIdx, pEncCtx, pBs); } - - /* Step 2: write coded block patern */ - if (IS_INTRA4x4 (pCurMb->uiMbType)) { - BsWriteUE (pBs, g_kuiIntra4x4CbpMap[pCurMb->uiCbp]); - } else if (!IS_INTRA16x16 (pCurMb->uiMbType)) { - BsWriteUE (pBs, g_kuiInterCbpMap[pCurMb->uiCbp]); - } - - /* Step 3: write QP and residual */ - if (pCurMb->uiCbp > 0 || IS_INTRA16x16 (pCurMb->uiMbType)) { - const int32_t kiDeltaQp = pCurMb->uiLumaQp - pSlice->uiLastMbQp; - pSlice->uiLastMbQp = pCurMb->uiLumaQp; - - BsWriteSE (pBs, kiDeltaQp); - if (WelsWriteMbResidual (pEncCtx->pFuncList, pMbCache, pCurMb, pBs)) - return ENC_RETURN_VLCOVERFLOWFOUND; - } else { - pCurMb->uiLumaQp = pSlice->uiLastMbQp; - pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp + - pEncCtx->pCurDqLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset)]; - } - - /* Step 4: Check the left buffer */ - return CheckBitstreamBuffer (pSlice->uiSliceIdx, pEncCtx, pBs); } int32_t WelsWriteMbResidual (SWelsFuncPtrList* pFuncList, SMbCache* sMbCacheInfo, SMB* pCurMb, SBitStringAux* pBs) { diff --git a/codec/encoder/targets.mk b/codec/encoder/targets.mk index 62a47f9d..0147bedc 100644 --- a/codec/encoder/targets.mk +++ b/codec/encoder/targets.mk @@ -1,6 +1,7 @@ ENCODER_SRCDIR=codec/encoder ENCODER_CPP_SRCS=\ $(ENCODER_SRCDIR)/core/src/au_set.cpp\ + $(ENCODER_SRCDIR)/core/src/cabac.cpp\ $(ENCODER_SRCDIR)/core/src/deblocking.cpp\ $(ENCODER_SRCDIR)/core/src/decode_mb_aux.cpp\ $(ENCODER_SRCDIR)/core/src/encode_mb_aux.cpp\ @@ -18,6 +19,7 @@ ENCODER_CPP_SRCS=\ $(ENCODER_SRCDIR)/core/src/ratectl.cpp\ $(ENCODER_SRCDIR)/core/src/ref_list_mgr_svc.cpp\ $(ENCODER_SRCDIR)/core/src/sample.cpp\ + $(ENCODER_SRCDIR)/core/src/set_mb_syn_cabac.cpp\ $(ENCODER_SRCDIR)/core/src/set_mb_syn_cavlc.cpp\ $(ENCODER_SRCDIR)/core/src/slice_multi_threading.cpp\ $(ENCODER_SRCDIR)/core/src/svc_base_layer_md.cpp\ @@ -26,6 +28,7 @@ ENCODER_CPP_SRCS=\ $(ENCODER_SRCDIR)/core/src/svc_encode_slice.cpp\ $(ENCODER_SRCDIR)/core/src/svc_mode_decision.cpp\ $(ENCODER_SRCDIR)/core/src/svc_motion_estimate.cpp\ + $(ENCODER_SRCDIR)/core/src/svc_set_mb_syn_cabac.cpp\ $(ENCODER_SRCDIR)/core/src/svc_set_mb_syn_cavlc.cpp\ $(ENCODER_SRCDIR)/core/src/wels_preprocess.cpp\ $(ENCODER_SRCDIR)/plus/src/welsEncoderExt.cpp\ diff --git a/test/BaseEncoderTest.h b/test/BaseEncoderTest.h index 686888a7..3c2ecfde 100644 --- a/test/BaseEncoderTest.h +++ b/test/BaseEncoderTest.h @@ -15,9 +15,9 @@ class BaseEncoderTest { void SetUp(); void TearDown(); void EncodeFile (const char* fileName, EUsageType usageType, int width, int height, float frameRate, - SliceModeEnum slices, bool denoise, int layers, bool losslessLink, bool enableLtr, Callback* cbk); + SliceModeEnum slices, bool denoise, int layers, bool losslessLink, bool enableLtr, bool cabac, Callback* cbk); void EncodeStream (InputStream* in, EUsageType usageType, int width, int height, float frameRate, SliceModeEnum slices, - bool denoise, int layers, bool losslessLink, bool enableLtr, Callback* cbk); + bool denoise, int layers, bool losslessLink, bool enableLtr, bool cabac, Callback* cbk); ISVCEncoder* encoder_; private: diff --git a/test/api/BaseEncoderTest.cpp b/test/api/BaseEncoderTest.cpp index 6404b23c..eba0813f 100644 --- a/test/api/BaseEncoderTest.cpp +++ b/test/api/BaseEncoderTest.cpp @@ -6,8 +6,8 @@ #include "BaseEncoderTest.h" static int InitWithParam (ISVCEncoder* encoder, EUsageType usageType, int width, - int height, float frameRate, SliceModeEnum sliceMode, bool denoise, int layers, bool losslessLink, bool enableLtr) { - if (SM_SINGLE_SLICE == sliceMode && !denoise && layers == 1 && !losslessLink && !enableLtr) { + int height, float frameRate, SliceModeEnum sliceMode, bool denoise, int layers, bool losslessLink, bool enableLtr,bool cabac) { + if (SM_SINGLE_SLICE == sliceMode && !denoise && layers == 1 && !losslessLink && !enableLtr &&!cabac) { SEncParamBase param; memset (¶m, 0, sizeof (SEncParamBase)); @@ -31,7 +31,7 @@ static int InitWithParam (ISVCEncoder* encoder, EUsageType usageType, int width, param.iSpatialLayerNum = layers; param.bIsLosslessLink = losslessLink; param.bEnableLongTermReference = enableLtr; - + param.iEntropyCodingModeFlag = cabac?1:0; if (sliceMode != SM_SINGLE_SLICE && sliceMode != SM_DYN_SLICE) //SM_DYN_SLICE don't support multi-thread now param.iMultipleThreadIdc = 2; @@ -69,9 +69,8 @@ void BaseEncoderTest::TearDown() { } void BaseEncoderTest::EncodeStream (InputStream* in, EUsageType usageType, int width, int height, - float frameRate, SliceModeEnum slices, bool denoise, int layers, bool losslessLink, bool enableLtr, Callback* cbk) { - int rv = InitWithParam (encoder_, usageType, width, height, frameRate, slices, denoise, layers, losslessLink, - enableLtr); + float frameRate, SliceModeEnum slices, bool denoise, int layers, bool losslessLink, bool enableLtr, bool cabac,Callback* cbk) { + int rv = InitWithParam (encoder_, usageType, width, height, frameRate, slices, denoise, layers, losslessLink, enableLtr,cabac); ASSERT_TRUE (rv == cmResultSuccess); // I420: 1(Y) + 1/4(U) + 1/4(V) @@ -104,8 +103,8 @@ void BaseEncoderTest::EncodeStream (InputStream* in, EUsageType usageType, int w } void BaseEncoderTest::EncodeFile (const char* fileName, EUsageType usageType, int width, int height, - float frameRate, SliceModeEnum slices, bool denoise, int layers, bool losslessLink, bool enableLtr, Callback* cbk) { + float frameRate, SliceModeEnum slices, bool denoise, int layers, bool losslessLink, bool enableLtr, bool cabac,Callback* cbk) { FileInputStream fileStream; ASSERT_TRUE (fileStream.Open (fileName)); - EncodeStream (&fileStream, usageType, width, height, frameRate, slices, denoise, layers, losslessLink, enableLtr, cbk); + EncodeStream (&fileStream, usageType, width, height, frameRate, slices, denoise, layers, losslessLink, enableLtr, cabac,cbk); } diff --git a/test/api/decode_encode_test.cpp b/test/api/decode_encode_test.cpp index b20c0e2d..7334b1dd 100644 --- a/test/api/decode_encode_test.cpp +++ b/test/api/decode_encode_test.cpp @@ -99,8 +99,7 @@ TEST_P (DecodeEncodeTest, CompareOutput) { #else ASSERT_TRUE (Open (p.fileName)); #endif - EncodeStream (this, CAMERA_VIDEO_REAL_TIME, p.width, p.height, p.frameRate, SM_SINGLE_SLICE, false, 1, false, false, - this); + EncodeStream (this, CAMERA_VIDEO_REAL_TIME, p.width, p.height, p.frameRate, SM_SINGLE_SLICE, false, 1, false, false,false, this); unsigned char digest[SHA_DIGEST_LENGTH]; SHA1Result (&ctx_, digest); if (!HasFatalFailure()) { diff --git a/test/api/encoder_test.cpp b/test/api/encoder_test.cpp index 1ffa05f6..f73f4640 100644 --- a/test/api/encoder_test.cpp +++ b/test/api/encoder_test.cpp @@ -37,6 +37,7 @@ struct EncodeFileParam { int layers; bool isLossless; bool enableLtr; + bool cabac; }; class EncoderOutputTest : public ::testing::WithParamInterface, @@ -62,10 +63,10 @@ TEST_P (EncoderOutputTest, CompareOutput) { #if defined(ANDROID_NDK) std::string filename = std::string ("/sdcard/") + p.fileName; EncodeFile (filename.c_str(), p.usageType , p.width, p.height, p.frameRate, p.slices, p.denoise, p.layers, p.isLossless, - p.enableLtr, this); + p.enableLtr,p.cabac, this); #else EncodeFile (p.fileName, p.usageType , p.width, p.height, p.frameRate, p.slices, p.denoise, p.layers, p.isLossless, - p.enableLtr, this); + p.enableLtr, p.cabac, this); #endif //will remove this after screen content algorithms are ready, //because the bitstream output will vary when the different algorithms are added. @@ -78,57 +79,65 @@ TEST_P (EncoderOutputTest, CompareOutput) { static const EncodeFileParam kFileParamArray[] = { { "res/CiscoVT2people_320x192_12fps.yuv", - "0a36b75e423fc6b49f6adf7eee12c039a096f538", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, false, 1, false, false + "0a36b75e423fc6b49f6adf7eee12c039a096f538", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, false, 1, false, false, false }, { "res/CiscoVT2people_160x96_6fps.yuv", - "73981e6ea5b62f7338212c538a7cc755e7c9c030", CAMERA_VIDEO_REAL_TIME, 160, 96, 6.0f, SM_SINGLE_SLICE, false, 1, false, false + "73981e6ea5b62f7338212c538a7cc755e7c9c030", CAMERA_VIDEO_REAL_TIME, 160, 96, 6.0f, SM_SINGLE_SLICE, false, 1, false, false, false }, { "res/Static_152_100.yuv", - "02bbff550ee0630e44e46e14dc459d3686f2a360", CAMERA_VIDEO_REAL_TIME, 152, 100, 6.0f, SM_SINGLE_SLICE, false, 1, false, false + "02bbff550ee0630e44e46e14dc459d3686f2a360", CAMERA_VIDEO_REAL_TIME, 152, 100, 6.0f, SM_SINGLE_SLICE, false, 1, false, false, false }, { "res/CiscoVT2people_320x192_12fps.yuv", - "c8b759bcec7ffa048f1d3ded594b8815bed0aead", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_ROWMB_SLICE, false, 1, false, false // One slice per MB row + "c8b759bcec7ffa048f1d3ded594b8815bed0aead", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_ROWMB_SLICE, false, 1, false, false, false // One slice per MB row }, { "res/CiscoVT2people_320x192_12fps.yuv", - "e64ba75456c821ca35a949eda89f85bff8ee69fa", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, true, 1, false, false + "e64ba75456c821ca35a949eda89f85bff8ee69fa", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, true, 1, false, false, false }, { "res/CiscoVT2people_320x192_12fps.yuv", - "684e6d141ada776892bdb01ee93efe475983ed36", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, false, 2, false, false + "684e6d141ada776892bdb01ee93efe475983ed36", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, false, 2, false, false, false }, { "res/Cisco_Absolute_Power_1280x720_30fps.yuv", - "2bc06262d87fa0897ad4c336cc4047d5a67f7203", CAMERA_VIDEO_REAL_TIME, 1280, 720, 30.0f, SM_DYN_SLICE, false, 1, false, false + "2bc06262d87fa0897ad4c336cc4047d5a67f7203", CAMERA_VIDEO_REAL_TIME, 1280, 720, 30.0f, SM_DYN_SLICE, false, 1, false, false, false }, { "res/Cisco_Absolute_Power_1280x720_30fps.yuv", - "68c3220e49b7a57d563faf7c99a870ab34a23400", CAMERA_VIDEO_REAL_TIME, 1280, 720, 30.0f, SM_SINGLE_SLICE, false, 4, false, false + "68c3220e49b7a57d563faf7c99a870ab34a23400", CAMERA_VIDEO_REAL_TIME, 1280, 720, 30.0f, SM_SINGLE_SLICE, false, 4, false, false, false }, // the following values may be adjusted for times since we start tuning the strategy { "res/CiscoVT2people_320x192_12fps.yuv", - "3ce65d9c326657b845cd00b22ce76128c29f8347", SCREEN_CONTENT_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, false, 1, false, false + "3ce65d9c326657b845cd00b22ce76128c29f8347", SCREEN_CONTENT_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, false, 1, false, false, false }, { "res/CiscoVT2people_160x96_6fps.yuv", - "2b57e1cc7a4db6258116c302eada3bf870ee94a1", SCREEN_CONTENT_REAL_TIME, 160, 96, 6.0f, SM_SINGLE_SLICE, false, 1, false, false + "2b57e1cc7a4db6258116c302eada3bf870ee94a1", SCREEN_CONTENT_REAL_TIME, 160, 96, 6.0f, SM_SINGLE_SLICE, false, 1, false, false, false }, { "res/Static_152_100.yuv", - "bad065da4564d0580a1722d91463fa0f9fd947c8", SCREEN_CONTENT_REAL_TIME, 152, 100, 6.0f, SM_SINGLE_SLICE, false, 1, false, false + "bad065da4564d0580a1722d91463fa0f9fd947c8", SCREEN_CONTENT_REAL_TIME, 152, 100, 6.0f, SM_SINGLE_SLICE, false, 1, false, false, false }, { "res/Cisco_Absolute_Power_1280x720_30fps.yuv", - "8ee6cd375b58e9877f6145fb72da844e65162b14", SCREEN_CONTENT_REAL_TIME, 1280, 720, 30.0f, SM_DYN_SLICE, false, 1, false, false + "8ee6cd375b58e9877f6145fb72da844e65162b14", SCREEN_CONTENT_REAL_TIME, 1280, 720, 30.0f, SM_DYN_SLICE, false, 1, false, false, false }, //for different strategy { "res/Cisco_Absolute_Power_1280x720_30fps.yuv", - "868f327765dc8e705ad6a9a942bfc7e32c03c791", SCREEN_CONTENT_REAL_TIME, 1280, 720, 30.0f, SM_DYN_SLICE, false, 1, true, true + "868f327765dc8e705ad6a9a942bfc7e32c03c791", SCREEN_CONTENT_REAL_TIME, 1280, 720, 30.0f, SM_DYN_SLICE, false, 1, true, true, false + }, + { + "res/CiscoVT2people_320x192_12fps.yuv", + "fc6faa6409150cce304bcdefb486fee4b4a70e1d", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, false, 1, false, false, true //turn on cabac + }, + { + "res/Cisco_Absolute_Power_1280x720_30fps.yuv", + "7b166367ece61cf489c793872c40c37d4047b7aa", CAMERA_VIDEO_REAL_TIME, 1280, 720, 30.0f, SM_DYN_SLICE, false, 1, false, false, true }, }; diff --git a/testbin/welsenc.cfg b/testbin/welsenc.cfg index 8bde477e..93dd167a 100644 --- a/testbin/welsenc.cfg +++ b/testbin/welsenc.cfg @@ -14,7 +14,7 @@ IntraPeriod 0 # Intra Period ( multipler of GoP si EnableSpsPpsIDAddition 1 EnableFrameCropping 1 # enable frame cropping flag - +EntropyCodingModeFlag 0 #0:cavlc 1:cabac MaxNalSize 0 # Unit:Byte, Maximum Nal size #============================== LOOP FILTER ============================== LoopFilterDisableIDC 0 # Loop filter idc (0: on, 1: off, diff --git a/testbin/welsenc_arbitrary_res.cfg b/testbin/welsenc_arbitrary_res.cfg index 17106b4e..dcb5c1e1 100644 --- a/testbin/welsenc_arbitrary_res.cfg +++ b/testbin/welsenc_arbitrary_res.cfg @@ -14,7 +14,7 @@ IntraPeriod 0 # Intra Period ( multiple of GoP siz EnableSpsPpsIDAddition 1 EnableFrameCropping 1 # enable frame cropping flag - +EntropyCodingModeFlag 0 #0:cavlc 1:cabac MaxNalSize 0 # Unit:Byte, Maximum Nal size #============================== LOOP FILTER ============================== LoopFilterDisableIDC 0 # Loop filter idc (0: on, 1: off, diff --git a/testbin/welsenc_ios.cfg b/testbin/welsenc_ios.cfg index 6a948b8c..05886aff 100644 --- a/testbin/welsenc_ios.cfg +++ b/testbin/welsenc_ios.cfg @@ -14,7 +14,7 @@ IntraPeriod 0 # Intra Period ( multipler of GoP si EnableSpsPpsIDAddition 1 EnableFrameCropping 1 # enable frame cropping flag - +EntropyCodingModeFlag 0 #0:cavlc 1:cabac MaxNalSize 0 # Unit:Byte, Maximum Nal size #============================== LOOP FILTER ============================== LoopFilterDisableIDC 0 # Loop filter idc (0: on, 1: off, diff --git a/testbin/welsenc_vd_1d.cfg b/testbin/welsenc_vd_1d.cfg index 30d2932f..3381729a 100644 --- a/testbin/welsenc_vd_1d.cfg +++ b/testbin/welsenc_vd_1d.cfg @@ -14,7 +14,7 @@ IntraPeriod 0 # Intra Period ( multipler of GoP si EnableSpsPpsIDAddition 1 EnableFrameCropping 1 # enable frame cropping flag - +EntropyCodingModeFlag 0 #0:cavlc 1:cabac MaxNalSize 0 # Unit:Byte, Maximum Nal size #============================== LOOP FILTER ============================== LoopFilterDisableIDC 0 # Loop filter idc (0: on, 1: off, diff --git a/testbin/welsenc_vd_rc.cfg b/testbin/welsenc_vd_rc.cfg index 30dabe05..4db90595 100644 --- a/testbin/welsenc_vd_rc.cfg +++ b/testbin/welsenc_vd_rc.cfg @@ -14,7 +14,7 @@ IntraPeriod 0 # Intra Period ( multipler of GoP si EnableSpsPpsIDAddition 1 EnableFrameCropping 1 # enable frame cropping flag - +EntropyCodingModeFlag 0 #0:cavlc 1:cabac MaxNalSize 0 # Unit:Byte, Maximum Nal size #============================== LOOP FILTER ============================== LoopFilterDisableIDC 0 # Loop filter idc (0: on, 1: off,