[x265] [PATCH] Make FrameEncoder partially virtual so it can be overloaded

Steve Borho steve at borho.org
Mon Feb 2 18:27:59 CET 2015


On 02/02, Nicolas Morey-Chaisemartin wrote:
> # 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.

I'm mostly fine with adding virtual declarations for these functions,
but I'm curious why this requires the frame encoders to be allocated in
seperate new() calls? This is accounting for most of the diffs.

Somewhat related to this, I made a patch a couple of days ago that has
yet to be pushed which added a hard-limit on the number of frame
encoders (to 16). With this you could avoid mallocing the array of
pointers, and just declare the max-sized array in the top level Encoder
class (if individual pointers are required).

> ---
>  source/encoder/encoder.cpp    | 25 +++++++++++++++----------
>  source/encoder/encoder.h      |  2 +-
>  source/encoder/frameencoder.h |  8 ++++----
>  3 files changed, 20 insertions(+), 15 deletions(-)
> 
> diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
> index 8dbd1b2..c1aaaf7 100644
> --- a/source/encoder/encoder.cpp
> +++ b/source/encoder/encoder.cpp
> @@ -151,9 +151,13 @@ void Encoder::create()
>               p->bEnableWavefront ? rows : 0, p->frameNumThreads, poolThreadCount,
>               p->bDistributeMotionEstimation ? " / pme" : "", p->bDistributeModeAnalysis ? " / pmode" : "");
> -    m_frameEncoder = new FrameEncoder[m_param->frameNumThreads];
> +    m_frameEncoder = X265_MALLOC(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())
>      {
> @@ -183,7 +187,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);
> @@ -235,7 +239,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;
> @@ -287,11 +291,12 @@ void Encoder::destroy()
>          for (int i = 0; i < m_param->frameNumThreads; 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;
> +        X265_FREE(m_frameEncoder);
>      }
>      for (int i = 0; i < m_numThreadLocalData; i++)
> @@ -339,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);
> @@ -496,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;
> @@ -825,7 +830,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..ef73c93 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;
>      DPB*               m_dpb;
>      Frame*             m_exportedPic;
> diff --git a/source/encoder/frameencoder.h b/source/encoder/frameencoder.h
> index f0c5b77..2c0faba 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();
> @@ -204,7 +204,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();
> @@ -215,8 +215,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); }
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel

-- 
Steve Borho


More information about the x265-devel mailing list