// ====================================================================================================================
// Public member functions
// ====================================================================================================================
/**
- 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* pcListPic = NULL;
ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary);
if (!bitstreamFile)
{
fprintf(stderr, "
failed to open bitstream file `%s' for reading
", 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 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. */
streampos location = bitstreamFile.tellg();
AnnexBStats stats = AnnexBStats();
vector 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
");
}
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) */
bitstreamFile.seekg(location-streamoff(3));
bytestream.reset();
}
}
}
if (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS)
{
if (!loopFiltered || bitstreamFile)
{
m_cTDecTop.executeLoopFilters(poc, pcListPic);
}
loopFiltered = (nalu.m_nalUnitType == NAL_UNIT_EOS);
}
#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 )
{
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
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 );
#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();
}