[x265] [PATCH] introduce new CLI single-sei to write all SEI messages in one single NAL

Ashok Kumar Mishra ashok at multicorewareinc.com
Tue Apr 3 10:54:26 CEST 2018


On Mon, Apr 2, 2018 at 6:31 PM, <santhoshini at multicorewareinc.com> wrote:

> # HG changeset patch
> # User Santhoshini Sekar <santhoshini at multicorewareinc.com>
> # Date 1522673234 -19800
> #      Mon Apr 02 18:17:14 2018 +0530
> # Node ID 6337356c86a4f5a49f275eb466d6fae32e6eb145
> # Parent  946f82dbf4e80cb272f43a32a78ba2b186469845
> introduce new CLI single-sei to write all SEI messages in one single NAL
>
> diff --git a/doc/reST/cli.rst b/doc/reST/cli.rst
> --- a/doc/reST/cli.rst
> +++ b/doc/reST/cli.rst
> @@ -2221,6 +2221,10 @@
>  .. option:: --idr-recovery-sei, --no-idr-recoveery-sei
>      Emit RecoveryPoint info as sei in bitstream for each IDR frame.
> Default disabled.
>
> +.. option:: --single-sei, --no-single-sei
> +    Emit SEI messages in a single NAL unit instead of multiple NALs.
> Default disabled.
> +    When HRD SEI is enabled the HM decoder will throw a warning.
> +
>  DCT Approximations
>  =================
>
> diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
> --- a/source/CMakeLists.txt
> +++ b/source/CMakeLists.txt
> @@ -29,7 +29,7 @@
>  option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)
>  mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)
>  # X265_BUILD must be incremented each time the public API is changed
> -set(X265_BUILD 156)
> +set(X265_BUILD 157)
>  configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
>                 "${PROJECT_BINARY_DIR}/x265.def")
>  configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
> diff --git a/source/common/param.cpp b/source/common/param.cpp
> --- a/source/common/param.cpp
> +++ b/source/common/param.cpp
> @@ -301,6 +301,7 @@
>      /* DCT Approximations */
>      param->bLowPassDct = 0;
>      param->bMVType = 0;
> +    param->bSingleSeiNal = 0;
>  }
>
>  int x265_param_default_preset(x265_param* param, const char* preset,
> const char* tune)
> @@ -1017,6 +1018,7 @@
>          OPT("radl") p->radl = atoi(value);
>          OPT("max-ausize-factor") p->maxAUSizeFactor = atof(value);
>          OPT("dynamic-refine") p->bDynamicRefine = atobool(value);
> +        OPT("single-sei") p->bSingleSeiNal = atobool(value);
>          else
>              return X265_PARAM_BAD_NAME;
>      }
> @@ -1382,6 +1384,14 @@
>      if (param->masteringDisplayColorVolume || param->maxFALL ||
> param->maxCLL)
>          param->bEmitHDRSEI = 1;
>
> +    bool isSingleSEI = ((param->bEmitHRDSEI || param->bEmitInfoSEI ||
> param->decodedPictureHashSEI ||
> +                         param->masteringDisplayColorVolume ||
> param->maxCLL || param->maxFALL ||
> +                         param->bEmitHDRSEI ||
> param->bEmitIDRRecoverySEI) && param->bSingleSeiNal);
> +    if (!isSingleSEI)
> +    {
> +        param->bSingleSeiNal = 0;
> +        x265_log(param, X265_LOG_WARNING, "None of the SEI messages are
> enabled. Diabling Single SEI NAL\n");
> +    }
>      return check_failed;
>  }
>
> @@ -1528,6 +1538,7 @@
>      TOOLOPT(!param->bSaoNonDeblocked && param->bEnableSAO, "sao");
>      TOOLOPT(param->rc.bStatWrite, "stats-write");
>      TOOLOPT(param->rc.bStatRead,  "stats-read");
> +    TOOLOPT(param->bSingleSeiNal, "single-sei");
>  #if ENABLE_HDR10_PLUS
>      TOOLOPT(param->toneMapFile != NULL, "dhdr10-info");
>  #endif
> @@ -1751,6 +1762,7 @@
>      s += sprintf(s, " copy-pic=%d", p->bCopyPicToFrame);
>      s += sprintf(s, " max-ausize-factor=%.1f", p->maxAUSizeFactor);
>      BOOL(p->bDynamicRefine, "dynamic-refine");
> +    BOOL(p->bSingleSeiNal, "single-sei");
>  #undef BOOL
>      return buf;
>  }
> diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
> --- a/source/encoder/encoder.cpp
> +++ b/source/encoder/encoder.cpp
> @@ -2289,26 +2289,26 @@
>      sbacCoder.codePPS(m_pps, (m_param->maxSlices <= 1), m_iPPSQpMinus26);
>      bs.writeByteAlignment();
>      list.serialize(NAL_UNIT_PPS, bs);
> -
> +    if (m_param->bSingleSeiNal)
> +        bs.resetBits();
>      if (m_param->bEmitHDRSEI)
>      {
>          SEIContentLightLevel cllsei;
>          cllsei.max_content_light_level = m_param->maxCLL;
>          cllsei.max_pic_average_light_level = m_param->maxFALL;
> -        bs.resetBits();
> +        if (!m_param->bSingleSeiNal)
> +            bs.resetBits();
>          cllsei.write(bs, m_sps);
> -        bs.writeByteAlignment();
> -        list.serialize(NAL_UNIT_PREFIX_SEI, bs);
> -
> +        cllsei.alignAndSerialize(bs, false, m_param->bSingleSeiNal,
> NAL_UNIT_PREFIX_SEI, list);
>          if (m_param->masteringDisplayColorVolume)
>          {
>              SEIMasteringDisplayColorVolume mdsei;
>              if (mdsei.parse(m_param->masteringDisplayColorVolume))
>              {
> -                bs.resetBits();
> +                if (!m_param->bSingleSeiNal)
> +                    bs.resetBits();
>                  mdsei.write(bs, m_sps);
> -                bs.writeByteAlignment();
> -                list.serialize(NAL_UNIT_PREFIX_SEI, bs);
> +                mdsei.alignAndSerialize(bs, false,
> m_param->bSingleSeiNal, NAL_UNIT_PREFIX_SEI, list);
>              }
>              else
>                  x265_log(m_param, X265_LOG_WARNING, "unable to parse
> mastering display color volume info\n");
> @@ -2328,15 +2328,13 @@
>                      "Copyright 2013-2018 (c) Multicoreware, Inc - "
>                      "http://x265.org - options: %s",
>                      X265_BUILD, PFX(version_str), PFX(build_info_str),
> opts);
> -
> -                bs.resetBits();
> +                if (!m_param->bSingleSeiNal)
> +                    bs.resetBits();
>                  SEIuserDataUnregistered idsei;
>                  idsei.m_userData = (uint8_t*)buffer;
>                  idsei.setSize((uint32_t)strlen(buffer));
>                  idsei.write(bs, m_sps);
> -                bs.writeByteAlignment();
> -                list.serialize(NAL_UNIT_PREFIX_SEI, bs);
> -
> +                idsei.alignAndSerialize(bs, false,
> m_param->bSingleSeiNal, NAL_UNIT_PREFIX_SEI, list);
>                  X265_FREE(buffer);
>              }
>
> @@ -2350,12 +2348,12 @@
>          SEIActiveParameterSets sei;
>          sei.m_selfContainedCvsFlag = true;
>          sei.m_noParamSetUpdateFlag = true;
> -        bs.resetBits();
> +        if (!m_param->bSingleSeiNal)
> +            bs.resetBits();
>          int payloadSize = sei.countPayloadSize(m_sps);
>          sei.setSize(payloadSize);
>          sei.write(bs, m_sps);
> -        bs.writeByteAlignment();
> -        list.serialize(NAL_UNIT_PREFIX_SEI, bs);
> +        sei.alignAndSerialize(bs, false, m_param->bSingleSeiNal,
> NAL_UNIT_PREFIX_SEI, list);
>      }
>  }
>
> diff --git a/source/encoder/frameencoder.cpp
> b/source/encoder/frameencoder.cpp
> --- a/source/encoder/frameencoder.cpp
> +++ b/source/encoder/frameencoder.cpp
> @@ -393,6 +393,7 @@
>       * not repeating headers (since AUD is supposed to be the first NAL
> in the access
>       * unit) */
>      Slice* slice = m_frame->m_encData->m_slice;
> +
>      if (m_param->bEnableAccessUnitDelimiters && (m_frame->m_poc ||
> m_param->bRepeatHeaders))
>      {
>          m_bs.resetBits();
> @@ -400,6 +401,8 @@
>          m_entropyCoder.codeAUD(*slice);
>          m_bs.writeByteAlignment();
>          m_nalList.serialize(NAL_UNIT_ACCESS_UNIT_DELIMITER, m_bs);
> +        if (m_param->bSingleSeiNal)
> +            m_bs.resetBits();
>      }
>      if (m_frame->m_lowres.bKeyframe && m_param->bRepeatHeaders)
>      {
> @@ -527,7 +530,7 @@
>                  }
>
>                  bool isIDR = m_frame->m_lowres.sliceType == X265_TYPE_IDR;
> -                writeSei = payloadChange || isIDR;
> +                writeSei = (payloadChange || isIDR);
>              }
>          }
>      }
> @@ -633,12 +636,12 @@
>              bpSei->m_dpbDelayOffset = 0;
>              // hrdFullness() calculates the initial CPB removal delay and
> offset
>              m_top->m_rateControl->hrdFullness(bpSei);
> -            m_bs.resetBits();
> +            if (!m_param->bSingleSeiNal)
> +                m_bs.resetBits();
>              int payloadSize = bpSei->countPayloadSize(*slice->m_sps);
>              bpSei->setSize(payloadSize);
>              bpSei->write(m_bs, *slice->m_sps);
> -            m_bs.writeByteAlignment();
> -            m_nalList.serialize(NAL_UNIT_PREFIX_SEI, m_bs);
> +            bpSei->alignAndSerialize(m_bs, false, m_param->bSingleSeiNal,
> NAL_UNIT_PREFIX_SEI, m_nalList);
>
>              m_top->m_lastBPSEI = m_rce.encodeOrder;
>          }
> @@ -650,11 +653,11 @@
>              sei.m_recoveryPocCnt = 0;
>              sei.m_exactMatchingFlag = true;
>              sei.m_brokenLinkFlag = false;
> -            m_bs.resetBits();
> +            if (!m_param->bSingleSeiNal)
> +                m_bs.resetBits();
>              sei.setSize(sei.countPayloadSize(*slice->m_sps));
>              sei.write(m_bs, *slice->m_sps);
> -            m_bs.writeByteAlignment();
> -            m_nalList.serialize(NAL_UNIT_PREFIX_SEI, m_bs);
> +            sei.alignAndSerialize(m_bs, false, m_param->bSingleSeiNal,
> NAL_UNIT_PREFIX_SEI, m_nalList);
>          }
>      }
>
> @@ -686,12 +689,12 @@
>              sei->m_auCpbRemovalDelay = X265_MIN(X265_MAX(1,
> m_rce.encodeOrder - prevBPSEI), (1 << hrd->cpbRemovalDelayLength));
>              sei->m_picDpbOutputDelay = slice->m_sps->numReorderPics + poc
> - m_rce.encodeOrder;
>          }
> -        m_bs.resetBits();
> +        if (!m_param->bSingleSeiNal)
> +            m_bs.resetBits();
>          int payloadSize = sei->countPayloadSize(*slice->m_sps);
>          sei->setSize(payloadSize);
>          sei->write(m_bs, *slice->m_sps);
> -        m_bs.writeByteAlignment();
> -        m_nalList.serialize(NAL_UNIT_PREFIX_SEI, m_bs);
> +        sei->alignAndSerialize(m_bs, false, m_param->bSingleSeiNal,
> NAL_UNIT_PREFIX_SEI, m_nalList);
>      }
>
>      /* Write user SEI */
> @@ -702,11 +705,11 @@
>          {
>              SEIuserDataUnregistered sei;
>              sei.m_userData = payload->payload;
> -            m_bs.resetBits();
> +            if (!m_param->bSingleSeiNal)
> +                m_bs.resetBits();
>              sei.setSize(payload->payloadSize);
>              sei.write(m_bs, *slice->m_sps);
> -            m_bs.writeByteAlignment();
> -            m_nalList.serialize(NAL_UNIT_PREFIX_SEI, m_bs);
> +            sei.alignAndSerialize(m_bs, false, m_param->bSingleSeiNal,
> NAL_UNIT_PREFIX_SEI, m_nalList);
>          }
>          else if (payload->payloadType == USER_DATA_REGISTERED_ITU_T_T35)
>          {
> @@ -717,13 +720,21 @@
>                  m_bs.resetBits();
>                  sei.setSize(payload->payloadSize);
>                  sei.write(m_bs, *slice->m_sps);
> -                m_bs.writeByteAlignment();
> -                m_nalList.serialize(NAL_UNIT_PREFIX_SEI, m_bs);
> +                sei.alignAndSerialize(m_bs, true, m_param->bSingleSeiNal,
> NAL_UNIT_PREFIX_SEI, m_nalList);
>              }
>          }
>          else
>              x265_log(m_param, X265_LOG_ERROR, "Unrecognized SEI type\n");
>      }
> +    bool isSei = (m_frame->m_lowres.bKeyframe &&
> +            (m_param->bRepeatHeaders || m_param->bEmitHRDSEI
> +            || !!m_param->interlaceMode || m_param->bEmitIDRRecoverySEI))
> ;
> +
> +    if (isSei && m_param->bSingleSeiNal)
> +    {
> +        m_bs.writeByteAlignment();
> +        m_nalList.serialize(NAL_UNIT_PREFIX_SEI, m_bs);
> +    }
>      /* CQP and CRF (without capped VBV) doesn't use mid-frame statistics
> to
>       * tune RateControl parameters for other frames.
>       * Hence, for these modes, update m_startEndOrder and unlock RC for
> previous threads waiting in
> @@ -1055,7 +1066,8 @@
>
>          m_nalList.serialize(slice->m_nalUnitType, m_bs);
>      }
> -
> +    if (isSei && m_param->bSingleSeiNal)
> +        m_bs.resetBits();
>
>      if (m_param->decodedPictureHashSEI)
>      {
> @@ -1085,8 +1097,7 @@
>          m_bs.resetBits();
>          m_seiReconPictureDigest.setSize(payloadSize);
>          m_seiReconPictureDigest.write(m_bs, *slice->m_sps);
> -        m_bs.writeByteAlignment();
> -        m_nalList.serialize(NAL_UNIT_SUFFIX_SEI, m_bs);
> +        m_seiReconPictureDigest.alignAndSerialize(m_bs, true,
> m_param->bSingleSeiNal, NAL_UNIT_SUFFIX_SEI, m_nalList);
>      }
>
>      uint64_t bytes = 0;
> diff --git a/source/encoder/sei.cpp b/source/encoder/sei.cpp
> --- a/source/encoder/sei.cpp
> +++ b/source/encoder/sei.cpp
> @@ -44,6 +44,15 @@
>      return count;
>  }
>
> +void SEI::alignAndSerialize(Bitstream& bs, int lastSei, int isSingleSei,
> NalUnitType nalUnitType, NALList& list)
> +{
> +    if (lastSei || !isSingleSei)
> +    {
> +        bs.writeByteAlignment();
> +        list.serialize(nalUnitType, bs);
> +    }
> +}
> +
>  /* marshal a single SEI message sei, storing the marshalled representation
>   * in bitstream bs */
>  void SEI::write(Bitstream& bs, const SPS& sps)
> diff --git a/source/encoder/sei.h b/source/encoder/sei.h
> --- a/source/encoder/sei.h
> +++ b/source/encoder/sei.h
> @@ -27,6 +27,7 @@
>  #include "common.h"
>  #include "bitstream.h"
>  #include "slice.h"
> +#include "nal.h"
>
>  namespace X265_NS {
>  // private namespace
> @@ -37,6 +38,7 @@
>      /* SEI users call write() to marshal an SEI to a bitstream.
>       * The write() method calls writeSEI() which encodes the header */
>      void write(Bitstream& bs, const SPS& sps);
> +    void alignAndSerialize(Bitstream& bs, int lastSei, int isSingleSei,
> NalUnitType nalUnitType, NALList& list);
>      int countPayloadSize(const SPS& sps);
>      void setSize(uint32_t size);
>      virtual ~SEI() {}
> diff --git a/source/x265.h b/source/x265.h
> --- a/source/x265.h
> +++ b/source/x265.h
> @@ -1563,6 +1563,9 @@
>
>      /* Dynamically change refine-inter at block level*/
>      int       bDynamicRefine;
> +
> +    /* Enable writing all SEI messgaes in one single NAL instead of mul*/
> +    int       bSingleSeiNal;
>  } x265_param;
>
>  /* x265_param_alloc:
> diff --git a/source/x265cli.h b/source/x265cli.h
> --- a/source/x265cli.h
> +++ b/source/x265cli.h
> @@ -298,6 +298,8 @@
>      { "max-ausize-factor", required_argument, NULL, 0 },
>      { "idr-recovery-sei",     no_argument, NULL, 0 },
>      { "no-idr-recovery-sei",  no_argument, NULL, 0 },
> +    { "single-sei", no_argument, NULL, 0 },
> +    { "no-single-sei", no_argument, NULL, 0 },
>      { 0, 0, 0, 0 },
>      { 0, 0, 0, 0 },
>      { 0, 0, 0, 0 },
>
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
>
Pushed.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20180403/1623a679/attachment-0001.html>


More information about the x265-devel mailing list