[x265] [PATCH] Make FrameEncoder partially virtual so it can be overloaded
Nicolas Morey-Chaisemartin
nmorey at kalray.eu
Wed Feb 4 09:35:51 CET 2015
# HG changeset patch
# User Nicolas Morey-Chaisemartin <nmorey at kalray.eu>
# Date 1414489826 -3600
# Tue Oct 28 10:50:26 2014 +0100
Make FrameEncoder partially virtual so it can be overloaded
FrameEncoder is a logical place to use a hardware accelerator or an alternative core encoder.
By making a few function virtual, it can be easily replaced by an inheriting class, transparently for the Encoder.
This way all the RC/interaction code can stay within the FrameEncoder class and reduce conflicts in later updates.
---
source/encoder/encoder.cpp | 32 ++++++++++++++++++--------------
source/encoder/encoder.h | 2 +-
source/encoder/frameencoder.h | 8 ++++----
3 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
index d1ade9f..58915b7 100644
--- a/source/encoder/encoder.cpp
+++ b/source/encoder/encoder.cpp
@@ -67,7 +67,6 @@ Encoder::Encoder()
m_numLumaWPBiFrames = 0;
m_numChromaWPBiFrames = 0;
m_lookahead = NULL;
- m_frameEncoder = NULL;
m_rateControl = NULL;
m_dpb = NULL;
m_exportedPic = NULL;
@@ -82,6 +81,10 @@ Encoder::Encoder()
m_threadPool = NULL;
m_numThreadLocalData = 0;
m_analysisFile = NULL;
+ for (int i = 0; i < X265_MAX_FRAME_THREADS; i++)
+ {
+ m_frameEncoder[i] = NULL;
+ }
}
void Encoder::create()
@@ -152,9 +155,11 @@ void Encoder::create()
p->bEnableWavefront ? rows : 0, p->frameNumThreads, poolThreadCount,
p->bDistributeMotionEstimation ? " / pme" : "", p->bDistributeModeAnalysis ? " / pmode" : "");
- m_frameEncoder = new FrameEncoder[m_param->frameNumThreads];
for (int i = 0; i < m_param->frameNumThreads; i++)
- m_frameEncoder[i].setThreadPool(m_threadPool);
+ {
+ m_frameEncoder[i] = new FrameEncoder;
+ m_frameEncoder[i]->setThreadPool(m_threadPool);
+ }
if (!m_scalingList.init())
{
@@ -184,7 +189,7 @@ void Encoder::create()
if (!m_param->bEnableWavefront)
for (int i = 0; i < m_param->frameNumThreads; i++)
- m_frameEncoder[i].m_tld = &m_threadLocalData[poolThreadCount + i];
+ m_frameEncoder[i]->m_tld = &m_threadLocalData[poolThreadCount + i];
m_lookahead = new Lookahead(m_param, m_threadPool);
m_dpb = new DPB(m_param);
@@ -236,7 +241,7 @@ void Encoder::create()
int numCols = (m_param->sourceWidth + g_maxCUSize - 1) / g_maxCUSize;
for (int i = 0; i < m_param->frameNumThreads; i++)
{
- if (!m_frameEncoder[i].init(this, numRows, numCols, i))
+ if (!m_frameEncoder[i]->init(this, numRows, numCols, i))
{
x265_log(m_param, X265_LOG_ERROR, "Unable to initialize frame encoder, aborting\n");
m_aborted = true;
@@ -283,16 +288,15 @@ void Encoder::destroy()
if (m_rateControl)
m_rateControl->terminate(); // unblock all blocked RC calls
- if (m_frameEncoder)
+ for (int i = 0; i < m_param->frameNumThreads; i++)
{
- for (int i = 0; i < m_param->frameNumThreads; i++)
+ if (m_frameEncoder[i])
{
// Ensure frame encoder is idle before destroying it
- m_frameEncoder[i].getEncodedPicture(m_nalList);
- m_frameEncoder[i].destroy();
+ m_frameEncoder[i]->getEncodedPicture(m_nalList);
+ m_frameEncoder[i]->destroy();
+ delete m_frameEncoder[i];
}
-
- delete [] m_frameEncoder;
}
for (int i = 0; i < m_numThreadLocalData; i++)
@@ -340,7 +344,7 @@ void Encoder::updateVbvPlan(RateControl* rc)
{
for (int i = 0; i < m_param->frameNumThreads; i++)
{
- FrameEncoder *encoder = &m_frameEncoder[i];
+ FrameEncoder *encoder = m_frameEncoder[i];
if (encoder->m_rce.isActive && encoder->m_rce.poc != rc->m_curSlice->m_poc)
{
int64_t bits = (int64_t) X265_MAX(encoder->m_rce.frameSizeEstimated, encoder->m_rce.frameSizePlanned);
@@ -497,7 +501,7 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture* pic_out)
else
m_lookahead->flush();
- FrameEncoder *curEncoder = &m_frameEncoder[m_curEncoder];
+ FrameEncoder *curEncoder = m_frameEncoder[m_curEncoder];
m_curEncoder = (m_curEncoder + 1) % m_param->frameNumThreads;
int ret = 0;
@@ -938,7 +942,7 @@ void Encoder::printSummary()
{
for (int i = 0; i < m_param->frameNumThreads; i++)
{
- StatisticLog& enclog = m_frameEncoder[i].m_sliceTypeLog[sliceType];
+ StatisticLog& enclog = m_frameEncoder[i]->m_sliceTypeLog[sliceType];
if (!depth)
finalLog.totalCu += enclog.totalCu;
finalLog.cntIntra[depth] += enclog.cntIntra[depth];
diff --git a/source/encoder/encoder.h b/source/encoder/encoder.h
index f1d73a3..ef30225 100644
--- a/source/encoder/encoder.h
+++ b/source/encoder/encoder.h
@@ -86,7 +86,7 @@ public:
int64_t m_prevReorderedPts[2];
ThreadPool* m_threadPool;
- FrameEncoder* m_frameEncoder;
+ FrameEncoder* m_frameEncoder[X265_MAX_FRAME_THREADS];
DPB* m_dpb;
Frame* m_exportedPic;
diff --git a/source/encoder/frameencoder.h b/source/encoder/frameencoder.h
index e796671..911349b 100644
--- a/source/encoder/frameencoder.h
+++ b/source/encoder/frameencoder.h
@@ -122,7 +122,7 @@ public:
virtual ~FrameEncoder() {}
- bool init(Encoder *top, int numRows, int numCols, int id);
+ virtual bool init(Encoder *top, int numRows, int numCols, int id);
void destroy();
@@ -207,7 +207,7 @@ protected:
void compressFrame();
/* called by compressFrame to perform wave-front compression analysis */
- void compressCTURows();
+ virtual void compressCTURows();
/* called by compressFrame to generate final per-row bitstreams */
void encodeSlice();
@@ -218,8 +218,8 @@ protected:
void noiseReductionUpdate();
/* Called by WaveFront::findJob() */
- void processRow(int row, int threadId);
- void processRowEncoder(int row, ThreadLocalData& tld);
+ virtual void processRow(int row, int threadId);
+ virtual void processRowEncoder(int row, ThreadLocalData& tld);
void enqueueRowEncoder(int row) { WaveFront::enqueueRow(row * 2 + 0); }
void enqueueRowFilter(int row) { WaveFront::enqueueRow(row * 2 + 1); }
More information about the x265-devel
mailing list