多线程处理:https://blog.csdn.net/strikedragon/article/details/82776001
bool allowPools = !p->numaPools || strcmp(p->numaPools, "none");
// Trim the thread pool if --wpp, --pme, and --pmode are disabled
if (!p->bEnableWavefront && !p->bDistributeModeAnalysis && !p->bDistributeMotionEstimation && !p->lookaheadSlices)
allowPools = false;
bDistributeModeAnalysis :评估使用多线程CU mode的花费
bDistributeMotionEstimation:使用多线程Motion estimation的花费
lookaheadSlices:使用多线程计算每一帧的花费
m_numPools = 0;
if (allowPools)
m_threadPool = ThreadPool::allocThreadPools(p, m_numPools, 0);
else
{
if (!p->frameNumThreads)
{
// auto-detect frame threads
int cpuCount = ThreadPool::getCpuCount();
ThreadPool::getFrameThreadsCount(p, cpuCount);
}
}
并发编码帧的数量
if (!m_numPools)
{
// issue warnings if any of these features were requested
if (p->bEnableWavefront)
x265_log(p, X265_LOG_WARNING, "No thread pool allocated, --wpp disabled\n");
if (p->bDistributeMotionEstimation)
x265_log(p, X265_LOG_WARNING, "No thread pool allocated, --pme disabled\n");
if (p->bDistributeModeAnalysis)
x265_log(p, X265_LOG_WARNING, "No thread pool allocated, --pmode disabled\n");
if (p->lookaheadSlices)
x265_log(p, X265_LOG_WARNING, "No thread pool allocated, --lookahead-slices disabled\n");
// disable all pool features if the thread pool is disabled or unusable.
p->bEnableWavefront = p->bDistributeModeAnalysis = p->bDistributeMotionEstimation = p->lookaheadSlices = 0;
}
对于每一个frame的线程,创建frameEncoder
for (int i = 0; i < m_param->frameNumThreads; i++)
{
m_frameEncoder[i] = new FrameEncoder;
m_frameEncoder[i]->m_nalList.m_annexB = !!m_param->bAnnexB;
}
if (m_numPools)
{
for (int i = 0; i < m_param->frameNumThreads; i++)
{
int pool = i % m_numPools;
m_frameEncoder[i]->m_pool = &m_threadPool[pool];
m_frameEncoder[i]->m_jpId = m_threadPool[pool].m_numProviders++;
m_threadPool[pool].m_jpTable[m_frameEncoder[i]->m_jpId] = m_frameEncoder[i];
把每个frameEncoder分配到对应的pool中,JobProvider是Frame level job providers. FrameEncoder and Lookahead derive from this class and implement findJob()
}
for (int i = 0; i < m_numPools; i++)
m_threadPool[i].start();
}
else
{
/* CU stats and noise-reduction buffers are indexed by jpId, so it cannot be left as -1 */
for (int i = 0; i < m_param->frameNumThreads; i++)
m_frameEncoder[i]->m_jpId = 0;
}
创建或者解析ScalingList
if (!m_scalingList.init())
{
x265_log(m_param, X265_LOG_ERROR, "Unable to allocate scaling list arrays\n");
m_aborted = true;
return;
}
else if (!m_param->scalingLists || !strcmp(m_param->scalingLists, "off"))
m_scalingList.m_bEnabled = false;
else if (!strcmp(m_param->scalingLists, "default"))
m_scalingList.setDefaultScalingList();
else if (m_scalingList.parseScalingList(m_param->scalingLists))
m_aborted = true;
根据Pool来计算lookahead的线程,Lookahead
int pools = m_numPools;
ThreadPool* lookAheadThreadPool = 0;
if (m_param->lookaheadThreads > 0)
{
lookAheadThreadPool = ThreadPool::allocThreadPools(p, pools, 1);
}
else
lookAheadThreadPool = m_threadPool;
m_lookahead = new Lookahead(m_param, lookAheadThreadPool);
if (pools)
{
m_lookahead->m_jpId = lookAheadThreadPool[0].m_numProviders++;
lookAheadThreadPool[0].m_jpTable[m_lookahead->m_jpId] = m_lookahead;
}
if (m_param->lookaheadThreads > 0)
for (int i = 0; i < pools; i++)
lookAheadThreadPool[i].start();
创建DPB和RateControl类
m_dpb = new DPB(m_param);
m_rateControl = new RateControl(*m_param);
初始化VPS,SPS和PPS
initVPS(&m_vps);
initSPS(&m_sps);
initPPS(&m_pps);