History

add a simple UT for debugging decoder crash

huili2 committed 12 years ago

Commit 32697b01 parent b896faa1 file · +209 −2Browse files

Showing the changes to test/api/encode_decode_api_test.cpp (1 of 1 file). Show all

Unified · Split

test/api/encode_decode_api_test.cpp+209−2
@@ -763,7 +763,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionLTR_ALLIDR) { · 762 unmodified lines
763763 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
764764 int32_t iSpsPpsIdAddition = 1;
765765 encoder_->SetOption (ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, &iSpsPpsIdAddition);
766− int32_t iIDRPeriod = pow(2.0f, (param_.iTemporalLayerNum-1)) * ((rand() % 5) + 1);
766+ int32_t iIDRPeriod = pow (2.0f, (param_.iTemporalLayerNum - 1)) * ((rand() % 5) + 1);
767767 encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
768768 SLTRConfig sLtrConfigVal;
769769 sLtrConfigVal.bEnableLongTermReference = 1;
@@ -1854,7 +1854,7 @@ TEST_F (EncodeDecodeTestAPI, Engine_SVC_Switch_I) { · 1084 unmodified lines
18541854 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
18551855 int32_t iSpsPpsIdAddition = 1;
18561856 encoder_->SetOption (ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, &iSpsPpsIdAddition);
1857− int32_t iIDRPeriod = pow(2.0f, (param_.iTemporalLayerNum-1)) * ((rand() % 5) + 1);
1857+ int32_t iIDRPeriod = pow (2.0f, (param_.iTemporalLayerNum - 1)) * ((rand() % 5) + 1);
18581858 encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
18591859 SLTRConfig sLtrConfigVal;
18601860 sLtrConfigVal.bEnableLongTermReference = 1;
@@ -2031,3 +2031,210 @@ TEST_F (EncodeDecodeTestAPI, SetOptionEncParamExt) { · 170 unmodified lines
20312031 iTraceLevel = WELS_LOG_ERROR;
20322032 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
20332033 }
2034+
2035+class DecodeCrashTestAPI : public EncodeDecodeTestBase {
2036+ public:
2037+ uint8_t iRandValue;
2038+ public:
2039+ void SetUp() {
2040+ EncodeDecodeTestBase::SetUp();
2041+ ucBuf_ = NULL;
2042+ ucBuf_ = new unsigned char [1000000];
2043+ ASSERT_TRUE (ucBuf_ != NULL);
2044+ }
2045+
2046+ void TearDown() {
2047+ EncodeDecodeTestBase::TearDown();
2048+ if (NULL != ucBuf_) {
2049+ delete[] ucBuf_;
2050+ ucBuf_ = NULL;
2051+ }
2052+ ASSERT_TRUE (ucBuf_ == NULL);
2053+ }
2054+
2055+ void prepareParam (int iLayerNum, int iSliceNum, int width, int height, float framerate) {
2056+ EncodeDecodeTestBase::prepareParam (iLayerNum, iSliceNum, width, height, framerate);
2057+ }
2058+
2059+ void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam);
2060+ void EncodeOneFrame() {
2061+ int frameSize = EncPic.iPicWidth * EncPic.iPicHeight * 3 / 2;
2062+ memset (buf_.data(), iRandValue, (frameSize >> 2));
2063+ memset (buf_.data() + (frameSize >> 2), rand() % 256, (frameSize - (frameSize >> 2)));
2064+ int rv = encoder_->EncodeFrame (&EncPic, &info);
2065+ ASSERT_TRUE (rv == cmResultSuccess || rv == cmUnkonwReason);
2066+ }
2067+ protected:
2068+ unsigned char* ucBuf_;
2069+};
2070+
2071+void DecodeCrashTestAPI::prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam) {
2072+ // for encoder
2073+ // I420: 1(Y) + 1/4(U) + 1/4(V)
2074+ int frameSize = EncDecFileParam.width * EncDecFileParam.height * 3 / 2;
2075+
2076+ buf_.SetLength (frameSize);
2077+ ASSERT_TRUE (buf_.Length() == (size_t)frameSize);
2078+
2079+ memset (&EncPic, 0, sizeof (SSourcePicture));
2080+ EncPic.iPicWidth = EncDecFileParam.width;
2081+ EncPic.iPicHeight = EncDecFileParam.height;
2082+ EncPic.iColorFormat = videoFormatI420;
2083+ EncPic.iStride[0] = EncPic.iPicWidth;
2084+ EncPic.iStride[1] = EncPic.iStride[2] = EncPic.iPicWidth >> 1;
2085+ EncPic.pData[0] = buf_.data();
2086+ EncPic.pData[1] = EncPic.pData[0] + EncDecFileParam.width * EncDecFileParam.height;
2087+ EncPic.pData[2] = EncPic.pData[1] + (EncDecFileParam.width * EncDecFileParam.height >> 2);
2088+
2089+ //for decoder
2090+ memset (&info, 0, sizeof (SFrameBSInfo));
2091+
2092+ //set a fixed random value
2093+ iRandValue = rand() % 256;
2094+}
2095+
2096+struct EncodeDecodeParamBase {
2097+ int width;
2098+ int height;
2099+ float frameRate;
2100+ int iTarBitrate;
2101+};
2102+
2103+
2104+static const EncodeDecodeParamBase kParamArray[] = {
2105+ {160, 90, 6.0f, 250000},
2106+ {320, 180, 12.0f, 500000},
2107+ {640, 360, 24.0f, 800000},
2108+};
2109+
2110+//#define DEBUG_FILE_SAVE
2111+TEST_F (DecodeCrashTestAPI, DecoderCrashTest) {
2112+ uint32_t uiGet;
2113+ encoder_->Uninitialize();
2114+
2115+ //do tests until crash
2116+ unsigned int uiLoopRound = 0;
2117+ unsigned char* pucBuf = ucBuf_;
2118+ int iDecAuSize;
2119+#ifdef DEBUG_FILE_SAVE
2120+ //open file to save tested BS
2121+ FILE* f = fopen ("test_crash.264", "wb");
2122+ int iFileSize = 0;
2123+#endif
2124+
2125+ do {
2126+ int iTotalFrameNum = (rand() % 100) + 1;
2127+ int iSeed = rand() % 3; //3 indicates the length of kParamArray[] used in the following
2128+ EncodeDecodeParamBase p = kParamArray[iSeed];
2129+ //Initialize Encoder
2130+ prepareParam (1, 1, p.width, p.height, p.frameRate);
2131+ param_.iRCMode = RC_BITRATE_MODE;
2132+ param_.iTargetBitrate = p.iTarBitrate;
2133+ param_.uiIntraPeriod = 0;
2134+ param_.bEnableSpsPpsIdAddition = true;
2135+ param_.bEnableBackgroundDetection = true;
2136+ param_.bEnableSceneChangeDetect = true;
2137+ param_.bPrefixNalAddingCtrl = true;
2138+ param_.iEntropyCodingModeFlag = 0;
2139+ param_.bEnableFrameSkip = true;
2140+ param_.uiMaxNalSize = 1400;
2141+ param_.iMultipleThreadIdc = 0;
2142+ param_.sSpatialLayers[0].iSpatialBitrate = p.iTarBitrate;
2143+ param_.sSpatialLayers[0].iMaxSpatialBitrate = p.iTarBitrate << 1;
2144+ param_.sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_DYN_SLICE;
2145+ param_.sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 1000;
2146+
2147+ int rv = encoder_->InitializeExt (&param_);
2148+ ASSERT_TRUE (rv == cmResultSuccess);
2149+ decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
2150+ EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY); //default value should be ERROR_CON_SLICE_COPY
2151+ int32_t iTraceLevel = WELS_LOG_QUIET;
2152+ encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
2153+ decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
2154+
2155+ //Start for enc/dec
2156+ int iIdx = 0;
2157+ unsigned char* pData[3] = { NULL };
2158+
2159+ EncodeDecodeFileParamBase pInput; //to conform with old functions
2160+ pInput.width = p.width;
2161+ pInput.height = p.height;
2162+ pInput.frameRate = p.frameRate;
2163+ prepareEncDecParam (pInput);
2164+ while (iIdx++ < iTotalFrameNum) { // loop in frame
2165+ EncodeOneFrame();
2166+#ifdef DEBUG_FILE_SAVE
2167+ //reset file if file size large
2168+ if ((info.eFrameType == videoFrameTypeIDR) && (iFileSize >= (1 << 25))) {
2169+ fclose (f);
2170+ f = fopen ("test_crash.264", "wb");
2171+ iFileSize = 0;
2172+ decoder_->Uninitialize();
2173+
2174+ SDecodingParam decParam;
2175+ memset (&decParam, 0, sizeof (SDecodingParam));
2176+ decParam.eOutputColorFormat = videoFormatI420;
2177+ decParam.uiTargetDqLayer = UCHAR_MAX;
2178+ decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
2179+ decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
2180+
2181+ rv = decoder_->Initialize (&decParam);
2182+ ASSERT_EQ (0, rv);
2183+ }
2184+#endif
2185+ if (info.eFrameType == videoFrameTypeSkip)
2186+ continue;
2187+ //deal with packets
2188+ unsigned char* pBsBuf;
2189+ iDecAuSize = 0;
2190+ pucBuf = ucBuf_; //init buf start pos for decoder usage
2191+ for (int iLayerNum = 0; iLayerNum < info.iLayerNum; iLayerNum++) {
2192+ SLayerBSInfo* pLayerBsInfo = &info.sLayerInfo[iLayerNum];
2193+ pBsBuf = info.sLayerInfo[iLayerNum].pBsBuf;
2194+ int iTotalNalCnt = pLayerBsInfo->iNalCount;
2195+ for (int iNalCnt = 0; iNalCnt < iTotalNalCnt; iNalCnt++) { //loop in NAL
2196+ int iPacketSize = pLayerBsInfo->pNalLengthInByte[iNalCnt];
2197+ //packet loss
2198+ int iLossRate = (rand() % 11); //loss rate among 0 ~ 10%
2199+ bool bPacketLost = (rand() % 101) > (100 -
2200+ iLossRate); // [0, (100-iLossRate)] indicates NO LOSS, (100-iLossRate, 100] indicates LOSS
2201+ if (!bPacketLost) { //no loss
2202+ memcpy (pucBuf, pBsBuf, iPacketSize);
2203+ pucBuf += iPacketSize;
2204+ iDecAuSize += iPacketSize;
2205+ }
2206+ //update bs info
2207+ pBsBuf += iPacketSize;
2208+ } //nal
2209+ } //layer
2210+
2211+#ifdef DEBUG_FILE_SAVE
2212+ //save to file
2213+ fwrite (ucBuf_, 1, iDecAuSize, f);
2214+ iFileSize += iDecAuSize;
2215+#endif
2216+
2217+ //decode
2218+ pData[0] = pData[1] = pData[2] = 0;
2219+ memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
2220+
2221+ rv = decoder_->DecodeFrame2 (ucBuf_, iDecAuSize, pData, &dstBufInfo_);
2222+ rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
2223+ //guarantee decoder EC status
2224+ decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
2225+ EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY);
2226+ } //frame
2227+ uiLoopRound ++;
2228+ if (uiLoopRound >= (1 << 30))
2229+ uiLoopRound = 0;
2230+#ifdef DEBUG_FILE_SAVE
2231+ if (uiLoopRound % 100 == 0)
2232+ printf ("run %d times.\n", uiLoopRound);
2233+ } while (1); //while (iLoopRound<100);
2234+ fclose (f);
2235+#else
2236+ }
2237+ while (uiLoopRound < 100);
2238+#endif
2239+
2240+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t