[x265] [PATCH 4 of 7] api: introduce api to reconfigure encoder param

Steve Borho steve at borho.org
Tue May 5 18:16:43 CEST 2015


On Tue, May 5, 2015 at 10:51 AM,  <aarthi at multicorewareinc.com> wrote:
> # HG changeset patch
> # User Aarthi Thirumalai
> # Date 1427257989 -19800
> #      Wed Mar 25 10:03:09 2015 +0530
> # Node ID 0c09d2320a9283c1a940043132415d82d4976f3f
> # Parent  303a09b9cb9419564804c3b79bca3caa61e07e82
> api: introduce api to reconfigure encoder param
>
> diff -r 303a09b9cb94 -r 0c09d2320a92 doc/reST/api.rst
> --- a/doc/reST/api.rst  Wed Mar 25 11:53:44 2015 +0530
> +++ b/doc/reST/api.rst  Wed Mar 25 10:03:09 2015 +0530
> @@ -173,6 +173,21 @@
>          *      (e.g. filenames) should not be modified by the calling application. */
>         void x265_encoder_parameters(x265_encoder *, x265_param *);
>
> +**x265_encoder_reconfig()** may be used to reconfigure encoder parameters::
> +
> +       /* x265_encoder_reconfig:
> +       *       used to modify encoder parameters.
> +        *      various parameters from x265_param are copied.
> +        *      this takes effect immediately, on whichever frame is encoded next;
> +        *      returns 0 on success, negative on parameter validation error.
> +        *      not all parameters can be changed; see the actual function for a detailed breakdown.
> +        *      since not all parameters can be changed, moving from preset to preset may not always
> +        *      fully copy all relevant parameters, but should still work usably in practice. however,
> +        *      more so than for other presets, many of the speed shortcuts used in ultrafast cannot be
> +        *      switched out of; using reconfig to switch between ultrafast and other presets is not
> +        *      recommended without a more fine-grained breakdown of parameters to take this into account. */
> +       int x265_encoder_reconfig(x265_encoder *, x265_param *);
> +
>  Pictures
>  ========
>
> diff -r 303a09b9cb94 -r 0c09d2320a92 source/CMakeLists.txt
> --- a/source/CMakeLists.txt     Wed Mar 25 11:53:44 2015 +0530
> +++ b/source/CMakeLists.txt     Wed Mar 25 10:03:09 2015 +0530
> @@ -30,7 +30,7 @@
>  mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)
>
>  # X265_BUILD must be incremented each time the public API is changed
> -set(X265_BUILD 57)
> +set(X265_BUILD 58)
>  configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
>                 "${PROJECT_BINARY_DIR}/x265.def")
>  configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
> diff -r 303a09b9cb94 -r 0c09d2320a92 source/encoder/api.cpp
> --- a/source/encoder/api.cpp    Wed Mar 25 11:53:44 2015 +0530
> +++ b/source/encoder/api.cpp    Wed Mar 25 10:03:09 2015 +0530
> @@ -123,6 +123,24 @@
>  }
>
>  extern "C"
> +int x265_encoder_reconfig(x265_encoder *enc, x265_param *param_in)
> +{
> +    if (!enc || !param_in)
> +        return -1;
> +
> +    Encoder *encoder = static_cast<Encoder*>(enc);
> +    x265_param* safe = X265_MALLOC(x265_param, 1);

why malloc 'safe' when it could be a stack allocation?

> +    memcpy(safe, encoder->m_latestParam, sizeof(x265_param));
> +    int ret = encoder->reconfigureParam(encoder->m_latestParam, param_in);
> +    if (!ret)
> +        encoder->m_reconfigured = true;
> +    else

probably deserves a comment that you are recovering the previous
'latest' params if the reconfigure was rejected

> +        memcpy(encoder->m_latestParam, safe, sizeof(x265_param));
> +    X265_FREE(safe);
> +    return ret;
> +}
> +
> +extern "C"
>  int x265_encoder_encode(x265_encoder *enc, x265_nal **pp_nal, uint32_t *pi_nal, x265_picture *pic_in, x265_picture *pic_out)
>  {
>      if (!enc)
> diff -r 303a09b9cb94 -r 0c09d2320a92 source/encoder/encoder.cpp
> --- a/source/encoder/encoder.cpp        Wed Mar 25 11:53:44 2015 +0530
> +++ b/source/encoder/encoder.cpp        Wed Mar 25 10:03:09 2015 +0530
> @@ -58,6 +58,7 @@
>  Encoder::Encoder()
>  {
>      m_aborted = false;
> +    m_reconfigured = false;
>      m_encodedFrameNum = 0;
>      m_pocLast = -1;
>      m_curEncoder = 0;
> @@ -448,7 +449,8 @@
>          if (m_dpb->m_freeList.empty())
>          {
>              inFrame = new Frame;
> -            if (inFrame->create(m_param))
> +            x265_param* p = m_reconfigured? m_latestParam : m_param;
> +            if (inFrame->create(p))
>              {
>                  /* the first PicYuv created is asked to generate the CU and block unit offset
>                   * arrays which are then shared with all subsequent PicYuv (orig and recon)
> @@ -501,6 +503,7 @@
>          inFrame->m_userData  = pic_in->userData;
>          inFrame->m_pts       = pic_in->pts;
>          inFrame->m_forceqp   = pic_in->forceqp;
> +        inFrame->m_param     = m_reconfigured ? m_latestParam : m_param;
>
>          if (m_pocLast == 0)
>              m_firstPts = inFrame->m_pts;
> @@ -732,6 +735,32 @@
>      return ret;
>  }
>
> +int Encoder::reconfigureParam(x265_param* encParam, x265_param* param)
> +{
> +    int width = 0, height = 0;
> +    encParam->maxNumReferences = param->maxNumReferences; // but never uses more refs than initially specified
> +    encParam->bEnableLoopFilter = param->bEnableLoopFilter;
> +    encParam->deblockingFilterTCOffset = param->deblockingFilterTCOffset;
> +    encParam->deblockingFilterBetaOffset = param->deblockingFilterBetaOffset;
> +    encParam->bEnableFastIntra = param->bEnableFastIntra;
> +    encParam->bEnableEarlySkip = param->bEnableEarlySkip;
> +    encParam->bEnableTemporalMvp = param->bEnableTemporalMvp;
> +    /* Scratch buffer prevents me_range from being increased for esa/tesa */
> +    if (param->searchMethod < X265_FULL_SEARCH || param->searchMethod < encParam->searchRange)
> +        encParam->searchRange = param->searchRange;

might be a useful check if we had ESA or TESA

> +    encParam->noiseReductionInter = param->noiseReductionInter;
> +    encParam->noiseReductionIntra = param->noiseReductionIntra;
> +    /* We can't switch out of subme=0 during encoding. */
> +    if (encParam->subpelRefine)
> +        encParam->subpelRefine = param->subpelRefine;
> +    encParam->rdoqLevel = param->psyRdoq;
> +    encParam->rdLevel = param->rdLevel;
> +    encParam->bEnableTSkipFast = param->bEnableTSkipFast;
> +    encParam->psyRd = param->psyRd;
> +    encParam->psyRdoq = param->psyRdoq;
> +    return x265_check_params(encParam);
> +}
> +
>  void EncStats::addPsnr(double psnrY, double psnrU, double psnrV)
>  {
>      m_psnrSumY += psnrY;
> diff -r 303a09b9cb94 -r 0c09d2320a92 source/encoder/encoder.h
> --- a/source/encoder/encoder.h  Wed Mar 25 11:53:44 2015 +0530
> +++ b/source/encoder/encoder.h  Wed Mar 25 10:03:09 2015 +0530
> @@ -132,6 +132,7 @@
>
>      bool               m_bZeroLatency;     // x265_encoder_encode() returns NALs for the input picture, zero lag
>      bool               m_aborted;          // fatal error detected
> +    bool               m_reconfigured;      // reconfigure of encoder detected
>
>      Encoder();
>      ~Encoder() {}
> @@ -142,6 +143,8 @@
>
>      int encode(const x265_picture* pic, x265_picture *pic_out);
>
> +    int reconfigureParam(x265_param* encParam, x265_param* param);
> +
>      void getStreamHeaders(NALList& list, Entropy& sbacCoder, Bitstream& bs);
>
>      void fetchStats(x265_stats* stats, size_t statsSizeBytes);
> diff -r 303a09b9cb94 -r 0c09d2320a92 source/x265.h
> --- a/source/x265.h     Wed Mar 25 11:53:44 2015 +0530
> +++ b/source/x265.h     Wed Mar 25 10:03:09 2015 +0530
> @@ -1245,6 +1245,18 @@
>   *      Once flushing has begun, all subsequent calls must pass pic_in as NULL. */
>  int x265_encoder_encode(x265_encoder *encoder, x265_nal **pp_nal, uint32_t *pi_nal, x265_picture *pic_in, x265_picture *pic_out);
>
> +/* x265_encoder_reconfig:
> + *      various parameters from x265_param are copied.
> + *      this takes effect immediately, on whichever frame is encoded next;
> + *      returns 0 on success, negative on parameter validation error.
> + *      not all parameters can be changed; see the actual function for a detailed breakdown.
> + *      since not all parameters can be changed, moving from preset to preset may not always
> + *      fully copy all relevant parameters, but should still work usably in practice. however,
> + *      more so than for other presets, many of the speed shortcuts used in ultrafast cannot be
> + *      switched out of; using reconfig to switch between ultrafast and other presets is not
> + *      recommended without a more fine-grained breakdown of parameters to take this into account. */
> +int x265_encoder_reconfig(x265_encoder *, x265_param *);
> +
>  /* x265_encoder_get_stats:
>   *       returns encoder statistics */
>  void x265_encoder_get_stats(x265_encoder *encoder, x265_stats *, uint32_t statsSizeBytes);
> _______________________________________________
> 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