HM16.0 TAppEncoder
参考: https://www.cnblogs.com/tiansha/p/6458573.html
https://blog.csdn.net/liangjiubujiu/article/details/81128013
一、编码流程
1、encmain.cpp:
{
cTAppEncTop.encode(); // call encoding function
...
}
2、TAppEncTop.cpp:
/**
- create internal class
- initialize internal variable
- until the end of input YUV file, call encoding function in TEncTop class
- delete allocated buffers
- destroy internal class
.
*/
// 对编码器所使用的几个对象进行初始化,分配YUV数据缓存,循环读取YUV文件
Void TAppEncTop::encode()
{
...
// call encoding function for one frame
if ( m_isField )
m_cTEncTop.encode( bEos, flush ? 0 : pcPicYuvOrg, flush ? 0 : &cPicYuvTrueOrg, snrCSC, m_cListPicYuvRec,
outputAccessUnits, iNumEncoded, m_isTopFieldFirst );
else
m_cTEncTop.encode( bEos, flush ? 0 : pcPicYuvOrg, flush ? 0 : &cPicYuvTrueOrg, snrCSC, m_cListPicYuvRec,
outputAccessUnits, iNumEncoded );
...
}
3、TEncTop.cpp:
// 调用m_cGOPEncoder.compressGOP()实现对GOP的实际编码
Void TEncTop::encode(Bool flush, TComPicYuv* pcPicYuvOrg, TComPicYuv* pcPicYuvTrueOrg, const InputColourSpaceConversion snrCSC,
TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsOut, Int& iNumEncoded, Bool isTff)
{
...
// compress GOP
m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut, true,
isTff, snrCSC, m_printFrameMSE);
...
}
4、TEncGOP.cpp:
// 设置GOP的参数;利用SPS和PPS中的信息创建编码的slice对象,对每一个slice进行编码
Void TEncGOP::compressGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic,
TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP,
Bool isField, Bool isTff, const InputColourSpaceConversion snr_conversion, const Bool printFrameMSE )
{
...
m_pcSliceEncoder->compressSlice ( pcPic ); //对每一个slice,找出编码的最优参数
...
m_pcSliceEncoder->encodeSlice(pcPic, pcSubstreamsOut); //对每一个slice,对其进行实际的熵编码工作
...
}
5、TEncSlice.cpp:
/** \param rpcPic picture class
*/
// 设置编码slice的参数,对slice中的每一个CU进行处理
Void TEncSlice::compressSlice( TComPic*& rpcPic )
{
...
// run CU encoder
m_pcCuEncoder->compressCU( pcCU ); //对每一个CU,找出编码的最优参数
...
m_pcCuEncoder->encodeCU( pcCU ); //对每一个CU,对其进行实际的熵编码工作
...
}
6、TEncCu.cpp:
/** \param rpcCU pointer of CU data class //指向CU的参数
*/
Void TEncCu::compressCU( TComDataCU*& rpcCU ) //找到编码一个CU的最优参数
{
m_ppcBestCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() ); //用来存储最好的QP和在每一个深度的预测模式决策。
DEBUG_STRING_OUTPUT(std::cout, sDebug)
if( m_pcEncCfg->getUseAdaptQpSelect() )
{
if(rpcCU->getSlice()->getSliceType()!=I_SLICE)
{
xLcuCollectARLStats( rpcCU);
}
}
#endif
}
/** Compress a CU block recursively with enabling sub-LCU-level delta QP
*\param rpcBestCU
*\param rpcTempCU
*\param uiDepth
*\returns Void
*
*- for loop of QP value to compress the current CU with all possible QP
*/
Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, UInt uiDepth DEBUG_STRING_FN_DECLARE(sDebug_), PartSize eParentPartSize )
{
...
{
// 尝试每一个可能的QP对应的每一种预测模式,得到QP和预测模式;实现对本层LCU的模式选择RDCost计算;
// 执行顺序:帧间模式(Inter、SKIP、AMP)----- 帧内模式(Intra)----- PCM模式;
// PCM以一种无损的方式进行编码,没有预测和残差,失真为0;如果最优模式产生的比特数大于PCM模式,则选择PCM模式;
// xCheckRDCostInter():帧间模式;xCheckRDCostMerge2Nx2N():帧间Merge模式;
// xCheckRDCostIntra():帧内模式;xCheckIntraPCM():PCM模式.
// 代码框架:
for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
{
// try all kinds of prediction modes for every possible QP
...
}
...
}
...
// 实现下层分割的计算,最后通过xCheckBestMode来比较是否选用分割
for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
{
const Bool bIsLosslessMode = false; // False at this level. Next level down may set it to true.
rpcTempCU->initEstData( uiDepth, iQP, bIsLosslessMode );
// further split
if( bSubBranch && uiDepth < g_uiMaxCUDepth - g_uiAddCUDepth )
{
...
xCheckBestMode( rpcBestCU, rpcTempCU, uiDepth DEBUG_STRING_PASS_INTO(sDebug) DEBUG_STRING_PASS_INTO(sTempDebug) DEBUG_STRING_PASS_INTO(false) ); // RD compare current larger prediction
}
}
...
}
二、预测模式选择
1、帧间模式:
TypeDef.h:
/// supported partition shape
/// AMP (SIZE_2NxnU, SIZE_2NxnD, SIZE_nLx2N, SIZE_nRx2N)
enum PartSize
{
SIZE_2Nx2N = , ///< symmetric motion partition, 2Nx2N
SIZE_2NxN = 1, ///< symmetric motion partition, 2Nx N
SIZE_Nx2N = 2, ///< symmetric motion partition, Nx2N
SIZE_NxN = 3, ///< symmetric motion partition, Nx N
SIZE_2NxnU = 4, ///< asymmetric motion partition, 2Nx( N/2) + 2Nx(3N/2)
SIZE_2NxnD = 5, ///< asymmetric motion partition, 2Nx(3N/2) + 2Nx( N/2)
SIZE_nLx2N = 6, ///< asymmetric motion partition, ( N/2)x2N + (3N/2)x2N
SIZE_nRx2N = 7, ///< asymmetric motion partition, (3N/2)x2N + ( N/2)x2N
NUMBER_OF_PART_SIZES = 8
};
#if AMP_MRG
Void TEncCu::xCheckRDCostInter( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize DEBUG_STRING_FN_DECLARE(sDebug), Bool bUseMRG)
#else
Void TEncCu::xCheckRDCostInter( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize )
#endif
{
DEBUG_STRING_NEW(sTest) UChar uhDepth = rpcTempCU->getDepth( ); rpcTempCU->setDepthSubParts( uhDepth, ); rpcTempCU->setSkipFlagSubParts( false, , uhDepth ); rpcTempCU->setPartSizeSubParts ( ePartSize, , uhDepth );
rpcTempCU->setPredModeSubParts ( MODE_INTER, , uhDepth );
rpcTempCU->setChromaQpAdjSubParts( rpcTempCU->getCUTransquantBypass() ? : m_ChromaQpAdjIdc, , uhDepth ); #if AMP_MRG
rpcTempCU->setMergeAMP (true);
m_pcPredSearch->predInterSearch ( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth] DEBUG_STRING_PASS_INTO(sTest), false, bUseMRG );
#else
m_pcPredSearch->predInterSearch ( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth] );
#endif #if AMP_MRG
if ( !rpcTempCU->getMergeAMP() )
{
return;
}
#endif m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcResiYuvBest[uhDepth], m_ppcRecoYuvTemp[uhDepth], false DEBUG_STRING_PASS_INTO(sTest) );
rpcTempCU->getTotalCost() = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() ); #ifdef DEBUG_STRING
DebugInterPredResiReco(sTest, *(m_ppcPredYuvTemp[uhDepth]), *(m_ppcResiYuvBest[uhDepth]), *(m_ppcRecoYuvTemp[uhDepth]), DebugStringGetPredModeMask(rpcTempCU->getPredictionMode()));
#endif xCheckDQP( rpcTempCU );
xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth DEBUG_STRING_PASS_INTO(sDebug) DEBUG_STRING_PASS_INTO(sTest));
}
2、帧间Merge模式:
/** check RD costs for a CU block encoded with merge
* \param rpcBestCU
* \param rpcTempCU
* \returns Void
*/
Void TEncCu::xCheckRDCostMerge2Nx2N( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU DEBUG_STRING_FN_DECLARE(sDebug), Bool *earlyDetectionSkipMode )
{
assert( rpcTempCU->getSlice()->getSliceType() != I_SLICE );
TComMvField cMvFieldNeighbours[ * MRG_MAX_NUM_CANDS]; // double length for mv of both lists
UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
Int numValidMergeCand = ;
const Bool bTransquantBypassFlag = rpcTempCU->getCUTransquantBypass(); for( UInt ui = ; ui < rpcTempCU->getSlice()->getMaxNumMergeCand(); ++ui )
{
uhInterDirNeighbours[ui] = ;
}
UChar uhDepth = rpcTempCU->getDepth( );
rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, , uhDepth ); // interprets depth relative to LCU level
rpcTempCU->getInterMergeCandidates( , , cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand ); Int mergeCandBuffer[MRG_MAX_NUM_CANDS];
for( UInt ui = ; ui < numValidMergeCand; ++ui )
{
mergeCandBuffer[ui] = ;
} Bool bestIsSkip = false; UInt iteration;
if ( rpcTempCU->isLosslessCoded())
{
iteration = ;
}
else
{
iteration = ;
}
DEBUG_STRING_NEW(bestStr) for( UInt uiNoResidual = ; uiNoResidual < iteration; ++uiNoResidual )
{
for( UInt uiMergeCand = ; uiMergeCand < numValidMergeCand; ++uiMergeCand )
{
if(!(uiNoResidual== && mergeCandBuffer[uiMergeCand]==))
{
if( !(bestIsSkip && uiNoResidual == ) )
{
DEBUG_STRING_NEW(tmpStr)
// set MC parameters
rpcTempCU->setPredModeSubParts( MODE_INTER, , uhDepth ); // interprets depth relative to LCU level
rpcTempCU->setCUTransquantBypassSubParts( bTransquantBypassFlag, , uhDepth );
rpcTempCU->setChromaQpAdjSubParts( bTransquantBypassFlag ? : m_ChromaQpAdjIdc, , uhDepth );
rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, , uhDepth ); // interprets depth relative to LCU level
rpcTempCU->setMergeFlagSubParts( true, , , uhDepth ); // interprets depth relative to LCU level
rpcTempCU->setMergeIndexSubParts( uiMergeCand, , , uhDepth ); // interprets depth relative to LCU level
rpcTempCU->setInterDirSubParts( uhInterDirNeighbours[uiMergeCand], , , uhDepth ); // interprets depth relative to LCU level
rpcTempCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMvFieldNeighbours[ + *uiMergeCand], SIZE_2Nx2N, , ); // interprets depth relative to rpcTempCU level
rpcTempCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMvFieldNeighbours[ + *uiMergeCand], SIZE_2Nx2N, , ); // interprets depth relative to rpcTempCU level // do MC
m_pcPredSearch->motionCompensation ( rpcTempCU, m_ppcPredYuvTemp[uhDepth] );
// estimate residual and encode everything
m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU,
m_ppcOrigYuv [uhDepth],
m_ppcPredYuvTemp[uhDepth],
m_ppcResiYuvTemp[uhDepth],
m_ppcResiYuvBest[uhDepth],
m_ppcRecoYuvTemp[uhDepth],
(uiNoResidual != ) DEBUG_STRING_PASS_INTO(tmpStr) ); #ifdef DEBUG_STRING
DebugInterPredResiReco(tmpStr, *(m_ppcPredYuvTemp[uhDepth]), *(m_ppcResiYuvBest[uhDepth]), *(m_ppcRecoYuvTemp[uhDepth]), DebugStringGetPredModeMask(rpcTempCU->getPredictionMode()));
#endif if ((uiNoResidual == ) && (rpcTempCU->getQtRootCbf() == ))
{
// If no residual when allowing for one, then set mark to not try case where residual is forced to 0
mergeCandBuffer[uiMergeCand] = ;
} rpcTempCU->setSkipFlagSubParts( rpcTempCU->getQtRootCbf() == , , uhDepth );
Int orgQP = rpcTempCU->getQP( );
xCheckDQP( rpcTempCU );
xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth DEBUG_STRING_PASS_INTO(bestStr) DEBUG_STRING_PASS_INTO(tmpStr)); rpcTempCU->initEstData( uhDepth, orgQP, bTransquantBypassFlag ); if( m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip )
{
bestIsSkip = rpcBestCU->getQtRootCbf() == ;
}
}
}
} if(uiNoResidual == && m_pcEncCfg->getUseEarlySkipDetection())
{
if(rpcBestCU->getQtRootCbf( ) == )
{
if( rpcBestCU->getMergeFlag( ))
{
*earlyDetectionSkipMode = true;
}
else if(m_pcEncCfg->getFastSearch() != SELECTIVE)
{
Int absoulte_MV=;
for ( UInt uiRefListIdx = ; uiRefListIdx < ; uiRefListIdx++ )
{
if ( rpcBestCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > )
{
TComCUMvField* pcCUMvField = rpcBestCU->getCUMvField(RefPicList( uiRefListIdx ));
Int iHor = pcCUMvField->getMvd( ).getAbsHor();
Int iVer = pcCUMvField->getMvd( ).getAbsVer();
absoulte_MV+=iHor+iVer;
}
} if(absoulte_MV == )
{
*earlyDetectionSkipMode = true;
}
}
}
}
}
DEBUG_STRING_APPEND(sDebug, bestStr)
}
3、帧内模式:
Void TEncCu::xCheckRDCostIntra( TComDataCU *&rpcBestCU,
TComDataCU *&rpcTempCU,
Double &cost,
PartSize eSize
DEBUG_STRING_FN_DECLARE(sDebug) )
{
DEBUG_STRING_NEW(sTest) UInt uiDepth = rpcTempCU->getDepth( ); rpcTempCU->setSkipFlagSubParts( false, , uiDepth ); rpcTempCU->setPartSizeSubParts( eSize, , uiDepth );
rpcTempCU->setPredModeSubParts( MODE_INTRA, , uiDepth );
rpcTempCU->setChromaQpAdjSubParts( rpcTempCU->getCUTransquantBypass() ? : m_ChromaQpAdjIdc, , uiDepth ); Bool bSeparateLumaChroma = true; // choose estimation mode Distortion uiPreCalcDistC = ;
if (rpcBestCU->getPic()->getChromaFormat()==CHROMA_400)
{
bSeparateLumaChroma=true;
} Pel resiLuma[NUMBER_OF_STORED_RESIDUAL_TYPES][MAX_CU_SIZE * MAX_CU_SIZE]; if( !bSeparateLumaChroma )
{
// after this function, the direction will be PLANAR, DC, HOR or VER
// however, if Luma ends up being one of those, the chroma dir must be later changed to DM_CHROMA.
m_pcPredSearch->preestChromaPredMode( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth] );
}
m_pcPredSearch->estIntraPredQT( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth], m_ppcResiYuvTemp[uiDepth], m_ppcRecoYuvTemp[uiDepth], resiLuma, uiPreCalcDistC, bSeparateLumaChroma DEBUG_STRING_PASS_INTO(sTest) ); m_ppcRecoYuvTemp[uiDepth]->copyToPicComponent(COMPONENT_Y, rpcTempCU->getPic()->getPicYuvRec(), rpcTempCU->getAddr(), rpcTempCU->getZorderIdxInCU() ); if (rpcBestCU->getPic()->getChromaFormat()!=CHROMA_400)
{
m_pcPredSearch->estIntraPredChromaQT( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth], m_ppcResiYuvTemp[uiDepth], m_ppcRecoYuvTemp[uiDepth], resiLuma, uiPreCalcDistC DEBUG_STRING_PASS_INTO(sTest) );
} m_pcEntropyCoder->resetBits(); if ( rpcTempCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
{
m_pcEntropyCoder->encodeCUTransquantBypassFlag( rpcTempCU, , true );
} m_pcEntropyCoder->encodeSkipFlag ( rpcTempCU, , true );
m_pcEntropyCoder->encodePredMode( rpcTempCU, , true );
m_pcEntropyCoder->encodePartSize( rpcTempCU, , uiDepth, true );
m_pcEntropyCoder->encodePredInfo( rpcTempCU, );
m_pcEntropyCoder->encodeIPCMInfo(rpcTempCU, , true ); // Encode Coefficients
Bool bCodeDQP = getdQPFlag();
Bool codeChromaQpAdjFlag = getCodeChromaQpAdjFlag();
m_pcEntropyCoder->encodeCoeff( rpcTempCU, , uiDepth, bCodeDQP, codeChromaQpAdjFlag );
setCodeChromaQpAdjFlag( codeChromaQpAdjFlag );
setdQPFlag( bCodeDQP ); m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]); rpcTempCU->getTotalBits() = m_pcEntropyCoder->getNumberOfWrittenBits();
rpcTempCU->getTotalBins() = ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
rpcTempCU->getTotalCost() = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() ); xCheckDQP( rpcTempCU ); cost = rpcTempCU->getTotalCost(); xCheckBestMode(rpcBestCU, rpcTempCU, uiDepth DEBUG_STRING_PASS_INTO(sDebug) DEBUG_STRING_PASS_INTO(sTest));
}
4、PCM模式:
/** Check R-D costs for a CU with PCM mode.
* \param rpcBestCU pointer to best mode CU data structure
* \param rpcTempCU pointer to testing mode CU data structure
* \returns Void
*
* \note Current PCM implementation encodes sample values in a lossless way. The distortion of PCM mode CUs are zero. PCM mode is selected if the best mode yields bits greater than that of PCM mode.
*/
Void TEncCu::xCheckIntraPCM( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU )
{
UInt uiDepth = rpcTempCU->getDepth( ); rpcTempCU->setSkipFlagSubParts( false, , uiDepth ); rpcTempCU->setIPCMFlag(, true);
rpcTempCU->setIPCMFlagSubParts (true, , rpcTempCU->getDepth());
rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, , uiDepth );
rpcTempCU->setPredModeSubParts( MODE_INTRA, , uiDepth );
rpcTempCU->setTrIdxSubParts ( , , uiDepth );
rpcTempCU->setChromaQpAdjSubParts( rpcTempCU->getCUTransquantBypass() ? : m_ChromaQpAdjIdc, , uiDepth ); m_pcPredSearch->IPCMSearch( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth], m_ppcResiYuvTemp[uiDepth], m_ppcRecoYuvTemp[uiDepth]); m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]); m_pcEntropyCoder->resetBits(); if ( rpcTempCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
{
m_pcEntropyCoder->encodeCUTransquantBypassFlag( rpcTempCU, , true );
} m_pcEntropyCoder->encodeSkipFlag ( rpcTempCU, , true );
m_pcEntropyCoder->encodePredMode ( rpcTempCU, , true );
m_pcEntropyCoder->encodePartSize ( rpcTempCU, , uiDepth, true );
m_pcEntropyCoder->encodeIPCMInfo ( rpcTempCU, , true ); m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]); rpcTempCU->getTotalBits() = m_pcEntropyCoder->getNumberOfWrittenBits();
rpcTempCU->getTotalBins() = ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
rpcTempCU->getTotalCost() = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() ); xCheckDQP( rpcTempCU );
DEBUG_STRING_NEW(a)
DEBUG_STRING_NEW(b)
xCheckBestMode(rpcBestCU, rpcTempCU, uiDepth DEBUG_STRING_PASS_INTO(a) DEBUG_STRING_PASS_INTO(b));
}
HM16.0 TAppEncoder的更多相关文章
- 使用HM16.0对视频编码
1.编译HM16.0源码: 步骤参照:https://www.vcodex.com/hevc-and-vp9-codecs-try-them-yourself/(可设置pq等参数) [编译过程中遇到l ...
- HM16.0之帧间Merge模式——xCheckRDCostMerge2Nx2N
参考:https://blog.csdn.net/nb_vol_1/article/details/51163625 1.源代码: /** check RD costs for a CU block ...
- HM16.0之帧间预测——xCheckRDCostInter()函数
参考:https://blog.csdn.net/nb_vol_1/article/category/6179825/1? 1.源代码: #if AMP_MRG Void TEncCu::xCheck ...
- HM16.0之帧内模式——xCheckRDCostIntra()函数
参考:https://blog.csdn.net/nb_vol_1/article/category/6179825/1? 1.源代码: Void TEncCu::xCheckRDCostIntra( ...
- HM16.0帧内预测重要函数笔记
Void TEncSearch::estIntraPredQT 亮度块的帧内预测入口函数 Void TComPrediction::initAdiPatternChType 获取参考样本点并滤波 ...
- HM16.0之PCM模式——xCheckIntraPCM
参考:https://blog.csdn.net/cxy19931018/article/details/79781042 1.源代码: /** Check R-D costs for a CU wi ...
- HEVC之路0:HM16.18的运行+码流分析
1.HM下载 HM不能直接网页下载,因为它是采用svn来管理代码的,因此需要利用svn下载,这里采用TortoiseSVN(软件下载地址为https://tortoisesvn.net/)进行下载. ...
- ZAM 3D 制作简单的3D字幕 流程(二)
原地址:http://www.cnblogs.com/yk250/p/5663907.html 文中表述仅为本人理解,若有偏差和错误请指正! 接着 ZAM 3D 制作简单的3D字幕 流程(一) .本篇 ...
- ZAM 3D 制作3D动画字幕 用于Xaml导出
原地址-> http://www.cnblogs.com/yk250/p/5662788.html 介绍:对经常使用Blend做动画的人来说,ZAM 3D 也很好上手,专业制作3D素材的XAML ...
随机推荐
- 手牵手,从零学习Vue源码 系列二(变化侦测篇)
系列文章: 手牵手,从零学习Vue源码 系列一(前言-目录篇) 手牵手,从零学习Vue源码 系列二(变化侦测篇) 陆续更新中... 预计八月中旬更新完毕. 1 概述 Vue最大的特点之一就是数据驱动视 ...
- Python打印到屏幕_读取键盘输入
Python打印到屏幕_读取键盘输入: print( ): 打印输出括号中的值 print("hello") # hello strs = 'hello' print(" ...
- 11-19 hashlib模块
Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 什么是摘要算法呢? 摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进 ...
- PHP xml_set_notation_decl_handler() 函数
定义和用法 xml_set_notation_decl_handler() 函数规定当解析器在 XML 文档中找到符号声明时被调用的函数. 如果成功,该函数则返回 TRUE.如果失败,则返回 FALS ...
- 5.19 省选模拟赛 T1 小B的棋盘 双指针 性质
LINK:小B的棋盘 考试的时候没有认真的思考 导致没做出来. 容易发现 当k>=n的时候存在无限解 其余都存在有限解 对于30分 容易想到暴力枚举 对称中心 然后 n^2判断. 对于前者 容易 ...
- 获取随机字符串(0~9,A~Z)
/// <summary> /// 生成随机数 /// </summary> /// <param name="cod ...
- 解决 IntelliJ IDEA占用C盘过大空间问题
原文地址:https://blog.csdn.net/weixin_44449518/article/details/103334235 问题描述: 在保证其他软件缓存不影响C盘可用空间的基础上,当我 ...
- Python预测2020高考分数和录取情况
“迟到”了一个月的高考终于要来了. 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识. ...
- List集合遍历时修改元素出现并发修改异常总结
什么是并发修改异常: 当我们在遍历实现了collection接口与iterator接口的集合时(List.Set.Map), 我们可以通过遍历索引也可以通过迭代器进行遍历.在我们使用迭代器进行遍历集合 ...
- WC2020 Cu 记
由于今年的 WC 既不 W 也不 C,所以其实应该叫吸吸F线上推广 3M 原则记 Day1 上午听了一会儿课跑去写题了,写着写着就摸了起来. 下午也摸了 晚上员交发现有好多听过的和好多好多没听过的 怎 ...