/** - create internal class - initialize internal class - until the end of the bitstream, call decoding function in TDecTop class - delete allocated buffers - destroy internal class . */ Void TAppDecTop::decode() { UInt uiPOC; TComList<TComPic*>* pcListPic = NULL; ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary); if (!bitstreamFile) { fprintf(stderr, "\nfailed to open bitstream file `%s' for reading\n", m_pchBitstreamFile); exit(EXIT_FAILURE); } InputByteStream bytestream(bitstreamFile); // create & initialize internal classes xCreateDecLib(); xInitDecLib (); m_iPOCLastDisplay += m_iSkipFrame; // set the last displayed POC correctly for skip forward. // main decoder loop bool recon_opened = false; // reconstruction file not yet opened. (must be performed after SPS is seen) while (!!bitstreamFile) { /* location serves to work around a design fault in the decoder, whereby * the process of reading a new slice that is the first slice of a new frame * requires the TDecTop::decode() method to be called again with the same * nal unit. */ streampos location = bitstreamFile.tellg(); AnnexBStats stats = AnnexBStats(); #if G1002_RPS bool bPreviousPictureDecoded = false; #endif vector<uint8_t> nalUnit; #if G1002_RPS && G1002_IDR_POC_ZERO_BUGFIX InputNALUnit nalu; #endif byteStreamNALUnit(bytestream, nalUnit, stats); // call actual decoding function bool bNewPicture = false; if (nalUnit.empty()) /* this can happen if the following occur: * - empty input file * - two back-to-back start_code_prefixes * - start_code_prefix immediately followed by EOF */ fprintf(stderr, "Warning: Attempt to decode an empty NAL unit\n"); else { #if !G1002_RPS || !G1002_IDR_POC_ZERO_BUGFIX InputNALUnit nalu; #endif read(nalu, nalUnit); #if G1002_RPS if(m_iMaxTemporalLayer >= 0 && nalu.m_TemporalID > m_iMaxTemporalLayer) { if(bPreviousPictureDecoded) { bNewPicture = true; bPreviousPictureDecoded = false; } else { bNewPicture = false; } } else { #endif bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay); if (bNewPicture) { bitstreamFile.clear(); /* location points to the current nalunit payload[1] due to the * need for the annexB parser to read three extra bytes. * [1] except for the first NAL unit in the file * (but bNewPicture doesn't happen then) */ bitstreamFile.seekg(location-streamoff(3)); bytestream.reset(); } #if G1002_RPS bPreviousPictureDecoded = true; } #endif } if (bNewPicture || !bitstreamFile) { m_cTDecTop.executeDeblockAndAlf(uiPOC, pcListPic, m_iSkipFrame, m_iPOCLastDisplay); #if G1002_RPS && G1002_IDR_POC_ZERO_BUGFIX if(nalu.m_UnitType == NAL_UNIT_CODED_SLICE_IDR) { xFlushOutput( pcListPic ); } #endif } if( pcListPic ) { if ( m_pchReconFile && !recon_opened ) { if ( m_outputBitDepth == 0 ) m_outputBitDepth = g_uiBitDepth + g_uiBitIncrement; m_cTVideoIOYuvReconFile.open( m_pchReconFile, true, m_outputBitDepth, g_uiBitDepth + g_uiBitIncrement ); // write mode recon_opened = true; } // write reconstuction to file #if G1002_RPS && G1002_IDR_POC_ZERO_BUGFIX if(bNewPicture) { xWriteOutput( pcListPic ); } #else xWriteOutput( pcListPic ); #endif } } #if G1002_RPS xFlushOutput( pcListPic ); #endif // delete buffers m_cTDecTop.deletePicBuffer(); // destroy internal classes xDestroyDecLib(); }
/** - create internal class - initialize internal class - until the end of the bitstream, call decoding function in TDecTop class - delete allocated buffers - destroy internal class . */ Void TAppDecTop::decode() { Int poc; TComList<TComPic*>* pcListPic = NULL; ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary); if (!bitstreamFile) { fprintf(stderr, "\nfailed to open bitstream file `%s' for reading\n", m_pchBitstreamFile); exit(EXIT_FAILURE); } InputByteStream bytestream(bitstreamFile); if (!m_outputDecodedSEIMessagesFilename.empty() && m_outputDecodedSEIMessagesFilename!="-") { m_seiMessageFileStream.open(m_outputDecodedSEIMessagesFilename.c_str(), std::ios::out); if (!m_seiMessageFileStream.is_open() || !m_seiMessageFileStream.good()) { fprintf(stderr, "\nUnable to open file `%s' for writing decoded SEI messages\n", m_outputDecodedSEIMessagesFilename.c_str()); exit(EXIT_FAILURE); } } // create & initialize internal classes xCreateDecLib(); xInitDecLib (); m_iPOCLastDisplay += m_iSkipFrame; // set the last displayed POC correctly for skip forward. // main decoder loop Bool openedReconFile = false; // reconstruction file not yet opened. (must be performed after SPS is seen) Bool loopFiltered = false; while (!!bitstreamFile) { /* location serves to work around a design fault in the decoder, whereby * the process of reading a new slice that is the first slice of a new frame * requires the TDecTop::decode() method to be called again with the same * nal unit. */ #if RExt__DECODER_DEBUG_BIT_STATISTICS TComCodingStatistics::TComCodingStatisticsData backupStats(TComCodingStatistics::GetStatistics()); streampos location = bitstreamFile.tellg() - streampos(bytestream.GetNumBufferedBytes()); #else streampos location = bitstreamFile.tellg(); #endif AnnexBStats stats = AnnexBStats(); vector<uint8_t> nalUnit; InputNALUnit nalu; byteStreamNALUnit(bytestream, nalUnit, stats); // call actual decoding function Bool bNewPicture = false; if (nalUnit.empty()) { /* this can happen if the following occur: * - empty input file * - two back-to-back start_code_prefixes * - start_code_prefix immediately followed by EOF */ fprintf(stderr, "Warning: Attempt to decode an empty NAL unit\n"); } else { read(nalu, nalUnit); if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu) ) { bNewPicture = false; } else { bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay); if (bNewPicture) { bitstreamFile.clear(); /* location points to the current nalunit payload[1] due to the * need for the annexB parser to read three extra bytes. * [1] except for the first NAL unit in the file * (but bNewPicture doesn't happen then) */ #if RExt__DECODER_DEBUG_BIT_STATISTICS bitstreamFile.seekg(location); bytestream.reset(); TComCodingStatistics::SetStatistics(backupStats); #else bitstreamFile.seekg(location-streamoff(3)); bytestream.reset(); #endif } } } #if FIX_OUTPUT_ORDER_BEHAVIOR if ( (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS) && !m_cTDecTop.getFirstSliceInSequence () ) #else if (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS) #endif { if (!loopFiltered || bitstreamFile) { m_cTDecTop.executeLoopFilters(poc, pcListPic); } loopFiltered = (nalu.m_nalUnitType == NAL_UNIT_EOS); #if FIX_OUTPUT_ORDER_BEHAVIOR if (nalu.m_nalUnitType == NAL_UNIT_EOS) { m_cTDecTop.setFirstSliceInSequence(true); } #endif } #if FIX_OUTPUT_ORDER_BEHAVIOR else if ( (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS ) && m_cTDecTop.getFirstSliceInSequence () ) { m_cTDecTop.setFirstSliceInPicture (true); } #endif #if !FIX_WRITING_OUTPUT #if SETTING_NO_OUT_PIC_PRIOR if (bNewPicture && m_cTDecTop.getIsNoOutputPriorPics()) { m_cTDecTop.checkNoOutputPriorPics( pcListPic ); } #endif #endif if( pcListPic ) { if ( m_pchReconFile && !openedReconFile ) { for (UInt channelType = 0; channelType < MAX_NUM_CHANNEL_TYPE; channelType++) { if (m_outputBitDepth[channelType] == 0) m_outputBitDepth[channelType] = g_bitDepth[channelType]; } m_cTVideoIOYuvReconFile.open( m_pchReconFile, true, m_outputBitDepth, m_outputBitDepth, g_bitDepth ); // write mode openedReconFile = true; } #if FIX_WRITING_OUTPUT // write reconstruction to file if( bNewPicture ) { xWriteOutput( pcListPic, nalu.m_temporalId ); } #if SETTING_NO_OUT_PIC_PRIOR if ( (bNewPicture || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA) && m_cTDecTop.getNoOutputPriorPicsFlag() ) { m_cTDecTop.checkNoOutputPriorPics( pcListPic ); m_cTDecTop.setNoOutputPriorPicsFlag (false); } #endif #endif if ( bNewPicture && ( nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP ) ) { xFlushOutput( pcListPic ); } if (nalu.m_nalUnitType == NAL_UNIT_EOS) { #if FIX_OUTPUT_EOS xWriteOutput( pcListPic, nalu.m_temporalId ); #if FIX_OUTPUT_ORDER_BEHAVIOR m_cTDecTop.setFirstSliceInPicture (false); #endif #else xFlushOutput( pcListPic ); #endif } // write reconstruction to file -- for additional bumping as defined in C.5.2.3 #if FIX_WRITING_OUTPUT if(!bNewPicture && nalu.m_nalUnitType >= NAL_UNIT_CODED_SLICE_TRAIL_N && nalu.m_nalUnitType <= NAL_UNIT_RESERVED_VCL31) #else if(bNewPicture) #endif { xWriteOutput( pcListPic, nalu.m_temporalId ); } } } xFlushOutput( pcListPic ); // delete buffers m_cTDecTop.deletePicBuffer(); // destroy internal classes xDestroyDecLib(); }
/** - create internal class - initialize internal class - until the end of the bitstream, call decoding function in TDecTop class - delete allocated buffers - destroy internal class . */ Void TAppDecTop::decode() { Int poc; TComList<TComPic*>* pcListPic = NULL; ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary); if (!bitstreamFile) { fprintf(stderr, "\nfailed to open bitstream file `%s' for reading\n", m_pchBitstreamFile); exit(EXIT_FAILURE); } InputByteStream bytestream(bitstreamFile); // create & initialize internal classes xCreateDecLib(); xInitDecLib (); m_iPOCLastDisplay += m_iSkipFrame; // set the last displayed POC correctly for skip forward. // main decoder loop Bool recon_opened = false; // reconstruction file not yet opened. (must be performed after SPS is seen) while (!!bitstreamFile) { /* location serves to work around a design fault in the decoder, whereby * the process of reading a new slice that is the first slice of a new frame * requires the TDecTop::decode() method to be called again with the same * nal unit. */ streampos location = bitstreamFile.tellg(); AnnexBStats stats = AnnexBStats(); Bool bPreviousPictureDecoded = false; vector<uint8_t> nalUnit; InputNALUnit nalu; byteStreamNALUnit(bytestream, nalUnit, stats); // call actual decoding function Bool bNewPicture = false; if (nalUnit.empty()) { /* this can happen if the following occur: * - empty input file * - two back-to-back start_code_prefixes * - start_code_prefix immediately followed by EOF */ fprintf(stderr, "Warning: Attempt to decode an empty NAL unit\n"); } else { read(nalu, nalUnit); if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu) ) { if(bPreviousPictureDecoded) { bNewPicture = true; bPreviousPictureDecoded = false; } else { bNewPicture = false; } } else { bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay); if (bNewPicture) { bitstreamFile.clear(); /* location points to the current nalunit payload[1] due to the * need for the annexB parser to read three extra bytes. * [1] except for the first NAL unit in the file * (but bNewPicture doesn't happen then) */ bitstreamFile.seekg(location-streamoff(3)); bytestream.reset(); } bPreviousPictureDecoded = true; } } if (bNewPicture || !bitstreamFile) { m_cTDecTop.executeLoopFilters(poc, pcListPic); } if( pcListPic ) { if ( m_pchReconFile && !recon_opened ) { if (!m_outputBitDepthY) { m_outputBitDepthY = g_bitDepthY; } if (!m_outputBitDepthC) { m_outputBitDepthC = g_bitDepthC; } m_cTVideoIOYuvReconFile.open( m_pchReconFile, true, m_outputBitDepthY, m_outputBitDepthC, g_bitDepthY, g_bitDepthC ); // write mode recon_opened = true; } if ( bNewPicture && ( nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_RADL || nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_W_LP ) ) { xFlushOutput( pcListPic ); } // write reconstruction to file if(bNewPicture) { xWriteOutput( pcListPic, nalu.m_temporalId ); } } } xFlushOutput( pcListPic ); // delete buffers m_cTDecTop.deletePicBuffer(); // destroy internal classes xDestroyDecLib(); }