Ticket #1070: lf_fix_2.patch
File lf_fix_2.patch, 15.5 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 }; -
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() … … 185 192 // Execute Deblock + Cleanup 186 193 187 194 m_cGopDecoder.filterPicture(pcPic); 188 195 m_digestCanBeChecked = true; 189 196 TComSlice::sortPicList( m_cListPic ); // sorting for application output 190 197 poc = pcPic->getSlice(m_uiSliceIdx-1)->getPOC(); 191 198 rpcListPic = &m_cListPic; 192 199 m_cCuDecoder.destroy(); 193 200 m_bFirstSliceInPicture = true; 194 201 if (m_decodedPictureHashSEIEnabled) 202 { 203 SEIMessages pictureHashes = getSeisByType(m_pcPic->getSEIs(), SEI::DECODED_PICTURE_HASH ); 204 const SEIDecodedPictureHash *hash = ( pictureHashes.size() > 0 ) ? (SEIDecodedPictureHash*) *(pictureHashes.begin()) : NULL; 205 if(pictureHashes.size() == 0) 206 { 207 return; 208 } 209 // Possible that the SUFFIX SEI was inserted before the last slice (but after the first one) 210 if (pictureHashes.size() > 1) 211 { 212 printf ("Warning: Got multiple decoded picture hash SEI messages. Using first."); 213 } 214 calcAndPrintHashStatus(*m_pcPic->getPicYuvRec(), hash); 215 } 195 216 return; 196 217 } 197 218 … … 282 303 m_cLoopFilter. create( g_uiMaxCUDepth ); 283 304 } 284 305 285 Bool TDecTop::xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay )306 Bool TDecTop::xDecodeSlice(InputNALUnit &nalu, Int &iSkipFrame, Int iPOCLastDisplay, Bool &bPicComplete ) 286 307 { 287 308 TComPic*& pcPic = m_pcPic; 288 309 m_apcSlicePilot->initSlice(); … … 570 591 } 571 592 572 593 // Decode a picture 573 m_cGopDecoder.decompressSlice(nalu.m_Bitstream, pcPic );574 594 m_cGopDecoder.decompressSlice(nalu.m_Bitstream, pcPic, bPicComplete); 595 575 596 m_bFirstSliceInPicture = false; 597 m_digestCanBeChecked = false; 576 598 m_uiSliceIdx++; 577 599 578 600 return false; … … 618 640 if(nalUnitType == NAL_UNIT_SEI_SUFFIX) 619 641 { 620 642 m_seiReader.parseSEImessage( bs, m_pcPic->getSEIs(), nalUnitType, m_parameterSetManagerDecoder.getActiveSPS() ); 643 if (m_decodedPictureHashSEIEnabled && m_digestCanBeChecked) 644 { 645 SEIMessages pictureHashes = getSeisByType(m_pcPic->getSEIs(), SEI::DECODED_PICTURE_HASH ); 646 const SEIDecodedPictureHash *hash = ( pictureHashes.size() > 0 ) ? (SEIDecodedPictureHash*) *(pictureHashes.begin()) : NULL; 647 if (pictureHashes.size() > 1) 648 { 649 printf ("Warning: Got multiple decoded picture hash SEI messages. Using first."); 650 } 651 calcAndPrintHashStatus(*m_pcPic->getPicYuvRec(), hash); 652 } 621 653 } 622 654 else 623 655 { … … 636 668 } 637 669 } 638 670 639 Bool TDecTop::decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay )671 Bool TDecTop::decode(InputNALUnit& nalu, Int& iSkipFrame, Int& iPOCLastDisplay, Bool& bPicComplete) 640 672 { 641 673 // Initialize entropy decoder 642 674 m_cEntropyDecoder.setEntropyDecoder (&m_cCavlcDecoder); … … 677 709 case NAL_UNIT_CODED_SLICE_DLP: 678 710 case NAL_UNIT_CODED_SLICE_RASL_N: 679 711 case NAL_UNIT_CODED_SLICE_TFD: 680 return xDecodeSlice(nalu, iSkipFrame, iPOCLastDisplay );712 return xDecodeSlice(nalu, iSkipFrame, iPOCLastDisplay, bPicComplete); 681 713 break; 682 714 default: 683 715 assert (1); … … 757 789 return false; 758 790 } 759 791 792 /** 793 * Calculate and print hash for pic, compare to picture_digest SEI if 794 * present in seis. seis may be NULL. Hash is printed to stdout, in 795 * a manner suitable for the status line. Theformat is: 796 * [Hash_type:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,(yyy)] 797 * Where, x..x is the hash 798 * yyy has the following meanings: 799 * OK - calculated hash matches the SEI message 800 * ***ERROR*** - calculated hash does not match the SEI message 801 * unk - no SEI message was available for comparison 802 */ 803 static void calcAndPrintHashStatus(TComPicYuv& pic, const SEIDecodedPictureHash* pictureHashSEI) 804 { 805 /* calculate MD5sum for entire reconstructed picture */ 806 UChar recon_digest[3][16]; 807 Int numChar=0; 808 const Char* hashType = "\0"; 809 810 if (pictureHashSEI) 811 { 812 switch (pictureHashSEI->method) 813 { 814 case SEIDecodedPictureHash::MD5: 815 { 816 hashType = "MD5"; 817 calcMD5(pic, recon_digest); 818 numChar = 16; 819 break; 820 } 821 case SEIDecodedPictureHash::CRC: 822 { 823 hashType = "CRC"; 824 calcCRC(pic, recon_digest); 825 numChar = 2; 826 break; 827 } 828 case SEIDecodedPictureHash::CHECKSUM: 829 { 830 hashType = "Checksum"; 831 calcChecksum(pic, recon_digest); 832 numChar = 4; 833 break; 834 } 835 default: 836 { 837 assert (!"unknown hash type"); 838 } 839 } 840 } 841 842 /* compare digest against received version */ 843 const Char* ok = "(unk)"; 844 Bool mismatch = false; 845 846 if (pictureHashSEI) 847 { 848 ok = "(OK)"; 849 for(Int yuvIdx = 0; yuvIdx < 3; yuvIdx++) 850 { 851 for (UInt i = 0; i < numChar; i++) 852 { 853 if (recon_digest[yuvIdx][i] != pictureHashSEI->digest[yuvIdx][i]) 854 { 855 ok = "(***ERROR***)"; 856 mismatch = true; 857 } 858 } 859 } 860 } 861 862 printf("[%s:%s,%s] ", hashType, digestToString(recon_digest, numChar), ok); 863 864 if (mismatch) 865 { 866 g_md5_mismatch = true; 867 printf("[rx%s:%s] ", hashType, digestToString(pictureHashSEI->digest, numChar)); 868 } 869 } 870 760 871 //! \} -
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();