diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 20f493195fd809f0c4c42d726960869d36844ace..053b6590d564ad706afcd86d7f22c3636329e57e 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -70,7 +70,8 @@ EncApp::EncApp() m_metricTime = std::chrono::milliseconds(0); #endif #if JVET_N0278_FIXES - m_numEncoded = 0; + m_numEncoded = 0; + m_flush = false; #endif } @@ -783,10 +784,9 @@ void EncApp::destroyLib() printRateSummary(); } -bool EncApp::encode() +bool EncApp::encodePrep( bool& eos ) { // main encoder loop - bool bEos = false; const InputColourSpaceConversion ipCSC = m_inputColourSpaceConvert; const InputColourSpaceConversion snrCSC = ( !m_snrInternalColourSpace ) ? m_inputColourSpaceConvert : IPCOLOURSPACE_UNCHANGED; @@ -807,33 +807,50 @@ bool EncApp::encode() // increase number of received frames m_iFrameRcvd++; - bEos = ( m_isField && ( m_iFrameRcvd == ( m_framesToBeEncoded >> 1 ) ) ) || ( !m_isField && ( m_iFrameRcvd == m_framesToBeEncoded ) ); + eos = ( m_isField && ( m_iFrameRcvd == ( m_framesToBeEncoded >> 1 ) ) ) || ( !m_isField && ( m_iFrameRcvd == m_framesToBeEncoded ) ); - bool flush = 0; // if end of file (which is only detected on a read failure) flush the encoder of any queued pictures if( m_cVideoIOYuvInputFile.isEof() ) { - flush = true; - bEos = true; + m_flush = true; + eos = true; m_iFrameRcvd--; m_cEncLib.setFramesToBeEncoded( m_iFrameRcvd ); } + bool keepDoing = false; + // call encoding function for one frame if( m_isField ) { - m_cEncLib.encode( bEos, flush ? 0 : m_orgPic, flush ? 0 : m_trueOrgPic, snrCSC, m_recBufList, m_numEncoded, m_isTopFieldFirst ); -#if JVET_O0756_CALCULATE_HDRMETRICS - m_metricTime = m_cEncLib.getMetricTime(); -#endif + keepDoing = m_cEncLib.encodePrep( eos, m_flush ? 0 : m_orgPic, m_flush ? 0 : m_trueOrgPic, snrCSC, m_recBufList, m_numEncoded, m_isTopFieldFirst ); } else { - m_cEncLib.encode( bEos, flush ? 0 : m_orgPic, flush ? 0 : m_trueOrgPic, snrCSC, m_recBufList, m_numEncoded ); + keepDoing = m_cEncLib.encodePrep( eos, m_flush ? 0 : m_orgPic, m_flush ? 0 : m_trueOrgPic, snrCSC, m_recBufList, m_numEncoded ); + } + + return keepDoing; +} + +bool EncApp::encode() +{ + const InputColourSpaceConversion snrCSC = ( !m_snrInternalColourSpace ) ? m_inputColourSpaceConvert : IPCOLOURSPACE_UNCHANGED; + bool keepDoing = false; + + // call encoding function for one frame + if( m_isField ) + { + keepDoing = m_cEncLib.encode( snrCSC, m_recBufList, m_numEncoded, m_isTopFieldFirst ); + } + else + { + keepDoing = m_cEncLib.encode( snrCSC, m_recBufList, m_numEncoded ); + } + #if JVET_O0756_CALCULATE_HDRMETRICS m_metricTime = m_cEncLib.getMetricTime(); #endif - } // write bistream to file if necessary if( m_numEncoded > 0 ) @@ -850,7 +867,7 @@ bool EncApp::encode() #endif } - return bEos; + return keepDoing; } #else /** diff --git a/source/App/EncoderApp/EncApp.h b/source/App/EncoderApp/EncApp.h index 27097c40c97ce29e94634a4c523d747b0b28dbdf..38c082f558d21f995694f1be04bd41e00844568e 100644 --- a/source/App/EncoderApp/EncApp.h +++ b/source/App/EncoderApp/EncApp.h @@ -103,6 +103,7 @@ private: #if EXTENSION_360_VIDEO TExt360AppEncTop* m_ext360; #endif + bool m_flush; #endif public: @@ -111,8 +112,9 @@ public: #if JVET_N0278_FIXES int getMaxLayers() const { return m_maxLayers; } - void createLib( int layerId ); ///< main encoding function - void destroyLib(); ///< main encoding function + void createLib( int layerId ); + void destroyLib(); + bool encodePrep( bool& eos ); bool encode(); ///< main encoding function #else void encode(); ///< main encoding function diff --git a/source/App/EncoderApp/encmain.cpp b/source/App/EncoderApp/encmain.cpp index b1151925e99890b4fa5b579b8d31def20b6ca7f5..abe16cd00694d10fbe279dd88b37b251047133a8 100644 --- a/source/App/EncoderApp/encmain.cpp +++ b/source/App/EncoderApp/encmain.cpp @@ -214,26 +214,58 @@ int main(int argc, char* argv[]) while( !eos ) { - for( auto & encApp : pcEncApp ) + // read GOP + bool keepLoop = true; + while( keepLoop ) { -#ifndef _DEBUG - try + for( auto & encApp : pcEncApp ) { +#ifndef _DEBUG + try + { #endif - eos = encApp->encode(); + keepLoop = encApp->encodePrep( eos ); #ifndef _DEBUG + } + catch( Exception &e ) + { + std::cerr << e.what() << std::endl; + return EXIT_FAILURE; + } + catch( const std::bad_alloc &e ) + { + std::cout << "Memory allocation failed: " << e.what() << std::endl; + return EXIT_FAILURE; + } +#endif } - catch( Exception &e ) - { - std::cerr << e.what() << std::endl; - return EXIT_FAILURE; - } - catch( const std::bad_alloc &e ) + } + + // encode GOP + keepLoop = true; + while( keepLoop ) + { + for( auto & encApp : pcEncApp ) { - std::cout << "Memory allocation failed: " << e.what() << std::endl; - return EXIT_FAILURE; - } +#ifndef _DEBUG + try + { +#endif + keepLoop = encApp->encode(); +#ifndef _DEBUG + } + catch( Exception &e ) + { + std::cerr << e.what() << std::endl; + return EXIT_FAILURE; + } + catch( const std::bad_alloc &e ) + { + std::cout << "Memory allocation failed: " << e.what() << std::endl; + return EXIT_FAILURE; + } #endif + } } } #else diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index a4e00845f98d189d34460553851af484ed846ec7..6e7eb3b6b764fd5a3e82fedfce09ca22c8328442 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -2115,7 +2115,7 @@ public: if( std::find( accessUnitApsNals.begin(), accessUnitApsNals.end(), apsId ) != accessUnitApsNals.end() ) { - CHECK( m_paramsetMap.find( apsId ) == m_paramsetMap.end(), "APS does not exists" ); + CHECK( m_paramsetMap.find( apsId ) == m_paramsetMap.end(), "APS does not exist" ); APS* existedAPS = m_paramsetMap[apsId].parameterSet; if( aps->getAPSType() == LMCS_APS ) diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index dd46c2c9d9f55f6dd6db2f35ee59dcb2813a6eef..a6c52be92dd4b23cde3efc3378c6fc5a74b0d971 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -1894,6 +1894,9 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, std::list<PelUnitBuf*>& rcListPicYuvRecOut, bool isField, bool isTff, const InputColourSpaceConversion snr_conversion, const bool printFrameMSE , bool isEncodeLtRef +#if JVET_N0278_FIXES + , const int picIdInGOP +#endif ) { // TODO: Split this function up. @@ -1905,9 +1908,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, AccessUnit::iterator itLocationToPushSliceHeaderNALU; // used to store location where NALU containing slice header is to be inserted Picture* scaledRefPic[MAX_NUM_REF] = {}; - xInitGOP(iPOCLast, iNumPicRcvd, isField - , isEncodeLtRef - ); + xInitGOP( iPOCLast, iNumPicRcvd, isField, isEncodeLtRef ); m_iNumPicCoded = 0; SEIMessages leadingSeiMessages; @@ -1922,6 +1923,12 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, effFieldIRAPMap.initialize(isField, m_iGopSize, iPOCLast, iNumPicRcvd, m_iLastIDR, this, m_pcCfg); } +#if JVET_N0278_FIXES + for( int iGOPid = picIdInGOP; iGOPid <= picIdInGOP; iGOPid++ ) + { + // reset flag indicating whether pictures have been encoded + m_pcCfg->setEncodedFlag( iGOPid, false ); +#else // reset flag indicating whether pictures have been encoded for ( int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ ) { @@ -1930,6 +1937,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, for ( int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ ) { +#endif if (m_pcCfg->getEfficientFieldIRAPEnabled()) { iGOPid=effFieldIRAPMap.adjustGOPid(iGOPid); @@ -2883,6 +2891,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, m_bSeqFirst = false; } + if (m_pcCfg->getAccessUnitDelimiter()) { xWriteAccessUnitDelimiter(accessUnit, pcSlice); @@ -3181,8 +3190,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, delete pcBitstreamRedirect; +#if JVET_N0278_FIXES + CHECK( m_iNumPicCoded > 1, "Unspecified error" ); +#else CHECK(!( (m_iNumPicCoded == iNumPicRcvd) ), "Unspecified error"); - +#endif } void EncGOP::printOutSummary( uint32_t uiNumAllPicCoded, bool isField, const bool printMSEBasedSNR, const bool printSequenceMSE, const bool printHexPsnr, const bool printRprPSNR, const BitDepths &bitDepths ) diff --git a/source/Lib/EncoderLib/EncGOP.h b/source/Lib/EncoderLib/EncGOP.h index 4a9700642c613607bc85f3b962c88a0d07d1d9b8..e2ef2b5363254a9c89314edfeb2531366ea87a2c 100644 --- a/source/Lib/EncoderLib/EncGOP.h +++ b/source/Lib/EncoderLib/EncGOP.h @@ -216,6 +216,9 @@ public: void compressGOP ( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, std::list<PelUnitBuf*>& rcListPicYuvRec, bool isField, bool isTff, const InputColourSpaceConversion snr_conversion, const bool printFrameMSE , bool isEncodeLtRef +#if JVET_N0278_FIXES + , const int picIdInGOP +#endif ); void xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, OutputBitstream* pcBitstreamRedirect); diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index b3d8fba4090fe4a3d02c98f3f82fbe75d3cb5f04..2c04f68d05ec1733bc7f2c9f385997d840d6848c 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -96,6 +96,8 @@ EncLib::EncLib() #if JVET_N0278_FIXES m_layerId = NOT_VALID; + m_isGopEncoding = false; + m_picIdInGOP = NOT_VALID; #endif } @@ -570,6 +572,185 @@ void EncLib::deletePicBuffer() #endif } +#if JVET_N0278_FIXES +bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYuvTrueOrg, const InputColourSpaceConversion snrCSC, std::list<PelUnitBuf*>& rcListPicYuvRecOut, int& iNumEncoded ) +{ + if( m_compositeRefEnabled && m_cGOPEncoder.getPicBg()->getSpliceFull() && m_iPOCLast >= 10 && m_iNumPicRcvd == 0 && m_cGOPEncoder.getEncodedLTRef() == false ) + { + Picture* picCurr = NULL; + xGetNewPicBuffer( rcListPicYuvRecOut, picCurr, 2 ); + const PPS *pps = m_ppsMap.getPS( 2 ); + const SPS *sps = m_spsMap.getPS( pps->getSPSId() ); + + picCurr->M_BUFS( 0, PIC_ORIGINAL ).copyFrom( m_cGOPEncoder.getPicBg()->getRecoBuf() ); + picCurr->finalInit( *sps, *pps, m_apss, m_lmcsAPS, m_scalinglistAPS ); + picCurr->poc = m_iPOCLast - 1; + m_iPOCLast -= 2; + if( getUseAdaptiveQP() ) + { + AQpPreanalyzer::preanalyze( picCurr ); + } + if( m_RCEnableRateControl ) + { + m_cRateCtrl.initRCGOP( m_iNumPicRcvd ); + } + + m_cGOPEncoder.compressGOP( m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, +#if JVET_N0278_FIXES + false, false, snrCSC, m_printFrameMSE, true, 0 ); +#else + false, false, snrCSC, m_printFrameMSE, true); +#endif + +#if JVET_O0756_CALCULATE_HDRMETRICS + m_metricTime = m_cGOPEncoder.getMetricTime(); +#endif + m_cGOPEncoder.setEncodedLTRef( true ); + if( m_RCEnableRateControl ) + { + m_cRateCtrl.destroyRCGOP(); + } + + iNumEncoded = 0; + m_iNumPicRcvd = 0; + } + + //PROF_ACCUM_AND_START_NEW_SET( getProfilerPic(), P_GOP_LEVEL ); + if( pcPicYuvOrg != NULL ) + { + // get original YUV + Picture* pcPicCurr = NULL; + + int ppsID = -1; // Use default PPS ID +#if ER_CHROMA_QP_WCG_PPS + if( getWCGChromaQPControl().isEnabled() ) + { + ppsID = getdQPs()[m_iPOCLast / ( m_compositeRefEnabled ? 2 : 1 ) + 1]; + ppsID += ( getSwitchPOC() != -1 && ( m_iPOCLast + 1 >= getSwitchPOC() ) ? 1 : 0 ); + } +#endif + + if( m_rprEnabled && m_uiIntraPeriod == -1 ) + { + const int poc = m_iPOCLast + ( m_compositeRefEnabled ? 2 : 1 ); + + if( poc / m_switchPocPeriod % 2 ) + { + ppsID = ENC_PPS_ID_RPR; + } + else + { + ppsID = 0; + } + } + +#if JVET_N0278_FIXES + if( m_cVPS.getMaxLayers() > 1 ) + { + ppsID = m_layerId; + } +#endif + + xGetNewPicBuffer( rcListPicYuvRecOut, pcPicCurr, ppsID ); + + const PPS *pPPS = ( ppsID < 0 ) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS( ppsID ); + const SPS *pSPS = m_spsMap.getPS( pPPS->getSPSId() ); + + if( m_rprEnabled ) + { + pcPicCurr->M_BUFS( 0, PIC_ORIGINAL_INPUT ).getBuf( COMPONENT_Y ).copyFrom( pcPicYuvOrg->getBuf( COMPONENT_Y ) ); + pcPicCurr->M_BUFS( 0, PIC_ORIGINAL_INPUT ).getBuf( COMPONENT_Cb ).copyFrom( pcPicYuvOrg->getBuf( COMPONENT_Cb ) ); + pcPicCurr->M_BUFS( 0, PIC_ORIGINAL_INPUT ).getBuf( COMPONENT_Cr ).copyFrom( pcPicYuvOrg->getBuf( COMPONENT_Cr ) ); + + pcPicCurr->M_BUFS( 0, PIC_TRUE_ORIGINAL_INPUT ).getBuf( COMPONENT_Y ).copyFrom( cPicYuvTrueOrg->getBuf( COMPONENT_Y ) ); + pcPicCurr->M_BUFS( 0, PIC_TRUE_ORIGINAL_INPUT ).getBuf( COMPONENT_Cb ).copyFrom( cPicYuvTrueOrg->getBuf( COMPONENT_Cb ) ); + pcPicCurr->M_BUFS( 0, PIC_TRUE_ORIGINAL_INPUT ).getBuf( COMPONENT_Cr ).copyFrom( cPicYuvTrueOrg->getBuf( COMPONENT_Cr ) ); + + const ChromaFormat chromaFormatIDC = pSPS->getChromaFormatIdc(); + + const PPS *refPPS = m_ppsMap.getPS( 0 ); + Picture::rescalePicture( *pcPicYuvOrg, refPPS->getConformanceWindow(), pcPicCurr->getOrigBuf(), pPPS->getConformanceWindow(), chromaFormatIDC, pSPS->getBitDepths(), true, true ); + Picture::rescalePicture( *cPicYuvTrueOrg, refPPS->getConformanceWindow(), pcPicCurr->getTrueOrigBuf(), pPPS->getConformanceWindow(), chromaFormatIDC, pSPS->getBitDepths(), true, true ); + } + else + { + pcPicCurr->M_BUFS( 0, PIC_ORIGINAL ).swap( *pcPicYuvOrg ); + pcPicCurr->M_BUFS( 0, PIC_TRUE_ORIGINAL ).swap( *cPicYuvTrueOrg ); + } + + pcPicCurr->finalInit( *pSPS, *pPPS, m_apss, m_lmcsAPS, m_scalinglistAPS ); + PPS *ptrPPS = ( ppsID < 0 ) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS( ppsID ); + ptrPPS->setNumBricksInPic( (int)pcPicCurr->brickMap->bricks.size() ); + + pcPicCurr->poc = m_iPOCLast; + + // compute image characteristics + if( getUseAdaptiveQP() ) + { + AQpPreanalyzer::preanalyze( pcPicCurr ); + } + } + + if( ( m_iNumPicRcvd == 0 ) || ( !flush && ( m_iPOCLast != 0 ) && ( m_iNumPicRcvd != m_iGOPSize ) && ( m_iGOPSize != 0 ) ) ) + { + iNumEncoded = 0; + return true; + } + + if( m_RCEnableRateControl ) + { + m_cRateCtrl.initRCGOP( m_iNumPicRcvd ); + } + + m_picIdInGOP = 0; + + return false; +} + +/** + - Application has picture buffer list with size of GOP + 1 + - Picture buffer list acts like as ring buffer + - End of the list has the latest picture + . + \param flush cause encoder to encode a partial GOP + \param pcPicYuvOrg original YUV picture + \param pcPicYuvTrueOrg + \param snrCSC + \retval rcListPicYuvRecOut list of reconstruction YUV pictures + \retval accessUnitsOut list of output access units + \retval iNumEncoded number of encoded pictures + */ + +bool EncLib::encode( const InputColourSpaceConversion snrCSC, std::list<PelUnitBuf*>& rcListPicYuvRecOut, int& iNumEncoded ) +{ + // compress GOP + m_cGOPEncoder.compressGOP( m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, + false, false, snrCSC, m_printFrameMSE, false, m_picIdInGOP ); + + m_picIdInGOP++; + + // go over all pictures in a GOP excluding the first IRAP + if( m_picIdInGOP != m_iGOPSize && m_iPOCLast ) + { + return true; + } + +#if JVET_O0756_CALCULATE_HDRMETRICS + m_metricTime = m_cGOPEncoder.getMetricTime(); +#endif + + if( m_RCEnableRateControl ) + { + m_cRateCtrl.destroyRCGOP(); + } + + iNumEncoded = m_iNumPicRcvd; + m_iNumPicRcvd = 0; + m_uiNumAllPicCoded += iNumEncoded; + + return false; +} +#else /** - Application has picture buffer list with size of GOP + 1 - Picture buffer list acts like as ring buffer @@ -605,8 +786,10 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYuvTru { m_cRateCtrl.initRCGOP(m_iNumPicRcvd); } + m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, false, false, snrCSC, m_printFrameMSE, true); + #if JVET_O0756_CALCULATE_HDRMETRICS m_metricTime = m_cGOPEncoder.getMetricTime(); #endif @@ -648,13 +831,6 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYuvTru } } -#if JVET_N0278_FIXES - if( m_cVPS.getMaxLayers() > 1 ) - { - ppsID = m_layerId; - } -#endif - xGetNewPicBuffer( rcListPicYuvRecOut, pcPicCurr, ppsID ); const PPS *pPPS = ( ppsID < 0 ) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS( ppsID ); @@ -711,6 +887,7 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYuvTru false, false, snrCSC, m_printFrameMSE , false ); + #if JVET_O0756_CALCULATE_HDRMETRICS m_metricTime = m_cGOPEncoder.getMetricTime(); #endif @@ -724,6 +901,7 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYuvTru m_iNumPicRcvd = 0; m_uiNumAllPicCoded += iNumEncoded; } +#endif /**------------------------------------------------ Separate interlaced frame into two fields @@ -747,6 +925,95 @@ void separateFields(Pel* org, Pel* dstField, uint32_t stride, uint32_t width, ui } +#if JVET_N0278_FIXES +bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* pcPicYuvTrueOrg, const InputColourSpaceConversion snrCSC, std::list<PelUnitBuf*>& rcListPicYuvRecOut, + int& iNumEncoded, bool isTff ) +{ + iNumEncoded = 0; + bool keepDoing = true; + + for( int fieldNum = 0; fieldNum < 2; fieldNum++ ) + { + if( pcPicYuvOrg ) + { + /* -- field initialization -- */ + const bool isTopField = isTff == ( fieldNum == 0 ); + + Picture *pcField; + xGetNewPicBuffer( rcListPicYuvRecOut, pcField, -1 ); + + for( uint32_t comp = 0; comp < ::getNumberValidComponents( pcPicYuvOrg->chromaFormat ); comp++ ) + { + const ComponentID compID = ComponentID( comp ); + { + PelBuf compBuf = pcPicYuvOrg->get( compID ); + separateFields( compBuf.buf, + pcField->getOrigBuf().get( compID ).buf, + compBuf.stride, + compBuf.width, + compBuf.height, + isTopField ); + } + } + + { + int ppsID = -1; // Use default PPS ID + const PPS *pPPS = ( ppsID < 0 ) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS( ppsID ); + const SPS *pSPS = m_spsMap.getPS( pPPS->getSPSId() ); + pcField->finalInit( *pSPS, *pPPS, m_apss, m_lmcsAPS, m_scalinglistAPS ); + } + + pcField->poc = m_iPOCLast; + pcField->reconstructed = false; + + pcField->setBorderExtension( false );// where is this normally? + + pcField->topField = isTopField; // interlaced requirement + + // compute image characteristics + if( getUseAdaptiveQP() ) + { + AQpPreanalyzer::preanalyze( pcField ); + } + } + + if( m_iNumPicRcvd && ( ( flush&&fieldNum == 1 ) || ( m_iPOCLast / 2 ) == 0 || m_iNumPicRcvd == m_iGOPSize ) ) + { + keepDoing = false; + } + } + + return keepDoing; +} + +bool EncLib::encode( const InputColourSpaceConversion snrCSC, std::list<PelUnitBuf*>& rcListPicYuvRecOut, int& iNumEncoded, bool isTff ) +{ + iNumEncoded = 0; + + for( int fieldNum = 0; fieldNum < 2; fieldNum++ ) + { + // compress GOP + m_cGOPEncoder.compressGOP( m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, true, isTff, snrCSC, m_printFrameMSE, false, m_picIdInGOP ); +#if JVET_O0756_CALCULATE_HDRMETRICS + m_metricTime = m_cGOPEncoder.getMetricTime(); +#endif + + m_picIdInGOP++; + + // go over all pictures in a GOP excluding the first IRAP + if( m_picIdInGOP != m_iGOPSize && m_iPOCLast / 2 ) + { + return true; + } + + iNumEncoded += m_iNumPicRcvd; + m_uiNumAllPicCoded += m_iNumPicRcvd; + m_iNumPicRcvd = 0; + } + + return false; +} +#else void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* pcPicYuvTrueOrg, const InputColourSpaceConversion snrCSC, std::list<PelUnitBuf*>& rcListPicYuvRecOut, int& iNumEncoded, bool isTff ) { @@ -806,14 +1073,13 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* pcPicYuvTr #if JVET_O0756_CALCULATE_HDRMETRICS m_metricTime = m_cGOPEncoder.getMetricTime(); #endif - iNumEncoded += m_iNumPicRcvd; m_uiNumAllPicCoded += m_iNumPicRcvd; m_iNumPicRcvd = 0; } } } - +#endif // ==================================================================================================================== // Protected member functions @@ -873,7 +1139,7 @@ void EncLib::xGetNewPicBuffer ( std::list<PelUnitBuf*>& rcListPicYuvRecOut, Pict // If PPS ID is the same, we will assume that it has not changed since it was last used // and return the old object. #if JVET_N0278_FIXES - if( pps.getPPSId() != rpcPic->cs->pps->getPPSId() && rpcPic ) + if( rpcPic && pps.getPPSId() != rpcPic->cs->pps->getPPSId() ) #else if (pps.getPPSId() != rpcPic->cs->pps->getPPSId()) #endif diff --git a/source/Lib/EncoderLib/EncLib.h b/source/Lib/EncoderLib/EncLib.h index c1eac8ea953fc898392eb7ef24125ab1d7ccea6a..00679a4543df4cef40ab012b0e57fc9b2a3dae6f 100644 --- a/source/Lib/EncoderLib/EncLib.h +++ b/source/Lib/EncoderLib/EncLib.h @@ -160,6 +160,10 @@ private: #if JVET_O0756_CALCULATE_HDRMETRICS std::chrono::duration<long long, ratio<1, 1000000000>> m_metricTime; #endif +#if JVET_N0278_FIXES + bool m_isGopEncoding; + int m_picIdInGOP; +#endif public: SPS* getSPS( int spsId ) { return m_spsMap.getPS( spsId ); }; @@ -272,6 +276,27 @@ public: // ------------------------------------------------------------------------------------------------------------------- /// encode several number of pictures until end-of-sequence +#if JVET_N0278_FIXES + bool encodePrep( bool bEos, + PelStorage* pcPicYuvOrg, + PelStorage* pcPicYuvTrueOrg, const InputColourSpaceConversion snrCSC, // used for SNR calculations. Picture in original colour space. + std::list<PelUnitBuf*>& rcListPicYuvRecOut, + int& iNumEncoded ); + + bool encode( const InputColourSpaceConversion snrCSC, // used for SNR calculations. Picture in original colour space. + std::list<PelUnitBuf*>& rcListPicYuvRecOut, + int& iNumEncoded ); + + bool encodePrep( bool bEos, + PelStorage* pcPicYuvOrg, + PelStorage* pcPicYuvTrueOrg, const InputColourSpaceConversion snrCSC, // used for SNR calculations. Picture in original colour space. + std::list<PelUnitBuf*>& rcListPicYuvRecOut, + int& iNumEncoded, bool isTff ); + + bool encode( const InputColourSpaceConversion snrCSC, // used for SNR calculations. Picture in original colour space. + std::list<PelUnitBuf*>& rcListPicYuvRecOut, + int& iNumEncoded, bool isTff ); +#else void encode( bool bEos, PelStorage* pcPicYuvOrg, PelStorage* pcPicYuvTrueOrg, const InputColourSpaceConversion snrCSC, // used for SNR calculations. Picture in original colour space. @@ -284,6 +309,7 @@ public: PelStorage* pcPicYuvTrueOrg, const InputColourSpaceConversion snrCSC, // used for SNR calculations. Picture in original colour space. std::list<PelUnitBuf*>& rcListPicYuvRecOut, int& iNumEncoded, bool isTff ); +#endif void printSummary( bool isField ) { m_cGOPEncoder.printOutSummary( m_uiNumAllPicCoded, isField, m_printMSEBasedSequencePSNR, m_printSequenceMSE, m_printHexPsnr, m_rprEnabled, m_spsMap.getFirstPS()->getBitDepths() ); }