📄 picencoder.cpp
字号:
}
}
else if( rcSliceHeader.isBSlice() )
{
if( rcSliceHeader.getPPS().getWeightedBiPredIdc() == 1 )
{
rcSliceHeader.setLumaLog2WeightDenom ( 6 );
rcSliceHeader.setChromaLog2WeightDenom( 6 );
RNOK( rcSliceHeader.getPredWeightTableL0().initDefaults( rcSliceHeader.getLumaLog2WeightDenom(), rcSliceHeader.getChromaLog2WeightDenom() ) );
RNOK( rcSliceHeader.getPredWeightTableL1().initDefaults( rcSliceHeader.getLumaLog2WeightDenom(), rcSliceHeader.getChromaLog2WeightDenom() ) );
RNOK( rcSliceHeader.getPredWeightTableL0().initRandomly() );
RNOK( rcSliceHeader.getPredWeightTableL1().initRandomly() );
}
}
return Err::m_nOK;
}
ErrVal
PicEncoder::xInitExtBinDataAccessor( ExtBinDataAccessor& rcExtBinDataAccessor )
{
ROF( m_pucWriteBuffer );
m_cBinData.reset ();
m_cBinData.set ( m_pucWriteBuffer, m_uiWriteBufferSize );
m_cBinData.setMemAccessor ( rcExtBinDataAccessor );
return Err::m_nOK;
}
ErrVal
PicEncoder::xAppendNewExtBinDataAccessor( ExtBinDataAccessorList& rcExtBinDataAccessorList,
ExtBinDataAccessor* pcExtBinDataAccessor )
{
ROF( pcExtBinDataAccessor );
ROF( pcExtBinDataAccessor->data() );
UInt uiNewSize = pcExtBinDataAccessor->size();
UChar* pucNewBuffer = new UChar [ uiNewSize ];
ROF( pucNewBuffer );
::memcpy( pucNewBuffer, pcExtBinDataAccessor->data(), uiNewSize * sizeof( UChar ) );
ExtBinDataAccessor* pcNewExtBinDataAccessor = new ExtBinDataAccessor;
ROF( pcNewExtBinDataAccessor );
m_cBinData .reset ();
m_cBinData .set ( pucNewBuffer, uiNewSize );
m_cBinData .setMemAccessor ( *pcNewExtBinDataAccessor );
rcExtBinDataAccessorList.push_back ( pcNewExtBinDataAccessor );
m_cBinData .reset ();
m_cBinData .setMemAccessor ( *pcExtBinDataAccessor );
return Err::m_nOK;
}
ErrVal
PicEncoder::xEncodePicture( ExtBinDataAccessorList& rcExtBinDataAccessorList,
RecPicBufUnit& rcRecPicBufUnit,
SliceHeader& rcSliceHeader,
Double dLambda,
UInt& ruiBits )
{
UInt uiBits = 0;
//===== start picture =====
RefFrameList cList0, cList1;
RNOK( xStartPicture( rcRecPicBufUnit, rcSliceHeader, cList0, cList1 ) );
//TMM_WP
if(rcSliceHeader.getSliceType() == P_SLICE)
m_pcSliceEncoder->xSetPredWeights( rcSliceHeader,
rcRecPicBufUnit.getRecFrame(),
cList0,
cList1);
else if(rcSliceHeader.getSliceType() == B_SLICE)
m_pcSliceEncoder->xSetPredWeights( rcSliceHeader,
rcRecPicBufUnit.getRecFrame(),
cList0,
cList1);
//TMM_WP
//===== encoding of slice groups =====
for( Int iSliceGroupID = 0; ! rcSliceHeader.getFMO()->SliceGroupCompletelyCoded( iSliceGroupID ); iSliceGroupID++ )
{
UInt uiBitsSlice = 0;
//----- init slice size -----
rcSliceHeader.setFirstMbInSlice( rcSliceHeader.getFMO()->getFirstMacroblockInSlice( iSliceGroupID ) );
rcSliceHeader.setLastMbInSlice ( rcSliceHeader.getFMO()->getLastMBInSliceGroup ( iSliceGroupID ) );
//----- init NAL unit -----
RNOK( xInitExtBinDataAccessor ( m_cExtBinDataAccessor ) );
RNOK( m_pcNalUnitEncoder->initNalUnit( &m_cExtBinDataAccessor ) );
//----- write slice header -----
ETRACE_NEWSLICE;
RNOK( m_pcNalUnitEncoder->write ( rcSliceHeader ) );
//----- real coding -----
RNOK( m_pcSliceEncoder->encodeSlice( rcSliceHeader,
rcRecPicBufUnit.getRecFrame (),
rcRecPicBufUnit.getMbDataCtrl(),
cList0,
cList1,
m_uiFrameWidthInMb,
dLambda ) );
//----- close NAL unit -----
RNOK( m_pcNalUnitEncoder->closeNalUnit( uiBitsSlice ) );
RNOK( xAppendNewExtBinDataAccessor( rcExtBinDataAccessorList, &m_cExtBinDataAccessor ) );
uiBitsSlice += 4*8;
uiBits += uiBitsSlice;
}
//===== finish =====
RNOK( xFinishPicture( rcRecPicBufUnit, rcSliceHeader, cList0, cList1, uiBits ) );
ruiBits += uiBits;
return Err::m_nOK;
}
ErrVal
PicEncoder::xStartPicture( RecPicBufUnit& rcRecPicBufUnit,
SliceHeader& rcSliceHeader,
RefFrameList& rcList0,
RefFrameList& rcList1 )
{
//===== initialize reference picture lists and update slice header =====
RNOK( m_pcRecPicBuffer->getRefLists( rcList0, rcList1, rcSliceHeader ) );
//===== init half-pel buffers =====
UInt uiPos;
for( uiPos = 0; uiPos < rcList0.getActive(); uiPos++ )
{
Frame* pcRefFrame = rcList0.getEntry( uiPos );
if( ! pcRefFrame->isHalfPel() )
{
RNOK( pcRefFrame->initHalfPel() );
RNOK( pcRefFrame->extendFrame( m_pcQuarterPelFilter ) );
}
else
if( ! pcRefFrame->isExtended() )
{
RNOK( pcRefFrame->extendFrame( m_pcQuarterPelFilter ) );
}
}
for( uiPos = 0; uiPos < rcList1.getActive(); uiPos++ )
{
Frame* pcRefFrame = rcList1.getEntry( uiPos );
if( ! pcRefFrame->isHalfPel() )
{
RNOK( pcRefFrame->initHalfPel() );
}
if( ! pcRefFrame->isExtended() )
{
RNOK( pcRefFrame->extendFrame( m_pcQuarterPelFilter ) );
}
}
//===== reset macroblock data =====
RNOK( rcRecPicBufUnit.getMbDataCtrl()->reset() );
RNOK( rcRecPicBufUnit.getMbDataCtrl()->clear() );
return Err::m_nOK;
}
ErrVal
PicEncoder::xFinishPicture( RecPicBufUnit& rcRecPicBufUnit,
SliceHeader& rcSliceHeader,
RefFrameList& rcList0,
RefFrameList& rcList1,
UInt uiBits )
{
//===== uninit half-pel data =====
UInt uiPos;
for( uiPos = 0; uiPos < rcList0.getActive(); uiPos++ )
{
Frame* pcRefFrame = rcList0.getEntry( uiPos );
if( pcRefFrame->isExtended() )
{
pcRefFrame->clearExtended();
}
if( pcRefFrame->isHalfPel() )
{
pcRefFrame->uninitHalfPel();
}
}
for( uiPos = 0; uiPos < rcList1.getActive(); uiPos++ )
{
Frame* pcRefFrame = rcList1.getEntry( uiPos );
if( pcRefFrame->isExtended() )
{
pcRefFrame->clearExtended();
}
if( pcRefFrame->isHalfPel() )
{
pcRefFrame->uninitHalfPel();
}
}
//===== deblocking =====
RNOK( m_pcLoopFilter->process( rcSliceHeader, rcRecPicBufUnit.getRecFrame(), NULL, rcRecPicBufUnit.getMbDataCtrl(), 0, false ) );
//===== get PSNR =====
Double dPSNR[3];
RNOK( xGetPSNR( rcRecPicBufUnit, dPSNR ) );
//===== output =====
printf( "%4d %c %s %4d QP%3d Y %7.4lf dB U %7.4lf dB V %7.4lf dB bits%8d\n",
m_uiCodedFrames,
rcSliceHeader.getSliceType ()==I_SLICE ? 'I' :
rcSliceHeader.getSliceType ()==P_SLICE ? 'P' : 'B',
rcSliceHeader.getNalUnitType()==NAL_UNIT_CODED_SLICE_IDR ? "IDR" :
rcSliceHeader.getNalRefIdc ()==NAL_REF_IDC_PRIORITY_LOWEST ? " " : "REF",
rcSliceHeader.getPoc(),
rcSliceHeader.getSliceQp(),
dPSNR[0],
dPSNR[1],
dPSNR[2],
uiBits
);
//===== update parameters =====
m_uiCodedFrames++;
ETRACE_NEWFRAME;
return Err::m_nOK;
}
ErrVal
PicEncoder::xGetPSNR( RecPicBufUnit& rcRecPicBufUnit,
Double* adPSNR )
{
//===== reset buffer control =====
RNOK( m_pcYuvBufferCtrlFullPel->initMb() );
//===== set parameters =====
const YuvBufferCtrl::YuvBufferParameter& cBufferParam = m_pcYuvBufferCtrlFullPel->getBufferParameter();
Frame* pcFrame = rcRecPicBufUnit.getRecFrame ();
PicBuffer* pcPicBuffer = rcRecPicBufUnit.getPicBuffer ();
//===== calculate PSNR =====
Pel* pPelOrig = pcPicBuffer->getBuffer() + cBufferParam.getMbLum();
XPel* pPelRec = pcFrame->getFullPelYuvBuffer()->getMbLumAddr();
Int iStride = cBufferParam.getStride();
Int iWidth = cBufferParam.getWidth ();
Int iHeight = cBufferParam.getHeight();
UInt uiSSDY = 0;
UInt uiSSDU = 0;
UInt uiSSDV = 0;
Int x, y;
for( y = 0; y < iHeight; y++ )
{
for( x = 0; x < iWidth; x++ )
{
Int iDiff = (Int)pPelOrig[x] - (Int)pPelRec[x];
uiSSDY += iDiff * iDiff;
}
pPelOrig += iStride;
pPelRec += iStride;
}
iHeight >>= 1;
iWidth >>= 1;
iStride >>= 1;
pPelOrig = pcPicBuffer->getBuffer() + cBufferParam.getMbCb();
pPelRec = pcFrame->getFullPelYuvBuffer()->getMbCbAddr();
for( y = 0; y < iHeight; y++ )
{
for( x = 0; x < iWidth; x++ )
{
Int iDiff = (Int)pPelOrig[x] - (Int)pPelRec[x];
uiSSDU += iDiff * iDiff;
}
pPelOrig += iStride;
pPelRec += iStride;
}
pPelOrig = pcPicBuffer->getBuffer() + cBufferParam.getMbCr();
pPelRec = pcFrame->getFullPelYuvBuffer()->getMbCrAddr();
for( y = 0; y < iHeight; y++ )
{
for( x = 0; x < iWidth; x++ )
{
Int iDiff = (Int)pPelOrig[x] - (Int)pPelRec[x];
uiSSDV += iDiff * iDiff;
}
pPelOrig += iStride;
pPelRec += iStride;
}
Double fRefValueY = 255.0 * 255.0 * 16.0 * 16.0 * (Double)m_uiMbNumber;
Double fRefValueC = fRefValueY / 4.0;
adPSNR[0] = ( uiSSDY ? 10.0 * log10( fRefValueY / (Double)uiSSDY ) : 99.99 );
adPSNR[1] = ( uiSSDU ? 10.0 * log10( fRefValueC / (Double)uiSSDU ) : 99.99 );
adPSNR[2] = ( uiSSDV ? 10.0 * log10( fRefValueC / (Double)uiSSDV ) : 99.99 );
m_dSumYPSNR += adPSNR[0];
m_dSumUPSNR += adPSNR[1];
m_dSumVPSNR += adPSNR[2];
return Err::m_nOK;
}
H264AVC_NAMESPACE_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -