Ticket #1070: lf_fix_hm10dev.patch

File lf_fix_hm10dev.patch, 15.6 KB (added by pieterkapsenberg, 10 years ago)

loop filter patch updated for HM10.0-dev

  • App/TAppDecoder/TAppDecTop.cpp

     
    126126
    127127    // call actual decoding function
    128128    Bool bNewPicture = false;
     129    Bool bPicComplete = false;
    129130    if (nalUnit.empty())
    130131    {
    131132      /* this can happen if the following occur:
     
    152153      }
    153154      else
    154155      {
    155         bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay);
     156        bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay, bPicComplete);
     157        if(bPicComplete)
     158        {
     159          m_cTDecTop.executeLoopFilters(poc, pcListPic);
     160        }
    156161        if (bNewPicture)
    157162        {
    158163          bitstreamFile.clear();
     
    166171        bPreviousPictureDecoded = true;
    167172      }
    168173    }
    169     if (bNewPicture || !bitstreamFile)
    170     {
    171       m_cTDecTop.executeLoopFilters(poc, pcListPic);
    172     }
    173 
    174174    if( pcListPic )
    175175    {
    176176      if ( m_pchReconFile && !recon_opened )
  • Lib/TLibDecoder/TDecGop.cpp

     
    4040#include "TDecSbac.h"
    4141#include "TDecBinCoder.h"
    4242#include "TDecBinCoderCABAC.h"
    43 #include "libmd5/MD5.h"
    44 #include "TLibCommon/SEI.h"
    4543
    4644#include <time.h>
    4745
    48 extern Bool g_md5_mismatch; ///< top level flag to signal when there is a decode problem
    49 
    5046//! \ingroup TLibDecoder
    5147//! \{
    52 static void calcAndPrintHashStatus(TComPicYuv& pic, const SEIDecodedPictureHash* pictureHashSEI);
     48
    5349// ====================================================================================================================
    5450// Constructor / destructor / initialization / destroy
    5551// ====================================================================================================================
     
    10298// Public member functions
    10399// ====================================================================================================================
    104100
    105 Void TDecGop::decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic)
     101Void TDecGop::decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic, Bool& bPicComplete)
    106102{
    107103  TComSlice*  pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx());
    108104  // Table of extracted substreams.
     
    152148    m_LFCrossSliceBoundaryFlag.push_back( pcSlice->getLFCrossSliceBoundaryFlag());
    153149  }
    154150  m_pcSbacDecoders[0].load(m_pcSbacDecoder);
    155   m_pcSliceDecoder->decompressSlice( ppcSubstreams, rpcPic, m_pcSbacDecoder, m_pcSbacDecoders);
     151  m_pcSliceDecoder->decompressSlice( ppcSubstreams, rpcPic, m_pcSbacDecoder, m_pcSbacDecoders, bPicComplete);
    156152  m_pcEntropyDecoder->setBitstream(  ppcSubstreams[uiNumSubstreams-1] );
    157153  // deallocate all created substreams, including internal buffers.
    158154  for (UInt ui = 0; ui < uiNumSubstreams; ui++)
     
    227223    }
    228224    printf ("] ");
    229225  }
    230   if (m_decodedPictureHashSEIEnabled)
    231   {
    232     SEIMessages pictureHashes = getSeisByType(rpcPic->getSEIs(), SEI::DECODED_PICTURE_HASH );
    233     const SEIDecodedPictureHash *hash = ( pictureHashes.size() > 0 ) ? (SEIDecodedPictureHash*) *(pictureHashes.begin()) : NULL;
    234     if (pictureHashes.size() > 1)
    235     {
    236       printf ("Warning: Got multiple decoded picture hash SEI messages. Using first.");
    237     }
    238     calcAndPrintHashStatus(*rpcPic->getPicYuvRec(), hash);
    239   }
    240226
    241227  rpcPic->setOutputMark(true);
    242228  rpcPic->setReconMark(true);
     
    244230  m_LFCrossSliceBoundaryFlag.clear();
    245231}
    246232
    247 /**
    248  * Calculate and print hash for pic, compare to picture_digest SEI if
    249  * present in seis.  seis may be NULL.  Hash is printed to stdout, in
    250  * a manner suitable for the status line. Theformat is:
    251  *  [Hash_type:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,(yyy)]
    252  * Where, x..x is the hash
    253  *        yyy has the following meanings:
    254  *            OK          - calculated hash matches the SEI message
    255  *            ***ERROR*** - calculated hash does not match the SEI message
    256  *            unk         - no SEI message was available for comparison
    257  */
    258 static void calcAndPrintHashStatus(TComPicYuv& pic, const SEIDecodedPictureHash* pictureHashSEI)
    259 {
    260   /* calculate MD5sum for entire reconstructed picture */
    261   UChar recon_digest[3][16];
    262   Int numChar=0;
    263   const Char* hashType = "\0";
    264233
    265   if (pictureHashSEI)
    266   {
    267     switch (pictureHashSEI->method)
    268     {
    269     case SEIDecodedPictureHash::MD5:
    270       {
    271         hashType = "MD5";
    272         calcMD5(pic, recon_digest);
    273         numChar = 16;
    274         break;
    275       }
    276     case SEIDecodedPictureHash::CRC:
    277       {
    278         hashType = "CRC";
    279         calcCRC(pic, recon_digest);
    280         numChar = 2;
    281         break;
    282       }
    283     case SEIDecodedPictureHash::CHECKSUM:
    284       {
    285         hashType = "Checksum";
    286         calcChecksum(pic, recon_digest);
    287         numChar = 4;
    288         break;
    289       }
    290     default:
    291       {
    292         assert (!"unknown hash type");
    293       }
    294     }
    295   }
    296 
    297   /* compare digest against received version */
    298   const Char* ok = "(unk)";
    299   Bool mismatch = false;
    300 
    301   if (pictureHashSEI)
    302   {
    303     ok = "(OK)";
    304     for(Int yuvIdx = 0; yuvIdx < 3; yuvIdx++)
    305     {
    306       for (UInt i = 0; i < numChar; i++)
    307       {
    308         if (recon_digest[yuvIdx][i] != pictureHashSEI->digest[yuvIdx][i])
    309         {
    310           ok = "(***ERROR***)";
    311           mismatch = true;
    312         }
    313       }
    314     }
    315   }
    316 
    317   printf("[%s:%s,%s] ", hashType, digestToString(recon_digest, numChar), ok);
    318 
    319   if (mismatch)
    320   {
    321     g_md5_mismatch = true;
    322     printf("[rx%s:%s] ", hashType, digestToString(pictureHashSEI->digest, numChar));
    323   }
    324 }
    325234//! \}
  • Lib/TLibDecoder/TDecGop.h

     
    8080 
    8181  TComSampleAdaptiveOffset*     m_pcSAO;
    8282  Double                m_dDecTime;
    83   Int                   m_decodedPictureHashSEIEnabled;  ///< Checksum(3)/CRC(2)/MD5(1)/disable(0) acting on decoded picture hash SEI message
    8483
    8584  //! list that contains the CU address of each slice plus the end address
    8685  std::vector<Int> m_sliceStartCUAddress;
     
    10099                 );
    101100  Void  create  ();
    102101  Void  destroy ();
    103   Void  decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic );
     102  Void  decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic, Bool &bPicComplete);
    104103  Void  filterPicture  (TComPic*& rpcPic );
    105104
    106   void setDecodedPictureHashSEIEnabled(Int enabled) { m_decodedPictureHashSEIEnabled = enabled; }
    107105
    108106};
    109107
  • Lib/TLibDecoder/TDecSlice.cpp

     
    105105  m_pcCuDecoder       = pcCuDecoder;
    106106}
    107107
    108 Void TDecSlice::decompressSlice(TComInputBitstream** ppcSubstreams, TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders)
     108Void TDecSlice::decompressSlice(TComInputBitstream** ppcSubstreams, TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders, Bool& bPicComplete)
    109109{
    110110  TComDataCU* pcCU;
    111111  UInt        uiIsLast = 0;
     
    379379         CTXMem[1]->loadContexts( &m_pcBufferSbacDecoders[uiTileCol] );//ctx 2.LCU
    380380       }
    381381      CTXMem[0]->loadContexts( pcSbacDecoder );//ctx end of dep.slice
     382      bPicComplete = iCUAddr == (rpcPic->getNumCUsInFrame()-1);
    382383      return;
    383384    }
     385  bPicComplete = iCUAddr == (rpcPic->getNumCUsInFrame()-1);
    384386  }
    385387}
    386388
  • Lib/TLibDecoder/TDecSlice.h

     
    8080  Void  create            ();
    8181  Void  destroy           ();
    8282 
    83   Void  decompressSlice   ( TComInputBitstream** ppcSubstreams,   TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders );
     83  Void  decompressSlice   ( TComInputBitstream** ppcSubstreams,   TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders, Bool& bPicComplete );
    8484  Void      initCtxMem(  UInt i );
    8585  Void      setCtxMem( TDecSbac* sb, Int b )   { CTXMem[b] = sb; }
    8686  Int       getCtxMemSize( )                   { return (Int)CTXMem.size(); }
  • Lib/TLibDecoder/TDecTop.cpp

     
    3737
    3838#include "NALread.h"
    3939#include "TDecTop.h"
     40#include "libmd5/MD5.h"
     41#include "TLibCommon/SEI.h"
    4042
    4143//! \ingroup TLibDecoder
     44extern Bool g_md5_mismatch; ///< top level flag to signal when there is a decode problem
     45
     46static void calcAndPrintHashStatus(TComPicYuv& pic, const SEIDecodedPictureHash* pictureHashSEI);
     47
    4248//! \{
    4349
    4450TDecTop::TDecTop()
     
    5662  m_prevPOC                = MAX_INT;
    5763  m_bFirstSliceInPicture    = true;
    5864  m_bFirstSliceInSequence   = true;
     65  m_digestCanBeChecked      = false;
    5966}
    6067
    6168TDecTop::~TDecTop()
     
    189196  // Execute Deblock + Cleanup
    190197
    191198  m_cGopDecoder.filterPicture(pcPic);
    192 
     199  m_digestCanBeChecked = true;
    193200  TComSlice::sortPicList( m_cListPic ); // sorting for application output
    194201  poc                 = pcPic->getSlice(m_uiSliceIdx-1)->getPOC();
    195202  rpcListPic          = &m_cListPic; 
    196203  m_cCuDecoder.destroy();       
    197204  m_bFirstSliceInPicture  = true;
    198 
     205  if (m_decodedPictureHashSEIEnabled)
     206    {
     207      SEIMessages pictureHashes = getSeisByType(m_pcPic->getSEIs(), SEI::DECODED_PICTURE_HASH );
     208      const SEIDecodedPictureHash *hash = ( pictureHashes.size() > 0 ) ? (SEIDecodedPictureHash*) *(pictureHashes.begin()) : NULL;
     209      if(pictureHashes.size() == 0)
     210      {
     211        return;
     212      }
     213      // Possible that the SUFFIX SEI was inserted before the last slice (but after the first one)
     214      if (pictureHashes.size() > 1)
     215      {
     216        printf ("Warning: Got multiple decoded picture hash SEI messages. Using first.");
     217      }
     218      calcAndPrintHashStatus(*m_pcPic->getPicYuvRec(), hash);
     219    }
    199220  return;
    200221}
    201222
     
    310331  m_cLoopFilter.create( sps->getMaxCUDepth() );
    311332}
    312333
    313 Bool TDecTop::xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay )
     334Bool TDecTop::xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay, Bool &bPicComplete )
    314335{
    315336  TComPic*&   pcPic         = m_pcPic;
    316337  m_apcSlicePilot->initSlice();
     
    604625  }
    605626
    606627  //  Decode a picture
    607   m_cGopDecoder.decompressSlice(nalu.m_Bitstream, pcPic);
    608 
     628  m_cGopDecoder.decompressSlice(nalu.m_Bitstream, pcPic, bPicComplete);
     629 
    609630  m_bFirstSliceInPicture = false;
     631  m_digestCanBeChecked = false;
    610632  m_uiSliceIdx++;
    611633
    612634  return false;
     
    639661  if(nalUnitType == NAL_UNIT_SUFFIX_SEI)
    640662  {
    641663    m_seiReader.parseSEImessage( bs, m_pcPic->getSEIs(), nalUnitType, m_parameterSetManagerDecoder.getActiveSPS() );
     664    if (m_decodedPictureHashSEIEnabled && m_digestCanBeChecked)
     665    {
     666      SEIMessages pictureHashes = getSeisByType(m_pcPic->getSEIs(), SEI::DECODED_PICTURE_HASH );
     667      const SEIDecodedPictureHash *hash = ( pictureHashes.size() > 0 ) ? (SEIDecodedPictureHash*) *(pictureHashes.begin()) : NULL;
     668      if (pictureHashes.size() > 1)
     669      {
     670        printf ("Warning: Got multiple decoded picture hash SEI messages. Using first.");
     671      }
     672      calcAndPrintHashStatus(*m_pcPic->getPicYuvRec(), hash);
     673    }
    642674  }
    643675  else
    644676  {
     
    657689  }
    658690}
    659691
    660 Bool TDecTop::decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay)
     692Bool TDecTop::decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay, Bool& bPicComplete)
    661693{
    662694  // Initialize entropy decoder
    663695  m_cEntropyDecoder.setEntropyDecoder (&m_cCavlcDecoder);
     
    698730    case NAL_UNIT_CODED_SLICE_RADL_R:
    699731    case NAL_UNIT_CODED_SLICE_RASL_N:
    700732    case NAL_UNIT_CODED_SLICE_RASL_R:
    701       return xDecodeSlice(nalu, iSkipFrame, iPOCLastDisplay);
     733      return xDecodeSlice(nalu, iSkipFrame, iPOCLastDisplay, bPicComplete);
    702734      break;
    703735    default:
    704736      assert (1);
     
    778810  return false;
    779811}
    780812
     813/**
     814 * Calculate and print hash for pic, compare to picture_digest SEI if
     815 * present in seis.  seis may be NULL.  Hash is printed to stdout, in
     816 * a manner suitable for the status line. Theformat is:
     817 *  [Hash_type:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,(yyy)]
     818 * Where, x..x is the hash
     819 *        yyy has the following meanings:
     820 *            OK          - calculated hash matches the SEI message
     821 *            ***ERROR*** - calculated hash does not match the SEI message
     822 *            unk         - no SEI message was available for comparison
     823 */
     824static void calcAndPrintHashStatus(TComPicYuv& pic, const SEIDecodedPictureHash* pictureHashSEI)
     825{
     826  /* calculate MD5sum for entire reconstructed picture */
     827  UChar recon_digest[3][16];
     828  Int numChar=0;
     829  const Char* hashType = "\0";
     830
     831  if (pictureHashSEI)
     832  {
     833    switch (pictureHashSEI->method)
     834    {
     835    case SEIDecodedPictureHash::MD5:
     836      {
     837        hashType = "MD5";
     838        calcMD5(pic, recon_digest);
     839        numChar = 16;
     840        break;
     841      }
     842    case SEIDecodedPictureHash::CRC:
     843      {
     844        hashType = "CRC";
     845        calcCRC(pic, recon_digest);
     846        numChar = 2;
     847        break;
     848      }
     849    case SEIDecodedPictureHash::CHECKSUM:
     850      {
     851        hashType = "Checksum";
     852        calcChecksum(pic, recon_digest);
     853        numChar = 4;
     854        break;
     855      }
     856    default:
     857      {
     858        assert (!"unknown hash type");
     859      }
     860    }
     861  }
     862
     863  /* compare digest against received version */
     864  const Char* ok = "(unk)";
     865  Bool mismatch = false;
     866
     867  if (pictureHashSEI)
     868  {
     869    ok = "(OK)";
     870    for(Int yuvIdx = 0; yuvIdx < 3; yuvIdx++)
     871    {
     872      for (UInt i = 0; i < numChar; i++)
     873      {
     874        if (recon_digest[yuvIdx][i] != pictureHashSEI->digest[yuvIdx][i])
     875        {
     876          ok = "(***ERROR***)";
     877          mismatch = true;
     878        }
     879      }
     880    }
     881  }
     882
     883  printf("[%s:%s,%s] ", hashType, digestToString(recon_digest, numChar), ok);
     884
     885  if (mismatch)
     886  {
     887    g_md5_mismatch = true;
     888    printf("[rx%s:%s] ", hashType, digestToString(pictureHashSEI->digest, numChar));
     889  }
     890}
     891
    781892//! \}
  • Lib/TLibDecoder/TDecTop.h

     
    9797  Int                     m_prevPOC;
    9898  Bool                    m_bFirstSliceInPicture;
    9999  Bool                    m_bFirstSliceInSequence;
     100  Int                     m_decodedPictureHashSEIEnabled;  ///< Checksum(3)/CRC(2)/MD5(1)/disable(0) acting on decoded picture hash SEI message
     101  Bool                    m_digestCanBeChecked;
    100102
    101103public:
    102104  TDecTop();
     
    105107  Void  create  ();
    106108  Void  destroy ();
    107109
    108   void setDecodedPictureHashSEIEnabled(Int enabled) { m_cGopDecoder.setDecodedPictureHashSEIEnabled(enabled); }
     110  void setDecodedPictureHashSEIEnabled(Int enabled) { m_decodedPictureHashSEIEnabled = enabled; }
    109111
    110112  Void  init();
    111   Bool  decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay);
     113  Bool  decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay, Bool &bPicComplete);
    112114 
    113115  Void  deletePicBuffer();
    114116
     
    119121  Void  xCreateLostPicture (Int iLostPOC);
    120122
    121123  Void      xActivateParameterSets();
    122   Bool      xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay);
     124  Bool      xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay, Bool &bPicComplete);
    123125  Void      xDecodeVPS();
    124126  Void      xDecodeSPS();
    125127  Void      xDecodePPS();