Ticket #1070: lf_fix_hm10dev.patch
File lf_fix_hm10dev.patch, 15.6 KB (added by pieterkapsenberg, 11 years ago) |
---|
-
App/TAppDecoder/TAppDecTop.cpp
126 126 127 127 // call actual decoding function 128 128 Bool bNewPicture = false; 129 Bool bPicComplete = false; 129 130 if (nalUnit.empty()) 130 131 { 131 132 /* this can happen if the following occur: … … 152 153 } 153 154 else 154 155 { 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 } 156 161 if (bNewPicture) 157 162 { 158 163 bitstreamFile.clear(); … … 166 171 bPreviousPictureDecoded = true; 167 172 } 168 173 } 169 if (bNewPicture || !bitstreamFile)170 {171 m_cTDecTop.executeLoopFilters(poc, pcListPic);172 }173 174 174 if( pcListPic ) 175 175 { 176 176 if ( m_pchReconFile && !recon_opened ) -
Lib/TLibDecoder/TDecGop.cpp
40 40 #include "TDecSbac.h" 41 41 #include "TDecBinCoder.h" 42 42 #include "TDecBinCoderCABAC.h" 43 #include "libmd5/MD5.h"44 #include "TLibCommon/SEI.h"45 43 46 44 #include <time.h> 47 45 48 extern Bool g_md5_mismatch; ///< top level flag to signal when there is a decode problem49 50 46 //! \ingroup TLibDecoder 51 47 //! \{ 52 static void calcAndPrintHashStatus(TComPicYuv& pic, const SEIDecodedPictureHash* pictureHashSEI); 48 53 49 // ==================================================================================================================== 54 50 // Constructor / destructor / initialization / destroy 55 51 // ==================================================================================================================== … … 102 98 // Public member functions 103 99 // ==================================================================================================================== 104 100 105 Void TDecGop::decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic )101 Void TDecGop::decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic, Bool& bPicComplete) 106 102 { 107 103 TComSlice* pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx()); 108 104 // Table of extracted substreams. … … 152 148 m_LFCrossSliceBoundaryFlag.push_back( pcSlice->getLFCrossSliceBoundaryFlag()); 153 149 } 154 150 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); 156 152 m_pcEntropyDecoder->setBitstream( ppcSubstreams[uiNumSubstreams-1] ); 157 153 // deallocate all created substreams, including internal buffers. 158 154 for (UInt ui = 0; ui < uiNumSubstreams; ui++) … … 227 223 } 228 224 printf ("] "); 229 225 } 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 }240 226 241 227 rpcPic->setOutputMark(true); 242 228 rpcPic->setReconMark(true); … … 244 230 m_LFCrossSliceBoundaryFlag.clear(); 245 231 } 246 232 247 /**248 * Calculate and print hash for pic, compare to picture_digest SEI if249 * present in seis. seis may be NULL. Hash is printed to stdout, in250 * a manner suitable for the status line. Theformat is:251 * [Hash_type:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,(yyy)]252 * Where, x..x is the hash253 * yyy has the following meanings:254 * OK - calculated hash matches the SEI message255 * ***ERROR*** - calculated hash does not match the SEI message256 * unk - no SEI message was available for comparison257 */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";264 233 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 }325 234 //! \} -
Lib/TLibDecoder/TDecGop.h
80 80 81 81 TComSampleAdaptiveOffset* m_pcSAO; 82 82 Double m_dDecTime; 83 Int m_decodedPictureHashSEIEnabled; ///< Checksum(3)/CRC(2)/MD5(1)/disable(0) acting on decoded picture hash SEI message84 83 85 84 //! list that contains the CU address of each slice plus the end address 86 85 std::vector<Int> m_sliceStartCUAddress; … … 100 99 ); 101 100 Void create (); 102 101 Void destroy (); 103 Void decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic 102 Void decompressSlice(TComInputBitstream* pcBitstream, TComPic*& rpcPic, Bool &bPicComplete); 104 103 Void filterPicture (TComPic*& rpcPic ); 105 104 106 void setDecodedPictureHashSEIEnabled(Int enabled) { m_decodedPictureHashSEIEnabled = enabled; }107 105 108 106 }; 109 107 -
Lib/TLibDecoder/TDecSlice.cpp
105 105 m_pcCuDecoder = pcCuDecoder; 106 106 } 107 107 108 Void TDecSlice::decompressSlice(TComInputBitstream** ppcSubstreams, TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders )108 Void TDecSlice::decompressSlice(TComInputBitstream** ppcSubstreams, TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders, Bool& bPicComplete) 109 109 { 110 110 TComDataCU* pcCU; 111 111 UInt uiIsLast = 0; … … 379 379 CTXMem[1]->loadContexts( &m_pcBufferSbacDecoders[uiTileCol] );//ctx 2.LCU 380 380 } 381 381 CTXMem[0]->loadContexts( pcSbacDecoder );//ctx end of dep.slice 382 bPicComplete = iCUAddr == (rpcPic->getNumCUsInFrame()-1); 382 383 return; 383 384 } 385 bPicComplete = iCUAddr == (rpcPic->getNumCUsInFrame()-1); 384 386 } 385 387 } 386 388 -
Lib/TLibDecoder/TDecSlice.h
80 80 Void create (); 81 81 Void destroy (); 82 82 83 Void decompressSlice ( TComInputBitstream** ppcSubstreams, TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders );83 Void decompressSlice ( TComInputBitstream** ppcSubstreams, TComPic*& rpcPic, TDecSbac* pcSbacDecoder, TDecSbac* pcSbacDecoders, Bool& bPicComplete ); 84 84 Void initCtxMem( UInt i ); 85 85 Void setCtxMem( TDecSbac* sb, Int b ) { CTXMem[b] = sb; } 86 86 Int getCtxMemSize( ) { return (Int)CTXMem.size(); } -
Lib/TLibDecoder/TDecTop.cpp
37 37 38 38 #include "NALread.h" 39 39 #include "TDecTop.h" 40 #include "libmd5/MD5.h" 41 #include "TLibCommon/SEI.h" 40 42 41 43 //! \ingroup TLibDecoder 44 extern Bool g_md5_mismatch; ///< top level flag to signal when there is a decode problem 45 46 static void calcAndPrintHashStatus(TComPicYuv& pic, const SEIDecodedPictureHash* pictureHashSEI); 47 42 48 //! \{ 43 49 44 50 TDecTop::TDecTop() … … 56 62 m_prevPOC = MAX_INT; 57 63 m_bFirstSliceInPicture = true; 58 64 m_bFirstSliceInSequence = true; 65 m_digestCanBeChecked = false; 59 66 } 60 67 61 68 TDecTop::~TDecTop() … … 189 196 // Execute Deblock + Cleanup 190 197 191 198 m_cGopDecoder.filterPicture(pcPic); 192 199 m_digestCanBeChecked = true; 193 200 TComSlice::sortPicList( m_cListPic ); // sorting for application output 194 201 poc = pcPic->getSlice(m_uiSliceIdx-1)->getPOC(); 195 202 rpcListPic = &m_cListPic; 196 203 m_cCuDecoder.destroy(); 197 204 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 } 199 220 return; 200 221 } 201 222 … … 310 331 m_cLoopFilter.create( sps->getMaxCUDepth() ); 311 332 } 312 333 313 Bool TDecTop::xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay )334 Bool TDecTop::xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay, Bool &bPicComplete ) 314 335 { 315 336 TComPic*& pcPic = m_pcPic; 316 337 m_apcSlicePilot->initSlice(); … … 604 625 } 605 626 606 627 // Decode a picture 607 m_cGopDecoder.decompressSlice(nalu.m_Bitstream, pcPic );608 628 m_cGopDecoder.decompressSlice(nalu.m_Bitstream, pcPic, bPicComplete); 629 609 630 m_bFirstSliceInPicture = false; 631 m_digestCanBeChecked = false; 610 632 m_uiSliceIdx++; 611 633 612 634 return false; … … 639 661 if(nalUnitType == NAL_UNIT_SUFFIX_SEI) 640 662 { 641 663 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 } 642 674 } 643 675 else 644 676 { … … 657 689 } 658 690 } 659 691 660 Bool TDecTop::decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay )692 Bool TDecTop::decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay, Bool& bPicComplete) 661 693 { 662 694 // Initialize entropy decoder 663 695 m_cEntropyDecoder.setEntropyDecoder (&m_cCavlcDecoder); … … 698 730 case NAL_UNIT_CODED_SLICE_RADL_R: 699 731 case NAL_UNIT_CODED_SLICE_RASL_N: 700 732 case NAL_UNIT_CODED_SLICE_RASL_R: 701 return xDecodeSlice(nalu, iSkipFrame, iPOCLastDisplay );733 return xDecodeSlice(nalu, iSkipFrame, iPOCLastDisplay, bPicComplete); 702 734 break; 703 735 default: 704 736 assert (1); … … 778 810 return false; 779 811 } 780 812 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 */ 824 static 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 781 892 //! \} -
Lib/TLibDecoder/TDecTop.h
97 97 Int m_prevPOC; 98 98 Bool m_bFirstSliceInPicture; 99 99 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; 100 102 101 103 public: 102 104 TDecTop(); … … 105 107 Void create (); 106 108 Void destroy (); 107 109 108 void setDecodedPictureHashSEIEnabled(Int enabled) { m_ cGopDecoder.setDecodedPictureHashSEIEnabled(enabled); }110 void setDecodedPictureHashSEIEnabled(Int enabled) { m_decodedPictureHashSEIEnabled = enabled; } 109 111 110 112 Void init(); 111 Bool decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay );113 Bool decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay, Bool &bPicComplete); 112 114 113 115 Void deletePicBuffer(); 114 116 … … 119 121 Void xCreateLostPicture (Int iLostPOC); 120 122 121 123 Void xActivateParameterSets(); 122 Bool xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay );124 Bool xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay, Bool &bPicComplete); 123 125 Void xDecodeVPS(); 124 126 Void xDecodeSPS(); 125 127 Void xDecodePPS();