hevc移植/优化-day 4:内存使用优化(内存泄漏问题修复。)
来源:互联网 发布:个体户年报有淘宝网店 编辑:程序博客网 时间:2024/06/05 05:48
在windows上测试的时候发现占用内存巨多,想经嵌入式平台上移植必需优化内存的使用。linux下的valgrind工具很适合做内存泄漏检测,不仅能分析内存泄漏,还能检测到内存未初始化/内存越界等问题。
检测方法:
valgrind -v --leak-check=full --show-reachable=yes ./TAppDecoderStaticd -b RaceHorses_416x240_30.265 -d 0 2>log.txt
在输出的log.txt中即可看出各种问题的说明以及出现该问题时的调用堆栈,方便查看并修正代码。
分析后发现,检测到的问题大部分由于重复解码引起,见TAppDecTop.cpp注释:
* the process of reading a new slice that is the first slice of a new frame
* requires the TDecTop::decode() method to be called again with the same
* nal unit. */
修正补丁:
diff --git a/source/App/TAppDecoder/TAppDecCfg.h b/source/App/TAppDecoder/TAppDecCfg.hindex e702c5c..f792d09 100644--- a/source/App/TAppDecoder/TAppDecCfg.h+++ b/source/App/TAppDecoder/TAppDecCfg.h@@ -64,7 +64,10 @@ protected: public: TAppDecCfg() {}- virtual ~TAppDecCfg() {}+ virtual ~TAppDecCfg() {+ if(m_pchBitstreamFile) free(m_pchBitstreamFile);+ if(m_pchReconFile) free(m_pchReconFile);+ } Bool parseCfg ( Int argc, Char* argv[] ); ///< initialize option class from configuration };diff --git a/source/Lib/TLibCommon/TComPicSym.cpp b/source/Lib/TLibCommon/TComPicSym.cppindex 646b8d7..54c897f 100644--- a/source/Lib/TLibCommon/TComPicSym.cpp+++ b/source/Lib/TLibCommon/TComPicSym.cpp@@ -47,7 +47,7 @@ Void TComPicSym::create ( Int iPicWidth, Int iPicHeight, UInt uiMaxWidth, UInt uiMaxHeight, UInt uiMaxDepth ) { UInt i;-+m_apcTComTile = NULL; m_uhTotalDepth = uiMaxDepth; m_uiNumPartitions = 1<<(m_uhTotalDepth<<1); @@ -180,6 +180,7 @@ UInt TComPicSym::getPicSCUAddr( UInt SCUEncOrder ) Void TComPicSym::xCreateTComTileArray() {+ if(m_apcTComTile) return; m_apcTComTile = new TComTile*[(m_iNumColumnsMinus1+1)*(m_iNumRowsMinus1+1)]; for( UInt i=0; i<(m_iNumColumnsMinus1+1)*(m_iNumRowsMinus1+1); i++ ) {diff --git a/source/Lib/TLibCommon/TComPrediction.cpp b/source/Lib/TLibCommon/TComPrediction.cppindex 0801988..2db4856 100644--- a/source/Lib/TLibCommon/TComPrediction.cpp+++ b/source/Lib/TLibCommon/TComPrediction.cpp@@ -116,6 +116,8 @@ Void TComPrediction::initTempBuff() m_acYuvPred[1] .create( g_uiMaxCUWidth, g_uiMaxCUHeight ); m_cYuvPredTemp.create( g_uiMaxCUWidth, g_uiMaxCUHeight );+ }else{+ return; } #if LM_CHROMA diff --git a/source/Lib/TLibCommon/TComRom.cpp b/source/Lib/TLibCommon/TComRom.cppindex a83eda6..8ae78e4 100644--- a/source/Lib/TLibCommon/TComRom.cpp+++ b/source/Lib/TLibCommon/TComRom.cpp@@ -115,6 +115,13 @@ Void destroyROM() #endif #endif //QC_MDCS }++#if NSQT+for ( i = 0; i < 2; i++ )+{+delete[] g_auiNonSquareSigLastScan[ i ];+}+#endif } // ====================================================================================================================diff --git a/source/Lib/TLibDecoder/NALread.h b/source/Lib/TLibDecoder/NALread.hindex 9964113..ce0f7b3 100644--- a/source/Lib/TLibDecoder/NALread.h+++ b/source/Lib/TLibDecoder/NALread.h@@ -47,6 +47,7 @@ struct InputNALUnit : public NALUnit { TComInputBitstream* m_Bitstream;+ virtual ~InputNALUnit(){delete m_Bitstream;} }; void read(InputNALUnit& nalu, std::vector<uint8_t>& nalUnitBuf);diff --git a/source/Lib/TLibDecoder/TDecGop.cpp b/source/Lib/TLibDecoder/TDecGop.cppindex 5f0e43c..5167df4 100644--- a/source/Lib/TLibDecoder/TDecGop.cpp+++ b/source/Lib/TLibDecoder/TDecGop.cpp@@ -391,7 +390,7 @@ Void TDecGop::decompressGop(TComInputBitstream* pcBitstream, TComPic*& rpcPic, B #endif #if OL_USE_WPP- if (iSymbolMode && pcSlice->getPPS()->getEntropyCodingSynchro())+ if (iSymbolMode /* && pcSlice->getPPS()->getEntropyCodingSynchro()*/) { // deallocate all created substreams, including internal buffers. for (UInt ui = 0; ui < uiNumSubstreams; ui++)diff --git a/source/Lib/TLibDecoder/TDecSlice.cpp b/source/Lib/TLibDecoder/TDecSlice.cppindex b1c8a3d..6be8230 100644--- a/source/Lib/TLibDecoder/TDecSlice.cpp+++ b/source/Lib/TLibDecoder/TDecSlice.cpp@@ -134,6 +134,8 @@ Void TDecSlice::decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPi if( iSymbolMode ) {+ delete[] m_pcBufferSbacDecoders;+ delete[] m_pcBufferBinCABACs; m_pcBufferSbacDecoders = new TDecSbac [uiTilesAcross]; m_pcBufferBinCABACs = new TDecBinCABAC[uiTilesAcross]; for (UInt ui = 0; ui < uiTilesAcross; ui++)diff --git a/source/Lib/TLibDecoder/TDecTop.cpp b/source/Lib/TLibDecoder/TDecTop.cppindex 2f35b29..e2eaf52 100644--- a/source/Lib/TLibDecoder/TDecTop.cpp+++ b/source/Lib/TLibDecoder/TDecTop.cpp@@ -106,6 +106,7 @@ Void TDecTop::destroy() } } }+ m_vAPS.clear(); } #else #if E045_SLICE_COMMON_INFO_SHARING@@ -442,6 +443,7 @@ Bool TDecTop::decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay) // Get a new picture buffer xGetNewPicBuffer (m_apcSlicePilot, pcPic); + delete pcPic->getSEIs(); /* transfer any SEI messages that have been received to the picture */ pcPic->setSEIs(m_SEIs); m_SEIs = NULL;
修正后在windows平台下测试发现最大内存用量减少将近一半!
另外附上前文提示的异常支持去除主要代码(source/Lib/TLibDecoder/AnnexBread.cpp):
bool byteStreamNALUnit(istream& is,vector<uint8_t>& unit,AnnexBStats& stats){//find start 00 00 01int zeros = 0;int ch = 0;for(;;){ch = is.get();if(is.eof() || ch) break;zeros++;}stats.m_numLeadingZero8BitsBytes = zeros;if(ch==1){stats.m_numStartCodePrefixBytes = 3;stats.m_numLeadingZero8BitsBytes -= 2;if(stats.m_numLeadingZero8BitsBytes>0){stats.m_numLeadingZero8BitsBytes--;stats.m_numZeroByteBytes = 1;}}else{return true;}//nal data | enduint32_t tmp = 0;//Conditional jump or move depends on uninitialised value,so set to 0is.read((char*)&tmp,3);if(is.eof()){int got = is.gcount();while(got){unit.push_back((tmp>>0) & 0xFF);tmp >>= 8;got--;}return true;}else{while(tmp!= 0 && tmp != 0x10000){unit.push_back((tmp>>0) & 0xFF);tmp>>=8;is.read(((char*)&tmp)+2,1);if(is.eof()){unit.push_back((tmp>>0) & 0xFF);unit.push_back((tmp>>8) & 0xFF);return true;}}if(tmp==0x10000){stats.m_numTrailingZero8BitsBytes = 0;is.seekg(-3,ios_base::cur);//for next nal unitreturn false;}else{stats.m_numTrailingZero8BitsBytes = 3;for(;;){ch = is.get();if(ch==1){stats.m_numTrailingZero8BitsBytes -= 3;if(stats.m_numTrailingZero8BitsBytes<0){stats.m_numTrailingZero8BitsBytes = 0;}is.seekg(-3,ios_base::cur);//for next nal unitreturn false;}else if(ch) {return true;}else{stats.m_numTrailingZero8BitsBytes++;}}}}}
- hevc移植/优化-day 4:内存使用优化(内存泄漏问题修复。)
- hevc移植/优化-day 3:profiling
- 内存泄漏,检测,优化
- 性能优化(内存泄漏)
- cocos内存泄漏以及优化问题
- 内存优化之内存泄漏问题
- 内存泄漏优化---Handler引发内存泄漏
- 内存溢出,内存泄漏,内存优化
- Android----内存溢出、内存优化、内存泄漏
- hevc移植/优化-day 2:dsp工程创建及测试
- Android 内存泄漏优化总结
- 性能优化(内存泄漏)
- 性能优化—内存泄漏
- Android性能优化-内存泄漏
- android 内存泄漏的优化
- Android性能优化 --- 内存泄漏
- BaseAdapter优化防止内存泄漏
- 性能优化1-内存泄漏
- uva 11151 Longest Palindrome
- 13.3 探索并获取数据
- 再谈Request_irq和setup_irq
- 1
- SQL分割字符串
- hevc移植/优化-day 4:内存使用优化(内存泄漏问题修复。)
- Android Launcher应用(基础版)
- 弃我去者、昨日之日不可留!乱我心者、今日之日多烦忧!
- Android系列之Service:建立一个Bound Service
- Hudson中使用ant编译工程乱码问题的解决
- iPhone4 iOS 4.3.3 越狱之后必装的插件
- iPhone SDK开发: 如何上传图片文件到服务器
- YII Framework学习教程-YII的Model-FormModel-2011-11-23
- 使用 Windows PowerShell 查看邮箱大小和邮箱配额