Compare commits

...

50 Commits

Author SHA1 Message Date
huili2
bdb7d758c1 Merge pull request #888 from huili2/update_API_docx
Update api docx
2014-05-23 22:54:42 +08:00
huili2
176495defe Merge pull request #887 from huili2/modif_README
Modif readme as release note for v1.0
2014-05-23 22:54:19 +08:00
huili2
890674bde4 add API docx for release v1.0 2014-05-23 07:38:27 -07:00
HaiboZhu
414a1ff975 Merge pull request #883 from huili2/API_dec_modify_v1
Api dec modify v1
2014-05-22 16:20:41 +08:00
huili2
a1ec7f0a35 Merge pull request #885 from ruil2/enc_quant_v1.0
remove some warnings
2014-05-22 16:13:53 +08:00
ruil2
6475c9b7f9 resolve unit test warnings 2014-05-22 16:03:41 +08:00
ruil2
fe05db7bca remove some warings 2014-05-22 15:09:32 +08:00
huili2
a64ddb407c Merge pull request #882 from ruil2/enc_quant_v1.0
Fix the improper slice mmco setting
2014-05-22 14:50:45 +08:00
huili2
a2b445f0b0 v1.0 release note 2014-05-21 23:38:10 -07:00
ruil2
2db1123bec Fix the improper slice mmco setting 2014-05-22 14:30:09 +08:00
huili2
41b71434f7 Merge pull request #881 from ruil2/enc_quant_v1.0
add maxnalsize parameter in configure file
2014-05-22 14:29:30 +08:00
ruil2
c034dcf958 add maxnalsize parameter in configure file 2014-05-22 14:19:30 +08:00
sijchen
77cb7c518c Merge pull request #879 from ruil2/enc_quant_v1.0
clean up console app(merge two path into one)
2014-05-22 00:14:18 -05:00
ruil2
c0cc575e74 clean up console app(merge two path into one) 2014-05-22 11:41:43 +08:00
ruil2
ca68f47db2 Merge pull request #877 from ganyangbbl/remove_enc_warning
[Fix] clean build warning related encoder
2014-05-22 10:56:32 +08:00
huili2
cae151981b modify dec API from void to explicit type, and some comments 2014-05-21 18:49:32 -07:00
huili2
650dc637b6 Merge pull request #869 from sijchen/rc_fix_101
[Fix] put all (int32_t) to WELS_ROUND
2014-05-21 16:49:12 +08:00
ganyang
679449f97d clean build warning related encoder 2014-05-21 15:44:09 +08:00
dongzha
11085e072a Merge pull request #875 from huili2/bug_fix_dec_bs_buffer
Bug fix dec bs buffer expand
2014-05-21 15:39:54 +08:00
huili2
af6105743a expand the bs buffer size 2014-05-21 00:23:41 -07:00
dongzha
3abf06705b Merge pull request #873 from ruil2/enc_quant_v1.0
update the minimum quant limiation as 10
2014-05-21 15:11:58 +08:00
ruil2
dd088d9979 Merge pull request #870 from sijchen/rm_warn_101
[Fix] Expand the size of m_pSpatialPic
2014-05-21 14:27:17 +08:00
ruil2
5eb0f0b92b update the minimum quant limiation as 10. quant 4 can't avoid overflow 2014-05-21 14:07:39 +08:00
sijchen
bf7ff18bae modify the size of m_pSpatialPic, the previous size cannot cover more LTR_num in screen 2014-05-20 17:04:56 +08:00
sijchen
d98d9194fd put all (int32_t) to WELS_ROUND to minimize possible mismatch on double-float calculation on different machines and remove some unnecessary (int32_t) 2014-05-20 16:57:29 +08:00
HaiboZhu
45d79d6d13 Merge pull request #861 from huili2/remove_warning_UT_PredMv
Remove build warning ut pred mv in Linux
2014-05-20 16:11:50 +08:00
HaiboZhu
a103ffc2e3 Merge pull request #866 from huili2/Add_new_seq_check_v1
Add new seq check v1.0
2014-05-20 16:08:58 +08:00
huili2
576b27238c Merge pull request #865 from ruil2/enc_quant_v1.0
set minimum quant as 4 to avoid level code overflow
2014-05-20 11:23:26 +08:00
unknown
680bc349f1 set minimum quant as 4 to avoid level code overflow 2014-05-20 11:04:47 +08:00
HaiboZhu
1d82df67f6 Merge pull request #862 from dongzha/FixEncOption
change comment in encoder option according to issue cisco#859 for openh264v1.0
2014-05-20 10:53:37 +08:00
huili2
996be050b9 add single function for new seq detection 2014-05-19 19:37:45 -07:00
dongzhang
62c12b2985 change comment in encoder option according to issue https://github.com/cisco/openh264/issues/859 2014-05-20 09:45:13 +08:00
huili2
10cbbbb2b2 remove build warning on Linux 2014-05-19 18:00:36 -07:00
huili2
8ca7b2e557 Merge pull request #851 from dongzha/FixEncUTDequantBug
Fix enc ut dequant bug
2014-05-16 13:33:14 +08:00
huili2
335857fe9a Merge pull request #855 from sijchen/bufferlencheck_fixe
add minimum buffer size (same to #854)
2014-05-16 13:17:21 +08:00
sijchen
d0e8ae0cf5 add minimum buffer size 2014-05-16 12:59:50 +08:00
dongzhang
6e34f5a7c9 Fix QP<18 dequant UT bug at encoder side
This should be UT for QP<12.
2014-05-16 10:17:33 +08:00
HaiboZhu
83f89406ca Merge pull request #846 from huili2/v1_bs_buffer_modif
V1 bs buffer modif
2014-05-15 16:31:20 +08:00
huili2
0a9a05ee4e Merge pull request #850 from ruil2/enc_bitrate_setting_v10
fix bitrate setting and add bitrate validation
2014-05-15 16:27:46 +08:00
huili2
294bfd5495 Merge pull request #849 from ruil2/enc_size_v10
fix input source width and height setting issue
2014-05-15 16:27:19 +08:00
ruil2
09cf107367 fix bitrate setting and add bitrate validation 2014-05-15 16:14:07 +08:00
unknown
e5d8957ad2 fix input source width and height setting issue 2014-05-15 16:06:45 +08:00
huili2
2dad4b7eb9 modify bs buffer size to double the AU size 2014-05-14 22:17:17 -07:00
huili2
00696ae9d9 Merge pull request #839 from sijchen/disablemetest
[v1.0] Temporarily disable ME tests due to random failure
2014-05-14 13:56:50 +08:00
sijchen
4f28cf772a temporarily disable ME tests due to random failure 2014-05-14 11:36:22 +08:00
sijchen
cf81b0095c Merge pull request #827 from dongzha/FixBugforDeblocking
Fix a bug in deblocking for neon 32 bit arm implementation
2014-05-14 09:26:17 +08:00
sijchen
c6538f1eb8 Merge pull request #828 from huili2/v1_clear_active_ps
V1 clear active ps
2014-05-13 17:22:48 +08:00
huili2
8b6c6943cd clear active PS when only IDR meets 2014-05-13 01:11:55 -07:00
sijchen
958207392c Merge pull request #811 from huili2/v1_ps_error
V1 ps error
2014-05-09 17:21:47 +08:00
huili2
eb6fdf4412 for PS error logic for EC 2014-05-09 01:18:55 -07:00
44 changed files with 247 additions and 473 deletions

BIN
OpenH264_API_v1.0.docx Normal file

Binary file not shown.

View File

@ -5,7 +5,7 @@ OpenH264 is a codec library which supports H.264 encoding and decoding. It is su
Encoder Features Encoder Features
---------------- ----------------
- Constrained Baseline Profile up to Level 5.2 (4096x2304) - Constrained Baseline Profile up to Level 5.2 (4096x2304)
- Arbitrary resolution, not constrained to multiples of 16x16 - Arbitrary resolution, support cropping
- Rate control with adaptive quantization, or constant quantization - Rate control with adaptive quantization, or constant quantization
- Slice options: 1 slice per frame, N slices per frame, N macroblocks per slice, or N bytes per slice - Slice options: 1 slice per frame, N slices per frame, N macroblocks per slice, or N bytes per slice
- Multiple threads automatically used for multiple slices - Multiple threads automatically used for multiple slices
@ -32,6 +32,8 @@ Decoder Features
- Multiple reference frames when specified in Sequence Parameter Set (SPS) - Multiple reference frames when specified in Sequence Parameter Set (SPS)
- Annex B byte stream input - Annex B byte stream input
- YUV 4:2:0 planar output - YUV 4:2:0 planar output
- Decoder output timing conformance
- Error concealment support with slice copy as default method
OS Support OS Support
---------- ----------
@ -39,7 +41,7 @@ OS Support
- Mac OS X 64-bit and 32-bit - Mac OS X 64-bit and 32-bit
- Linux 64-bit and 32-bit - Linux 64-bit and 32-bit
- Android 32-bit - Android 32-bit
- iOS 64-bit and 32-bit - iOS 64-bit and 32-bit (not fully tested)
Processor Support Processor Support
----------------- -----------------
@ -136,6 +138,9 @@ Known Issues
See the issue tracker on https://github.com/cisco/openh264/issues See the issue tracker on https://github.com/cisco/openh264/issues
- Encoder errors when resolution exceeds 3840x2160 - Encoder errors when resolution exceeds 3840x2160
- Encoder errors when compressed frame size exceeds half uncompressed size - Encoder errors when compressed frame size exceeds half uncompressed size
- Encoder does not support QP < 10 encoding
- Encoder does not support slice number > 35 encoding
- The result of float-point calculation in rate control will be affected by preciseness of double-typed variable on different platform
- Decoder errors when compressed frame size exceeds 1MB - Decoder errors when compressed frame size exceeds 1MB
- Encoder RC requires frame skipping to be enabled to hit the target bitrate, - Encoder RC requires frame skipping to be enabled to hit the target bitrate,
if frame skipping is disabled the target bitrate may be exceeded if frame skipping is disabled the target bitrate may be exceeded

View File

@ -109,7 +109,7 @@ class ISVCDecoder {
*/ */
virtual DECODING_STATE EXTAPI DecodeFrame2 (const unsigned char* pSrc, virtual DECODING_STATE EXTAPI DecodeFrame2 (const unsigned char* pSrc,
const int iSrcLen, const int iSrcLen,
void** ppDst, unsigned char** ppDst,
SBufferInfo* pDstInfo) = 0; SBufferInfo* pDstInfo) = 0;
/* /*
@ -174,7 +174,7 @@ DECODING_STATE (*DecodeFrame) (ISVCDecoder*, const unsigned char* pSrc,
DECODING_STATE (*DecodeFrame2) (ISVCDecoder*, const unsigned char* pSrc, DECODING_STATE (*DecodeFrame2) (ISVCDecoder*, const unsigned char* pSrc,
const int iSrcLen, const int iSrcLen,
void** ppDst, unsigned char** ppDst,
SBufferInfo* pDstInfo); SBufferInfo* pDstInfo);
DECODING_STATE (*DecodeFrameEx) (ISVCDecoder*, const unsigned char* pSrc, DECODING_STATE (*DecodeFrameEx) (ISVCDecoder*, const unsigned char* pSrc,

View File

@ -87,9 +87,9 @@ typedef enum {
ENCOCER_LTR_MARKING_PERIOD, ENCOCER_LTR_MARKING_PERIOD,
ENCODER_OPTION_LTR, ENCODER_OPTION_LTR,
ENCODER_OPTION_ENABLE_SSEI, //disable SSEI: true--disable ssei; false--enable ssei ENCODER_OPTION_ENABLE_SSEI, //enable SSEI: true--enable ssei; false--disable ssei
ENCODER_OPTION_ENABLE_PREFIX_NAL_ADDING, //enable prefix: true--enable prefix; false--disable prefix ENCODER_OPTION_ENABLE_PREFIX_NAL_ADDING, //enable prefix: true--enable prefix; false--disable prefix
ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, //disable pSps/pPps id addition: true--disable pSps/pPps id; false--enable pSps/pPps id addistion ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, //enable pSps/pPps id addition: true--enable pSps/pPps id; false--disable pSps/pPps id addistion
ENCODER_OPTION_CURRENT_PATH, ENCODER_OPTION_CURRENT_PATH,
ENCODER_OPTION_DUMP_FILE, ENCODER_OPTION_DUMP_FILE,

View File

@ -7,6 +7,7 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
9ABF4379192DE20800A6BD61 /* EncUT_MemoryAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9ABF4378192DE20800A6BD61 /* EncUT_MemoryAlloc.cpp */; };
FAA3D9D318BD729500BCD52D /* welsenc_ios.cfg in Resources */ = {isa = PBXBuildFile; fileRef = FAA3D9D218BD729500BCD52D /* welsenc_ios.cfg */; }; FAA3D9D318BD729500BCD52D /* welsenc_ios.cfg in Resources */ = {isa = PBXBuildFile; fileRef = FAA3D9D218BD729500BCD52D /* welsenc_ios.cfg */; };
FAA3D9D818BD777100BCD52D /* CiscoVT2people_320x192_12fps.yuv in Resources */ = {isa = PBXBuildFile; fileRef = FAA3D9D718BD777100BCD52D /* CiscoVT2people_320x192_12fps.yuv */; }; FAA3D9D818BD777100BCD52D /* CiscoVT2people_320x192_12fps.yuv in Resources */ = {isa = PBXBuildFile; fileRef = FAA3D9D718BD777100BCD52D /* CiscoVT2people_320x192_12fps.yuv */; };
FAA3D9DD18BD8A5600BCD52D /* layer2.cfg in Resources */ = {isa = PBXBuildFile; fileRef = FAA3D9DC18BD8A5600BCD52D /* layer2.cfg */; }; FAA3D9DD18BD8A5600BCD52D /* layer2.cfg in Resources */ = {isa = PBXBuildFile; fileRef = FAA3D9DC18BD8A5600BCD52D /* layer2.cfg */; };
@ -94,6 +95,7 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
9ABF4378192DE20800A6BD61 /* EncUT_MemoryAlloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = EncUT_MemoryAlloc.cpp; path = ../../../../../test/encoder/EncUT_MemoryAlloc.cpp; sourceTree = "<group>"; };
FAA3D9D218BD729500BCD52D /* welsenc_ios.cfg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = welsenc_ios.cfg; path = ../../../../../../testbin/welsenc_ios.cfg; sourceTree = "<group>"; }; FAA3D9D218BD729500BCD52D /* welsenc_ios.cfg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = welsenc_ios.cfg; path = ../../../../../../testbin/welsenc_ios.cfg; sourceTree = "<group>"; };
FAA3D9D718BD777100BCD52D /* CiscoVT2people_320x192_12fps.yuv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CiscoVT2people_320x192_12fps.yuv; path = ../../../../../../res/CiscoVT2people_320x192_12fps.yuv; sourceTree = "<group>"; }; FAA3D9D718BD777100BCD52D /* CiscoVT2people_320x192_12fps.yuv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CiscoVT2people_320x192_12fps.yuv; path = ../../../../../../res/CiscoVT2people_320x192_12fps.yuv; sourceTree = "<group>"; };
FAA3D9DC18BD8A5600BCD52D /* layer2.cfg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = layer2.cfg; path = ../../../../../../testbin/layer2.cfg; sourceTree = "<group>"; }; FAA3D9DC18BD8A5600BCD52D /* layer2.cfg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = layer2.cfg; path = ../../../../../../testbin/layer2.cfg; sourceTree = "<group>"; };
@ -141,6 +143,7 @@
FAFB4F9C18BC8DD700315438 = { FAFB4F9C18BC8DD700315438 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
9ABF4378192DE20800A6BD61 /* EncUT_MemoryAlloc.cpp */,
FAFB4FAE18BC8DD700315438 /* encDemo */, FAFB4FAE18BC8DD700315438 /* encDemo */,
FAFB4FA718BC8DD700315438 /* Frameworks */, FAFB4FA718BC8DD700315438 /* Frameworks */,
FAFB4FA618BC8DD700315438 /* Products */, FAFB4FA618BC8DD700315438 /* Products */,
@ -388,6 +391,7 @@
FAFB502F18BCA50900315438 /* read_config.cpp in Sources */, FAFB502F18BCA50900315438 /* read_config.cpp in Sources */,
FAFB500B18BC8F6C00315438 /* welsenc.cpp in Sources */, FAFB500B18BC8F6C00315438 /* welsenc.cpp in Sources */,
FAFB4FB918BC8DD700315438 /* AppDelegate.m in Sources */, FAFB4FB918BC8DD700315438 /* AppDelegate.m in Sources */,
9ABF4379192DE20800A6BD61 /* EncUT_MemoryAlloc.cpp in Sources */,
FAFB4FB518BC8DD700315438 /* main.m in Sources */, FAFB4FB518BC8DD700315438 /* main.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;

View File

@ -122,7 +122,7 @@ __declspec(align(alignment)) type name[(sizex)*(sizey)]
#endif//WELS_FLOOR #endif//WELS_FLOOR
#ifndef WELS_ROUND #ifndef WELS_ROUND
#define WELS_ROUND(x) ((int32_t)(0.5f+(x))) #define WELS_ROUND(x) ((int32_t)(0.5+(x)))
#endif//WELS_ROUND #endif//WELS_ROUND
#define WELS_NON_ZERO_COUNT_AVERAGE(nC,nA,nB) { \ #define WELS_NON_ZERO_COUNT_AVERAGE(nC,nA,nB) { \

View File

@ -76,7 +76,7 @@ void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, cons
uint8_t* pBuf = NULL; uint8_t* pBuf = NULL;
uint8_t uiStartCode[4] = {0, 0, 0, 1}; uint8_t uiStartCode[4] = {0, 0, 0, 1};
void* pData[3] = {NULL}; uint8_t* pData[3] = {NULL};
uint8_t* pDst[3] = {NULL}; uint8_t* pDst[3] = {NULL};
SBufferInfo sDstBufInfo; SBufferInfo sDstBufInfo;
@ -212,9 +212,9 @@ void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, cons
pDecoder->DecodeFrame2 (pBuf + iBufPos, iSliceSize, pData, &sDstBufInfo); pDecoder->DecodeFrame2 (pBuf + iBufPos, iSliceSize, pData, &sDstBufInfo);
if (sDstBufInfo.iBufferStatus == 1) { if (sDstBufInfo.iBufferStatus == 1) {
pDst[0] = (uint8_t*)pData[0]; pDst[0] = pData[0];
pDst[1] = (uint8_t*)pData[1]; pDst[1] = pData[1];
pDst[2] = (uint8_t*)pData[2]; pDst[2] = pData[2];
} }
iEnd = WelsTime(); iEnd = WelsTime();
iTotal += iEnd - iStart; iTotal += iEnd - iStart;
@ -247,9 +247,9 @@ void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, cons
pDecoder->DecodeFrame2 (NULL, 0, pData, &sDstBufInfo); pDecoder->DecodeFrame2 (NULL, 0, pData, &sDstBufInfo);
if (sDstBufInfo.iBufferStatus == 1) { if (sDstBufInfo.iBufferStatus == 1) {
pDst[0] = (uint8_t*)pData[0]; pDst[0] = pData[0];
pDst[1] = (uint8_t*)pData[1]; pDst[1] = pData[1];
pDst[2] = (uint8_t*)pData[2]; pDst[2] = pData[2];
} }
if (sDstBufInfo.iBufferStatus == 1) { if (sDstBufInfo.iBufferStatus == 1) {

View File

@ -212,6 +212,8 @@ int ParseConfig (CReadConfig& cRdCfg, SSourcePicture* pSrcPic, SEncParamExt& pSv
pSvcParam.iTemporalLayerNum = atoi (strTag[1].c_str()); pSvcParam.iTemporalLayerNum = atoi (strTag[1].c_str());
} else if (strTag[0].compare ("IntraPeriod") == 0) { } else if (strTag[0].compare ("IntraPeriod") == 0) {
pSvcParam.uiIntraPeriod = atoi (strTag[1].c_str()); pSvcParam.uiIntraPeriod = atoi (strTag[1].c_str());
} else if (strTag[0].compare ("MaxNalSize") == 0) {
pSvcParam.uiMaxNalSize = atoi (strTag[1].c_str());
} else if (strTag[0].compare ("EnableSpsPpsIDAddition") == 0) { } else if (strTag[0].compare ("EnableSpsPpsIDAddition") == 0) {
pSvcParam.bEnableSpsPpsIdAddition = atoi (strTag[1].c_str()) ? true : false; pSvcParam.bEnableSpsPpsIdAddition = atoi (strTag[1].c_str()) ? true : false;
} else if (strTag[0].compare ("EnableScalableSEI") == 0) { } else if (strTag[0].compare ("EnableScalableSEI") == 0) {
@ -310,70 +312,6 @@ int ParseConfig (CReadConfig& cRdCfg, SSourcePicture* pSrcPic, SEncParamExt& pSv
return iRet; return iRet;
} }
int ParseCommandLine (int argc, char** argv, SEncParamExt& sParam) {
char* pCmd;
int i = 0;
while (i < argc) {
pCmd = argv[i++];
if (!strcmp (pCmd, "-numl") && (i < argc))
sParam.iSpatialLayerNum = atoi (argv[i++]);
else if (!strcmp (pCmd, "-numt") && (i < argc))
sParam.iTemporalLayerNum = atoi (argv[i++]);
else if (!strcmp (pCmd, "-iper") && (i < argc))
sParam.uiIntraPeriod = atoi (argv[i++]);
else if (!strcmp (pCmd, "-spsid") && (i < argc))
sParam.bEnableSpsPpsIdAddition = atoi (argv[i++]) ? true : false;
else if (!strcmp (pCmd, "-denois") && (i < argc))
sParam.bEnableDenoise = atoi (argv[i++]) ? true : false;
else if (!strcmp (pCmd, "-bgd") && (i < argc))
sParam.bEnableBackgroundDetection = atoi (argv[i++]) ? true : false;
else if (!strcmp (pCmd, "-aq") && (i < argc))
sParam.bEnableAdaptiveQuant = atoi (argv[i++]) ? true : false;
else if (!strcmp (pCmd, "-fs") && (i < argc))
sParam.bEnableFrameSkip = atoi (argv[i++]) ? true : false;
else if (!strcmp (pCmd, "-ltr") && (i < argc))
sParam.bEnableLongTermReference = atoi (argv[i++]) ? true : false;
else if (!strcmp (pCmd, "-ltrnum") && (i < argc))
sParam.iLTRRefNum = atoi (argv[i++]);
else if (!strcmp (pCmd, "-ltrper") && (i < argc))
sParam.iLtrMarkPeriod = atoi (argv[i++]);
else if (!strcmp (pCmd, "-rcm") && (i < argc))
sParam.iRCMode = (RC_MODES) atoi (argv[i++]);
else if (!strcmp (pCmd, "-tarb") && (i < argc))
sParam.iTargetBitrate = atoi (argv[i++]);
else if (!strcmp (pCmd, "-ltarb") && (i + 1 < argc)) {
int iLayer = atoi (argv[i++]);
sParam.sSpatialLayers[iLayer].iSpatialBitrate = atoi (argv[i++]);
}
else if (!strcmp (pCmd, "-trace") && (i < argc))
g_LevelSetting = atoi (argv[i++]);
else if (!strcmp (pCmd, "-dw") && (i < argc))
sParam.iPicWidth = atoi (argv[i++]);
else if (!strcmp (pCmd, "-dh") && (i < argc))
sParam.iPicHeight = atoi (argv[i++]);
}
return 0;
}
void PrintHelp() { void PrintHelp() {
printf ("\n Wels SVC Encoder Usage:\n\n"); printf ("\n Wels SVC Encoder Usage:\n\n");
printf (" Syntax: welsenc.exe -h\n"); printf (" Syntax: welsenc.exe -h\n");
@ -388,6 +326,7 @@ void PrintHelp() {
printf (" -frms Number of total frames to be encoded\n"); printf (" -frms Number of total frames to be encoded\n");
printf (" -gop GOPSize - GOP size (1,2,4,8, default: 1)\n"); printf (" -gop GOPSize - GOP size (1,2,4,8, default: 1)\n");
printf (" -iper Intra period (default: -1) : must be a power of 2 of GOP size (or -1)\n"); 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 (" -spsid Enable id adding in SPS/PPS per IDR \n");
printf (" -denois Control denoising (default: 0)\n"); printf (" -denois Control denoising (default: 0)\n");
printf (" -scene Control scene change detection (default: 0)\n"); printf (" -scene Control scene change detection (default: 0)\n");
@ -395,10 +334,15 @@ void PrintHelp() {
printf (" -aq Control adaptive quantization (default: 0)\n"); printf (" -aq Control adaptive quantization (default: 0)\n");
printf (" -ltr Control long term reference (default: 0)\n"); printf (" -ltr Control long term reference (default: 0)\n");
printf (" -ltrnum Control the number of long term reference((1-4):screen LTR,(1-2):video LTR \n"); printf (" -ltrnum Control the number of long term reference((1-4):screen LTR,(1-2):video LTR \n");
printf (" -threadIdc 0: auto(dynamic imp. internal encoder); 1: multiple threads imp. disabled; > 1: count number of threads \n");
printf (" -deblockIdc Loop filter idc (0: on, 1: off, \n");
printf (" -alphaOffset AlphaOffset(-6..+6): valid range \n");
printf (" -betaOffset BetaOffset (-6..+6): valid range\n");
printf (" -rc rate control mode: 0-quality mode; 1-bitrate mode; 2-bitrate limited mode; -1-rc off \n"); printf (" -rc rate control mode: 0-quality mode; 1-bitrate mode; 2-bitrate limited mode; -1-rc off \n");
printf (" -tarb Overall target bitrate\n"); printf (" -tarb Overall target bitrate\n");
printf (" -numl Number Of Layers: Must exist with layer_cfg file and the number of input layer_cfg file must equal to the value set by this command\n"); printf (" -numl Number Of Layers: Must exist with layer_cfg file and the number of input layer_cfg file must equal to the value set by this command\n");
printf (" The options below are layer-based: (need to be set with layer id)\n"); printf (" The options below are layer-based: (need to be set with layer id)\n");
printf (" -lconfig (Layer) (spatial layer configure file)\n");
printf (" -drec (Layer) (reconstruction file);example: -drec 0 rec.yuv. Setting the reconstruction file, this will only functioning when dumping reconstruction is enabled\n"); printf (" -drec (Layer) (reconstruction file);example: -drec 0 rec.yuv. Setting the reconstruction file, this will only functioning when dumping reconstruction is enabled\n");
printf (" -dw (Layer) (output width)\n"); printf (" -dw (Layer) (output width)\n");
printf (" -dh (Layer) (output height)\n"); printf (" -dh (Layer) (output height)\n");
@ -442,6 +386,9 @@ int ParseCommandLine (int argc, char** argv, SSourcePicture* pSrcPic, SEncParamE
else if (!strcmp (pCommand, "-iper") && (n < argc)) else if (!strcmp (pCommand, "-iper") && (n < argc))
pSvcParam.uiIntraPeriod = atoi (argv[n++]); pSvcParam.uiIntraPeriod = atoi (argv[n++]);
else if (!strcmp (pCommand, "-nalsize") && (n < argc))
pSvcParam.uiMaxNalSize = atoi (argv[n++]);
else if (!strcmp (pCommand, "-spsid") && (n < argc)) else if (!strcmp (pCommand, "-spsid") && (n < argc))
pSvcParam.bEnableSpsPpsIdAddition = atoi (argv[n++]) ? true : false; pSvcParam.bEnableSpsPpsIdAddition = atoi (argv[n++]) ? true : false;
@ -469,6 +416,18 @@ int ParseCommandLine (int argc, char** argv, SSourcePicture* pSrcPic, SEncParamE
else if (!strcmp (pCommand, "-ltrper") && (n < argc)) else if (!strcmp (pCommand, "-ltrper") && (n < argc))
pSvcParam.iLtrMarkPeriod = atoi (argv[n++]); pSvcParam.iLtrMarkPeriod = atoi (argv[n++]);
else if (!strcmp (pCommand, "-threadIdc") && (n < argc))
pSvcParam.iMultipleThreadIdc= atoi (argv[n++]);
else if (!strcmp (pCommand, "-deblockIdc") && (n < argc))
pSvcParam.iLoopFilterDisableIdc = atoi (argv[n++]);
else if (!strcmp (pCommand, "-alphaOffset") && (n < argc))
pSvcParam.iLoopFilterAlphaC0Offset = atoi (argv[n++]);
else if (!strcmp (pCommand, "-betaOffset") && (n < argc))
pSvcParam.iLoopFilterBetaOffset = atoi (argv[n++]);
else if (!strcmp (pCommand, "-rc") && (n < argc)) else if (!strcmp (pCommand, "-rc") && (n < argc))
pSvcParam.iRCMode = static_cast<RC_MODES> (atoi (argv[n++])); pSvcParam.iRCMode = static_cast<RC_MODES> (atoi (argv[n++]));
@ -476,20 +435,17 @@ int ParseCommandLine (int argc, char** argv, SSourcePicture* pSrcPic, SEncParamE
g_LevelSetting = atoi (argv[n++]); g_LevelSetting = atoi (argv[n++]);
else if (!strcmp (pCommand, "-tarb") && (n < argc)) else if (!strcmp (pCommand, "-tarb") && (n < argc))
pSvcParam.iTargetBitrate = atoi (argv[n++]); pSvcParam.iTargetBitrate = 1000*atoi (argv[n++]);
else if (!strcmp (pCommand, "-numl") && (n < argc)) { else if (!strcmp (pCommand, "-numl") && (n < argc)) {
pSvcParam.iSpatialLayerNum = atoi (argv[n++]); pSvcParam.iSpatialLayerNum = atoi (argv[n++]);
for (int ln = 0 ; (ln < pSvcParam.iSpatialLayerNum) && (n < argc) ; ln++) { }
// pSvcParam.sDependencyLayers[ln].uiDependencyId = ln; else if (!strcmp (pCommand, "-lconfig") && (n < argc)) {
sFileSet.strLayerCfgFile[ln].assign (argv[n++]); unsigned int iLayer = atoi (argv[n++]);
} sFileSet.strLayerCfgFile[iLayer].assign (argv[n++]);
CReadConfig cRdLayerCfg (sFileSet.strLayerCfgFile[iLayer]);
for (int8_t iLayer = 0; iLayer < pSvcParam.iSpatialLayerNum; ++ iLayer) { if (-1 == ParseLayerConfig (cRdLayerCfg, iLayer, pSvcParam, sFileSet)) {
CReadConfig cRdLayerCfg (sFileSet.strLayerCfgFile[iLayer]); return 1;
if (-1 == ParseLayerConfig (cRdLayerCfg, iLayer, pSvcParam, sFileSet)) {
return 1;
}
} }
} else if (!strcmp (pCommand, "-drec") && (n + 1 < argc)) { } else if (!strcmp (pCommand, "-drec") && (n + 1 < argc)) {
unsigned int iLayer = atoi (argv[n++]); unsigned int iLayer = atoi (argv[n++]);
@ -595,9 +551,10 @@ int FillSpecificParameters (SEncParamExt& sParam) {
sParam.iInputCsp = videoFormatI420; // color space of input sequence sParam.iInputCsp = videoFormatI420; // color space of input sequence
sParam.uiIntraPeriod = 320; // period of Intra frame sParam.uiIntraPeriod = 320; // period of Intra frame
sParam.bEnableSpsPpsIdAddition = 1; sParam.bEnableSpsPpsIdAddition = 1;
sParam.bPrefixNalAddingCtrl = 1; sParam.bPrefixNalAddingCtrl = 0;
int iIndexLayer = 0; int iIndexLayer = 0;
sParam.sSpatialLayers[iIndexLayer].uiProfileIdc = PRO_BASELINE;
sParam.sSpatialLayers[iIndexLayer].iVideoWidth = 160; sParam.sSpatialLayers[iIndexLayer].iVideoWidth = 160;
sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 90; sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 90;
sParam.sSpatialLayers[iIndexLayer].fFrameRate = 7.5f; sParam.sSpatialLayers[iIndexLayer].fFrameRate = 7.5f;
@ -605,6 +562,7 @@ int FillSpecificParameters (SEncParamExt& sParam) {
sParam.sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE; sParam.sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
++ iIndexLayer; ++ iIndexLayer;
sParam.sSpatialLayers[iIndexLayer].uiProfileIdc = PRO_SCALABLE_BASELINE;
sParam.sSpatialLayers[iIndexLayer].iVideoWidth = 320; sParam.sSpatialLayers[iIndexLayer].iVideoWidth = 320;
sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 180; sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 180;
sParam.sSpatialLayers[iIndexLayer].fFrameRate = 15.0f; sParam.sSpatialLayers[iIndexLayer].fFrameRate = 15.0f;
@ -612,6 +570,7 @@ int FillSpecificParameters (SEncParamExt& sParam) {
sParam.sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE; sParam.sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
++ iIndexLayer; ++ iIndexLayer;
sParam.sSpatialLayers[iIndexLayer].uiProfileIdc = PRO_SCALABLE_BASELINE;
sParam.sSpatialLayers[iIndexLayer].iVideoWidth = 640; sParam.sSpatialLayers[iIndexLayer].iVideoWidth = 640;
sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 360; sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 360;
sParam.sSpatialLayers[iIndexLayer].fFrameRate = 30.0f; sParam.sSpatialLayers[iIndexLayer].fFrameRate = 30.0f;
@ -620,6 +579,7 @@ int FillSpecificParameters (SEncParamExt& sParam) {
sParam.sSpatialLayers[iIndexLayer].sSliceCfg.sSliceArgument.uiSliceNum = 1; sParam.sSpatialLayers[iIndexLayer].sSliceCfg.sSliceArgument.uiSliceNum = 1;
++ iIndexLayer; ++ iIndexLayer;
sParam.sSpatialLayers[iIndexLayer].uiProfileIdc = PRO_SCALABLE_BASELINE;
sParam.sSpatialLayers[iIndexLayer].iVideoWidth = 1280; sParam.sSpatialLayers[iIndexLayer].iVideoWidth = 1280;
sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 720; sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 720;
sParam.sSpatialLayers[iIndexLayer].fFrameRate = 30.0f; sParam.sSpatialLayers[iIndexLayer].fFrameRate = 30.0f;
@ -637,174 +597,7 @@ int FillSpecificParameters (SEncParamExt& sParam) {
return 0; return 0;
} }
/* For SVC Demo test */ int ProcessEncoding(ISVCEncoder* pPtrEnc, int argc, char** argv,bool bConfigFile) {
int ProcessEncodingSvcWithParam (ISVCEncoder* pPtrEnc, int argc, char** argv) {
const char* kpSrcFile = argv[1];
const char* kpStrBsFile = argv[2];
if (pPtrEnc == NULL || kpSrcFile == NULL || kpStrBsFile == NULL)
return 1;
FILE* pFpBs = NULL;
FILE* pFpSrc = NULL;
SFrameBSInfo sFbi;
SEncParamExt sSvcParam;
int64_t iStart = 0, iTotal = 0;
int32_t ret = 0;
int32_t iPicLumaSize = 0;
int32_t iFrameSize = 0;
uint8_t* pPlanes[3] = { 0 };
int32_t iFrame = 0;
SSourcePicture* pSrcPic = NULL;
#if defined ( STICK_STREAM_SIZE )
FILE* fTrackStream = fopen ("coding_size.stream", "wb");;
#endif
pFpSrc = fopen (kpSrcFile, "rb");
if (NULL == pFpSrc)
return 1;
pFpBs = fopen (kpStrBsFile, "wb");
if (NULL == pFpBs) {
fclose (pFpSrc);
pFpSrc = NULL;
return 1;
}
memset (&sFbi, 0, sizeof (SFrameBSInfo));
memset (&sSvcParam, 0, sizeof (SEncParamExt));
FillSpecificParameters (sSvcParam);
int iParsedNum = 3;
if (ParseCommandLine (argc - iParsedNum, argv + iParsedNum, sSvcParam) != 0) {
printf ("parse pCommand line failed\n");
ret = 1;
goto ERROR_RET;
}
pPtrEnc->SetOption (ENCODER_OPTION_TRACE_LEVEL, &g_LevelSetting);
if (cmResultSuccess != pPtrEnc->InitializeExt (&sSvcParam)) {
fprintf (stderr, "Encoder Initialization failed!\n");
ret = 1;
goto ERROR_RET;
}
iPicLumaSize = sSvcParam.iPicWidth * sSvcParam.iPicHeight;
switch (sSvcParam.iInputCsp) {
int iStride;
case videoFormatI420:
case videoFormatYV12:
iFrameSize = (3 * iPicLumaSize) >> 1;
pPlanes[0] = new uint8_t[iFrameSize];
pPlanes[1] = pPlanes[0] + iPicLumaSize;
pPlanes[2] = pPlanes[1] + (iPicLumaSize >> 2);
break;
case videoFormatYUY2:
case videoFormatYVYU:
case videoFormatUYVY:
iStride = CALC_BI_STRIDE (sSvcParam.iPicWidth, 16);
iFrameSize = iStride * sSvcParam.iPicHeight;
pPlanes[0] = new uint8_t[iFrameSize];
break;
case videoFormatRGB:
case videoFormatBGR:
iStride = CALC_BI_STRIDE (sSvcParam.iPicWidth, 24);
iFrameSize = iStride * sSvcParam.iPicHeight;
pPlanes[0] = new uint8_t[iFrameSize];
break;
case videoFormatBGRA:
case videoFormatRGBA:
case videoFormatARGB:
case videoFormatABGR:
iStride = 4 * sSvcParam.iPicWidth;
iFrameSize = iStride * sSvcParam.iPicHeight;
pPlanes[0] = new uint8_t[iFrameSize];
break;
default:
ret = 1;
goto ERROR_RET;
}
pSrcPic = new SSourcePicture;
if (pSrcPic == NULL) {
ret = 1;
goto ERROR_RET;
}
pSrcPic->iColorFormat = sSvcParam.iInputCsp;
pSrcPic->iPicHeight = sSvcParam.iPicHeight;
pSrcPic->iPicWidth = sSvcParam.iPicWidth;
pSrcPic->iStride[0] = sSvcParam.iPicWidth;
pSrcPic->iStride[1] = pSrcPic->iStride[2] = sSvcParam.iPicWidth >> 1;
pSrcPic->pData[0] = pPlanes[0];
pSrcPic->pData[1] = pSrcPic->pData[0] + (sSvcParam.iPicWidth * sSvcParam.iPicHeight);
pSrcPic->pData[2] = pSrcPic->pData[1] + (sSvcParam.iPicWidth * sSvcParam.iPicHeight >> 2);
while (true) {
if (feof (pFpSrc))
break;
#ifdef ONLY_ENC_FRAMES_NUM
if (iFrame >= ONLY_ENC_FRAMES_NUM)
break;
#endif//ONLY_ENC_FRAMES_NUM
if (fread (pPlanes[0], sizeof (uint8_t), iFrameSize, pFpSrc) <= 0)
break;
iStart = WelsTime();
long iEncode = pPtrEnc->EncodeFrame (pSrcPic, &sFbi);
iTotal += WelsTime() - iStart;
if (cmResultSuccess != iEncode) {
fprintf (stderr, "EncodeFrame() failed: %ld.\n", iEncode);
break;
}
/* Write bit-stream */
if (pFpBs != NULL && videoFrameTypeSkip != sFbi.eOutputFrameType) { // file handler to write bit stream
int iLayer = 0;
while (iLayer < sFbi.iLayerNum) {
SLayerBSInfo* pLayerBsInfo = &sFbi.sLayerInfo[iLayer];
if (pLayerBsInfo != NULL) {
int iLayerSize = 0;
int iNalIdx = pLayerBsInfo->iNalCount - 1;
do {
iLayerSize += pLayerBsInfo->iNalLengthInByte[iNalIdx];
-- iNalIdx;
} while (iNalIdx >= 0);
fwrite (pLayerBsInfo->pBsBuf, 1, iLayerSize, pFpBs); // write pure bit stream into file
}
++ iLayer;
}
++ iFrame;
}
}
if (iFrame > 0) {
double dElapsed = iTotal / 1e6;
printf ("Frames: %d\nencode time: %f sec\nFPS: %f fps\n", iFrame, dElapsed, (iFrame * 1.0) / dElapsed);
}
if (NULL != pPlanes[0]) {
delete [] pPlanes[0];
pPlanes[0] = NULL;
}
ERROR_RET:
if (pFpBs) {
fclose (pFpBs);
pFpBs = NULL;
}
if (pFpSrc) {
fclose (pFpSrc);
pFpSrc = NULL;
}
if (pSrcPic) {
delete pSrcPic;
pSrcPic = NULL;
}
return ret;
}
int ProcessEncodingSvcWithConfig (ISVCEncoder* pPtrEnc, int argc, char** argv) {
int iRet = 0; int iRet = 0;
if (pPtrEnc == NULL) if (pPtrEnc == NULL)
@ -834,24 +627,13 @@ int ProcessEncodingSvcWithConfig (ISVCEncoder* pPtrEnc, int argc, char** argv) {
SFilesSet fs; SFilesSet fs;
// for configuration file // for configuration file
CReadConfig cRdCfg; CReadConfig cRdCfg;
int iParsedNum = 2; int iParsedNum = 1;
memset (&sFbi, 0, sizeof (SFrameBSInfo)); memset (&sFbi, 0, sizeof (SFrameBSInfo));
memset (&sSvcParam, 0, sizeof (SEncParamExt)); memset (&sSvcParam, 0, sizeof (SEncParamExt));
memset (&fs.sRecFileName[0][0], 0, sizeof (fs.sRecFileName)); memset (&fs.sRecFileName[0][0], 0, sizeof (fs.sRecFileName));
sSvcParam.iInputCsp = videoFormatI420; // I420 in default
sSvcParam.sSpatialLayers[0].uiProfileIdc = PRO_BASELINE;
// svc_cfg->sDependencyLayers[0].frext_mode = 0;
// for configuration file
cRdCfg.Openf (argv[1]);
if (!cRdCfg.ExistFile()) {
fprintf (stderr, "Specified file: %s not exist, maybe invalid path or parameter settting.\n",
cRdCfg.GetFileName().c_str());
iRet = 1;
goto INSIDE_MEM_FREE;
}
FillSpecificParameters (sSvcParam);
pSrcPic = new SSourcePicture; pSrcPic = new SSourcePicture;
if (pSrcPic == NULL) { if (pSrcPic == NULL) {
iRet = 1; iRet = 1;
@ -860,19 +642,29 @@ int ProcessEncodingSvcWithConfig (ISVCEncoder* pPtrEnc, int argc, char** argv) {
//fill default pSrcPic //fill default pSrcPic
pSrcPic->iColorFormat = videoFormatI420; pSrcPic->iColorFormat = videoFormatI420;
pSrcPic->uiTimeStamp = 0; pSrcPic->uiTimeStamp = 0;
iRet = ParseConfig (cRdCfg, pSrcPic, sSvcParam, fs);
if (iRet) {
fprintf (stderr, "parse svc parameter config file failed.\n");
iRet = 1;
goto INSIDE_MEM_FREE;
}
// if configure file exit, reading configure file firstly
if(bConfigFile){
iParsedNum = 2;
cRdCfg.Openf (argv[1]);
if (!cRdCfg.ExistFile()) {
fprintf (stderr, "Specified file: %s not exist, maybe invalid path or parameter settting.\n",
cRdCfg.GetFileName().c_str());
iRet = 1;
goto INSIDE_MEM_FREE;
}
iRet = ParseConfig (cRdCfg, pSrcPic, sSvcParam, fs);
if (iRet) {
fprintf (stderr, "parse svc parameter config file failed.\n");
iRet = 1;
goto INSIDE_MEM_FREE;
}
}
if (ParseCommandLine (argc - iParsedNum, argv + iParsedNum, pSrcPic, sSvcParam, fs) != 0) { if (ParseCommandLine (argc - iParsedNum, argv + iParsedNum, pSrcPic, sSvcParam, fs) != 0) {
printf ("parse pCommand line failed\n"); printf ("parse pCommand line failed\n");
iRet = 1; iRet = 1;
goto INSIDE_MEM_FREE; goto INSIDE_MEM_FREE;
} }
//finish reading the configurations //finish reading the configurations
iSourceWidth = pSrcPic->iPicWidth; iSourceWidth = pSrcPic->iPicWidth;
iSourceHeight = pSrcPic->iPicHeight; iSourceHeight = pSrcPic->iPicHeight;
@ -893,6 +685,8 @@ int ProcessEncodingSvcWithConfig (ISVCEncoder* pPtrEnc, int argc, char** argv) {
pSrcPic->pData[2] = pSrcPic->pData[1] + (iSourceWidth * iSourceHeight >> 2); pSrcPic->pData[2] = pSrcPic->pData[1] + (iSourceWidth * iSourceHeight >> 2);
//update sSvcParam //update sSvcParam
sSvcParam.iPicWidth = 0;
sSvcParam.iPicHeight = 0;
for (int iLayer = 0; iLayer < sSvcParam.iSpatialLayerNum; iLayer++) { for (int iLayer = 0; iLayer < sSvcParam.iSpatialLayerNum; iLayer++) {
SSpatialLayerConfig* pDLayer = &sSvcParam.sSpatialLayers[iLayer]; SSpatialLayerConfig* pDLayer = &sSvcParam.sSpatialLayers[iLayer];
sSvcParam.iPicWidth = WELS_MAX (sSvcParam.iPicWidth, pDLayer->iVideoWidth); sSvcParam.iPicWidth = WELS_MAX (sSvcParam.iPicWidth, pDLayer->iVideoWidth);
@ -1139,7 +933,7 @@ int main (int argc, char** argv)
} else { } else {
if (!strstr (argv[1], ".cfg")) { // check configuration type (like .cfg?) if (!strstr (argv[1], ".cfg")) { // check configuration type (like .cfg?)
if (argc > 2) { if (argc > 2) {
iRet = ProcessEncodingSvcWithParam (pSVCEncoder, argc, argv); iRet = ProcessEncoding(pSVCEncoder, argc, argv,false);
if (iRet != 0) if (iRet != 0)
goto exit; goto exit;
} else if (argc == 2 && ! strcmp (argv[1], "-h")) } else if (argc == 2 && ! strcmp (argv[1], "-h"))
@ -1149,7 +943,7 @@ int main (int argc, char** argv)
goto exit; goto exit;
} }
} else { } else {
iRet = ProcessEncodingSvcWithConfig (pSVCEncoder, argc, argv); iRet = ProcessEncoding(pSVCEncoder, argc, argv,true);
if (iRet > 0) if (iRet > 0)
goto exit; goto exit;
} }

View File

@ -96,6 +96,8 @@ bool CheckAccessUnitBoundary (PWelsDecoderContext pCtx, const PNalUnit kpCurNal,
const PSps kpSps); const PSps kpSps);
bool CheckAccessUnitBoundaryExt (PNalUnitHeaderExt pLastNalHdrExt, PNalUnitHeaderExt pCurNalHeaderExt, bool CheckAccessUnitBoundaryExt (PNalUnitHeaderExt pLastNalHdrExt, PNalUnitHeaderExt pCurNalHeaderExt,
PSliceHeader pLastSliceHeader, PSliceHeader pCurSliceHeader); PSliceHeader pLastSliceHeader, PSliceHeader pCurSliceHeader);
bool CheckNextAuNewSeq (PWelsDecoderContext pCtx, const PNalUnit kpCurNal, const PSps kpSps);
/*! /*!
************************************************************************************* *************************************************************************************
* \brief to parse Sequence Parameter Set (SPS) * \brief to parse Sequence Parameter Set (SPS)

View File

@ -93,6 +93,7 @@
#define MAX_NAL_UNIT_NUM_IN_AU 32 // predefined maximal number of NAL Units in an access unit #define MAX_NAL_UNIT_NUM_IN_AU 32 // predefined maximal number of NAL Units in an access unit
#define MAX_ACCESS_UNIT_CAPACITY 1048576 // Maximal AU capacity in bytes: (1<<20) = 1024 KB predefined #define MAX_ACCESS_UNIT_CAPACITY 1048576 // Maximal AU capacity in bytes: (1<<20) = 1024 KB predefined
#define BS_BUFFER_SIZE (MAX_ACCESS_UNIT_CAPACITY * 3) //for delay case, keep three AU size to prevent buffer overwrite
#define MAX_MACROBLOCK_CAPACITY 5000 //Maximal legal MB capacity, 15000 bits is enough #define MAX_MACROBLOCK_CAPACITY 5000 //Maximal legal MB capacity, 15000 bits is enough
#endif//WELS_CONSTANCE_H__ #endif//WELS_CONSTANCE_H__

View File

@ -322,12 +322,16 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
return NULL; return NULL;
} }
if ((uiAvailNalNum == 1) && ((NAL_UNIT_CODED_SLICE_IDR == pNalUnitHeader->eNalUnitType)
|| (pCurNal->sNalHeaderExt.bIdrFlag))) {
ResetActiveSPSForEachLayer (pCtx);
}
if ((uiAvailNalNum > 1) && if ((uiAvailNalNum > 1) &&
CheckAccessUnitBoundary (pCtx, pCurAu->pNalUnitsList[uiAvailNalNum - 1], pCurAu->pNalUnitsList[uiAvailNalNum - 2], CheckAccessUnitBoundary (pCtx, pCurAu->pNalUnitsList[uiAvailNalNum - 1], pCurAu->pNalUnitsList[uiAvailNalNum - 2],
pCurAu->pNalUnitsList[uiAvailNalNum - 1]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps)) { pCurAu->pNalUnitsList[uiAvailNalNum - 1]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps)) {
pCurAu->uiEndPos = uiAvailNalNum - 2; pCurAu->uiEndPos = uiAvailNalNum - 2;
pCtx->bAuReadyFlag = true; pCtx->bAuReadyFlag = true;
pCtx->bNextNewSeqBegin = CheckNextAuNewSeq (pCtx, pCurNal, pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps);
} }
} }
@ -407,10 +411,9 @@ bool CheckAccessUnitBoundary (PWelsDecoderContext pCtx, const PNalUnit kpCurNal,
const SSliceHeader* kpCurSliceHeader = &kpCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader; const SSliceHeader* kpCurSliceHeader = &kpCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;
if (pCtx->pActiveLayerSps[kpCurNalHeaderExt->uiDependencyId] != NULL if (pCtx->pActiveLayerSps[kpCurNalHeaderExt->uiDependencyId] != NULL
&& pCtx->pActiveLayerSps[kpCurNalHeaderExt->uiDependencyId] != kpSps) { && pCtx->pActiveLayerSps[kpCurNalHeaderExt->uiDependencyId] != kpSps) {
pCtx->bNextNewSeqBegin = true;
return true; // the active sps changed, new sequence begins, so the current au is ready return true; // the active sps changed, new sequence begins, so the current au is ready
} }
//Sub-clause 7.1.4.1.1 temporal_id //Sub-clause 7.1.4.1.1 temporal_id
if (kpLastNalHeaderExt->uiTemporalId != kpCurNalHeaderExt->uiTemporalId) { if (kpLastNalHeaderExt->uiTemporalId != kpCurNalHeaderExt->uiTemporalId) {
return true; return true;
@ -456,6 +459,17 @@ bool CheckAccessUnitBoundary (PWelsDecoderContext pCtx, const PNalUnit kpCurNal,
return false; return false;
} }
bool CheckNextAuNewSeq (PWelsDecoderContext pCtx, const PNalUnit kpCurNal, const PSps kpSps) {
const PNalUnitHeaderExt kpCurNalHeaderExt = &kpCurNal->sNalHeaderExt;
if (pCtx->pActiveLayerSps[kpCurNalHeaderExt->uiDependencyId] != NULL
&& pCtx->pActiveLayerSps[kpCurNalHeaderExt->uiDependencyId] != kpSps)
return true;
if (kpCurNalHeaderExt->bIdrFlag)
return true;
return false;
}
/*! /*!
************************************************************************************* *************************************************************************************
* \brief to parse NON VCL NAL Units * \brief to parse NON VCL NAL Units
@ -493,7 +507,8 @@ int32_t ParseNonVclNal (PWelsDecoderContext pCtx, uint8_t* pRbsp, const int32_t
#endif #endif
iErr = ParseSps (pCtx, pBs, &iPicWidth, &iPicHeight); iErr = ParseSps (pCtx, pBs, &iPicWidth, &iPicHeight);
if (ERR_NONE != iErr) { // modified for pSps/pSubsetSps invalid, 12/1/2009 if (ERR_NONE != iErr) { // modified for pSps/pSubsetSps invalid, 12/1/2009
pCtx->iErrorCode |= dsNoParamSets; if (pCtx->iErrorConMethod == ERROR_CON_DISABLE)
pCtx->iErrorCode |= dsNoParamSets;
return iErr; return iErr;
} }
@ -507,7 +522,8 @@ int32_t ParseNonVclNal (PWelsDecoderContext pCtx, uint8_t* pRbsp, const int32_t
#endif #endif
iErr = ParsePps (pCtx, &pCtx->sPpsBuffer[0], pBs); iErr = ParsePps (pCtx, &pCtx->sPpsBuffer[0], pBs);
if (ERR_NONE != iErr) { // modified for pps invalid, 12/1/2009 if (ERR_NONE != iErr) { // modified for pps invalid, 12/1/2009
pCtx->iErrorCode |= dsNoParamSets; if (pCtx->iErrorConMethod == ERROR_CON_DISABLE)
pCtx->iErrorCode |= dsNoParamSets;
return iErr; return iErr;
} }

View File

@ -314,13 +314,13 @@ int32_t WelsInitMemory (PWelsDecoderContext pCtx) {
if (MemInitNalList (&pCtx->pAccessUnitList, MAX_NAL_UNIT_NUM_IN_AU) != 0) if (MemInitNalList (&pCtx->pAccessUnitList, MAX_NAL_UNIT_NUM_IN_AU) != 0)
return ERR_INFO_OUT_OF_MEMORY; return ERR_INFO_OUT_OF_MEMORY;
if ((pCtx->sRawData.pHead = static_cast<uint8_t*> (WelsMalloc (MAX_ACCESS_UNIT_CAPACITY, if ((pCtx->sRawData.pHead = static_cast<uint8_t*> (WelsMalloc (BS_BUFFER_SIZE,
"pCtx->sRawData->pHead"))) == NULL) { "pCtx->sRawData->pHead"))) == NULL) {
return ERR_INFO_OUT_OF_MEMORY; return ERR_INFO_OUT_OF_MEMORY;
} }
pCtx->sRawData.pStartPos = pCtx->sRawData.pStartPos =
pCtx->sRawData.pCurPos = pCtx->sRawData.pHead; pCtx->sRawData.pCurPos = pCtx->sRawData.pHead;
pCtx->sRawData.pEnd = pCtx->sRawData.pHead + MAX_ACCESS_UNIT_CAPACITY; pCtx->sRawData.pEnd = pCtx->sRawData.pHead + BS_BUFFER_SIZE;
pCtx->uiTargetDqId = (uint8_t) - 1; pCtx->uiTargetDqId = (uint8_t) - 1;
pCtx->bEndOfStreamFlag = false; pCtx->bEndOfStreamFlag = false;

View File

@ -64,7 +64,7 @@ class CWelsDecoder : public ISVCDecoder {
/*************************************************************************** /***************************************************************************
* Description: * Description:
* Decompress one frame, and output RGB24 or YV12 decoded stream and its length. * Decompress one frame, and output I420 or RGB24(in the future) decoded stream and its length.
* Input parameters: * Input parameters:
* Parameter TYPE Description * Parameter TYPE Description
* pSrc unsigned char* the h264 stream to decode * pSrc unsigned char* the h264 stream to decode
@ -83,7 +83,7 @@ class CWelsDecoder : public ISVCDecoder {
virtual DECODING_STATE EXTAPI DecodeFrame2 (const unsigned char* kpSrc, virtual DECODING_STATE EXTAPI DecodeFrame2 (const unsigned char* kpSrc,
const int kiSrcLen, const int kiSrcLen,
void** ppDst, unsigned char** ppDst,
SBufferInfo* pDstInfo); SBufferInfo* pDstInfo);
virtual DECODING_STATE EXTAPI DecodeFrameEx (const unsigned char* kpSrc, virtual DECODING_STATE EXTAPI DecodeFrameEx (const unsigned char* kpSrc,
const int kiSrcLen, const int kiSrcLen,

View File

@ -320,13 +320,13 @@ long CWelsDecoder::GetOption (DECODER_OPTION eOptID, void* pOption) {
DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc, DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
const int kiSrcLen, const int kiSrcLen,
void** ppDst, unsigned char** ppDst,
SBufferInfo* pDstInfo) { SBufferInfo* pDstInfo) {
if (kiSrcLen > MAX_ACCESS_UNIT_CAPACITY - MAX_MACROBLOCK_CAPACITY) {//prevent from residual reading overflow if (kiSrcLen > MAX_ACCESS_UNIT_CAPACITY - MAX_MACROBLOCK_CAPACITY) {//prevent from residual reading overflow
m_pDecContext->iErrorCode |= dsOutOfMemory; m_pDecContext->iErrorCode |= dsOutOfMemory;
IWelsTrace::WelsVTrace (m_pTrace, IWelsTrace::WELS_LOG_INFO, IWelsTrace::WelsVTrace (m_pTrace, IWelsTrace::WELS_LOG_INFO,
"max AU size exceeded. Allowed size = %d, current size = %d", "max AU size exceeded. Allowed size = %d, current size = %d",
MAX_ACCESS_UNIT_CAPACITY, kiSrcLen); MAX_ACCESS_UNIT_CAPACITY - MAX_MACROBLOCK_CAPACITY, kiSrcLen);
return dsOutOfMemory; return dsOutOfMemory;
} }
if (kiSrcLen > 0 && kpSrc != NULL) { if (kiSrcLen > 0 && kpSrc != NULL) {
@ -361,7 +361,7 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
m_pDecContext->iFeedbackTidInAu = -1; //initialize m_pDecContext->iFeedbackTidInAu = -1; //initialize
WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, (unsigned char**)ppDst, WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, ppDst,
pDstInfo); //iErrorCode has been modified in this function pDstInfo); //iErrorCode has been modified in this function
if (m_pDecContext->iErrorCode) { if (m_pDecContext->iErrorCode) {
@ -406,7 +406,7 @@ DECODING_STATE CWelsDecoder::DecodeFrame (const unsigned char* kpSrc,
DstInfo.UsrData.sSystemBuffer.iWidth = iWidth; DstInfo.UsrData.sSystemBuffer.iWidth = iWidth;
DstInfo.UsrData.sSystemBuffer.iHeight = iHeight; DstInfo.UsrData.sSystemBuffer.iHeight = iHeight;
eDecState = DecodeFrame2 (kpSrc, kiSrcLen, (void**)ppDst, &DstInfo); eDecState = DecodeFrame2 (kpSrc, kiSrcLen, ppDst, &DstInfo);
if (eDecState == dsErrorFree) { if (eDecState == dsErrorFree) {
pStride[0] = DstInfo.UsrData.sSystemBuffer.iStride[0]; pStride[0] = DstInfo.UsrData.sSystemBuffer.iStride[0];
pStride[1] = DstInfo.UsrData.sSystemBuffer.iStride[1]; pStride[1] = DstInfo.UsrData.sSystemBuffer.iStride[1];

View File

@ -64,7 +64,7 @@ namespace WelsSVCEnc {
*/ */
typedef struct TagRefList { typedef struct TagRefList {
SPicture* pShortRefList[1 + MAX_SHORT_REF_COUNT]; // reference list 0 - int16_t SPicture* pShortRefList[1 + MAX_SHORT_REF_COUNT]; // reference list 0 - int16_t
SPicture* pLongRefList[1 + MAX_LONG_REF_COUNT]; // reference list 1 - int32_t SPicture* pLongRefList[1 + MAX_REF_PIC_COUNT]; // reference list 1 - int32_t
SPicture* pNextBuffer; SPicture* pNextBuffer;
SPicture* pRef[1 + MAX_REF_PIC_COUNT]; // plus 1 for swap intend SPicture* pRef[1 + MAX_REF_PIC_COUNT]; // plus 1 for swap intend
uint8_t uiShortRefCount; uint8_t uiShortRefCount;

View File

@ -66,6 +66,8 @@ enum {
VGOP_SIZE = 8, VGOP_SIZE = 8,
//qp information //qp information
FIX_MIN_QP_MODE = 10, //qp <10 will cause level code overflow in cavlc coding which isn't suppored in baseline profile
FIX_MAX_QP_MODE = 51,
GOM_MIN_QP_MODE = 12, GOM_MIN_QP_MODE = 12,
GOM_MAX_QP_MODE = 36, GOM_MAX_QP_MODE = 36,
MAX_LOW_BR_QP = 42, MAX_LOW_BR_QP = 42,

View File

@ -178,9 +178,8 @@ class CWelsPreProcess {
uint8_t m_uiSpatialPicNum[MAX_DEPENDENCY_LAYER]; uint8_t m_uiSpatialPicNum[MAX_DEPENDENCY_LAYER];
public: public:
/* For Downsampling & VAA I420 based source pictures */ /* For Downsampling & VAA I420 based source pictures */
SPicture* m_pSpatialPic[MAX_DEPENDENCY_LAYER][MAX_TEMPORAL_LEVEL + 1 + SPicture* m_pSpatialPic[MAX_DEPENDENCY_LAYER][MAX_REF_PIC_COUNT+1];
LONG_TERM_REF_NUM]; // need memory requirement with total number of (log2(uiGopSize)+1+1+long_term_ref_num) // need memory requirement with total number of (log2(uiGopSize)+1+1+long_term_ref_num)
}; };
} }

View File

@ -41,14 +41,6 @@
#include "au_set.h" #include "au_set.h"
#include "svc_enc_golomb.h" #include "svc_enc_golomb.h"
namespace WelsSVCEnc { namespace WelsSVCEnc {
static const uint32_t g_kuiMaxDPBx2AtLevel[52] = { // *2 on the basic of Annex A, Table A-1, for int32_t type
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0~9
297, 675, 1782, 1782, 0, 0, 0, 0, 0, 0, //10, 11, 12, 13
1782, 3564, 6075, 0, 0, 0, 0, 0, 0, 0, //20, 21, 22
6075, 13500, 15360, 0, 0, 0, 0, 0, 0, 0, //30, 31, 32
24576, 24576, 26112, 0, 0, 0, 0, 0, 0, 0, //40, 41, 42
82800, 138240 //50, 51
};
#define LEVEL_NUMBER 16 #define LEVEL_NUMBER 16

View File

@ -115,37 +115,6 @@ static const uint8_t g_kuiTableBIdx[2][8] = {
}, // table_bn_idx }, // table_bn_idx
}; };
static const ALIGNED_DECLARE (int32_t, g_kiTableBlock8x8Idx[2][4][4], 16) = {
{
{0, 0, 2, 2},
{0, 0, 2, 2},
{1, 1, 3, 3},
{1, 1, 3, 3}
},
{
{0, 0, 1, 1},
{0, 0, 1, 1},
{2, 2, 3, 3},
{2, 2, 3, 3}
}
};
static const ALIGNED_DECLARE (int32_t, g_kiTableBlock8x8NIdx[2][4][4], 16) = {
{
{1, 1, 3, 3},
{0, 0, 2, 2},
{0, 0, 2, 2},
{1, 1, 3, 3}
},
{
{2, 2, 3, 3},
{0, 0, 1, 1},
{0, 0, 1, 1},
{2, 2, 3, 3}
}
};
#define TC0_TBL_LOOKUP(iTc, iIdexA, pBS, bchroma) \ #define TC0_TBL_LOOKUP(iTc, iIdexA, pBS, bchroma) \
{\ {\
iTc[0] = g_kiTc0Table(iIdexA)[pBS[0]] + bchroma;\ iTc[0] = g_kiTc0Table(iIdexA)[pBS[0]] + bchroma;\

View File

@ -112,6 +112,19 @@ int32_t ParamValidation (SWelsSvcCodingParam* pCfg) {
pCfg->fMaxFrameRate = fMaxFrameRate; pCfg->fMaxFrameRate = fMaxFrameRate;
} }
//bitrate setting validation
if (pCfg->iRCMode != RC_OFF_MODE){
int32_t iTotalBitrate = 0;
for (i = 0; i < pCfg->iSpatialLayerNum; ++ i) {
SDLayerParam* fDlp = &pCfg->sDependencyLayers[i];
iTotalBitrate += fDlp->iSpatialBitrate;
}
if(iTotalBitrate > pCfg->iTargetBitrate){
WelsLog(NULL, WELS_LOG_ERROR,"Invalid setttings in bitrate. the sum of each layer bitrate(%d) is larger than total bitrate setting(%d)\n",
iTotalBitrate,pCfg->iTargetBitrate);
}
}
return ENC_RETURN_SUCCESS; return ENC_RETURN_SUCCESS;
} }
@ -1272,7 +1285,7 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
fCompressRatioThr = COMPRESS_RATIO_THR; fCompressRatioThr = COMPRESS_RATIO_THR;
iLayerBsSize = WELS_ROUND (((3 * fDlp->iFrameWidth * fDlp->iFrameHeight) >> 1) * fCompressRatioThr); iLayerBsSize = WELS_ROUND (((3 * fDlp->iFrameWidth * fDlp->iFrameHeight) >> 1) * fCompressRatioThr) + MAX_MACROBLOCK_SIZE_IN_BYTE;
iLayerBsSize = WELS_ALIGN (iLayerBsSize, 4); // 4 bytes alinged iLayerBsSize = WELS_ALIGN (iLayerBsSize, 4); // 4 bytes alinged
iVclLayersBsSizeCount += iLayerBsSize; iVclLayersBsSizeCount += iLayerBsSize;
++ iIndex; ++ iIndex;

View File

@ -127,10 +127,10 @@ void RcInitSequenceParameter (sWelsEncCtx* pEncCtx) {
pWelsSvcRc->dSkipBufferRatio = SKIP_RATIO; pWelsSvcRc->dSkipBufferRatio = SKIP_RATIO;
pWelsSvcRc->iQpRangeUpperInFrame = QP_RANGE_UPPER_MODE1 - (int32_t) ((QP_RANGE_UPPER_MODE1 - QP_RANGE_MODE0) * pWelsSvcRc->iQpRangeUpperInFrame = QP_RANGE_UPPER_MODE1 - WELS_ROUND ((QP_RANGE_UPPER_MODE1 - QP_RANGE_MODE0) *
pWelsSvcRc->dRcVaryRatio + 0.5); pWelsSvcRc->dRcVaryRatio);
pWelsSvcRc->iQpRangeLowerInFrame = QP_RANGE_LOWER_MODE1 - (int32_t) ((QP_RANGE_LOWER_MODE1 - QP_RANGE_MODE0) * pWelsSvcRc->iQpRangeLowerInFrame = QP_RANGE_LOWER_MODE1 - WELS_ROUND ((QP_RANGE_LOWER_MODE1 - QP_RANGE_MODE0) *
pWelsSvcRc->dRcVaryRatio + 0.5); pWelsSvcRc->dRcVaryRatio);
if (iMbWidth <= MB_WIDTH_THRESHOLD_90P) { if (iMbWidth <= MB_WIDTH_THRESHOLD_90P) {
pWelsSvcRc->iSkipQpValue = SKIP_QP_90P; pWelsSvcRc->iSkipQpValue = SKIP_QP_90P;
@ -149,17 +149,17 @@ void RcInitSequenceParameter (sWelsEncCtx* pEncCtx) {
iGomRowMode0 = GOM_ROW_MODE0_720P; iGomRowMode0 = GOM_ROW_MODE0_720P;
iGomRowMode1 = GOM_ROW_MODE1_720P; iGomRowMode1 = GOM_ROW_MODE1_720P;
} }
iGomRowMode0 = iGomRowMode1 + (int32_t) ((iGomRowMode0 - iGomRowMode1) * pWelsSvcRc->dRcVaryRatio + 0.5); iGomRowMode0 = iGomRowMode1 + WELS_ROUND ((iGomRowMode0 - iGomRowMode1) * pWelsSvcRc->dRcVaryRatio);
pWelsSvcRc->iNumberMbGom = iMbWidth * iGomRowMode0; pWelsSvcRc->iNumberMbGom = iMbWidth * iGomRowMode0;
pWelsSvcRc->iMinQp = GOM_MIN_QP_MODE; pWelsSvcRc->iMinQp = GOM_MIN_QP_MODE;
pWelsSvcRc->iMaxQp = GOM_MAX_QP_MODE; pWelsSvcRc->iMaxQp = GOM_MAX_QP_MODE;
pWelsSvcRc->iFrameDeltaQpUpper = LAST_FRAME_QP_RANGE_UPPER_MODE1 - (int32_t) ((LAST_FRAME_QP_RANGE_UPPER_MODE1 - pWelsSvcRc->iFrameDeltaQpUpper = LAST_FRAME_QP_RANGE_UPPER_MODE1 - WELS_ROUND ((LAST_FRAME_QP_RANGE_UPPER_MODE1 -
LAST_FRAME_QP_RANGE_UPPER_MODE0) * pWelsSvcRc->dRcVaryRatio + 0.5); LAST_FRAME_QP_RANGE_UPPER_MODE0) * pWelsSvcRc->dRcVaryRatio);
pWelsSvcRc->iFrameDeltaQpLower = LAST_FRAME_QP_RANGE_LOWER_MODE1 - (int32_t) ((LAST_FRAME_QP_RANGE_LOWER_MODE1 - pWelsSvcRc->iFrameDeltaQpLower = LAST_FRAME_QP_RANGE_LOWER_MODE1 - WELS_ROUND ((LAST_FRAME_QP_RANGE_LOWER_MODE1 -
LAST_FRAME_QP_RANGE_LOWER_MODE0) * pWelsSvcRc->dRcVaryRatio + 0.5); LAST_FRAME_QP_RANGE_LOWER_MODE0) * pWelsSvcRc->dRcVaryRatio);
pWelsSvcRc->iSkipFrameNum = 0; pWelsSvcRc->iSkipFrameNum = 0;
pWelsSvcRc->iGomSize = (pWelsSvcRc->iNumberMbFrame + pWelsSvcRc->iNumberMbGom - 1) / pWelsSvcRc->iNumberMbGom; pWelsSvcRc->iGomSize = (pWelsSvcRc->iNumberMbFrame + pWelsSvcRc->iNumberMbGom - 1) / pWelsSvcRc->iNumberMbGom;
@ -213,7 +213,7 @@ void RcUpdateBitrateFps (sWelsEncCtx* pEncCtx) {
const int32_t kiGopSize = (1 << pDLayerParam->iDecompositionStages); const int32_t kiGopSize = (1 << pDLayerParam->iDecompositionStages);
const int32_t kiHighestTid = pDLayerParam->iHighestTemporalId; const int32_t kiHighestTid = pDLayerParam->iHighestTemporalId;
double input_dBitsPerFrame = pDLayerParam->iSpatialBitrate / pDLayerParam->fInputFrameRate; double input_dBitsPerFrame = pDLayerParam->iSpatialBitrate / pDLayerParam->fInputFrameRate;
const int32_t kiGopBits = (int32_t) (input_dBitsPerFrame * kiGopSize); const int32_t kiGopBits = WELS_ROUND (input_dBitsPerFrame * kiGopSize);
int32_t i; int32_t i;
pWelsSvcRc->iBitRate = pDLayerParam->iSpatialBitrate; pWelsSvcRc->iBitRate = pDLayerParam->iSpatialBitrate;
@ -225,16 +225,16 @@ void RcUpdateBitrateFps (sWelsEncCtx* pEncCtx) {
for (i = 0; i <= kiHighestTid; i++) { for (i = 0; i <= kiHighestTid; i++) {
const double kdConstraitBits = kiGopBits * pTOverRc[i].dTlayerWeight; const double kdConstraitBits = kiGopBits * pTOverRc[i].dTlayerWeight;
pTOverRc[i].iMinBitsTl = (int32_t) (kdConstraitBits * dMinBitsRatio); pTOverRc[i].iMinBitsTl = WELS_ROUND(kdConstraitBits * dMinBitsRatio);
pTOverRc[i].iMaxBitsTl = (int32_t) (kdConstraitBits * dMaxBitsRatio); pTOverRc[i].iMaxBitsTl = WELS_ROUND(kdConstraitBits * dMaxBitsRatio);
} }
//When bitrate is changed, pBuffer size should be updated //When bitrate is changed, pBuffer size should be updated
pWelsSvcRc->iBufferSizeSkip = (int32_t) (pWelsSvcRc->iBitRate * pWelsSvcRc->dSkipBufferRatio); pWelsSvcRc->iBufferSizeSkip = WELS_ROUND(pWelsSvcRc->iBitRate * pWelsSvcRc->dSkipBufferRatio);
pWelsSvcRc->iBufferSizePadding = (int32_t) (pWelsSvcRc->iBitRate * PADDING_BUFFER_RATIO); pWelsSvcRc->iBufferSizePadding = WELS_ROUND(pWelsSvcRc->iBitRate * PADDING_BUFFER_RATIO);
//change remaining bits //change remaining bits
if (pWelsSvcRc->dBitsPerFrame > 0.1) if (pWelsSvcRc->dBitsPerFrame > 0.1)
pWelsSvcRc->iRemainingBits = (int32_t) (pWelsSvcRc->iRemainingBits * input_dBitsPerFrame / pWelsSvcRc->dBitsPerFrame); pWelsSvcRc->iRemainingBits = WELS_ROUND(pWelsSvcRc->iRemainingBits * input_dBitsPerFrame / pWelsSvcRc->dBitsPerFrame);
pWelsSvcRc->dBitsPerFrame = input_dBitsPerFrame; pWelsSvcRc->dBitsPerFrame = input_dBitsPerFrame;
} }
@ -245,7 +245,7 @@ void RcInitVGop (sWelsEncCtx* pEncCtx) {
SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc; SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc;
const int32_t kiHighestTid = pEncCtx->pSvcParam->sDependencyLayers[kiDid].iHighestTemporalId; const int32_t kiHighestTid = pEncCtx->pSvcParam->sDependencyLayers[kiDid].iHighestTemporalId;
pWelsSvcRc->iRemainingBits = (int32_t) (VGOP_SIZE * pWelsSvcRc->dBitsPerFrame); pWelsSvcRc->iRemainingBits = WELS_ROUND(VGOP_SIZE * pWelsSvcRc->dBitsPerFrame);
pWelsSvcRc->dRemainingWeights = pWelsSvcRc->iGopNumberInVGop; pWelsSvcRc->dRemainingWeights = pWelsSvcRc->iGopNumberInVGop;
pWelsSvcRc->iFrameCodedInVGop = 0; pWelsSvcRc->iFrameCodedInVGop = 0;
@ -325,9 +325,9 @@ void RcTraceVGopBitrate (sWelsEncCtx* pEncCtx) {
} }
int32_t iFrameInVGop = pWelsSvcRc->iFrameCodedInVGop + pWelsSvcRc->iSkipFrameInVGop; int32_t iFrameInVGop = pWelsSvcRc->iFrameCodedInVGop + pWelsSvcRc->iSkipFrameInVGop;
if (0 != iFrameInVGop) if (0 != iFrameInVGop)
iVGopBitrate = (int32_t) (iTotalBits / iFrameInVGop * pWelsSvcRc->fFrameRate); iVGopBitrate = WELS_ROUND(iTotalBits / iFrameInVGop * pWelsSvcRc->fFrameRate);
#ifdef _TEST_TEMP_Rc_ #ifdef _TEST_TEMP_Rc_
fprintf (fp_vgop, "%d\n", (int32_t) ((double)iTotalBits / iFrameInVGop)); fprintf (fp_vgop, "%d\n", WELS_ROUND((double)iTotalBits / iFrameInVGop));
#endif #endif
WelsLog (pEncCtx, WELS_LOG_INFO, "[Rc] VGOPbitrate%d: %d \n", kiDid, iVGopBitrate); WelsLog (pEncCtx, WELS_LOG_INFO, "[Rc] VGOPbitrate%d: %d \n", kiDid, iVGopBitrate);
if (iTotalBits > 0) { if (iTotalBits > 0) {
@ -400,7 +400,7 @@ void RcInitIdrQp (sWelsEncCtx* pEncCtx) {
break; break;
} }
pWelsSvcRc->iInitialQp = dInitialQPArray[iBppIndex][i]; pWelsSvcRc->iInitialQp = dInitialQPArray[iBppIndex][i];
pWelsSvcRc->iInitialQp = (int32_t)WELS_CLIP3 (pWelsSvcRc->iInitialQp, MIN_IDR_QP, MAX_IDR_QP); pWelsSvcRc->iInitialQp = WELS_CLIP3 (pWelsSvcRc->iInitialQp, MIN_IDR_QP, MAX_IDR_QP);
pEncCtx->iGlobalQp = pWelsSvcRc->iInitialQp; pEncCtx->iGlobalQp = pWelsSvcRc->iInitialQp;
pWelsSvcRc->dQStep = RcConvertQp2QStep (pEncCtx->iGlobalQp); pWelsSvcRc->dQStep = RcConvertQp2QStep (pEncCtx->iGlobalQp);
pWelsSvcRc->iLastCalculatedQScale = pEncCtx->iGlobalQp; pWelsSvcRc->iLastCalculatedQScale = pEncCtx->iGlobalQp;
@ -410,11 +410,11 @@ void RcCalculateIdrQp (sWelsEncCtx* pEncCtx) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
//obtain the idr qp using previous idr complexity //obtain the idr qp using previous idr complexity
if (pWelsSvcRc->iNumberMbFrame != pWelsSvcRc->iIntraMbCount) { if (pWelsSvcRc->iNumberMbFrame != pWelsSvcRc->iIntraMbCount) {
pWelsSvcRc->iIntraComplexity = (int32_t) ((double)pWelsSvcRc->iIntraComplexity * pWelsSvcRc->iNumberMbFrame / pWelsSvcRc->iIntraComplexity = WELS_ROUND((double)pWelsSvcRc->iIntraComplexity * pWelsSvcRc->iNumberMbFrame /
pWelsSvcRc->iIntraMbCount + 0.5); pWelsSvcRc->iIntraMbCount);
} }
pWelsSvcRc->iInitialQp = (int32_t)RcConvertQStep2Qp ((double)pWelsSvcRc->iIntraComplexity / pWelsSvcRc->iTargetBits); pWelsSvcRc->iInitialQp = WELS_ROUND(RcConvertQStep2Qp ((double)pWelsSvcRc->iIntraComplexity / pWelsSvcRc->iTargetBits));
pWelsSvcRc->iInitialQp = (int32_t)WELS_CLIP3 (pWelsSvcRc->iInitialQp, MIN_IDR_QP, MAX_IDR_QP); pWelsSvcRc->iInitialQp = WELS_ROUND(WELS_CLIP3 (pWelsSvcRc->iInitialQp, MIN_IDR_QP, MAX_IDR_QP));
pEncCtx->iGlobalQp = pWelsSvcRc->iInitialQp; pEncCtx->iGlobalQp = pWelsSvcRc->iInitialQp;
pWelsSvcRc->dQStep = RcConvertQp2QStep (pEncCtx->iGlobalQp); pWelsSvcRc->dQStep = RcConvertQp2QStep (pEncCtx->iGlobalQp);
pWelsSvcRc->iLastCalculatedQScale = pEncCtx->iGlobalQp; pWelsSvcRc->iLastCalculatedQScale = pEncCtx->iGlobalQp;
@ -451,7 +451,7 @@ void RcCalculatePictureQp (sWelsEncCtx* pEncCtx) {
pWelsSvcRc->iLastCalculatedQScale = iLumaQp; pWelsSvcRc->iLastCalculatedQScale = iLumaQp;
if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) { if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) {
iLumaQp = (int32_t) (iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp); iLumaQp = WELS_ROUND(iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp);
} }
pEncCtx->iGlobalQp = iLumaQp; pEncCtx->iGlobalQp = iLumaQp;
@ -462,7 +462,7 @@ void RcCalculatePictureQp (sWelsEncCtx* pEncCtx) {
dCmplxRatio = WELS_CLIP3 (dCmplxRatio, 1.0 - FRAME_CMPLX_RATIO_RANGE, 1.0 + FRAME_CMPLX_RATIO_RANGE); dCmplxRatio = WELS_CLIP3 (dCmplxRatio, 1.0 - FRAME_CMPLX_RATIO_RANGE, 1.0 + FRAME_CMPLX_RATIO_RANGE);
pWelsSvcRc->dQStep = pTOverRc->dLinearCmplx * dCmplxRatio / pWelsSvcRc->iTargetBits; pWelsSvcRc->dQStep = pTOverRc->dLinearCmplx * dCmplxRatio / pWelsSvcRc->iTargetBits;
iLumaQp = (int32_t) (RcConvertQStep2Qp (pWelsSvcRc->dQStep) + 0.5); iLumaQp = WELS_ROUND(RcConvertQStep2Qp (pWelsSvcRc->dQStep));
//limit QP //limit QP
int32_t iLastIdxCodecInVGop = pWelsSvcRc->iFrameCodedInVGop - 1; int32_t iLastIdxCodecInVGop = pWelsSvcRc->iFrameCodedInVGop - 1;
@ -487,10 +487,10 @@ void RcCalculatePictureQp (sWelsEncCtx* pEncCtx) {
#ifndef _NOT_USE_AQ_FOR_TEST_ #ifndef _NOT_USE_AQ_FOR_TEST_
if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) { if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) {
iLumaQp = (int32_t) (iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp); iLumaQp = WELS_ROUND(iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp);
if (pEncCtx->pSvcParam->iRCMode != RC_LOW_BW_MODE) if (pEncCtx->pSvcParam->iRCMode != RC_LOW_BW_MODE)
iLumaQp = (int32_t)WELS_CLIP3 (iLumaQp, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp); iLumaQp = WELS_CLIP3 (iLumaQp, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
} }
#endif #endif
@ -510,7 +510,7 @@ void RcInitSliceInformation (sWelsEncCtx* pEncCtx) {
pSOverRc->iEndMbSlice += (pCurSliceCtx->pCountMbNumInSlice[i] - 1); pSOverRc->iEndMbSlice += (pCurSliceCtx->pCountMbNumInSlice[i] - 1);
pSOverRc->iTotalQpSlice = 0; pSOverRc->iTotalQpSlice = 0;
pSOverRc->iTotalMbSlice = 0; pSOverRc->iTotalMbSlice = 0;
pSOverRc->iTargetBitsSlice = (int32_t) (kdBitsPerMb * pCurSliceCtx->pCountMbNumInSlice[i]); pSOverRc->iTargetBitsSlice = WELS_ROUND(kdBitsPerMb * pCurSliceCtx->pCountMbNumInSlice[i]);
pSOverRc->iFrameBitsSlice = 0; pSOverRc->iFrameBitsSlice = 0;
pSOverRc->iGomBitsSlice = 0; pSOverRc->iGomBitsSlice = 0;
++ pSOverRc; ++ pSOverRc;
@ -524,9 +524,9 @@ void RcDecideTargetBits (sWelsEncCtx* pEncCtx) {
pWelsSvcRc->iCurrentBitsLevel = BITS_NORMAL; pWelsSvcRc->iCurrentBitsLevel = BITS_NORMAL;
//allocate bits //allocate bits
if (pEncCtx->eSliceType == I_SLICE) { if (pEncCtx->eSliceType == I_SLICE) {
pWelsSvcRc->iTargetBits = (int32_t) (pWelsSvcRc->dBitsPerFrame * IDR_BITRATE_RATIO); pWelsSvcRc->iTargetBits = WELS_ROUND(pWelsSvcRc->dBitsPerFrame * IDR_BITRATE_RATIO);
} else { } else {
pWelsSvcRc->iTargetBits = (int32_t) (pWelsSvcRc->iRemainingBits * pTOverRc->dTlayerWeight / pWelsSvcRc->iTargetBits = WELS_ROUND(pWelsSvcRc->iRemainingBits * pTOverRc->dTlayerWeight /
pWelsSvcRc->dRemainingWeights); pWelsSvcRc->dRemainingWeights);
if ((pWelsSvcRc->iTargetBits <= 0) && (pEncCtx->pSvcParam->iRCMode == RC_LOW_BW_MODE)) { if ((pWelsSvcRc->iTargetBits <= 0) && (pEncCtx->pSvcParam->iRCMode == RC_LOW_BW_MODE)) {
pWelsSvcRc->iCurrentBitsLevel = BITS_EXCEEDED; pWelsSvcRc->iCurrentBitsLevel = BITS_EXCEEDED;
@ -665,11 +665,11 @@ void RcCalculateGomQp (sWelsEncCtx* pEncCtx, SMB* pCurMb, int32_t iSliceId) {
void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) { void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc; SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc;
const int32_t kiOutputBits = (int32_t) (pWelsSvcRc->dBitsPerFrame + 0.5); const int32_t kiOutputBits = WELS_ROUND(pWelsSvcRc->dBitsPerFrame);
//condition 1: whole pBuffer fullness //condition 1: whole pBuffer fullness
pWelsSvcRc->iBufferFullnessSkip += (pWelsSvcRc->iFrameDqBits - kiOutputBits); pWelsSvcRc->iBufferFullnessSkip += (pWelsSvcRc->iFrameDqBits - kiOutputBits);
//condition 2: VGOP bits constraint //condition 2: VGOP bits constraint
const int32_t kiVGopBits = (int32_t) (pWelsSvcRc->dBitsPerFrame * VGOP_SIZE); const int32_t kiVGopBits = WELS_ROUND(pWelsSvcRc->dBitsPerFrame * VGOP_SIZE);
int32_t iVGopBitsPred = 0; int32_t iVGopBitsPred = 0;
for (int32_t i = pWelsSvcRc->iFrameCodedInVGop + 1; i < VGOP_SIZE; i++) for (int32_t i = pWelsSvcRc->iFrameCodedInVGop + 1; i < VGOP_SIZE; i++)
iVGopBitsPred += pTOverRc[pWelsSvcRc->iTlOfFrames[i]].iMinBitsTl; iVGopBitsPred += pTOverRc[pWelsSvcRc->iTlOfFrames[i]].iMinBitsTl;
@ -690,7 +690,7 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
pWelsSvcRc->iBufferFullnessSkip = 0; pWelsSvcRc->iBufferFullnessSkip = 0;
if (pEncCtx->iSkipFrameFlag == 1) { if (pEncCtx->iSkipFrameFlag == 1) {
pWelsSvcRc->iRemainingBits += (int32_t) (pWelsSvcRc->dBitsPerFrame + 0.5); pWelsSvcRc->iRemainingBits += WELS_ROUND(pWelsSvcRc->dBitsPerFrame);
pWelsSvcRc->iSkipFrameNum++; pWelsSvcRc->iSkipFrameNum++;
pWelsSvcRc->iSkipFrameInVGop++; pWelsSvcRc->iSkipFrameInVGop++;
} }
@ -698,8 +698,8 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
void RcVBufferCalculationPadding (sWelsEncCtx* pEncCtx) { void RcVBufferCalculationPadding (sWelsEncCtx* pEncCtx) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
const int32_t kiOutputBits = (int32_t) (pWelsSvcRc->dBitsPerFrame + 0.5); const int32_t kiOutputBits = WELS_ROUND(pWelsSvcRc->dBitsPerFrame);
const int32_t kiBufferThreshold = (int32_t) (PADDING_THRESHOLD * (-pWelsSvcRc->iBufferSizePadding)); const int32_t kiBufferThreshold = WELS_ROUND(PADDING_THRESHOLD * (-pWelsSvcRc->iBufferSizePadding));
pWelsSvcRc->iBufferFullnessPadding += (pWelsSvcRc->iFrameDqBits - kiOutputBits); pWelsSvcRc->iBufferFullnessPadding += (pWelsSvcRc->iFrameDqBits - kiOutputBits);
@ -736,7 +736,7 @@ void RcUpdatePictureQpBits (sWelsEncCtx* pEncCtx, int32_t iCodedBits) {
++ pSOverRc; ++ pSOverRc;
} }
if (iTotalMb > 0) if (iTotalMb > 0)
pWelsSvcRc->iAverageFrameQp = (int32_t) (1.0 * iTotalQp / iTotalMb + 0.5); pWelsSvcRc->iAverageFrameQp = WELS_ROUND(1.0 * iTotalQp / iTotalMb);
else else
pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp; pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp;
} else { } else {
@ -753,7 +753,7 @@ void RcUpdateIntraComplexity (sWelsEncCtx* pEncCtx) {
double dIntraCmplx = pWelsSvcRc->dQStep * pWelsSvcRc->iFrameDqBits; double dIntraCmplx = pWelsSvcRc->dQStep * pWelsSvcRc->iFrameDqBits;
dIntraCmplx = (1.0 - iAlpha) * pWelsSvcRc->iIntraComplexity + iAlpha * dIntraCmplx; dIntraCmplx = (1.0 - iAlpha) * pWelsSvcRc->iIntraComplexity + iAlpha * dIntraCmplx;
pWelsSvcRc->iIntraComplexity = (int32_t) (dIntraCmplx + 0.5); pWelsSvcRc->iIntraComplexity = WELS_ROUND(dIntraCmplx);
pWelsSvcRc->iIntraMbCount = pWelsSvcRc->iNumberMbFrame; pWelsSvcRc->iIntraMbCount = pWelsSvcRc->iNumberMbFrame;
pWelsSvcRc->iIdrNum++; pWelsSvcRc->iIdrNum++;
@ -775,8 +775,8 @@ void RcUpdateFrameComplexity (sWelsEncCtx* pEncCtx) {
double iAlpha = 1.0 / (1 + pTOverRc->iPFrameNum); double iAlpha = 1.0 / (1 + pTOverRc->iPFrameNum);
if (iAlpha < SMOOTH_FACTOR_MIN_VALUE) if (iAlpha < SMOOTH_FACTOR_MIN_VALUE)
iAlpha = SMOOTH_FACTOR_MIN_VALUE; iAlpha = SMOOTH_FACTOR_MIN_VALUE;
pTOverRc->iFrameCmplxMean = (int32_t) ((1.0 - iAlpha) * pTOverRc->iFrameCmplxMean + iAlpha * pTOverRc->iFrameCmplxMean = WELS_ROUND((1.0 - iAlpha) * pTOverRc->iFrameCmplxMean + iAlpha *
pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity + 0.5); pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity);
pTOverRc->iPFrameNum++; pTOverRc->iPFrameNum++;
if (pTOverRc->iPFrameNum > 255) if (pTOverRc->iPFrameNum > 255)
@ -918,9 +918,12 @@ void WelsRcPictureInitDisable (void* pCtx) {
pEncCtx->iGlobalQp = RcCalculateCascadingQp (pEncCtx, kiQp); pEncCtx->iGlobalQp = RcCalculateCascadingQp (pEncCtx, kiQp);
if (pEncCtx->pSvcParam->bEnableAdaptiveQuant && (pEncCtx->eSliceType == P_SLICE)) { if (pEncCtx->pSvcParam->bEnableAdaptiveQuant && (pEncCtx->eSliceType == P_SLICE)) {
pEncCtx->iGlobalQp = (int32_t)WELS_CLIP3 (pEncCtx->iGlobalQp - pEncCtx->iGlobalQp = WELS_CLIP3 (WELS_ROUND(pEncCtx->iGlobalQp -
pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp, GOM_MIN_QP_MODE, GOM_MAX_QP_MODE); pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp), GOM_MIN_QP_MODE, GOM_MAX_QP_MODE);
}else{
pEncCtx->iGlobalQp = WELS_CLIP3(pEncCtx->iGlobalQp, FIX_MIN_QP_MODE, FIX_MAX_QP_MODE);
} }
pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp; pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp;
} }
@ -934,6 +937,8 @@ void WelsRcMbInitDisable (void* pCtx, SMB* pCurMb, SSlice* pSlice) {
if (pEncCtx->pSvcParam->bEnableAdaptiveQuant && (pEncCtx->eSliceType == P_SLICE)) { if (pEncCtx->pSvcParam->bEnableAdaptiveQuant && (pEncCtx->eSliceType == P_SLICE)) {
iLumaQp = (int8_t)WELS_CLIP3 (iLumaQp + iLumaQp = (int8_t)WELS_CLIP3 (iLumaQp +
pEncCtx->pVaa->sAdaptiveQuantParam.pMotionTextureIndexToDeltaQp[pCurMb->iMbXY], GOM_MIN_QP_MODE, 51); pEncCtx->pVaa->sAdaptiveQuantParam.pMotionTextureIndexToDeltaQp[pCurMb->iMbXY], GOM_MIN_QP_MODE, 51);
}else{
iLumaQp = WELS_CLIP3(iLumaQp,FIX_MIN_QP_MODE,FIX_MAX_QP_MODE);
} }
pCurMb->uiChromaQp = g_kuiChromaQpTable[iLumaQp]; pCurMb->uiChromaQp = g_kuiChromaQpTable[iLumaQp];
pCurMb->uiLumaQp = iLumaQp; pCurMb->uiLumaQp = iLumaQp;

View File

@ -482,9 +482,6 @@ void WelsMarkPic (void* pEncCtx) {
memset (pRefPicMark, 0, sizeof (SRefPicMarking)); memset (pRefPicMark, 0, sizeof (SRefPicMarking));
if (iSliceIdx != kiCountSliceNum - 1) { //marking syntax only exist in last slice head
continue;
}
if (pCtx->pSvcParam->bEnableLongTermReference && pLtr->bLTRMarkingFlag) { if (pCtx->pSvcParam->bEnableLongTermReference && pLtr->bLTRMarkingFlag) {
if (pLtr->iLTRMarkMode == LTR_DIRECT_MARK) { if (pLtr->iLTRMarkMode == LTR_DIRECT_MARK) {
pRefPicMark->SMmcoRef[pRefPicMark->uiMmcoCount].iMaxLongTermFrameIdx = LONG_TERM_REF_NUM - 1; pRefPicMark->SMmcoRef[pRefPicMark->uiMmcoCount].iMaxLongTermFrameIdx = LONG_TERM_REF_NUM - 1;

View File

@ -49,10 +49,6 @@ const ALIGNED_DECLARE (uint8_t, g_kuiZeroLeftMap[16], 16) = {
0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7
}; };
const ALIGNED_DECLARE (uint8_t, g_kuiTrailingOneIndex[8], 16) = {
3, 0, 1, 0, 2, 0, 1, 0
};
int32_t CavlcParamCal_c (int16_t* pCoffLevel, uint8_t* pRun, int16_t* pLevel, int32_t* pTotalCoeff , int32_t CavlcParamCal_c (int16_t* pCoffLevel, uint8_t* pRun, int16_t* pLevel, int32_t* pTotalCoeff ,
int32_t iLastIndex) { int32_t iLastIndex) {
int32_t iTotalZeros = 0; int32_t iTotalZeros = 0;

View File

@ -236,11 +236,11 @@ void DynamicAdjustSlicing (sWelsEncCtx* pCtx,
iSliceIdx = 0; iSliceIdx = 0;
while (iSliceIdx + 1 < kiCountSliceNum) { while (iSliceIdx + 1 < kiCountSliceNum) {
int32_t iNumMbAssigning = (int32_t) (kiCountNumMb * pSliceComplexRatio[iSliceIdx] + EPSN); int32_t iNumMbAssigning = WELS_ROUND(kiCountNumMb * pSliceComplexRatio[iSliceIdx]);
// GOM boundary aligned // GOM boundary aligned
if (pCtx->pSvcParam->iRCMode != RC_OFF_MODE) { if (pCtx->pSvcParam->iRCMode != RC_OFF_MODE) {
iNumMbAssigning = (int32_t) (1.0f * iNumMbAssigning / iNumMbInEachGom + 0.5f + EPSN) * iNumMbInEachGom; iNumMbAssigning = WELS_ROUND (1.0f * iNumMbAssigning / iNumMbInEachGom) * iNumMbInEachGom;
} }
// make sure one GOM at least in each pSlice for safe // make sure one GOM at least in each pSlice for safe

View File

@ -276,7 +276,7 @@ void GomValidCheckSliceMbNum (const int32_t kiMbWidth, const int32_t kiMbHeight,
while (uiSliceIdx + 1 < kuiSliceNum) { while (uiSliceIdx + 1 < kuiSliceNum) {
// GOM boundary aligned // GOM boundary aligned
int32_t iNumMbAssigning = (int32_t) (1.0f * kiMbNumPerSlice / iGomSize + 0.5f + EPSN) * iGomSize; int32_t iNumMbAssigning = WELS_ROUND(1.0f * kiMbNumPerSlice / iGomSize) * iGomSize;
// make sure one GOM at least in each slice for safe // make sure one GOM at least in each slice for safe
if (iNumMbAssigning < iMinimalMbNum) if (iNumMbAssigning < iMinimalMbNum)

View File

@ -914,47 +914,6 @@ void UpdateFMESwitch (SDqLayer* pCurLayer) {
} }
void UpdateFMESwitchNull (SDqLayer* pCurLayer) { void UpdateFMESwitchNull (SDqLayer* pCurLayer) {
} }
/////////////////////////
// Search function options
/////////////////////////
void WelsDiamondCrossSearch (SWelsFuncPtrList* pFunc, void* vpMe, void* vpSlice, const int32_t kiEncStride,
const int32_t kiRefStride) {
SWelsME* pMe = static_cast<SWelsME*> (vpMe);
SSlice* pSlice = static_cast<SSlice*> (vpSlice);
// Step 1: diamond search
WelsDiamondSearch (pFunc, vpMe, vpSlice, kiEncStride, kiRefStride);
// Step 2: CROSS search
SScreenBlockFeatureStorage pRefBlockFeature; //TODO: use this structure from Ref
pMe->uiSadCostThreshold = pRefBlockFeature.uiSadCostThreshold[pMe->uiBlockSize];
if (pMe->uiSadCost >= pMe->uiSadCostThreshold) {
WelsMotionCrossSearch (pFunc, pMe, pSlice, kiEncStride, kiRefStride);
}
}
void WelsDiamondCrossFeatureSearch (SWelsFuncPtrList* pFunc, void* vpMe, void* vpSlice, const int32_t kiEncStride,
const int32_t kiRefStride) {
SWelsME* pMe = static_cast<SWelsME*> (vpMe);
SSlice* pSlice = static_cast<SSlice*> (vpSlice);
// Step 1: diamond search + cross
WelsDiamondCrossSearch (pFunc, pMe, pSlice, kiEncStride, kiRefStride);
// Step 2: FeatureSearch
if (pMe->uiSadCost >= pMe->uiSadCostThreshold) {
pSlice->uiSliceFMECostDown += pMe->uiSadCost;
SScreenBlockFeatureStorage tmpScreenBlockFeatureStorage; //TODO: use this structure from Ref
uint32_t uiMaxSearchPoint = INT_MAX;//TODO: change it according to computational-complexity setting
SFeatureSearchIn sFeatureSearchIn = {0};
SetFeatureSearchIn (pFunc, *pMe, pSlice, &tmpScreenBlockFeatureStorage,
kiEncStride, kiRefStride,
&sFeatureSearchIn);
MotionEstimateFeatureFullSearch (sFeatureSearchIn, uiMaxSearchPoint, pMe);
pSlice->uiSliceFMECostDown -= pMe->uiSadCost;
}
}
} // namespace WelsSVCEnc } // namespace WelsSVCEnc

View File

@ -177,6 +177,12 @@ int32_t CWelsPreProcess::BuildSpatialPicList (sWelsEncCtx* pCtx, const SSourcePi
if (!m_bInitDone) { if (!m_bInitDone) {
if (WelsPreprocessCreate() != 0) if (WelsPreprocessCreate() != 0)
return -1; return -1;
//init source width and height
pSvcParam->SUsedPicRect.iLeft = 0;
pSvcParam->SUsedPicRect.iTop = 0;
pSvcParam->SUsedPicRect.iWidth = ((kpSrcPic->iPicWidth >> 1) << 1);
pSvcParam->SUsedPicRect.iHeight = ((kpSrcPic->iPicHeight >> 1) << 1);
if (WelsPreprocessReset (pCtx) != 0) if (WelsPreprocessReset (pCtx) != 0)
return -1; return -1;
@ -962,14 +968,12 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
int32_t iNumOfLargeChange = 0, iNumOfMediumChangeToLtr = 0; int32_t iNumOfLargeChange = 0, iNumOfMediumChangeToLtr = 0;
bool bBestRefIsLtr = false, bIsClosestLtrFrame = false; bool bIsClosestLtrFrame = false;
int32_t ret = 1, iScdIdx = 0; int32_t ret = 1, iScdIdx = 0;
SPicture* pRefPic = NULL; SPicture* pRefPic = NULL;
SRefInfoParam* pRefPicInfo = NULL; SRefInfoParam* pRefPicInfo = NULL;
uint8_t* pCurBlockStaticPointer = NULL; uint8_t* pCurBlockStaticPointer = NULL;
uint8_t* pBestStrBlockStaticPointer = NULL;
uint8_t* pBestLtrBlockStaticPointer = NULL;
const int32_t iNegligibleMotionBlocks = (static_cast<int32_t> ((pCurPicture->iWidthInPixel >> 3) * const int32_t iNegligibleMotionBlocks = (static_cast<int32_t> ((pCurPicture->iWidthInPixel >> 3) *
(pCurPicture->iHeightInPixel >> 3) * STATIC_SCENE_MOTION_RATIO)); (pCurPicture->iHeightInPixel >> 3) * STATIC_SCENE_MOTION_RATIO));
@ -1024,13 +1028,10 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
if (JudgeBestRef (pRefPic, sLtrJudgement, iFrameComplexity, bIsClosestLtrFrame)) { if (JudgeBestRef (pRefPic, sLtrJudgement, iFrameComplexity, bIsClosestLtrFrame)) {
SaveBestRefToJudgement (iRefPicAvQP, iFrameComplexity, &sLtrJudgement); SaveBestRefToJudgement (iRefPicAvQP, iFrameComplexity, &sLtrJudgement);
SaveBestRefToLocal (pRefPicInfo, sSceneChangeResult, &sLtrSaved); SaveBestRefToLocal (pRefPicInfo, sSceneChangeResult, &sLtrSaved);
bBestRefIsLtr = bCurRefIsLtr;
pBestStrBlockStaticPointer = sSceneChangeResult.pStaticBlockIdc;
} }
if (bCurRefIsLtr && JudgeBestRef (pRefPic, sSceneLtrJudgement, iFrameComplexity, bIsClosestLtrFrame)) { if (bCurRefIsLtr && JudgeBestRef (pRefPic, sSceneLtrJudgement, iFrameComplexity, bIsClosestLtrFrame)) {
SaveBestRefToJudgement (iRefPicAvQP, iFrameComplexity, &sSceneLtrJudgement); SaveBestRefToJudgement (iRefPicAvQP, iFrameComplexity, &sSceneLtrJudgement);
SaveBestRefToLocal (pRefPicInfo, sSceneChangeResult, &sSceneLtrSaved); SaveBestRefToLocal (pRefPicInfo, sSceneChangeResult, &sSceneLtrSaved);
pBestLtrBlockStaticPointer = sSceneChangeResult.pStaticBlockIdc;
} }
if (iMotionBlockNum <= iNegligibleMotionBlocks) { if (iMotionBlockNum <= iNegligibleMotionBlocks) {

View File

@ -67,12 +67,23 @@ WELSVP_NAMESPACE_BEGIN
#define WELS_MAX(x, y) ((x) > (y) ? (x) : (y)) #define WELS_MAX(x, y) ((x) > (y) ? (x) : (y))
#define WELS_MIN(x, y) ((x) < (y) ? (x) : (y)) #define WELS_MIN(x, y) ((x) < (y) ? (x) : (y))
#ifndef WELS_SIGN
#define WELS_SIGN(a) ((int32_t)(a) >> 31) #define WELS_SIGN(a) ((int32_t)(a) >> 31)
#endif
#ifndef WELS_ABS
#define WELS_ABS(a) ((WELS_SIGN(a) ^ (int32_t)(a)) - WELS_SIGN(a)) #define WELS_ABS(a) ((WELS_SIGN(a) ^ (int32_t)(a)) - WELS_SIGN(a))
#endif
#define WELS_CLAMP(x, minv, maxv) WELS_MIN(WELS_MAX(x, minv), maxv) #define WELS_CLAMP(x, minv, maxv) WELS_MIN(WELS_MAX(x, minv), maxv)
#define ALIGNBYTES (16) /* Worst case is requiring alignment to an 16 byte boundary */ #define ALIGNBYTES (16) /* Worst case is requiring alignment to an 16 byte boundary */
#ifndef WELS_ALIGN
#define WELS_ALIGN(iInput) ((iInput+(ALIGNMENT-1)) & ~(ALIGNMENT-1)) #define WELS_ALIGN(iInput) ((iInput+(ALIGNMENT-1)) & ~(ALIGNMENT-1))
#endif
#define WELS_ALIGN2(iInput) ((iInput+1) & ~1) #define WELS_ALIGN2(iInput) ((iInput+1) & ~1)
#define WELS_ALIGN4(iInput) ((iInput+3) & ~3) #define WELS_ALIGN4(iInput) ((iInput+3) & ~3)
#define WELS_ALIGN8(iInput) ((iInput+7) & ~7) #define WELS_ALIGN8(iInput) ((iInput+7) & ~7)

View File

@ -37,7 +37,7 @@
* 10/24/2008 Created * 10/24/2008 Created
* *
*****************************************************************************/ *****************************************************************************/
#include "macros.h"
#include "downsample.h" #include "downsample.h"
@ -73,8 +73,8 @@ void GeneralBilinearFastDownsampler_c (uint8_t* pDst, const int32_t kiDstStride,
uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight) { uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight) {
const uint32_t kuiScaleBitWidth = 16, kuiScaleBitHeight = 15; const uint32_t kuiScaleBitWidth = 16, kuiScaleBitHeight = 15;
const uint32_t kuiScaleWidth = (1 << kuiScaleBitWidth), kuiScaleHeight = (1 << kuiScaleBitHeight); const uint32_t kuiScaleWidth = (1 << kuiScaleBitWidth), kuiScaleHeight = (1 << kuiScaleBitHeight);
int32_t fScalex = (int32_t) ((float)kiSrcWidth / (float)kiDstWidth * kuiScaleWidth); int32_t fScalex = WELS_ROUND((float)kiSrcWidth / (float)kiDstWidth * kuiScaleWidth);
int32_t fScaley = (int32_t) ((float)kiSrcHeight / (float)kiDstHeight * kuiScaleHeight); int32_t fScaley = WELS_ROUND((float)kiSrcHeight / (float)kiDstHeight * kuiScaleHeight);
uint32_t x; uint32_t x;
int32_t iYInverse, iXInverse; int32_t iYInverse, iXInverse;
@ -142,8 +142,8 @@ void GeneralBilinearAccurateDownsampler_c (uint8_t* pDst, const int32_t kiDstStr
uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight) { uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight) {
const int32_t kiScaleBit = 15; const int32_t kiScaleBit = 15;
const int32_t kiScale = (1 << kiScaleBit); const int32_t kiScale = (1 << kiScaleBit);
int32_t iScalex = (int32_t) ((float)kiSrcWidth / (float)kiDstWidth * kiScale); int32_t iScalex = WELS_ROUND((float)kiSrcWidth / (float)kiDstWidth * kiScale);
int32_t iScaley = (int32_t) ((float)kiSrcHeight / (float)kiDstHeight * kiScale); int32_t iScaley = WELS_ROUND((float)kiSrcHeight / (float)kiDstHeight * kiScale);
int64_t x; int64_t x;
int32_t iYInverse, iXInverse; int32_t iYInverse, iXInverse;

View File

@ -71,7 +71,7 @@ void BaseDecoderTest::TearDown() {
void BaseDecoderTest::DecodeFrame(const uint8_t* src, int sliceSize, Callback* cbk) { void BaseDecoderTest::DecodeFrame(const uint8_t* src, int sliceSize, Callback* cbk) {
void* data[3]; uint8_t* data[3];
SBufferInfo bufInfo; SBufferInfo bufInfo;
memset(data, 0, sizeof(data)); memset(data, 0, sizeof(data));
memset(&bufInfo, 0, sizeof(SBufferInfo)); memset(&bufInfo, 0, sizeof(SBufferInfo));
@ -82,19 +82,19 @@ void BaseDecoderTest::DecodeFrame(const uint8_t* src, int sliceSize, Callback* c
if (bufInfo.iBufferStatus == 1 && cbk != NULL) { if (bufInfo.iBufferStatus == 1 && cbk != NULL) {
const Frame frame = { const Frame frame = {
{ // y plane { // y plane
static_cast<uint8_t*>(data[0]), data[0],
bufInfo.UsrData.sSystemBuffer.iWidth, bufInfo.UsrData.sSystemBuffer.iWidth,
bufInfo.UsrData.sSystemBuffer.iHeight, bufInfo.UsrData.sSystemBuffer.iHeight,
bufInfo.UsrData.sSystemBuffer.iStride[0] bufInfo.UsrData.sSystemBuffer.iStride[0]
}, },
{ // u plane { // u plane
static_cast<uint8_t*>(data[1]), data[1],
bufInfo.UsrData.sSystemBuffer.iWidth / 2, bufInfo.UsrData.sSystemBuffer.iWidth / 2,
bufInfo.UsrData.sSystemBuffer.iHeight / 2, bufInfo.UsrData.sSystemBuffer.iHeight / 2,
bufInfo.UsrData.sSystemBuffer.iStride[1] bufInfo.UsrData.sSystemBuffer.iStride[1]
}, },
{ // v plane { // v plane
static_cast<uint8_t*>(data[2]), data[2],
bufInfo.UsrData.sSystemBuffer.iWidth / 2, bufInfo.UsrData.sSystemBuffer.iWidth / 2,
bufInfo.UsrData.sSystemBuffer.iHeight / 2, bufInfo.UsrData.sSystemBuffer.iHeight / 2,
bufInfo.UsrData.sSystemBuffer.iStride[1] bufInfo.UsrData.sSystemBuffer.iStride[1]

View File

@ -73,7 +73,7 @@ void BaseEncoderTest::EncodeStream(InputStream* in, EUsageType usageType, int wi
BufferedData buf; BufferedData buf;
buf.SetLength(frameSize); buf.SetLength(frameSize);
ASSERT_TRUE(buf.Length() == frameSize); ASSERT_TRUE(buf.Length() == (size_t)frameSize);
SFrameBSInfo info; SFrameBSInfo info;
memset(&info, 0, sizeof(SFrameBSInfo)); memset(&info, 0, sizeof(SFrameBSInfo));

View File

@ -19,7 +19,7 @@ bool YUVPixelDataGenerator( uint8_t* pPointer, int32_t iWidth, int32_t iHeight,
const int32_t kiFrameSize = SRC_FRAME_WIDTH*SRC_FRAME_HEIGHT; const int32_t kiFrameSize = SRC_FRAME_WIDTH*SRC_FRAME_HEIGHT;
BufferedData sBuf; BufferedData sBuf;
sBuf.SetLength(kiFrameSize); sBuf.SetLength(kiFrameSize);
if (sBuf.Length() != kiFrameSize) { if (sBuf.Length() != (size_t)kiFrameSize) {
return false; return false;
} }

View File

@ -83,7 +83,7 @@ struct SVCDecoderImpl : public ISVCDecoder {
return static_cast<DECODING_STATE>(3); return static_cast<DECODING_STATE>(3);
} }
virtual DECODING_STATE EXTAPI DecodeFrame2(const unsigned char* pSrc, virtual DECODING_STATE EXTAPI DecodeFrame2(const unsigned char* pSrc,
const int iSrcLen, void** ppDst, SBufferInfo* pDstInfo) { const int iSrcLen, unsigned char** ppDst, SBufferInfo* pDstInfo) {
EXPECT_TRUE(gThis == this); EXPECT_TRUE(gThis == this);
return static_cast<DECODING_STATE>(4); return static_cast<DECODING_STATE>(4);
} }

View File

@ -104,8 +104,8 @@ TEST_P(DecodeEncodeTest, CompareOutput) {
} }
static const DecodeEncodeFileParam kFileParamArray[] = { static const DecodeEncodeFileParam kFileParamArray[] = {
{"res/test_vd_1d.264", "028b5de8a9110223fc611d8a490c7bbb75d93974", 320, 192, 12.0f}, {"res/test_vd_1d.264", "c73c1cc9b7dbab51f48cf41453073bb11337a445", 320, 192, 12.0f},
{"res/test_vd_rc.264", "31b4b12d0f91b5407f39ad6f8622cab1366bff2b", 320, 192, 12.0f}, {"res/test_vd_rc.264", "593ab31fdc67cbad7373abbf7d08daf2771fb229", 320, 192, 12.0f},
}; };
INSTANTIATE_TEST_CASE_P(DecodeEncodeFile, DecodeEncodeTest, INSTANTIATE_TEST_CASE_P(DecodeEncodeFile, DecodeEncodeTest,

View File

@ -73,27 +73,27 @@ TEST_P(EncoderOutputTest, CompareOutput) {
static const EncodeFileParam kFileParamArray[] = { static const EncodeFileParam kFileParamArray[] = {
{ {
"res/CiscoVT2people_320x192_12fps.yuv", "res/CiscoVT2people_320x192_12fps.yuv",
"8d4c87f48e8a679c1ccbf5fe1ee040fed4776b30", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, false, 1 "5fa8c8551133b7d7586f498121028d0e05a28e1d", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, false, 1
}, },
{ {
"res/CiscoVT2people_160x96_6fps.yuv", "res/CiscoVT2people_160x96_6fps.yuv",
"75334dc69d95b8ac2e0a52977bba0179df4f151f", CAMERA_VIDEO_REAL_TIME, 160, 96, 6.0f, SM_SINGLE_SLICE, false, 1 "c619645a7d46f8fade40d2b0e5ae01adc2e5c3ff", CAMERA_VIDEO_REAL_TIME, 160, 96, 6.0f, SM_SINGLE_SLICE, false, 1
}, },
{ {
"res/Static_152_100.yuv", "res/Static_152_100.yuv",
"3467201e18a934e7f8c50f3c8f3e05f4334ad12c", CAMERA_VIDEO_REAL_TIME, 152, 100, 6.0f, SM_SINGLE_SLICE, false, 1 "68cde1b5f790213baab1a10d4a19a3618c138405", CAMERA_VIDEO_REAL_TIME, 152, 100, 6.0f, SM_SINGLE_SLICE, false, 1
}, },
{ {
"res/CiscoVT2people_320x192_12fps.yuv", "res/CiscoVT2people_320x192_12fps.yuv",
"a57c7cc8a00ffe8d8ca5527a13af1683a41b5150", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_ROWMB_SLICE, false, 1 // One slice per MB row "d0d0a087451c2813e9b0fd61bc5b25a4e82519ac", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_ROWMB_SLICE, false, 1 // One slice per MB row
}, },
{ {
"res/CiscoVT2people_320x192_12fps.yuv", "res/CiscoVT2people_320x192_12fps.yuv",
"bc9b203c1b031299df7981201c2af393994d876f", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, true, 1 "d3760e61e38af978d5b59232d8402448812d1540", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, true, 1
}, },
{ {
"res/CiscoVT2people_320x192_12fps.yuv", "res/CiscoVT2people_320x192_12fps.yuv",
"ba81a0f1a14214e6d3c7f1608991b3ac97789370", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, false, 2 "a74ae382356098fb5cce216a97f2c0cef00a0a9d", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, false, 2
}, },
{ {
"res/CiscoVT2people_320x192_12fps.yuv", "res/CiscoVT2people_320x192_12fps.yuv",

View File

@ -272,7 +272,7 @@ void AnchorPredPSkipMvFromNeighbor (PDqLayer pCurLayer, int16_t iMvp[2]) {
int32_t iCurSliceIdc, iTopSliceIdc, iLeftTopSliceIdc, iRightTopSliceIdc, iLeftSliceIdc; int32_t iCurSliceIdc, iTopSliceIdc, iLeftTopSliceIdc, iRightTopSliceIdc, iLeftSliceIdc;
int32_t iLeftTopType, iRightTopType, iTopType, iLeftType; int32_t iLeftTopType, iRightTopType, iTopType, iLeftType;
int32_t iCurX, iCurY, iCurXy, iLeftXy, iTopXy, iLeftTopXy, iRightTopXy; int32_t iCurX, iCurY, iCurXy, iLeftXy, iTopXy, iLeftTopXy, iRightTopXy = 0;
int8_t iLeftRef; int8_t iLeftRef;
int8_t iTopRef; int8_t iTopRef;

View File

@ -63,17 +63,18 @@ TEST(DecodeMbAuxTest, TestIhdm_4x4_dc) {
TEST(DecodeMbAuxTest, TestDequant_4x4_luma_dc) { TEST(DecodeMbAuxTest, TestDequant_4x4_luma_dc) {
short T[16],W[16]; short T[16],W[16];
srand((uint32_t)time(NULL)); srand((uint32_t)time(NULL));
for(int i=0;i<16;i++) {
T[i]=rand()%256+1;
W[i]=T[i];
}
//TODO: QP<18 will cause case fail, need fix and enable the test afterwards for (int qp=0; qp<12; qp++) {
for (int qp=18;qp<52;qp++) { for(int i=0; i<16; i++) {
T[i]=rand()%256+1;
W[i]=T[i];
}
WelsDequantLumaDc4x4(W,qp); WelsDequantLumaDc4x4(W,qp);
for(int i=0;i<16;i++) for(int i=0; i<16; i++) {
EXPECT_EQ(((T[i]*g_kuiDequantCoeff[qp%6][0]+(1 << (1 - qp / 6))))>>(2- qp / 6),W[i]); T[i]= (((T[i]*g_kuiDequantCoeff[qp%6][0]+(1 << (1 - qp / 6))))>>(2- qp / 6));
} EXPECT_EQ(T[i],W[i]);
}
}
} }
TEST(DecodeMbAuxTest, TestDequant_ihdm_4x4_c) { TEST(DecodeMbAuxTest, TestDequant_ihdm_4x4_c) {

View File

@ -18,18 +18,20 @@ TEST(MemoryAlignTest, GetCacheLineSize_LoopWithin16K) {
TEST(MemoryAlignTest, GetCacheLineSize_Zero) { TEST(MemoryAlignTest, GetCacheLineSize_Zero) {
CMemoryAlign cTestMa(0); CMemoryAlign cTestMa(0);
ASSERT_EQ( 16, cTestMa.WelsGetCacheLineSize() ); const uint32_t kuiSixteen = 16;
ASSERT_EQ( kuiSixteen, cTestMa.WelsGetCacheLineSize() );
} }
TEST(MemoryAlignTest, GetCacheLineSize_MaxUINT) { TEST(MemoryAlignTest, GetCacheLineSize_MaxUINT) {
CMemoryAlign cTestMa(0xFFFFFFFF); CMemoryAlign cTestMa(0xFFFFFFFF);
ASSERT_EQ( 16, cTestMa.WelsGetCacheLineSize() ); const uint32_t kuiSixteen = 16;
ASSERT_EQ( kuiSixteen, cTestMa.WelsGetCacheLineSize() );
} }
//Tests of WelsGetCacheLineSize End //Tests of WelsGetCacheLineSize End
//Tests of WelsMallocAndFree Begin //Tests of WelsMallocAndFree Begin
TEST(MemoryAlignTest, WelsMallocAndFreeOnceFunctionVerify) { TEST(MemoryAlignTest, WelsMallocAndFreeOnceFunctionVerify) {
const uint32_t kuiTargetAlignSize[4] = {32, 16, 64, 8}; const uint32_t kuiTargetAlignSize[4] = {32, 16, 64, 8};
srand((uint32_t)time(NULL)); srand((uint32_t)time(NULL));
const uint32_t kuiZero = 0;
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
const uint32_t kuiTestAlignSize = kuiTargetAlignSize[i]; const uint32_t kuiTestAlignSize = kuiTargetAlignSize[i];
const uint32_t kuiTestDataSize = abs(rand()); const uint32_t kuiTestDataSize = abs(rand());
@ -45,13 +47,13 @@ TEST(MemoryAlignTest, WelsMallocAndFreeOnceFunctionVerify) {
ASSERT_TRUE( (((uintptr_t)(pUnitTestData)) & kuiExtraAlignSize) == 0 ); ASSERT_TRUE( (((uintptr_t)(pUnitTestData)) & kuiExtraAlignSize) == 0 );
EXPECT_EQ( kuiExpectedSize, cTestMa.WelsGetMemoryUsage() ); EXPECT_EQ( kuiExpectedSize, cTestMa.WelsGetMemoryUsage() );
cTestMa.WelsFree( pUnitTestData, strUnitTestTag ); cTestMa.WelsFree( pUnitTestData, strUnitTestTag );
EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() ); EXPECT_EQ( kuiZero, cTestMa.WelsGetMemoryUsage() );
} }
else { else {
EXPECT_EQ( NULL, pUnitTestData ); EXPECT_EQ( NULL, pUnitTestData );
EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() ); EXPECT_EQ( kuiZero, cTestMa.WelsGetMemoryUsage() );
cTestMa.WelsFree( pUnitTestData, strUnitTestTag ); cTestMa.WelsFree( pUnitTestData, strUnitTestTag );
EXPECT_EQ( 0, cTestMa.WelsGetMemoryUsage() ); EXPECT_EQ( kuiZero, cTestMa.WelsGetMemoryUsage() );
} }
} }
} }

View File

@ -211,7 +211,7 @@ void MotionEstimateTest::DoLineTest(PLineFullSearchFunc func, bool vertical) {
//it is possible that ref at differnt position is identical, but that should be under a low probability //it is possible that ref at differnt position is identical, but that should be under a low probability
} }
} }
/*
TEST_F(MotionEstimateTest, TestVerticalSearch) { TEST_F(MotionEstimateTest, TestVerticalSearch) {
DoLineTest(LineFullSearch_c, true); DoLineTest(LineFullSearch_c, true);
} }
@ -238,7 +238,7 @@ TEST_F(MotionEstimateTest, TestHorizontalSearch_SSE41)
DoLineTest(HorizontalFullSearchUsingSSE41, false); DoLineTest(HorizontalFullSearchUsingSSE41, false);
} }
#endif #endif
*/
class FeatureMotionEstimateTest : public ::testing::Test { class FeatureMotionEstimateTest : public ::testing::Test {
public: public:
virtual void SetUp() { virtual void SetUp() {

View File

@ -15,6 +15,7 @@ EnableSpsPpsIDAddition 1
EnableFrameCropping 1 # enable frame cropping flag EnableFrameCropping 1 # enable frame cropping flag
MaxNalSize 0 # Unit:Byte, Maximum Nal size
#============================== LOOP FILTER ============================== #============================== LOOP FILTER ==============================
LoopFilterDisableIDC 0 # Loop filter idc (0: on, 1: off, LoopFilterDisableIDC 0 # Loop filter idc (0: on, 1: off,
# 2: on except for slice boundaries, # 2: on except for slice boundaries,

View File

@ -15,6 +15,7 @@ EnableSpsPpsIDAddition 1
EnableFrameCropping 1 # enable frame cropping flag EnableFrameCropping 1 # enable frame cropping flag
MaxNalSize 0 # Unit:Byte, Maximum Nal size
#============================== LOOP FILTER ============================== #============================== LOOP FILTER ==============================
LoopFilterDisableIDC 0 # Loop filter idc (0: on, 1: off, LoopFilterDisableIDC 0 # Loop filter idc (0: on, 1: off,
# 2: on except for slice boundaries, # 2: on except for slice boundaries,

View File

@ -15,6 +15,7 @@ EnableSpsPpsIDAddition 1
EnableFrameCropping 1 # enable frame cropping flag EnableFrameCropping 1 # enable frame cropping flag
MaxNalSize 0 # Unit:Byte, Maximum Nal size
#============================== LOOP FILTER ============================== #============================== LOOP FILTER ==============================
LoopFilterDisableIDC 0 # Loop filter idc (0: on, 1: off, LoopFilterDisableIDC 0 # Loop filter idc (0: on, 1: off,
# 2: on except for slice boundaries, # 2: on except for slice boundaries,

View File

@ -15,6 +15,7 @@ EnableSpsPpsIDAddition 1
EnableFrameCropping 1 # enable frame cropping flag EnableFrameCropping 1 # enable frame cropping flag
MaxNalSize 0 # Unit:Byte, Maximum Nal size
#============================== LOOP FILTER ============================== #============================== LOOP FILTER ==============================
LoopFilterDisableIDC 0 # Loop filter idc (0: on, 1: off, LoopFilterDisableIDC 0 # Loop filter idc (0: on, 1: off,
# 2: on except for slice boundaries, # 2: on except for slice boundaries,

View File

@ -15,6 +15,7 @@ EnableSpsPpsIDAddition 1
EnableFrameCropping 1 # enable frame cropping flag EnableFrameCropping 1 # enable frame cropping flag
MaxNalSize 0 # Unit:Byte, Maximum Nal size
#============================== LOOP FILTER ============================== #============================== LOOP FILTER ==============================
LoopFilterDisableIDC 0 # Loop filter idc (0: on, 1: off, LoopFilterDisableIDC 0 # Loop filter idc (0: on, 1: off,
# 2: on except for slice boundaries, # 2: on except for slice boundaries,