[x265] [PATCH 1 of 5] Add API to read CTU Information
Pradeep Ramachandran
pradeep at multicorewareinc.com
Tue May 9 11:22:05 CEST 2017
On Tue, May 9, 2017 at 2:14 PM, <vignesh at multicorewareinc.com> wrote:
> # HG changeset patch
> # User Santhoshini Sekar
> # Date 1493009037 -19800
> # Mon Apr 24 10:13:57 2017 +0530
> # Node ID b5f7b13bf089d09bba8c121e11bdfce824f42e64
> # Parent 7ecd263f6d43966df308d53029a67cfda03bb185
> Add API to read CTU Information
>
> diff -r 7ecd263f6d43 -r b5f7b13bf089 doc/reST/api.rst
> --- a/doc/reST/api.rst Tue May 09 12:43:04 2017 +0530
> +++ b/doc/reST/api.rst Mon Apr 24 10:13:57 2017 +0530
> @@ -193,6 +193,13 @@
> * parameters to take this into account. */
> int x265_encoder_reconfig(x265_encoder *, x265_param *);
>
> +**x265_encoder_ctu_info**
> + /* x265_encoder_ctu_info:
> + * Copy CTU information such as ctu address and ctu partition
> structure of all
> + * CTUs in each frame. The function is invoked only if
> "--ctu-info" is enabled and
> + * the encoder will wait for this copy to complete if enabled.
> + */
> +
> Pictures
> ========
>
> diff -r 7ecd263f6d43 -r b5f7b13bf089 source/common/frame.cpp
> --- a/source/common/frame.cpp Tue May 09 12:43:04 2017 +0530
> +++ b/source/common/frame.cpp Mon Apr 24 10:13:57 2017 +0530
> @@ -48,6 +48,8 @@
> m_rcData = NULL;
> m_encodeStartTime = 0;
> m_reconfigureRc = false;
> + m_ctuInfo = NULL;
> + m_prevCtuInfoChange = NULL;
> }
>
> bool Frame::create(x265_param *param, float* quantOffsets)
> @@ -166,6 +168,23 @@
> delete[] m_userSEI.payloads;
> }
>
> + if (m_ctuInfo)
> + {
> + uint32_t widthInCU = (m_param->sourceWidth + g_maxCUSize - 1) >>
> g_maxLog2CUSize;
> + uint32_t heightInCU = (m_param->sourceHeight + g_maxCUSize - 1)
> >> g_maxLog2CUSize;
> + uint32_t numCUsInFrame = widthInCU * heightInCU;
> + for (uint32_t i = 0; i < numCUsInFrame; i++)
> + {
> + X265_FREE((*m_ctuInfo + i)->ctuInfo);
> + (*m_ctuInfo + i)->ctuInfo = NULL;
> + }
> + X265_FREE(*m_ctuInfo);
> + *m_ctuInfo = NULL;
> + X265_FREE(m_ctuInfo);
> + m_ctuInfo = NULL;
> + X265_FREE(m_prevCtuInfoChange);
> + m_prevCtuInfoChange = NULL;
> + }
> m_lowres.destroy();
> X265_FREE(m_rcData);
> }
> diff -r 7ecd263f6d43 -r b5f7b13bf089 source/common/frame.h
> --- a/source/common/frame.h Tue May 09 12:43:04 2017 +0530
> +++ b/source/common/frame.h Mon Apr 24 10:13:57 2017 +0530
> @@ -107,6 +107,9 @@
> x265_analysis_data m_analysisData;
> x265_analysis_2Pass m_analysis2Pass;
> RcStats* m_rcData;
> + x265_ctu_info_t** m_ctuInfo;
> + Event m_copied;
> + int* m_prevCtuInfoChange;
>
> int64_t m_encodeStartTime;
> Frame();
> diff -r 7ecd263f6d43 -r b5f7b13bf089 source/common/param.cpp
> --- a/source/common/param.cpp Tue May 09 12:43:04 2017 +0530
> +++ b/source/common/param.cpp Mon Apr 24 10:13:57 2017 +0530
> @@ -275,6 +275,7 @@
>
> param->toneMapFile = NULL;
> param->bDhdr10opt = 0;
> + param->bCTUInfo = 0;
> }
>
> int x265_param_default_preset(x265_param* param, const char* preset,
> const char* tune)
> @@ -954,6 +955,7 @@
> OPT("limit-sao") p->bLimitSAO = atobool(value);
> OPT("dhdr10-info") p->toneMapFile = strdup(value);
> OPT("dhdr10-opt") p->bDhdr10opt = atobool(value);
> + OPT("ctu-info") p->bCTUInfo = atoi(value);
> else
> return X265_PARAM_BAD_NAME;
> }
> @@ -1457,6 +1459,7 @@
> TOOLOPT(param->bEnableStrongIntraSmoothing,
> "strong-intra-smoothing");
> TOOLVAL(param->lookaheadSlices, "lslices=%d");
> TOOLVAL(param->lookaheadThreads, "lthreads=%d")
> + TOOLVAL(param->bCTUInfo, "ctu-info=%d");
> if (param->maxSlices > 1)
> TOOLVAL(param->maxSlices, "slices=%d");
> if (param->bEnableLoopFilter)
> @@ -1670,6 +1673,7 @@
> BOOL(p->bDhdr10opt, "dhdr10-opt");
> s += sprintf(s, " refine-level=%d", p->analysisRefineLevel);
> BOOL(p->bLimitSAO, "limit-sao");
> + s += sprintf(s, " ctu-info=%d", p->bCTUInfo);
> #undef BOOL
> return buf;
> }
> diff -r 7ecd263f6d43 -r b5f7b13bf089 source/encoder/api.cpp
> --- a/source/encoder/api.cpp Tue May 09 12:43:04 2017 +0530
> +++ b/source/encoder/api.cpp Mon Apr 24 10:13:57 2017 +0530
> @@ -296,6 +296,15 @@
> return 0;
> }
>
> +int x265_encoder_ctu_info(x265_encoder *enc, int poc, x265_ctu_info_t**
> ctu)
> +{
> + if (!ctu || !enc)
> + return -1;
> + Encoder* encoder = static_cast<Encoder*>(enc);
> + encoder->copyCtuInfo(ctu, poc);
> + return 0;
> +}
> +
> void x265_cleanup(void)
> {
> if (!g_ctuSizeConfigured)
> @@ -372,6 +381,7 @@
>
> sizeof(x265_frame_stats),
> &x265_encoder_intra_refresh,
> + &x265_encoder_ctu_info,
> };
>
>
Since api is now changing, the BUILD_NUMBER in CMakeLists.txt should be
incremented.
> typedef const x265_api* (*api_get_func)(int bitDepth);
> diff -r 7ecd263f6d43 -r b5f7b13bf089 source/encoder/dpb.cpp
> --- a/source/encoder/dpb.cpp Tue May 09 12:43:04 2017 +0530
> +++ b/source/encoder/dpb.cpp Mon Apr 24 10:13:57 2017 +0530
> @@ -105,6 +105,23 @@
> }
> }
>
> + if (curFrame->m_ctuInfo != NULL)
> + {
> + uint32_t widthInCU = (curFrame->m_param->sourceWidth +
> g_maxCUSize - 1) >> g_maxLog2CUSize;
> + uint32_t heightInCU = (curFrame->m_param->sourceHeight +
> g_maxCUSize - 1) >> g_maxLog2CUSize;
> + uint32_t numCUsInFrame = widthInCU * heightInCU;
> + for (uint32_t i = 0; i < numCUsInFrame; i++)
> + {
> + X265_FREE((*curFrame->m_ctuInfo + i)->ctuInfo);
> + (*curFrame->m_ctuInfo + i)->ctuInfo = NULL;
> + }
> + X265_FREE(*curFrame->m_ctuInfo);
> + *(curFrame->m_ctuInfo) = NULL;
> + X265_FREE(curFrame->m_ctuInfo);
> + curFrame->m_ctuInfo = NULL;
> + X265_FREE(curFrame->m_prevCtuInfoChange);
> + curFrame->m_prevCtuInfoChange = NULL;
> + }
> curFrame->m_encData = NULL;
> curFrame->m_reconPic = NULL;
> }
> diff -r 7ecd263f6d43 -r b5f7b13bf089 source/encoder/encoder.cpp
> --- a/source/encoder/encoder.cpp Tue May 09 12:43:04 2017 +0530
> +++ b/source/encoder/encoder.cpp Mon Apr 24 10:13:57 2017 +0530
> @@ -1157,6 +1157,120 @@
> return x265_check_params(encParam);
> }
>
> +void Encoder::copyCtuInfo(x265_ctu_info_t** frameCtuInfo, int poc)
> +{
> + uint32_t widthInCU = (m_param->sourceWidth + g_maxCUSize - 1) >>
> g_maxLog2CUSize;
> + uint32_t heightInCU = (m_param->sourceHeight + g_maxCUSize - 1) >>
> g_maxLog2CUSize;
> + Frame* curFrame;
> + Frame* prevFrame = NULL;
> + int32_t* frameCTU;
> + uint32_t numCUsInFrame = widthInCU * heightInCU;
> + uint32_t maxNum8x8Partitions = 64;
> + bool copied = false;
> + do
> + {
> + curFrame = m_lookahead->m_inputQueue.getPOC(poc);
> + if (!curFrame)
> + curFrame = m_lookahead->m_outputQueue.getPOC(poc);
> +
> + if (poc > 0)
> + {
> + prevFrame = m_lookahead->m_inputQueue.getPOC(poc - 1);
> + if (!prevFrame)
> + prevFrame = m_lookahead->m_outputQueue.getPOC(poc - 1);
> + if (!prevFrame)
> + {
> + FrameEncoder* prevEncoder;
> + for (int i = 0; i < m_param->frameNumThreads; i++)
> + {
> + prevEncoder = m_frameEncoder[i];
> + prevFrame = prevEncoder->m_frame;
> + if (prevFrame && (prevEncoder->m_frame->m_poc == poc
> - 1))
> + {
> + prevFrame = prevEncoder->m_frame;
> + break;
> + }
> + }
> + }
> + }
> + x265_ctu_info_t* ctuTemp, *prevCtuTemp;
> + if (curFrame)
> + {
> + if (!curFrame->m_ctuInfo)
> + CHECKED_MALLOC(curFrame->m_ctuInfo, x265_ctu_info_t*, 1);
> + CHECKED_MALLOC(*curFrame->m_ctuInfo, x265_ctu_info_t,
> numCUsInFrame);
> + CHECKED_MALLOC_ZERO(curFrame->m_prevCtuInfoChange, int,
> numCUsInFrame * maxNum8x8Partitions);
> + for (uint32_t i = 0; i < numCUsInFrame; i++)
> + {
> + ctuTemp = *curFrame->m_ctuInfo + i;
> + CHECKED_MALLOC(frameCTU, int32_t, maxNum8x8Partitions);
> + ctuTemp->ctuInfo = (int32_t*)frameCTU;
> + ctuTemp->ctuAddress = frameCtuInfo[i]->ctuAddress;
> + memcpy(ctuTemp->ctuPartitions, frameCtuInfo[i]->ctuPartitions,
> sizeof(int32_t) * maxNum8x8Partitions);
> + memcpy(ctuTemp->ctuInfo, frameCtuInfo[i]->ctuInfo,
> sizeof(int32_t) * maxNum8x8Partitions);
> + if (prevFrame && curFrame->m_poc > 1)
> + {
> + prevCtuTemp = *prevFrame->m_ctuInfo + i;
> + for (uint32_t j = 0; j < maxNum8x8Partitions; j++)
> + curFrame->m_prevCtuInfoChange[i *
> maxNum8x8Partitions + j] = (*((int32_t *)prevCtuTemp->ctuInfo + j) == 2) ?
> (poc - 1) : prevFrame->m_prevCtuInfoChange[i * maxNum8x8Partitions + j];
> + }
> + }
> + copied = true;
> + curFrame->m_copied.trigger();
> + }
> + else
> + {
> + FrameEncoder* curEncoder;
> + for (int i = 0; i < m_param->frameNumThreads; i++)
> + {
> + curEncoder = m_frameEncoder[i];
> + curFrame = curEncoder->m_frame;
> + if (curFrame)
> + {
> + if (poc == curFrame->m_poc)
> + {
> + if (!curFrame->m_ctuInfo)
> + CHECKED_MALLOC(curFrame->m_ctuInfo,
> x265_ctu_info_t*, 1);
> + CHECKED_MALLOC(*curFrame->m_ctuInfo,
> x265_ctu_info_t, numCUsInFrame);
> + CHECKED_MALLOC_ZERO(curFrame->m_prevCtuInfoChange,
> int, numCUsInFrame * maxNum8x8Partitions);
> + for (uint32_t l = 0; l < numCUsInFrame; l++)
> + {
> + ctuTemp = *curFrame->m_ctuInfo + l;
> + CHECKED_MALLOC(frameCTU, int32_t,
> maxNum8x8Partitions);
> + ctuTemp->ctuInfo = (int32_t*)frameCTU;
> + ctuTemp->ctuAddress =
> frameCtuInfo[l]->ctuAddress;
> + memcpy(ctuTemp->ctuPartitions,
> frameCtuInfo[l]->ctuPartitions, sizeof(int32_t) * maxNum8x8Partitions);
> + memcpy(ctuTemp->ctuInfo,
> frameCtuInfo[l]->ctuInfo, sizeof(int32_t) * maxNum8x8Partitions);
> + if (prevFrame && curFrame->m_poc > 1)
> + {
> + prevCtuTemp = *prevFrame->m_ctuInfo + l;
> + for (uint32_t j = 0; j <
> maxNum8x8Partitions; j++)
> + curFrame->m_prevCtuInfoChange[l *
> maxNum8x8Partitions + j] = (*((int32_t *)prevCtuTemp->ctuInfo + j) ==
> CTU_INFO_CHANGE) ? (poc - 1) : prevFrame->m_prevCtuInfoChange[l *
> maxNum8x8Partitions + j];
> + }
> + }
> + copied = true;
> + curFrame->m_copied.trigger();
> + break;
> + }
> + }
> + }
> + }
> + } while (!copied);
> + return;
> +fail:
> + for (uint32_t i = 0; i < numCUsInFrame; i++)
> + {
> + X265_FREE((*curFrame->m_ctuInfo + i)->ctuInfo);
> + (*curFrame->m_ctuInfo + i)->ctuInfo = NULL;
> + }
> + X265_FREE(*curFrame->m_ctuInfo);
> + *(curFrame->m_ctuInfo) = NULL;
> + X265_FREE(curFrame->m_ctuInfo);
> + curFrame->m_ctuInfo = NULL;
> + X265_FREE(curFrame->m_prevCtuInfoChange);
> + curFrame->m_prevCtuInfoChange = NULL;
> +}
> +
> void EncStats::addPsnr(double psnrY, double psnrU, double psnrV)
> {
> m_psnrSumY += psnrY;
> diff -r 7ecd263f6d43 -r b5f7b13bf089 source/encoder/encoder.h
> --- a/source/encoder/encoder.h Tue May 09 12:43:04 2017 +0530
> +++ b/source/encoder/encoder.h Mon Apr 24 10:13:57 2017 +0530
> @@ -199,6 +199,8 @@
>
> int reconfigureParam(x265_param* encParam, x265_param* param);
>
> + void copyCtuInfo(x265_ctu_info_t** frameCtuInfo, int poc);
> +
> void getStreamHeaders(NALList& list, Entropy& sbacCoder, Bitstream&
> bs);
>
> void fetchStats(x265_stats* stats, size_t statsSizeBytes);
> diff -r 7ecd263f6d43 -r b5f7b13bf089 source/encoder/frameencoder.cpp
> --- a/source/encoder/frameencoder.cpp Tue May 09 12:43:04 2017 +0530
> +++ b/source/encoder/frameencoder.cpp Mon Apr 24 10:13:57 2017 +0530
> @@ -295,6 +295,11 @@
>
> while (m_threadActive)
> {
> + if (m_param->bCTUInfo)
> + {
> + while (!m_frame->m_ctuInfo)
> + m_frame->m_copied.wait();
> + }
> compressFrame();
> m_done.trigger(); /* FrameEncoder::getEncodedPicture() blocks
> for this event */
> m_enable.wait();
> diff -r 7ecd263f6d43 -r b5f7b13bf089 source/x265.h
> --- a/source/x265.h Tue May 09 12:43:04 2017 +0530
> +++ b/source/x265.h Mon Apr 24 10:13:57 2017 +0530
> @@ -161,6 +161,21 @@
> double totalFrameTime;
> } x265_frame_stats;
>
> +typedef struct x265_ctu_info_t
> +{
> + int32_t ctuAddress;
> + int32_t ctuPartitions[64];
> + void* ctuInfo;
> +} x265_ctu_info_t;
> +
> +typedef enum
> +{
> + NO_CTU_INFO = 0,
> + HAS_CTU_INFO = 1,
> + CTU_INFO_CHANGE = 2,
> +}CTUInfo;
> +
> +
> /* Arbitrary User SEI
> * Payload size is in bytes and the payload pointer must be non-NULL.
> * Payload types and syntax can be found in Annex D of the H.265
> Specification.
> @@ -1391,6 +1406,9 @@
> /* Insert tone mapping information only for IDR frames and when the
> * tone mapping information changes. */
> int bDhdr10opt;
> +
> + /* Determine how x265 react to the content information recieved
> through the API */
> + int bCTUInfo;
> } x265_param;
> /* x265_param_alloc:
> * Allocates an x265_param instance. The returned param structure is not
> @@ -1580,6 +1598,12 @@
> * Should not be called during an x265_encoder_encode. */
>
> int x265_encoder_intra_refresh(x265_encoder *);
> +/* x265_encoder_ctu_info:
> + * Copy CTU information such as ctu address and ctu partition
> structure of all
> + * CTUs in each frame. The function is invoked only if "--ctu-info" is
> enabled and
> + * the encoder will wait for this copy to complete if enabled.
> + */
> +int x265_encoder_ctu_info(x265_encoder *, int poc, x265_ctu_info_t**
> ctu);
>
> /* x265_cleanup:
> * release library static allocations, reset configured CTU size */
> @@ -1629,6 +1653,7 @@
>
> int sizeof_frame_stats; /* sizeof(x265_frame_stats) */
> int (*encoder_intra_refresh)(x265_encoder*);
> + int (*encoder_ctu_info)(x265_encoder*, int,
> x265_ctu_info_t**);
> /* add new pointers to the end, or increment X265_MAJOR_VERSION */
> } x265_api;
>
> diff -r 7ecd263f6d43 -r b5f7b13bf089 source/x265cli.h
> --- a/source/x265cli.h Tue May 09 12:43:04 2017 +0530
> +++ b/source/x265cli.h Mon Apr 24 10:13:57 2017 +0530
> @@ -122,6 +122,7 @@
> { "scenecut", required_argument, NULL, 0 },
> { "no-scenecut", no_argument, NULL, 0 },
> { "scenecut-bias", required_argument, NULL, 0 },
> + { "ctu-info", required_argument, NULL, 0 },
> { "intra-refresh", no_argument, NULL, 0 },
> { "rc-lookahead", required_argument, NULL, 0 },
> { "lookahead-slices", required_argument, NULL, 0 },
> @@ -367,6 +368,7 @@
> H1(" --[no-]tskip-fast Enable fast intra transform
> skipping. Default %s\n", OPT(param->bEnableTSkipFast));
> H1(" --nr-intra <integer> An integer value in range of 0
> to 2000, which denotes strength of noise reduction in intra CUs. Default
> 0\n");
> H1(" --nr-inter <integer> An integer value in range of 0
> to 2000, which denotes strength of noise reduction in inter CUs. Default
> 0\n");
> + H0(" --ctu-info <integer> Enable receiving ctu information
> asynchronously and determine reaction to the ctu information. Default 0\n");
>
Need a description of what the various values of ctu-info mean. Should also
add this information to cli.rst so that online docs are up-to-date.
> H0("\nCoding tools:\n");
> H0("-w/--[no-]weightp Enable weighted prediction in P
> slices. Default %s\n", OPT(param->bEnableWeightedPred));
> H0(" --[no-]weightb Enable weighted prediction in B
> slices. Default %s\n", OPT(param->bEnableWeightedBiPred));
> _______________________________________________
> 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/20170509/8d4bd2f1/attachment-0001.html>
More information about the x265-devel
mailing list