• HEVC预测块(PU)模式划分显示


    转自:http://blog.csdn.net/pc__wang/article/details/27225443#L316

    1. PU模式划分显示效果图

    HEVC第一帧划分显示

    HEVC帧间PU划分显示

    2. HEVC decoder 代码修改

    该程序是基于HM 11.0/3D-HTM的,废话不多说了,给出修改代码步骤。

    2.1 PU划分数据结构体定义及宏定义

    为了不改变源代码程序逻辑,我们所有修改的代码都放在自己定义的预处理命令宏定义中。
    在TypeDef.h中,定义自己的条件编译预处理命令。
     1
    #define statistics_mode 1//用于统计输出块信息
    来自CODE的代码片
    snippet_file_0.h
    在TypeDef.h中,定义保存PU划分坐标点结构体。
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
    #if statistics_mode
    struct PtPair
    {
    unsigned int _pt1x;
    unsigned int _pt1y;
    unsigned int _pt2x;
    unsigned int _pt2y;
    unsigned char mode;
    };
    #endif
    来自CODE的代码片
    snippet_file_0.h

    2.2 PU划分及mode向量定义

    为了保存各帧CU及mode最终划分结果,在TAppDecTop.h文件中定义如下代码:
     1
     2
     3
     4
     5
     6
     7
    class TAppDecTop : public TAppDecCfg
    {
    private:
    #if statistics_mode
    std::vector<PtPair> m_plistPt;//用于保存CU划分及mode结果
    std::vector<int> flag;//用于保存每帧的mode数量
    #endif
    来自CODE的代码片
    snippet_file_0.cpp

    2.3 修改各函数头,将m_plistPt传递进去

    在TAppDecTop.cpp文件中, 按照下面的方式替换源代码:
     1
     2
     3
     4
     5
     6
     7
     8
    //原来的代码
    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
    来自CODE的代码片
    snippet_file_0.cpp
    编译程序,肯定会出错,因为没有修改相应的函数头。在TDecTop.cpp文件中,按照下面的方式修改decode函数头:
     1
     2
     3
     4
     5
    #if statistics_mode
    Bool TDecTop::decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay,std::vector<PtPair>& list)
    #else
    Bool TDecTop::decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay)
    #endif
    来自CODE的代码片
    snippet_file_0.cpp
    在TDecTop.h中,也需要对应修改decode函数声明,按照以下方式修改该函数声明:
     1
     2
     3
     4
     5
    #if statistics_mode
    Bool TDecTop::decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay,std::vector<PtPair>& list);
    #else
    Bool decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay);
    #endif
    来自CODE的代码片
    snippet_file_0.h
    接下来,将m_plistPt传递到xDecodeSlice函数中,将decode函数中的xDecodeSlice(nalu, iSkipFrame, iPOCLastDisplay)修改成xDecodeSlice(nalu, iSkipFrame, iPOCLastDisplay,list);即将m_plistPt传递到xDecodeSlice函数中。同样地,需要修改相应的函数头,在TDecTop.cpp文件中,修改对应的函数头,按照下面方式修改:
     1
     2
     3
     4
     5
    #if statistics_mode
    Bool TDecTop::xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay,std::vector<PtPair>& list )
    #else
    Bool TDecTop::xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay )
    #endif
    来自CODE的代码片
    snippet_file_0.cpp
    在TDecTop.h中,按照下面方式替换DecodeSlice函数声明:
     1
     2
     3
     4
     5
    #if statistics_mode
    Bool TDecTop::xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay,std::vector<PtPair>& list );
    #else
    Bool xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay);
    #endif
    来自CODE的代码片
    snippet_file_0.h
    接下来,在xDecodeSlice函数中,将m_cGopDecoder.decompressSlice(nalu.m_Bitstream, pcPic);替换成如下代码:
     1
     2
     3
     4
     5
     6
    // Decode a picture
    #if statistics_mode
    m_cGopDecoder.decompressSlice(nalu.m_Bitstream, pcPic,list);
    #else
    m_cGopDecoder.decompressSlice(nalu.m_Bitstream, pcPic);
    #endif
    来自CODE的代码片
    snippet_file_0.cpp
    不要忘了,修改对应的函数头和声明,按照下面方式修改:
    在TDecTop.cpp文件中,
     1
     2
     3
     4
     5
    #if statistics_mode
    Void TDecGop::decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic, std::vector<PtPair>& list)
    #else
    Void TDecGop::decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic)
    #endif
    来自CODE的代码片
    snippet_file_0.cpp
    在TDecTop.h文件中,
     1
     2
     3
     4
     5
    #if statistics_mode
    Void TDecGop::decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic, std::vector<PtPair>& list);
    #else
    Void decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic );
    #endif
    来自CODE的代码片
    snippet_file_0.h
    在decompressSlice函数中,将m_pcSliceDecoder->decompressSlice( ppcSubstreams, rpcPic, m_pcSbacDecoder, m_pcSbacDecoders) 修改成如下代码:
     1
     2
     3
     4
     5
    #if statistics_mode
    m_pcSliceDecoder->decompressSlice( ppcSubstreams, rpcPic, m_pcSbacDecoder, m_pcSbacDecoders, list);
    #else
    m_pcSliceDecoder->decompressSlice( ppcSubstreams, rpcPic, m_pcSbacDecoder, m_pcSbacDecoders);
    #endif
    来自CODE的代码片
    snippet_file_0.h
    接着,修改相应的函数头函数声明:
    在TDecSlice.cpp文件中,
     1
     2
     3
     4
     5
    #if statistics_mode
    Void TDecSlice::decompressSlice(TComInputBitstream** ppcSubstreams, TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders, std::vector<PtPair>& list)
    #else
    Void TDecSlice::decompressSlice(TComInputBitstream** ppcSubstreams, TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders)
    #endif
    来自CODE的代码片
    snippet_file_0.h
    在TDecSlice.h文件中,
     1
     2
     3
     4
     5
    #if statistics_mode
    Void TDecSlice::decompressSlice(TComInputBitstream** ppcSubstreams, TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders, std::vector<PtPair>& list);
    #else
    Void decompressSlice ( TComInputBitstream** ppcSubstreams, TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders );
    #endif
    来自CODE的代码片
    snippet_file_0.h

    接下来,将decompressSlice函数中的m_pcCuDecoder->decompressCU ( pcCU );修改成如下代码:
     1
     2
     3
     4
     5
     6
     7
    #if statistics_mode
    m_pcCuDecoder->decodeCU ( pcCU, uiIsLast, list);
    m_pcCuDecoder->decompressCU ( pcCU , list);
    #else
    m_pcCuDecoder->decodeCU ( pcCU, uiIsLast );
    m_pcCuDecoder->decompressCU ( pcCU );
    #endif
    来自CODE的代码片
    snippet_file_0.cpp
    当然,也有修改相应的函数头和函数声明:
    在TDecCu.cpp文件中,
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
    #if statistics_mode
    Void TDecCu::decompressCU( TComDataCU* pcCU,std::vector<PtPair>& list )
    #else
    Void TDecCu::decompressCU( TComDataCU* pcCU )
    #endif
    {
    #if statistics_mode
    xDecompressCU( pcCU, 0, 0,list );
    #else
    xDecompressCU( pcCU, 0, 0);
    #enif
    }
    来自CODE的代码片
    snippet_file_0.cpp
    在TDecCu.h文件中,
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
    /// reconstruct CU information
    #if statistics_mode
    Void decompressCU( TComDataCU* pcCU,std::vector<PtPair>& list );
    #else
    Void decompressCU ( TComDataCU* pcCU );
    #endif
     
    #if statistics_mode
    Void xDecompressCU( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth,std::vector<PtPair>& list );
    #else
    Void xDecompressCU ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
    #endif
    来自CODE的代码片
    snippet_file_0.cpp

    2.4 保存CU划分和mode选择结果

    在xDecompressCU函数中,保存每一帧的CU划分结果及mode结果,在if( ( ( uiDepth < pcCU->getDepth( uiAbsPartIdx ) ) && ( uiDepth < g_uiMaxCUDepth - g_uiAddCUDepth ) ) || bBoundary )结束后,添加如下代码保存结果:
     1
     2
     3
     4
     5
     6
     7
     8
    //==================================================================================//
    //==================================模式大小统计====================================//
    //==================================================================================//
    #if statistics_mode
    struct PtPair tmp;
    tmp._pt1x=uiLPelX; tmp._pt1y=uiTPelY; tmp._pt2x=uiRPelX; tmp._pt2y=uiBPelY;tmp.mode=*pcCU->getPartitionSize();
    list.push_back(tmp);
    #endif
    来自CODE的代码片
    snippet_file_0.h
    接着,修改xDecompressCU函数中的xDecompressCU函数递归调用,
     1
     2
     3
     4
     5
     6
     7
     8
    if(binSlice&&( uiLPelX < pcSlice->getSPS()->getPicWidthInLumaSamples() ) && ( uiTPelY < pcSlice->getSPS()->getPicHeightInLumaSamples() ) )
    {
    #if statistics_mode
    xDecompressCU(pcCU, uiIdx, uiNextDepth,list );
    #else
    xDecompressCU(pcCU, uiIdx, uiNextDepth);
    #endif
    }
    来自CODE的代码片
    snippet_file_0.cpp
    到目前为止,数据保存完成。接下来,就是怎样把CU划分显示出来。

    2.5 PU划分结果显示

    在decode()函数中修改xFlushOutput和xWriteOutput函数调用,

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
    #if statistics_mode
    xFlushOutput( pcListPic,m_plistPt,flag );
    #else
    xFlushOutput( pcListPic);
    #endif
     
    #if statistics_mode
    unsigned long temp=0;
    for(int i=0;i<flag.size();i++)
    {
    temp +=flag[i];
    }
    if(flag.empty())
    flag.push_back(m_plistPt.size());//保存每帧mode个数
    else
    flag.push_back(m_plistPt.size()-temp);//保存每帧mode个数
    xWriteOutput( pcListPic, nalu.m_temporalId,m_plistPt,flag );
    #else
    xWriteOutput( pcListPic, nalu.m_temporalId);
    #endif
     
    #if statistics_mode
    if(flag.empty())
    flag.push_back(m_plistPt.size());
    xFlushOutput( pcListPic,m_plistPt,flag );
    #else
    xFlushOutput( pcListPic);
    #endif
    来自CODE的代码片
    snippet_file_0.cpp
    接着,修改xFlushOutput和xWriteOutput函数头和声明,
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
    //TAppDecTop.cpp中修改对应的函数头
    #if statistics_mode
    Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId,std::vector<PtPair>& list,std::vector<int>& flag)
    #else
    Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId)
    #endif
     
    #if statistics_mode
    Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic,std::vector<PtPair>& list,std::vector<int>& flag )
    #else
    Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic )
    #endif
     
    //TAppDecTop.h中修改对应的函数声明
    #if statistics_mode
    Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId,std::vector<PtPair>& list,std::vector<int>& flag);
    Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic,std::vector<PtPair>& list,std::vector<int>& flag );
    #else
    Void xWriteOutput ( TComList<TComPic*>* pcListPic , UInt tId); ///< write YUV to file
    Void xFlushOutput ( TComList<TComPic*>* pcListPic ); ///< flush all remaining decoded pictures to file
    #endif
    来自CODE的代码片
    snippet_file_0.cpp

    现在到了最后关头,也是最重要的一部分,贴出xWriteOutput和xFlushOutput函数全部代码,不想具体说了,对照代码修改吧!

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
     100
     101
     102
     103
     104
     105
     106
     107
     108
     109
     110
     111
     112
     113
     114
     115
     116
     117
     118
     119
     120
     121
     122
     123
     124
     125
     126
     127
     128
     129
     130
     131
     132
     133
     134
     135
     136
     137
     138
     139
     140
     141
     142
     143
     144
     145
     146
     147
     148
     149
     150
     151
     152
     153
     154
     155
     156
     157
     158
     159
     160
     161
     162
     163
     164
     165
     166
     167
     168
     169
     170
     171
     172
     173
     174
     175
     176
     177
     178
     179
     180
     181
     182
     183
     184
     185
     186
     187
     188
     189
     190
     191
     192
     193
     194
     195
     196
     197
     198
     199
     200
     201
     202
     203
     204
     205
     206
     207
     208
     209
     210
     211
     212
     213
     214
     215
     216
     217
     218
     219
     220
     221
     222
     223
     224
     225
     226
     227
     228
     229
     230
     231
     232
     233
     234
     235
     236
     237
     238
     239
     240
     241
     242
     243
     244
     245
     246
     247
     248
     249
     250
     251
     252
     253
     254
     255
     256
     257
     258
     259
     260
     261
     262
     263
     264
     265
     266
     267
     268
     269
     270
     271
     272
     273
     274
     275
     276
     277
     278
     279
     280
     281
     282
     283
     284
     285
     286
     287
     288
     289
     290
     291
     292
     293
     294
     295
     296
     297
     298
     299
     300
     301
     302
     303
     304
     305
     306
     307
     308
     309
     310
     311
     312
     313
     314
     315
     316
     317
     318
     319
     320
     321
     322
     323
     324
     325
     326
     327
     328
     329
     330
     331
     332
     333
     334
     335
     336
     337
     338
     339
     340
     341
     342
     343
     344
     345
     346
     347
     348
     349
     350
     351
     352
     353
     354
     355
     356
     357
     358
     359
     360
     361
     362
     363
     364
     365
     366
     367
     368
     369
     370
     371
     372
     373
     374
     375
     376
     377
     378
     379
     380
     381
     382
     383
     384
     385
     386
     387
     388
     389
     390
     391
     392
     393
     394
     395
    #if statistics_mode
    Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId,std::vector<PtPair>& list,std::vector<int>& flag)
    #else
    Void TAppDecTop::xWriteOutput( TComList<TComPic*>* pcListPic, UInt tId)
    #endif
    #endif
    {
    TComList<TComPic*>::iterator iterPic = pcListPic->begin();
    Int not_displayed = 0;
     
    while (iterPic != pcListPic->end())
    {
    TComPic* pcPic = *(iterPic);
    #if H_MV
    if(pcPic->getOutputMark() && pcPic->getPOC() > m_pocLastDisplay[decIdx])
    #else
    if(pcPic->getOutputMark() && pcPic->getPOC() > m_iPOCLastDisplay)
    #endif
    {
    not_displayed++;
    }
    iterPic++;
    }
    iterPic = pcListPic->begin();
     
    while (iterPic != pcListPic->end())
    {
    TComPic* pcPic = *(iterPic);
     
     
     
    #if H_MV
    if ( pcPic->getOutputMark() && (not_displayed > pcPic->getNumReorderPics(tId) && pcPic->getPOC() > m_pocLastDisplay[decIdx]))
    #else
    if ( pcPic->getOutputMark() && (not_displayed > pcPic->getNumReorderPics(tId) && pcPic->getPOC() > m_iPOCLastDisplay))
    #endif
    {
    // write to file
    not_displayed--;
     
    #if statistics_mode
    TComPicYuv *p_dstyuv=new TComPicYuv;
    TComPicYuv *p_orgyuv=pcPic->getPicYuvRec();
    p_dstyuv->create(p_orgyuv->getWidth(),p_orgyuv->getHeight(),1,1,0);
    p_orgyuv->copyToPic(p_dstyuv);
    Pel *pY=p_dstyuv->getLumaAddr();
    UInt stride = p_dstyuv->getStride();
    for(UInt index = 0; index < flag[0]; index++)
    {
    for(UInt y = list[index]._pt1y; y <= list[index]._pt2y; y++)
    {
    for(UInt x = list[index]._pt1x; x <= list[index]._pt2x; x++)
    {
    switch(list[index].mode)
    {
    case SIZE_2Nx2N:
    if(y == list[index]._pt1y )
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x )
    pY[y*stride + x] = 0;
    break;
    case SIZE_2NxN:
    if(y == list[index]._pt1y )
    pY[y*stride + x] = 0;
    if(y == list[index]._pt1y+(list[index]._pt2y-list[index]._pt1y+1)/2)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x )
    pY[y*stride + x] = 0;
    break;
    case SIZE_Nx2N:
    if(y == list[index]._pt1y )
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x+(list[index]._pt2x-list[index]._pt1x+1)/2)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x )
    pY[y*stride + x] = 0;
    break;
    case SIZE_NxN:
    if(y == list[index]._pt1y )
    pY[y*stride + x] = 0;
    if(y == list[index]._pt1y+(list[index]._pt2y-list[index]._pt1y+1)/2)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x+(list[index]._pt2x-list[index]._pt1x+1)/2)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x )
    pY[y*stride + x] = 0;
    break;
    case SIZE_2NxnU:
    if(y == list[index]._pt1y )
    pY[y*stride + x] = 0;
    if(y == list[index]._pt1y+(list[index]._pt2y-list[index]._pt1y+1)/4)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x )
    pY[y*stride + x] = 0;
    break;
    case SIZE_2NxnD:
    if(y == list[index]._pt1y )
    pY[y*stride + x] = 0;
    if(y == list[index]._pt1y+3*(list[index]._pt2y-list[index]._pt1y+1)/4)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x )
    pY[y*stride + x] = 0;
    break;
    case SIZE_nLx2N:
    if(y == list[index]._pt1y )
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x+(list[index]._pt2x-list[index]._pt1x+1)/4)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x )
    pY[y*stride + x] = 0;
    break;
    case SIZE_nRx2N:
    if(y == list[index]._pt1y )
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x+3*(list[index]._pt2x-list[index]._pt1x+1)/4)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x )
    pY[y*stride + x] = 0;
    break;
    default:
    break;
     
    }
    }
    }
    }
    if(flag.size()>1)
    {
    list.erase(list.begin(),list.begin()+flag[0]);
    flag.erase(flag.begin());
    }
    #endif
     
    #if H_MV
    if ( m_pchReconFiles[decIdx] )
    #else
    if ( m_pchReconFile )
    #endif
    {
    const Window &conf = pcPic->getConformanceWindow();
    const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
    #if H_MV
    #if H_MV5
    assert( conf .getScaledFlag() );
    assert( defDisp.getScaledFlag() );
    #endif
    #if statistics_mode
    m_tVideoIOYuvReconFile[decIdx]->write( p_dstyuv,
    #else
    m_tVideoIOYuvReconFile[decIdx]->write( pcPic->getPicYuvRec(),
    #endif
    #else
    #if statistics_mode
    m_cTVideoIOYuvReconFile.write( p_dstyuv,
    #else
    m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
    #endif
    #endif
    conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
    conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
    conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
    conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
    }
     
    // update POC of display order
    #if H_MV
    m_pocLastDisplay[decIdx] = pcPic->getPOC();
    #else
    m_iPOCLastDisplay = pcPic->getPOC();
    #endif
     
    // erase non-referenced picture in the reference picture list after display
    if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
    {
    #if !DYN_REF_FREE
    pcPic->setReconMark(false);
     
    // mark it should be extended later
    pcPic->getPicYuvRec()->setBorderExtension( false );
     
    #else
    pcPic->destroy();
    pcListPic->erase( iterPic );
    iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
    continue;
    #endif
    }
    pcPic->setOutputMark(false);
    }
     
    iterPic++;
    }
    }
     
    /** param pcListPic list of pictures to be written to file
    odo DYN_REF_FREE should be revised
    */
    #if H_MV
    #if statistics_mode
    Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic, Int decIdx,std::vector<PtPair>& list,std::vector<int>& flag)
    #else
    Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic, Int decIdx)
    #endif
    #else
    #if statistics_mode
    Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic,std::vector<PtPair>& list,std::vector<int>& flag )
    #else
    Void TAppDecTop::xFlushOutput( TComList<TComPic*>* pcListPic )
    #endif
    #endif
    {
    if(!pcListPic)
    {
    return;
    }
    TComList<TComPic*>::iterator iterPic = pcListPic->begin();
     
    iterPic = pcListPic->begin();
     
    while (iterPic != pcListPic->end())
    {
    TComPic* pcPic = *(iterPic);
     
     
    if ( pcPic->getOutputMark() )
    {
    // write to file
     
    #if statistics_mode
    TComPicYuv *p_dstyuv=new TComPicYuv;
    TComPicYuv *p_orgyuv=pcPic->getPicYuvRec();
    p_dstyuv->create(p_orgyuv->getWidth(),p_orgyuv->getHeight(),1,1,0);
    p_orgyuv->copyToPic(p_dstyuv);
    Pel *pY=p_dstyuv->getLumaAddr();
    UInt stride = p_dstyuv->getStride();
    for(UInt index = 0; index < flag[0]; index++)
    {
    for(UInt y = list[index]._pt1y; y <= list[index]._pt2y; y++)
    {
    for(UInt x = list[index]._pt1x; x <= list[index]._pt2x; x++)
    {
    switch(list[index].mode)
    {
    case SIZE_2Nx2N:
    if(y == list[index]._pt1y )
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x )
    pY[y*stride + x] = 0;
    break;
    case SIZE_2NxN:
    if(y == list[index]._pt1y )
    pY[y*stride + x] = 0;
    if(y == list[index]._pt1y+(list[index]._pt2y-list[index]._pt1y+1)/2)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x )
    pY[y*stride + x] = 0;
    break;
    case SIZE_Nx2N:
    if(y == list[index]._pt1y)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x+(list[index]._pt2x-list[index]._pt1x+1)/2)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x)
    pY[y*stride + x] = 0;
    break;
    case SIZE_NxN:
    if(y == list[index]._pt1y)
    pY[y*stride + x] = 0;
    if(y == list[index]._pt1y+(list[index]._pt2y-list[index]._pt1y+1)/2)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x+(list[index]._pt2x-list[index]._pt1x+1)/2)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x )
    pY[y*stride + x] = 0;
    break;
    case SIZE_2NxnU:
    if(y == list[index]._pt1y )
    pY[y*stride + x] = 0;
    if(y == list[index]._pt1y+(list[index]._pt2y-list[index]._pt1y+1)/4)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x )
    pY[y*stride + x] = 0;
    break;
    case SIZE_2NxnD:
    if(y == list[index]._pt1y )
    pY[y*stride + x] = 0;
    if(y == list[index]._pt1y+3*(list[index]._pt2y-list[index]._pt1y+1)/4)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x)
    pY[y*stride + x] = 0;
    break;
    case SIZE_nLx2N:
    if(y == list[index]._pt1y)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x+(list[index]._pt2x-list[index]._pt1x+1)/4)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x)
    pY[y*stride + x] = 0;
    break;
    case SIZE_nRx2N:
    if(y == list[index]._pt1y )
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x+3*(list[index]._pt2x-list[index]._pt1x+1)/4)
    pY[y*stride + x] = 0;
    if(x == list[index]._pt1x )
    pY[y*stride + x] = 0;
    break;
    default:
    break;
     
    }
    }
    }
    }
    if(flag.size()>1)
    {
    list.erase(list.begin(),list.begin()+flag[0]);
    flag.erase(flag.begin());
    }
    #endif
    #if H_MV
    if ( m_pchReconFiles[decIdx] )
    #else
    if ( m_pchReconFile )
    #endif
    {
    const Window &conf = pcPic->getConformanceWindow();
    const Window &defDisp = m_respectDefDispWindow ? pcPic->getDefDisplayWindow() : Window();
    #if H_MV
    #if H_MV5
    assert( conf .getScaledFlag() );
    assert( defDisp.getScaledFlag() );
    #endif
    #if statistics_mode
    m_tVideoIOYuvReconFile[decIdx]->write( p_dstyuv,
    #else
    m_tVideoIOYuvReconFile[decIdx]->write( pcPic->getPicYuvRec(),
    #endif
    #else
    #if statistics_mode
    m_cTVideoIOYuvReconFile.write( p_dstyuv,
    #else
    m_cTVideoIOYuvReconFile.write( pcPic->getPicYuvRec(),
    #endif
    #endif
    conf.getWindowLeftOffset() + defDisp.getWindowLeftOffset(),
    conf.getWindowRightOffset() + defDisp.getWindowRightOffset(),
    conf.getWindowTopOffset() + defDisp.getWindowTopOffset(),
    conf.getWindowBottomOffset() + defDisp.getWindowBottomOffset() );
    }
     
    // update POC of display order
    #if H_MV
    m_pocLastDisplay[decIdx] = pcPic->getPOC();
    #else
    m_iPOCLastDisplay = pcPic->getPOC();
    #endif
     
    // erase non-referenced picture in the reference picture list after display
    if ( !pcPic->getSlice(0)->isReferenced() && pcPic->getReconMark() == true )
    {
    #if !DYN_REF_FREE
    pcPic->setReconMark(false);
     
    // mark it should be extended later
    pcPic->getPicYuvRec()->setBorderExtension( false );
     
    #else
    pcPic->destroy();
    pcListPic->erase( iterPic );
    iterPic = pcListPic->begin(); // to the beginning, non-efficient way, have to be revised!
    continue;
    #endif
    }
    pcPic->setOutputMark(false);
    }
    #if !H_MV
    #if !DYN_REF_FREE
    if(pcPic)
    {
    pcPic->destroy();
    delete pcPic;
    pcPic = NULL;
    }
    #endif
    #endif
    iterPic++;
    }
    #if H_MV
    m_pocLastDisplay[decIdx] = -MAX_INT;
    #else
    pcListPic->clear();
    m_iPOCLastDisplay = -MAX_INT;
    #endif
    }
    来自CODE的代码片
    snippet_file_0.cpp

    2.6 解码看结果

    将先编码过后的文件,用解码器解码,就会看到最终结果。有的可能不知道怎样使用解码器,贴出命令行供参考

    TAppDecoder -b 2Dmodes.bin -o 2Dmodes.yuv (TAppDecoder解码器应用程序,2Dmodes.bin编码器输出的压缩文件,2Dmodes.yuv 为重建文件名,2Dmodes.yuv 总的2Dmodes可以任意取名)。

  • 相关阅读:
    sqlmap注入分类
    sqlmap简单中文说明
    【Python Learning第一篇】Linux命令学习及Vim命令的使用
    模拟退火算法从原理到实战【基础篇】
    平面上给定n条线段,找出一个点,使这个点到这n条线段的距离和最小。
    使用VMWareWorkstation10搭建学习环境笔记
    洛谷P1313 计算系数【快速幂+dp】
    浅析Numpy.genfromtxt及File I/O讲解
    持续交付中高效率与高质量
    持续集成CI与自动化测试
  • 原文地址:https://www.cnblogs.com/Bill-LHR/p/6830182.html
Copyright © 2020-2023  润新知