最近在做关于3D-HEVC的实验,很想直观显示出最终的预测模式(PU)划分结果。最近看到了一个帖子,动了HEVC解码器部分,能直观显示出PU划分结果,但是,只能显示一帧(即解码的第一帧 I-Slice), 后面的全乱了。对于做帧间的是不够的,必须把每帧的划分结果直观地显示出来。仔细看了他的教程,我在此基础进行了改进,目前能够正常显示出HEVC、MV-HEVC的PU划分结果。在此,感谢网站(程光曦微)的作者。
1. PU模式划分显示效果图
2. HEVC decoder 代码修改
该程序是基于HM 11.0/3D-HTM的,废话不多说了,给出修改代码步骤。
2.1 PU划分数据结构体定义及宏定义
为了不改变源代码程序逻辑,我们所有修改的代码都放在自己定义的预处理命令宏定义中。
在TypeDef.h中,定义自己的条件编译预处理命令。
#define statistics_mode 1//用于统计输出块信息
#if statistics_mode
struct PtPair
{
unsigned int _pt1x;
unsigned int _pt1y;
unsigned int _pt2x;
unsigned int _pt2y;
unsigned char mode;
};
#endif
2.2 PU划分及mode向量定义
为了保存各帧CU及mode最终划分结果,在TAppDecTop.h文件中定义如下代码:
class TAppDecTop : public TAppDecCfg
{
private:
#if statistics_mode
std::vector
m_plistPt;//用于保存CU划分及mode结果
std::vector
flag;//用于保存每帧的mode数量
#endif
2.3 修改各函数头,将m_plistPt传递进去
在TAppDecTop.cpp文件中, 按照下面的方式替换源代码:
//原来的代码
bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay);
//修改成如下代码
#if statistics_mode
bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay,m_plistPt);
#else
bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay);
#endif
编译程序,肯定会出错,因为没有修改相应的函数头。在TDecTop.cpp文件中,按照下面的方式修改decode函数头:
#if statistics_mode
Bool TDecTop::decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay,std::vector
& list)
#else
Bool TDecTop::decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay)
#endif
#if statistics_mode
Bool TDecTop::decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay,std::vector
& list);
#else
Bool decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay);
#endif
接下来,将m_plistPt传递到xDecodeSlice函数中,将decode函数中的xDecodeSlice(nalu, iSkipFrame, iPOCLastDisplay)修改成xDecodeSlice(nalu, iSkipFrame, iPOCLastDisplay,list);即将m_plistPt传递到xDecodeSlice函数中。同样地,需要修改相应的函数头,在TDecTop.cpp文件中,修改对应的函数头,按照下面方式修改:
#if statistics_mode
Bool TDecTop::xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay,std::vector
& list )
#else
Bool TDecTop::xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay )
#endif
在TDecTop.h中,按照下面方式替换DecodeSlice函数声明:
#if statistics_mode
Bool TDecTop::xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay,std::vector
& list );
#else
Bool xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay);
#endif
接下来,在xDecodeSlice函数中,将m_cGopDecoder.decompressSlice(nalu.m_Bitstream, pcPic);替换成如下代码:
// Decode a picture
#if statistics_mode
m_cGopDecoder.decompressSlice(nalu.m_Bitstream, pcPic,list);
#else
m_cGopDecoder.decompressSlice(nalu.m_Bitstream, pcPic);
#endif
#if statistics_mode
Void TDecGop::decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic, std::vector
& list)
#else
Void TDecGop::decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic)
#endif
#if statistics_mode