[x265] [PATCH] do not use std;:list for the class AccessUnit

Deepthi Nandakumar deepthi at multicorewareinc.com
Thu Sep 19 10:09:21 CEST 2013


FrameEncoder and compressFrame needs to be refactored for mallocs and
failures to be handled correctly.


On Thu, Sep 19, 2013 at 1:31 PM, Gopu Govindaswamy <
gopu at multicorewareinc.com> wrote:

> # HG changeset patch
> # User Gopu Govindaswamy <gopu at multicorewareinc.com>
> # Date 1379577682 -19800
> # Node ID 92e1ac03b081eccd8bc797142cc22033c87d475d
> # Parent  26d6f155f8df69147f40f4945d99c29a52988c56
> do not use std;:list for the class AccessUnit
>
> Removed std::list from encoder and nalunits
>
> diff -r 26d6f155f8df -r 92e1ac03b081 source/Lib/TLibCommon/NAL.h
> --- a/source/Lib/TLibCommon/NAL.h       Wed Sep 18 16:13:33 2013 -0500
> +++ b/source/Lib/TLibCommon/NAL.h       Thu Sep 19 13:31:22 2013 +0530
> @@ -114,6 +114,7 @@
>       * emulation_prevention_three_byte symbols.
>       */
>      NALUnitEBSP(OutputNALUnit& nalu);
> +    void init(OutputNALUnit& nalu);
>  };
>  }
>  //! \}
> diff -r 26d6f155f8df -r 92e1ac03b081 source/Lib/TLibEncoder/NALwrite.h
> --- a/source/Lib/TLibEncoder/NALwrite.h Wed Sep 18 16:13:33 2013 -0500
> +++ b/source/Lib/TLibEncoder/NALwrite.h Thu Sep 19 13:31:22 2013 +0530
> @@ -83,6 +83,14 @@
>      write(m_nalUnitData, nalu, m_packetSize);
>  }
>
> +inline void NALUnitEBSP::init(OutputNALUnit& nalu)
> +{
> +    m_nalUnitType = nalu.m_nalUnitType;
> +    m_temporalId = nalu.m_temporalId;
> +    m_reservedZero6Bits = nalu.m_reservedZero6Bits;
> +    write(m_nalUnitData, nalu, m_packetSize);
> +}
> +
>  void copyNaluData(OutputNALUnit& naluDest, const OutputNALUnit& naluSrc);
>  }
>
> diff -r 26d6f155f8df -r 92e1ac03b081 source/Lib/TLibEncoder/TEncTop.cpp
> --- a/source/Lib/TLibEncoder/TEncTop.cpp        Wed Sep 18 16:13:33 2013
> -0500
> +++ b/source/Lib/TLibEncoder/TEncTop.cpp        Thu Sep 19 13:31:22 2013
> +0530
> @@ -114,7 +114,7 @@
>          for (int i = 0; i < param.frameNumThreads; i++)
>          {
>              // Ensure frame encoder is idle before destroying it
> -            AccessUnit tmp;
> +            NALUnitEBSP **tmp = NULL;
>              m_frameEncoder[i].getEncodedPicture(tmp);
>              m_frameEncoder[i].destroy();
>          }
> @@ -155,19 +155,19 @@
>      }
>  }
>
> -int TEncTop::getStreamHeaders(AccessUnit& accessUnit)
> +int TEncTop::getStreamHeaders(NALUnitEBSP **nalunits)
>  {
> -    return m_frameEncoder->getStreamHeaders(accessUnit);
> +    return m_frameEncoder->getStreamHeaders(nalunits);
>  }
>
>  /**
>   \param   flush               force encoder to encode a frame
>   \param   pic_in              input original YUV picture or NULL
>   \param   pic_out             pointer to reconstructed picture struct
> - \param   accessUnitsOut      output bitstream
> + \param   nalunits            output bitstream
>   \retval                      number of encoded pictures
>   */
> -int TEncTop::encode(bool flush, const x265_picture_t* pic_in,
> x265_picture_t *pic_out, AccessUnit& accessUnitOut)
> +int TEncTop::encode(bool flush, const x265_picture_t* pic_in,
> x265_picture_t *pic_out, NALUnitEBSP **nalunits)
>  {
>      if (pic_in)
>      {
> @@ -207,7 +207,7 @@
>      // getEncodedPicture() should block until the FrameEncoder has
> completed
>      // encoding the frame.  This is how back-pressure through the API is
>      // accomplished when the encoder is full.
> -    TComPic *out = curEncoder->getEncodedPicture(accessUnitOut);
> +    TComPic *out = curEncoder->getEncodedPicture(nalunits);
>
>      if (!out && flush)
>      {
> @@ -221,7 +221,7 @@
>          {
>              curEncoder = &m_frameEncoder[m_curEncoder];
>              m_curEncoder = (m_curEncoder + 1) % param.frameNumThreads;
> -            out = curEncoder->getEncodedPicture(accessUnitOut);
> +            out = curEncoder->getEncodedPicture(nalunits);
>          }
>          while (!out && flushed != m_curEncoder);
>      }
> @@ -253,7 +253,7 @@
>              pic_out->stride[2] = recpic->getCStride();
>          }
>
> -        double bits = calculateHashAndPSNR(out, accessUnitOut);
> +        double bits = calculateHashAndPSNR(out, nalunits);
>          // Allow this frame to be recycled if no frame encoders are using
> it for reference
>          ATOMIC_DEC(&out->m_countRefEncoders);
>
> @@ -481,7 +481,7 @@
>
>  /* Returns Number of bits in current encoded pic */
>
> -double TEncTop::calculateHashAndPSNR(TComPic* pic, AccessUnit& accessUnit)
> +double TEncTop::calculateHashAndPSNR(TComPic* pic, NALUnitEBSP **nalunits)
>  {
>      TComPicYuv* recon = pic->getPicYuvRec();
>      TComPicYuv* orig  = pic->getPicYuvOrg();
> @@ -537,8 +537,12 @@
>          OutputNALUnit onalu(NAL_UNIT_SUFFIX_SEI, 0);
>          m_frameEncoder->m_seiWriter.writeSEImessage(onalu.m_Bitstream,
> sei_recon_picture_digest, pic->getSlice()->getSPS());
>          writeRBSPTrailingBits(onalu.m_Bitstream);
> -
> -        accessUnit.insert(accessUnit.end(), new NALUnitEBSP(onalu));
> +
> +        int count = 0;
> +        while(nalunits[count] != NULL)
> +            count++;
> +        nalunits[count] = (NALUnitEBSP *)X265_MALLOC(NALUnitEBSP, 1);
> +        nalunits[count]->init(onalu);
>      }
>
>      /* calculate the size of the access unit, excluding:
> @@ -546,13 +550,14 @@
>       *  - SEI NAL units
>       */
>      UInt numRBSPBytes = 0;
> -    for (AccessUnit::const_iterator it = accessUnit.begin(); it !=
> accessUnit.end(); it++)
> +    UInt count = 0;
> +    for (; nalunits[count] != NULL; count++)
>      {
> -        UInt numRBSPBytes_nal = (*it)->m_packetSize;
> +        UInt numRBSPBytes_nal = nalunits[count]->m_packetSize;
>  #if VERBOSE_RATE
>          printf("*** %6s numBytesInNALunit: %u\n",
> nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
>  #endif
> -        if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI &&
> (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
> +        if (nalunits[count]->m_nalUnitType != NAL_UNIT_PREFIX_SEI &&
> nalunits[count]->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
>          {
>              numRBSPBytes += numRBSPBytes_nal;
>          }
> diff -r 26d6f155f8df -r 92e1ac03b081 source/Lib/TLibEncoder/TEncTop.h
> --- a/source/Lib/TLibEncoder/TEncTop.h  Wed Sep 18 16:13:33 2013 -0500
> +++ b/source/Lib/TLibEncoder/TEncTop.h  Thu Sep 19 13:31:22 2013 +0530
> @@ -101,9 +101,9 @@
>      void xInitSPS(TComSPS *sps);
>      void xInitPPS(TComPPS *pps);
>
> -    int encode(bool bEos, const x265_picture_t* pic, x265_picture_t
> *pic_out, AccessUnit& accessUnit);
> +    int encode(bool bEos, const x265_picture_t* pic, x265_picture_t
> *pic_out, NALUnitEBSP **nalunits);
>
> -    int getStreamHeaders(AccessUnit& accessUnit);
> +    int getStreamHeaders(NALUnitEBSP **nalunits);
>
>      double printSummary();
>
> @@ -113,7 +113,7 @@
>
>  protected:
>
> -    double calculateHashAndPSNR(TComPic* pic, AccessUnit&); // Returns
> total number of bits for encoded pic
> +    double calculateHashAndPSNR(TComPic* pic, NALUnitEBSP **nalunits); //
> Returns total number of bits for encoded pic
>  };
>  }
>  //! \}
> diff -r 26d6f155f8df -r 92e1ac03b081 source/encoder/encoder.cpp
> --- a/source/encoder/encoder.cpp        Wed Sep 18 16:13:33 2013 -0500
> +++ b/source/encoder/encoder.cpp        Thu Sep 19 13:31:22 2013 +0530
> @@ -47,7 +47,7 @@
>
>      void configure(x265_param_t *param);
>      void determineLevelAndProfile(x265_param_t *param);
> -    void extract_naldata(AccessUnit &au, size_t &nalcount);
> +    void extract_naldata(NALUnitEBSP **nalunits, size_t &nalcount);
>  };
>
>  x265_t::x265_t()
> @@ -356,18 +356,23 @@
>
>  int x265_encoder_headers(x265_t *encoder, x265_nal_t **pp_nal, int
> *pi_nal)
>  {
> -    // there is a lot of duplicated code here, see x265_encoder_encode()
>      if (!pp_nal)
>          return 0;
>
> -    AccessUnit au;
> -    if (encoder->getStreamHeaders(au) == 0)
> +    NALUnitEBSP *nalunits[X265_NAL_UNITS] = { 0, 0, 0, 0, 0 };
> +    if (encoder->getStreamHeaders(nalunits) == 0)
>      {
>          size_t nalcount;
> -        encoder->extract_naldata( au, nalcount);
> +        encoder->extract_naldata(nalunits, nalcount);
>
>          *pp_nal = &encoder->m_nals[0];
>          if (pi_nal) *pi_nal = (int)nalcount;
> +
> +        for (nalcount = 0; nalcount < X265_NAL_UNITS; nalcount++)
> +        {
> +            if (nalunits[nalcount])
> +                X265_FREE(nalunits[nalcount]);
> +        }
>          return 0;
>      }
>      else
> @@ -377,17 +382,22 @@
>  extern "C"
>  int x265_encoder_encode(x265_t *encoder, x265_nal_t **pp_nal, int
> *pi_nal, x265_picture_t *pic_in, x265_picture_t *pic_out)
>  {
> -    AccessUnit au;
> -
> -    int numEncoded = encoder->encode(!pic_in, pic_in, pic_out, au);
> +    NALUnitEBSP *nalunits[X265_NAL_UNITS] = { 0, 0, 0, 0, 0 };
> +    int numEncoded = encoder->encode(!pic_in, pic_in, pic_out, nalunits);
>
>      if (pp_nal && numEncoded)
>      {
>          size_t nalcount;
> -        encoder->extract_naldata( au, nalcount);
> +        encoder->extract_naldata(nalunits, nalcount);
>
>          *pp_nal = &encoder->m_nals[0];
>          if (pi_nal) *pi_nal =(int) nalcount;
> +
> +        for (nalcount = 0; nalcount < X265_NAL_UNITS; nalcount++)
> +        {
> +            if (nalunits[nalcount])
> +                X265_FREE(nalunits[nalcount]);
> +        }
>      }
>      else if (pi_nal)
>          *pi_nal = 0;
> @@ -417,15 +427,14 @@
>      BitCost::destroy();
>  }
>
> -void x265_t::extract_naldata( AccessUnit &au, size_t &nalcount)
> +void x265_t::extract_naldata(NALUnitEBSP **nalunits, size_t &nalcount)
>  {
>          UInt memsize = 0;
>          nalcount = 0;
> -        for (AccessUnit::const_iterator t = au.begin(); t != au.end();
> t++)
> +        for (; nalunits[nalcount] != NULL; nalcount++)
>          {
> -            const NALUnitEBSP& temp = **t;
> +            const NALUnitEBSP& temp = *nalunits[nalcount];
>              memsize += temp.m_packetSize + 4;
> -            nalcount++;
>          }
>
>          if (m_packetData)
> @@ -440,13 +449,13 @@
>          memsize = 0;
>
>          /* Copy NAL output packets into x265_nal_t structures */
> -        for (AccessUnit::const_iterator it = au.begin(); it != au.end();
> it++)
> +        for (; nalunits[nalcount] != NULL; nalcount++)
>          {
> -            const NALUnitEBSP& nalu = **it;
> +            const NALUnitEBSP& nalu = *nalunits[nalcount];
>              int size = 0; /* size of annexB unit in bytes */
>
>              static const char start_code_prefix[] = { 0, 0, 0, 1 };
> -            if (it == au.begin() || nalu.m_nalUnitType == NAL_UNIT_SPS ||
> nalu.m_nalUnitType == NAL_UNIT_PPS)
> +            if (nalcount == 0 || nalu.m_nalUnitType == NAL_UNIT_SPS ||
> nalu.m_nalUnitType == NAL_UNIT_PPS)
>              {
>                  /* From AVC, When any of the following conditions are
> fulfilled, the
>                      * zero_byte syntax element shall be present:
> @@ -472,7 +481,6 @@
>
>              m_nals[nalcount].i_type = nalu.m_nalUnitType;
>              m_nals[nalcount].i_payload = size;
> -            nalcount++;
>              free(nalu.m_nalUnitData);
>          }
>
> diff -r 26d6f155f8df -r 92e1ac03b081 source/encoder/frameencoder.cpp
> --- a/source/encoder/frameencoder.cpp   Wed Sep 18 16:13:33 2013 -0500
> +++ b/source/encoder/frameencoder.cpp   Thu Sep 19 13:31:22 2013 +0530
> @@ -55,7 +55,12 @@
>      , m_cfg(NULL)
>      , m_pic(NULL)
>      , m_rows(NULL)
> -{}
> +{
> +    for (int i = 0; i < 5; i++)
> +        m_accessUnit[i] = NULL;
> +
> +    m_nalcount = 0;
> +}
>
>  void FrameEncoder::setThreadPool(ThreadPool *p)
>  {
> @@ -158,30 +163,40 @@
>      start();
>  }
>
> -int FrameEncoder::getStreamHeaders(AccessUnit& accessUnit)
> +int FrameEncoder::getStreamHeaders(NALUnitEBSP **nalunits)
>  {
>      TEncEntropy* entropyCoder = getEntropyCoder(0);
>
>      entropyCoder->setEntropyCoder(&m_cavlcCoder, NULL);
> +    int count = 0;
>
>      /* headers for start of bitstream */
>      OutputNALUnit nalu(NAL_UNIT_VPS);
>      entropyCoder->setBitstream(&nalu.m_Bitstream);
>      entropyCoder->encodeVPS(m_cfg->getVPS());
>      writeRBSPTrailingBits(nalu.m_Bitstream);
> -    accessUnit.push_back(new NALUnitEBSP(nalu));
> +    if ((nalunits[count] = (NALUnitEBSP *)X265_MALLOC(NALUnitEBSP, 1)) ==
> NULL)
> +        return -1;
> +    nalunits[count]->init(nalu);
> +    count++;
>
>      nalu = NALUnit(NAL_UNIT_SPS);
>      entropyCoder->setBitstream(&nalu.m_Bitstream);
>      entropyCoder->encodeSPS(&m_sps);
>      writeRBSPTrailingBits(nalu.m_Bitstream);
> -    accessUnit.push_back(new NALUnitEBSP(nalu));
> +    if ((nalunits[count] = (NALUnitEBSP *)X265_MALLOC(NALUnitEBSP, 1)) ==
> NULL)
> +        return -1;
> +    nalunits[count]->init(nalu);
> +    count++;
>
>      nalu = NALUnit(NAL_UNIT_PPS);
>      entropyCoder->setBitstream(&nalu.m_Bitstream);
>      entropyCoder->encodePPS(&m_pps);
>      writeRBSPTrailingBits(nalu.m_Bitstream);
> -    accessUnit.push_back(new NALUnitEBSP(nalu));
> +    if ((nalunits[count] = (NALUnitEBSP *)X265_MALLOC(NALUnitEBSP, 1)) ==
> NULL)
> +        return -1;
> +    nalunits[count]->init(nalu);
> +    count++;
>
>      if (m_cfg->getActiveParameterSetsSEIEnabled())
>      {
> @@ -195,7 +210,10 @@
>          entropyCoder->setBitstream(&nalu.m_Bitstream);
>          m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei, &m_sps);
>          writeRBSPTrailingBits(nalu.m_Bitstream);
> -        accessUnit.push_back(new NALUnitEBSP(nalu));
> +        if ((nalunits[count] = (NALUnitEBSP *)X265_MALLOC(NALUnitEBSP,
> 1)) == NULL)
> +            return -1;
> +        nalunits[count]->init(nalu);
> +        count++;
>      }
>
>      if (m_cfg->getDisplayOrientationSEIAngle())
> @@ -210,7 +228,9 @@
>          entropyCoder->setBitstream(&nalu.m_Bitstream);
>          m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei, &m_sps);
>          writeRBSPTrailingBits(nalu.m_Bitstream);
> -        accessUnit.push_back(new NALUnitEBSP(nalu));
> +        if ((nalunits[count] = (NALUnitEBSP *)X265_MALLOC(NALUnitEBSP,
> 1)) == NULL)
> +            return -1;
> +        nalunits[count]->init(nalu);
>      }
>      return 0;
>  }
> @@ -275,7 +295,8 @@
>  void FrameEncoder::compressFrame()
>  {
>      PPAScopeEvent(FrameEncoder_compressFrame);
> -
> +
> +    m_nalcount = 0;
>      TEncEntropy* entropyCoder = getEntropyCoder(0);
>      TComSlice*   slice        = m_pic->getSlice();
>
> @@ -470,7 +491,9 @@
>
>              m_seiWriter.writeSEImessage(nalu.m_Bitstream,
> seiGradualDecodingRefreshInfo, slice->getSPS());
>              writeRBSPTrailingBits(nalu.m_Bitstream);
> -            m_accessUnit.push_back(new NALUnitEBSP(nalu));
> +            m_accessUnit[m_nalcount] = (NALUnitEBSP
> *)X265_MALLOC(NALUnitEBSP, 1);
> +            m_accessUnit[m_nalcount]->init(nalu);
> +            m_nalcount++;
>          }
>          // Recovery point SEI
>          OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
> @@ -482,7 +505,9 @@
>
>          m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recovery_point,
> slice->getSPS());
>          writeRBSPTrailingBits(nalu.m_Bitstream);
> -        m_accessUnit.push_back(new NALUnitEBSP(nalu));
> +        m_accessUnit[m_nalcount] = (NALUnitEBSP
> *)X265_MALLOC(NALUnitEBSP, 1);
> +        m_accessUnit[m_nalcount]->init(nalu);
> +        m_nalcount++;
>      }
>
>      /* use the main bitstream buffer for storing the marshaled picture */
> @@ -617,7 +642,9 @@
>      entropyCoder->setBitstream(&nalu.m_Bitstream);
>      bitstreamRedirect->clear();
>
> -    m_accessUnit.push_back(new NALUnitEBSP(nalu));
> +    m_accessUnit[m_nalcount] = (NALUnitEBSP *)X265_MALLOC(NALUnitEBSP, 1);
> +    m_accessUnit[m_nalcount]->init(nalu);
> +    m_nalcount++;
>
>      if (m_sps.getUseSAO())
>      {
> @@ -982,7 +1009,7 @@
>      }
>  }
>
> -TComPic *FrameEncoder::getEncodedPicture(AccessUnit& accessUnit)
> +TComPic *FrameEncoder::getEncodedPicture(NALUnitEBSP **nalunits)
>  {
>      if (m_pic)
>      {
> @@ -992,8 +1019,8 @@
>          TComPic *ret = m_pic;
>          m_pic = NULL;
>
> -        // move NALs from member variable list to end of user's container
> -        accessUnit.splice(accessUnit.end(), m_accessUnit);
> +        // move NALs from member variable to end of user's container
> +        ::memcpy(nalunits, m_accessUnit, sizeof(NALUnitEBSP) *
> m_nalcount);
>          return ret;
>      }
>
> diff -r 26d6f155f8df -r 92e1ac03b081 source/encoder/frameencoder.h
> --- a/source/encoder/frameencoder.h     Wed Sep 18 16:13:33 2013 -0500
> +++ b/source/encoder/frameencoder.h     Thu Sep 19 13:31:22 2013 +0530
> @@ -135,7 +135,7 @@
>          }
>      }
>
> -    int getStreamHeaders(AccessUnit& accessUnitOut);
> +    int getStreamHeaders(NALUnitEBSP **nalunits);
>
>      void initSlice(TComPic* pic);
>
> @@ -148,7 +148,7 @@
>      void encodeSlice(TComOutputBitstream* substreams);
>
>      /* blocks until worker thread is done, returns encoded picture and
> bitstream */
> -    TComPic *getEncodedPicture(AccessUnit& accessUnit);
> +    TComPic *getEncodedPicture(NALUnitEBSP **nalunits);
>
>      // worker thread
>      void threadMain();
> @@ -178,7 +178,8 @@
>
>      /* Picture being encoded, and its output NAL list */
>      TComPic*                 m_pic;
> -    AccessUnit               m_accessUnit;
> +    NALUnitEBSP              *m_accessUnit[X265_NAL_UNITS];
> +    int                      m_nalcount;
>
>      int                      m_numRows;
>      int                      m_filterRowDelay;
> diff -r 26d6f155f8df -r 92e1ac03b081 source/x265.h
> --- a/source/x265.h     Wed Sep 18 16:13:33 2013 -0500
> +++ b/source/x265.h     Thu Sep 19 13:31:22 2013 +0530
> @@ -173,6 +173,7 @@
>  #define X265_TYPE_KEYFRAME      0x0006  /* IDR or I depending on
> b_open_gop option */
>  #define IS_X265_TYPE_I(x) ((x)==X265_TYPE_I || (x)==X265_TYPE_IDR)
>  #define IS_X265_TYPE_B(x) ((x)==X265_TYPE_B || (x)==X265_TYPE_BREF)
> +#define X265_NAL_UNITS          5
>
>  /* rate tolerance method */
>  typedef enum RcMethod
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20130919/b0658071/attachment-0001.html>


More information about the x265-devel mailing list