<div dir="ltr"><div>Yup, TComPicSym or even Frame should be fine - since every Frame will be associated with one FrameEncoder at start of encode. <br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Oct 14, 2014 at 11:45 AM, Steve Borho <span dir="ltr"><<a href="mailto:steve@borho.org" target="_blank">steve@borho.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 10/14, <a href="mailto:deepthi@multicorewareinc.com">deepthi@multicorewareinc.com</a> wrote:<br>
> # HG changeset patch<br>
> # User Deepthi Nandakumar <<a href="mailto:deepthi@multicorewareinc.com">deepthi@multicorewareinc.com</a>><br>
> # Date 1413196915 -19800<br>
> #      Mon Oct 13 16:11:55 2014 +0530<br>
> # Node ID d12a9a16ed2b975c6b57ca67a9ea5af1a96692ae<br>
> # Parent  f26e81eb555aa586380b34314c302ea9b148f357<br>
> noiseReduction: make noiseReduction deterministic<br>
><br>
> diff -r f26e81eb555a -r d12a9a16ed2b source/Lib/TLibCommon/TComRom.h<br>
> --- a/source/Lib/TLibCommon/TComRom.h Mon Oct 13 14:36:40 2014 +0530<br>
> +++ b/source/Lib/TLibCommon/TComRom.h Mon Oct 13 16:11:55 2014 +0530<br>
> @@ -43,29 +43,6 @@<br>
>  namespace x265 {<br>
>  // private namespace<br>
<br>
</span>most of this deserves to be in its own patch<br>
<div><div class="h5"><br>
> -#define NUM_CU_DEPTH            4                           // maximun number of CU depths<br>
> -#define NUM_FULL_DEPTH          5                           // maximun number of full depths<br>
> -#define MIN_LOG2_CU_SIZE        3                           // log2(minCUSize)<br>
> -#define MAX_LOG2_CU_SIZE        6                           // log2(maxCUSize)<br>
> -#define MIN_CU_SIZE             (1 << MIN_LOG2_CU_SIZE)     // minimum allowable size of CU<br>
> -#define MAX_CU_SIZE             (1 << MAX_LOG2_CU_SIZE)     // maximum allowable size of CU<br>
> -<br>
> -#define LOG2_UNIT_SIZE          2                           // log2(unitSize)<br>
> -#define UNIT_SIZE               (1 << LOG2_UNIT_SIZE)       // unit size of CU partition<br>
> -#define TMVP_UNIT_MASK          0xF0                        // mask for mapping index to CompressMV field<br>
> -<br>
> -#define MAX_NUM_PARTITIONS      256<br>
> -<br>
> -#define MIN_PU_SIZE             4<br>
> -#define MIN_TU_SIZE             4<br>
> -#define MAX_NUM_SPU_W           (MAX_CU_SIZE / MIN_PU_SIZE) // maximum number of SPU in horizontal line<br>
> -#define ADI_BUF_STRIDE          (2 * MAX_CU_SIZE + 1 + 15)  // alignment to 16 bytes<br>
> -<br>
> -#define MAX_LOG2_TR_SIZE 5<br>
> -#define MAX_LOG2_TS_SIZE 2 // TODO: RExt<br>
> -#define MAX_TR_SIZE (1 << MAX_LOG2_TR_SIZE)<br>
> -#define MAX_TS_SIZE (1 << MAX_LOG2_TS_SIZE)<br>
> -<br>
>  #define SLFASE_CONSTANT 0x5f4e4a53<br>
><br>
>  void initROM();<br>
> diff -r f26e81eb555a -r d12a9a16ed2b source/common/common.h<br>
> --- a/source/common/common.h  Mon Oct 13 14:36:40 2014 +0530<br>
> +++ b/source/common/common.h  Mon Oct 13 16:11:55 2014 +0530<br>
> @@ -214,15 +214,40 @@<br>
>  namespace x265 {<br>
><br>
>  enum { SAO_NUM_OFFSET = 4 };<br>
> +#define NUM_CU_DEPTH            4                           // maximun number of CU depths<br>
> +#define NUM_FULL_DEPTH          5                           // maximun number of full depths<br>
> +#define MIN_LOG2_CU_SIZE        3                           // log2(minCUSize)<br>
> +#define MAX_LOG2_CU_SIZE        6                           // log2(maxCUSize)<br>
> +#define MIN_CU_SIZE             (1 << MIN_LOG2_CU_SIZE)     // minimum allowable size of CU<br>
> +#define MAX_CU_SIZE             (1 << MAX_LOG2_CU_SIZE)     // maximum allowable size of CU<br>
> +<br>
> +#define LOG2_UNIT_SIZE          2                           // log2(unitSize)<br>
> +#define UNIT_SIZE               (1 << LOG2_UNIT_SIZE)       // unit size of CU partition<br>
> +#define TMVP_UNIT_MASK          0xF0                        // mask for mapping index to CompressMV field<br>
> +<br>
> +#define MAX_NUM_PARTITIONS      256<br>
> +<br>
> +#define MIN_PU_SIZE             4<br>
> +#define MIN_TU_SIZE             4<br>
> +#define MAX_NUM_SPU_W           (MAX_CU_SIZE / MIN_PU_SIZE) // maximum number of SPU in horizontal line<br>
> +#define ADI_BUF_STRIDE          (2 * MAX_CU_SIZE + 1 + 15)  // alignment to 16 bytes<br>
> +<br>
> +#define MAX_LOG2_TR_SIZE 5<br>
> +#define MAX_LOG2_TS_SIZE 2 // TODO: RExt<br>
> +#define MAX_TR_SIZE (1 << MAX_LOG2_TR_SIZE)<br>
> +#define MAX_TS_SIZE (1 << MAX_LOG2_TS_SIZE)<br>
> +<br>
> +#define MAX_NUM_TR_COEFFS MAX_TR_SIZE * MAX_TR_SIZE /* Maximum number of transform coefficients, for a 32x32 transform */<br>
> +#define MAX_NUM_TR_CATEGORIES    8   /* 32, 16, 8, 4 transform categories each for luma and chroma */<br>
><br>
>  // NOTE: MUST be alignment to 16 or 32 bytes for asm code<br>
>  struct NoiseReduction<br>
>  {<br>
>      /* 0 = luma 4x4, 1 = luma 8x8, 2 = luma 16x16, 3 = luma 32x32<br>
>       * 4 = chroma 4x4, 5 = chroma 8x8, 6 = chroma 16x16, 7 = chroma 32x32 */<br>
> -    uint16_t offsetDenoise[8][1024];<br>
> -    uint32_t residualSum[8][1024];<br>
> -    uint32_t count[8];<br>
> +    uint16_t offsetDenoise[MAX_NUM_TR_CATEGORIES][MAX_NUM_TR_COEFFS];<br>
> +    uint32_t residualSum[MAX_NUM_TR_CATEGORIES][MAX_NUM_TR_COEFFS];<br>
> +    uint32_t count[MAX_NUM_TR_CATEGORIES];<br>
>  };<br>
><br>
>  struct SaoCtuParam<br>
> diff -r f26e81eb555a -r d12a9a16ed2b source/encoder/analysis.cpp<br>
> --- a/source/encoder/analysis.cpp     Mon Oct 13 14:36:40 2014 +0530<br>
> +++ b/source/encoder/analysis.cpp     Mon Oct 13 16:11:55 2014 +0530<br>
> @@ -292,7 +292,8 @@<br>
>          if (!jobId || m_param->rdLevel > 4)<br>
>          {<br>
>              slave->m_quant.setQPforQuant(cu);<br>
> -            slave->m_quant.m_nr = m_quant.m_nr;<br>
> +            int frameEncoderID = m_tld[threadId].frameEncoderID;<br>
> +            slave->m_quant.m_nr = m_tld[threadId].m_nr[frameEncoderID];<br>
<br>
</div></div>almost. this is taking the frameEncoderID from the slave, which has not<br>
beeen initialized<br>
<br>
frameEncoderID needs to come from the master TLD, which you probably<br>
can't easily access from here. So frameEncoderID should probably be a<br>
member of Analysis or (perhaps even better) the TComPicSym.<br>
<span class=""><br>
>              slave->m_rdContexts[depth].cur.load(m_rdContexts[depth].cur);<br>
>          }<br>
>      }<br>
> diff -r f26e81eb555a -r d12a9a16ed2b source/encoder/analysis.h<br>
> --- a/source/encoder/analysis.h       Mon Oct 13 14:36:40 2014 +0530<br>
> +++ b/source/encoder/analysis.h       Mon Oct 13 16:11:55 2014 +0530<br>
> @@ -172,8 +172,18 @@<br>
>  struct ThreadLocalData<br>
>  {<br>
>      Analysis analysis;<br>
> +    NoiseReduction** m_nr;<br>
<br>
</span>why a double pointer? why not just allocate an array of them?<br>
<div><div class="h5"><br>
> +    int frameEncoderID;<br>
><br>
> -    ~ThreadLocalData() { analysis.destroy(); }<br>
> +    ThreadLocalData()<br>
> +    {<br>
> +        m_nr = NULL;<br>
> +    }<br>
> +<br>
> +    ~ThreadLocalData()<br>
> +    {<br>
> +        analysis.destroy();<br>
> +    }<br>
>  };<br>
><br>
>  }<br>
> diff -r f26e81eb555a -r d12a9a16ed2b source/encoder/encoder.cpp<br>
> --- a/source/encoder/encoder.cpp      Mon Oct 13 14:36:40 2014 +0530<br>
> +++ b/source/encoder/encoder.cpp      Mon Oct 13 16:11:55 2014 +0530<br>
> @@ -162,15 +162,21 @@<br>
><br>
>      /* Allocate thread local data, one for each thread pool worker and<br>
>       * if --no-wpp, one for each frame encoder */<br>
> -    int numLocalData = poolThreadCount;<br>
> +    m_numThreadLocalData = poolThreadCount;<br>
>      if (!m_param->bEnableWavefront)<br>
> -        numLocalData += m_param->frameNumThreads;<br>
> -    m_threadLocalData = new ThreadLocalData[numLocalData];<br>
> -    for (int i = 0; i < numLocalData; i++)<br>
> +        m_numThreadLocalData += m_param->frameNumThreads;<br>
> +    m_threadLocalData = new ThreadLocalData[m_numThreadLocalData];<br>
> +    for (int i = 0; i < m_numThreadLocalData; i++)<br>
>      {<br>
>          m_threadLocalData[i].analysis.setThreadPool(m_threadPool);<br>
>          m_threadLocalData[i].analysis.initSearch(m_param, m_scalingList);<br>
>          m_threadLocalData[i].analysis.create(g_maxCUDepth + 1, g_maxCUSize, m_threadLocalData);<br>
> +        m_threadLocalData[i].m_nr = X265_MALLOC(NoiseReduction*, m_param->frameNumThreads);<br>
> +        for (int j = 0; j < m_param->frameNumThreads; j++)<br>
> +        {<br>
> +            m_threadLocalData[i].m_nr[j] = X265_MALLOC(NoiseReduction, 1);<br>
> +            memset(m_threadLocalData[i].m_nr[j], 0, sizeof(NoiseReduction));<br>
> +        }<br>
>      }<br>
<br>
</div></div>ok, except for the double allocations<br>
<div><div class="h5"><br>
>      if (!m_param->bEnableWavefront)<br>
> @@ -240,6 +246,13 @@<br>
>          delete [] m_frameEncoder;<br>
>      }<br>
><br>
> +    for (int i = 0; i < m_numThreadLocalData; i++)<br>
> +    {<br>
> +        for (int j = 0; j < m_param->frameNumThreads; j++)<br>
> +           X265_FREE(m_threadLocalData[i].m_nr[j]);<br>
> +        X265_FREE(m_threadLocalData[i].m_nr);<br>
> +    }<br>
> +<br>
>      delete [] m_threadLocalData;<br>
><br>
>      if (m_lookahead)<br>
> @@ -400,6 +413,7 @@<br>
>          m_lookahead->flush();<br>
><br>
>      FrameEncoder *curEncoder = &m_frameEncoder[m_curEncoder];<br>
> +    curEncoder->m_frameEncoderID = m_curEncoder;<br>
>      m_curEncoder = (m_curEncoder + 1) % m_param->frameNumThreads;<br>
>      int ret = 0;<br>
><br>
> diff -r f26e81eb555a -r d12a9a16ed2b source/encoder/encoder.h<br>
> --- a/source/encoder/encoder.h        Mon Oct 13 14:36:40 2014 +0530<br>
> +++ b/source/encoder/encoder.h        Mon Oct 13 16:11:55 2014 +0530<br>
> @@ -93,7 +93,6 @@<br>
><br>
>      int                m_curEncoder;<br>
><br>
> -<br>
>      /* Collect statistics globally */<br>
>      EncStats           m_analyzeAll;<br>
>      EncStats           m_analyzeI;<br>
> @@ -116,6 +115,7 @@<br>
>      PPS                m_pps;<br>
>      NALList            m_nalList;<br>
>      ScalingList        m_scalingList;      // quantization matrix information<br>
> +    int                m_numThreadLocalData;<br>
><br>
>      int                m_lastBPSEI;<br>
>      uint32_t           m_numDelayedPic;<br>
> diff -r f26e81eb555a -r d12a9a16ed2b source/encoder/frameencoder.cpp<br>
> --- a/source/encoder/frameencoder.cpp Mon Oct 13 14:36:40 2014 +0530<br>
> +++ b/source/encoder/frameencoder.cpp Mon Oct 13 16:11:55 2014 +0530<br>
> @@ -49,8 +49,9 @@<br>
>      m_vbvResetTriggerRow = -1;<br>
>      m_outStreams = NULL;<br>
>      m_substreamSizes = NULL;<br>
> -    m_nr = NULL;<br>
> +    m_frameNR = NULL;<br>
>      m_tld = NULL;<br>
> +    m_frameEncoderID = 0;<br>
>      memset(&m_frameStats, 0, sizeof(m_frameStats));<br>
>      memset(&m_rce, 0, sizeof(RateControlEntry));<br>
>  }<br>
> @@ -75,7 +76,7 @@<br>
>      X265_FREE(m_substreamSizes);<br>
>      m_frameFilter.destroy();<br>
><br>
> -    X265_FREE(m_nr);<br>
> +    X265_FREE(m_frameNR);<br>
><br>
>      // wait for worker thread to exit<br>
>      stop();<br>
> @@ -119,9 +120,9 @@<br>
>      }<br>
><br>
>      if (m_param->noiseReduction)<br>
> -        m_nr = X265_MALLOC(NoiseReduction, 1);<br>
> -    if (m_nr)<br>
> -        memset(m_nr, 0, sizeof(NoiseReduction));<br>
> +        m_frameNR = X265_MALLOC(NoiseReduction, 1);<br>
> +    if (m_frameNR)<br>
> +        memset(m_frameNR, 0, sizeof(NoiseReduction));<br>
>      else<br>
>          m_param->noiseReduction = 0;<br>
><br>
> @@ -393,8 +394,36 @@<br>
>      if (m_top->m_rateControl->rateControlEnd(m_frame, m_accessUnitBits, &m_rce, &m_frameStats) < 0)<br>
>          m_top->m_aborted = true;<br>
><br>
> +    /* Accumulate NR statistics from all worker threads */<br>
> +    if (m_frameNR)<br>
> +    {<br>
> +        for (int i = 0; i < m_top->m_numThreadLocalData; i++)<br>
> +        {<br>
> +            NoiseReduction* nr = m_top->m_threadLocalData[i].m_nr[m_frameEncoderID];<br>
> +            for (int cat = 0; cat < MAX_NUM_TR_CATEGORIES; cat++)<br>
> +            {<br>
> +                for(int coeff = 0; coeff < MAX_NUM_TR_COEFFS; coeff++)<br>
> +                    m_frameNR->residualSum[cat][coeff] += nr->residualSum[cat][coeff];<br>
> +<br>
> +                m_frameNR->count[cat] += nr->count[cat];<br>
> +            }<br>
> +        }<br>
> +    }<br>
> +<br>
>      noiseReductionUpdate();<br>
><br>
> +    /* Copy updated NR coefficients back to all worker threads */<br>
> +    if (m_frameNR)<br>
> +    {<br>
> +        for (int i = 0; i < m_top->m_numThreadLocalData; i++)<br>
> +        {<br>
> +            NoiseReduction* nr = m_top->m_threadLocalData[i].m_nr[m_frameEncoderID];<br>
> +            memcpy(nr->offsetDenoise, m_frameNR->offsetDenoise, sizeof(uint32_t) * MAX_NUM_TR_CATEGORIES * MAX_NUM_TR_COEFFS);<br>
> +            memset(nr->count, 0, sizeof(uint32_t) * MAX_NUM_TR_CATEGORIES);<br>
> +            memset(nr->residualSum, 0, sizeof(uint32_t) * MAX_NUM_TR_CATEGORIES * MAX_NUM_TR_COEFFS);<br>
> +        }<br>
> +    }<br>
<br>
</div></div>\o/<br>
<div><div class="h5"><br>
> +<br>
>      // Decrement referenced frame reference counts, allow them to be recycled<br>
>      for (int l = 0; l < numPredDir; l++)<br>
>      {<br>
> @@ -616,7 +645,8 @@<br>
>      // setup thread-local data<br>
>      Slice *slice = m_frame->m_picSym->m_slice;<br>
>      TComPicYuv* fenc = m_frame->getPicYuvOrg();<br>
> -    tld.analysis.m_quant.m_nr = m_nr;<br>
> +    tld.analysis.m_quant.m_nr = tld.m_nr[m_frameEncoderID];<br>
> +    tld.frameEncoderID = m_frameEncoderID;<br>
>      tld.analysis.m_me.setSourcePlane(fenc->getLumaAddr(), fenc->getStride());<br>
>      tld.analysis.m_log = &tld.analysis.m_sliceTypeLog[m_frame->m_picSym->m_slice->m_sliceType];<br>
>      tld.analysis.setQP(slice, slice->m_sliceQp);<br>
> @@ -866,34 +896,34 @@<br>
>  /* DCT-domain noise reduction / adaptive deadzone from libavcodec */<br>
>  void FrameEncoder::noiseReductionUpdate()<br>
>  {<br>
> -    if (!m_nr)<br>
> +    if (!m_frameNR)<br>
>          return;<br>
><br>
>      static const uint32_t maxBlocksPerTrSize[4] = {1 << 18, 1 << 16, 1 << 14, 1 << 12};<br>
><br>
> -    for (int cat = 0; cat < 8; cat++)<br>
> +    for (int cat = 0; cat < MAX_NUM_TR_CATEGORIES; cat++)<br>
>      {<br>
>          int trSize = cat & 3;<br>
>          int coefCount = 1 << ((trSize + 2) * 2);<br>
><br>
> -        if (m_nr->count[cat] > maxBlocksPerTrSize[trSize])<br>
> +        if (m_frameNR->count[cat] > maxBlocksPerTrSize[trSize])<br>
>          {<br>
>              for (int i = 0; i < coefCount; i++)<br>
> -                m_nr->residualSum[cat][i] >>= 1;<br>
> -            m_nr->count[cat] >>= 1;<br>
> +                m_frameNR->residualSum[cat][i] >>= 1;<br>
> +            m_frameNR->count[cat] >>= 1;<br>
>          }<br>
><br>
> -        uint64_t scaledCount = (uint64_t)m_param->noiseReduction * m_nr->count[cat];<br>
> +        uint64_t scaledCount = (uint64_t)m_param->noiseReduction * m_frameNR->count[cat];<br>
><br>
>          for (int i = 0; i < coefCount; i++)<br>
>          {<br>
> -            uint64_t value = scaledCount + m_nr->residualSum[cat][i] / 2;<br>
> -            uint64_t denom = m_nr->residualSum[cat][i] + 1;<br>
> -            m_nr->offsetDenoise[cat][i] = (uint16_t)(value / denom);<br>
> +            uint64_t value = scaledCount + m_frameNR->residualSum[cat][i] / 2;<br>
> +            uint64_t denom = m_frameNR->residualSum[cat][i] + 1;<br>
> +            m_frameNR->offsetDenoise[cat][i] = (uint16_t)(value / denom);<br>
>          }<br>
><br>
>          // Don't denoise DC coefficients<br>
> -        m_nr->offsetDenoise[cat][0] = 0;<br>
> +        m_frameNR->offsetDenoise[cat][0] = 0;<br>
>      }<br>
>  }<br>
><br>
> diff -r f26e81eb555a -r d12a9a16ed2b source/encoder/frameencoder.h<br>
> --- a/source/encoder/frameencoder.h   Mon Oct 13 14:36:40 2014 +0530<br>
> +++ b/source/encoder/frameencoder.h   Mon Oct 13 16:11:55 2014 +0530<br>
> @@ -140,7 +140,7 @@<br>
>      Bitstream                m_bs;<br>
>      Bitstream*               m_outStreams;<br>
>      uint32_t*                m_substreamSizes;<br>
> -    NoiseReduction*          m_nr;<br>
> +    NoiseReduction*          m_frameNR;<br>
>      NALList                  m_nalList;<br>
>      ThreadLocalData*         m_tld; /* for --no-wpp */<br>
><br>
> @@ -148,6 +148,7 @@<br>
>      int                      m_filterRowDelayCus;<br>
>      Event                    m_completionEvent;<br>
>      int64_t                  m_totalTime;<br>
> +    int                      m_frameEncoderID;<br>
><br>
>  protected:<br>
><br>
</div></div>> _______________________________________________<br>
> x265-devel mailing list<br>
> <a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
> <a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Steve Borho<br>
_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</font></span></blockquote></div><br></div>