<div dir="ltr">From 011a05a14afa614425c34b18eeabfb4a38851c6c Mon Sep 17 00:00:00 2001<br>From: Mahesh <<a href="mailto:mahesh@multicorewareinc.com">mahesh@multicorewareinc.com</a>><br>Date: Wed, 17 Jan 2024 12:00:35 +0530<br>Subject: [PATCH] cli: add new option --cra-nal<br><br>Force nal type to CRA to all frames expect for the first frame, works only with keyint 1<br>---<br> source/CMakeLists.txt      | 2 +-<br> source/common/param.cpp    | 3 +++<br> source/encoder/dpb.cpp     | 2 +-<br> source/encoder/dpb.h       | 2 ++<br> source/encoder/encoder.cpp | 6 ++++++<br> source/x265.h              | 3 +++<br> source/x265cli.cpp         | 1 +<br> source/x265cli.h           | 1 +<br> 8 files changed, 18 insertions(+), 2 deletions(-)<br><br>diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt<br>index 760ef0a19..ab5ddfeb7 100755<br>--- a/source/CMakeLists.txt<br>+++ b/source/CMakeLists.txt<br>@@ -29,7 +29,7 @@ option(NATIVE_BUILD "Target the build CPU" OFF)<br> option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)<br> mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)<br> # X265_BUILD must be incremented each time the public API is changed<br>-set(X265_BUILD 208)<br>+set(X265_BUILD 209)<br> configure_file("${PROJECT_SOURCE_DIR}/<a href="http://x265.def.in">x265.def.in</a>"<br>                "${PROJECT_BINARY_DIR}/x265.def")<br> configure_file("${PROJECT_SOURCE_DIR}/<a href="http://x265_config.h.in">x265_config.h.in</a>"<br>diff --git a/source/common/param.cpp b/source/common/param.cpp<br>index 1a4df4cdc..e90b08e3b 100755<br>--- a/source/common/param.cpp<br>+++ b/source/common/param.cpp<br>@@ -165,6 +165,7 @@ void x265_param_default(x265_param* param)<br>     param->keyframeMax = 250;<br>     param->gopLookahead = 0;<br>     param->bOpenGOP = 1;<br>+     param->craNal = 0;<br>     param->bframes = 4;<br>     param->lookaheadDepth = 20;<br>     param->bFrameAdaptive = X265_B_ADAPT_TRELLIS;<br>@@ -1284,6 +1285,7 @@ int x265_param_parse(x265_param* p, const char* name, const char* value)<br>         OPT("multi-pass-opt-distortion") p->analysisMultiPassDistortion = atobool(value);<br>         OPT("aq-motion") p->bAQMotion = atobool(value);<br>         OPT("dynamic-rd") p->dynamicRd = atof(value);<br>+          OPT("cra-nal") p->craNal = atobool(value);<br>         OPT("analysis-reuse-level")<br>         {<br>             p->analysisReuseLevel = atoi(value);<br>@@ -2594,6 +2596,7 @@ void x265_copy_params(x265_param* dst, x265_param* src)<br>     dst->decodedPictureHashSEI = src->decodedPictureHashSEI;<br>     dst->bEnableTemporalSubLayers = src->bEnableTemporalSubLayers;<br>     dst->bOpenGOP = src->bOpenGOP;<br>+        dst->craNal = src->craNal;<br>     dst->keyframeMax = src->keyframeMax;<br>     dst->keyframeMin = src->keyframeMin;<br>     dst->bframes = src->bframes;<br>diff --git a/source/encoder/dpb.cpp b/source/encoder/dpb.cpp<br>index 24d3cd202..52ef91af0 100644<br>--- a/source/encoder/dpb.cpp<br>+++ b/source/encoder/dpb.cpp<br>@@ -489,7 +489,7 @@ NalUnitType DPB::getNalUnitType(int curPOC, bool bIsKeyFrame)<br>     if (!curPOC)<br>         return NAL_UNIT_CODED_SLICE_IDR_N_LP;<br>     if (bIsKeyFrame)<br>-        return m_bOpenGOP ? NAL_UNIT_CODED_SLICE_CRA : m_bhasLeadingPicture ? NAL_UNIT_CODED_SLICE_IDR_W_RADL : NAL_UNIT_CODED_SLICE_IDR_N_LP;<br>+        return (m_bOpenGOP || m_craNal) ? NAL_UNIT_CODED_SLICE_CRA : m_bhasLeadingPicture ? NAL_UNIT_CODED_SLICE_IDR_W_RADL : NAL_UNIT_CODED_SLICE_IDR_N_LP;<br>     if (m_pocCRA && curPOC < m_pocCRA)<br>         // All leading pictures are being marked as TFD pictures here since<br>         // current encoder uses all reference pictures while encoding leading<br>diff --git a/source/encoder/dpb.h b/source/encoder/dpb.h<br>index 2cc7df778..a9543fc69 100644<br>--- a/source/encoder/dpb.h<br>+++ b/source/encoder/dpb.h<br>@@ -40,6 +40,7 @@ public:<br>     int                m_lastIDR;<br>     int                m_pocCRA;<br>     int                m_bOpenGOP;<br>+        int                m_craNal;<br>     int                m_bhasLeadingPicture;<br>     bool               m_bRefreshPending;<br>     bool               m_bTemporalSublayer;<br>@@ -66,6 +67,7 @@ public:<br>         m_bRefreshPending = false;<br>         m_frameDataFreeList = NULL;<br>         m_bOpenGOP = param->bOpenGOP;<br>+         m_craNal = param->craNal;<br>         m_bTemporalSublayer = (param->bEnableTemporalSubLayers > 2);<br>     }<br> <br>diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp<br>index 1280ccc66..17bc4046f 100644<br>--- a/source/encoder/encoder.cpp<br>+++ b/source/encoder/encoder.cpp<br>@@ -3662,6 +3662,12 @@ void Encoder::configure(x265_param *p)<br>     if (!p->rdoqLevel)<br>         p->psyRdoq = 0;<br> <br>+    if (p->craNal && p->keyframeMax > 1)<br>+    {<br>+        x265_log_file(NULL, X265_LOG_ERROR, " --cra-nal works only with keyint 1, but given keyint = %s\n", p->keyframeMax);<br>+        m_aborted = true;<br>+    }<br>+<br>     /* Disable features which are not supported by the current RD level */<br>     if (p->rdLevel < 3)<br>     {<br>diff --git a/source/x265.h b/source/x265.h<br>index d2bee6e37..4452526ae 100644<br>--- a/source/x265.h<br>+++ b/source/x265.h<br>@@ -1260,6 +1260,9 @@ typedef struct x265_param<br>      * performance impact, but the use case may preclude it.  Default true */<br>     int       bOpenGOP;<br> <br>+  /*Force nal type to CRA to all frames expect first frame. Default disabled*/<br>+ int       craNal;<br>+<br>     /* Scene cuts closer together than this are coded as I, not IDR. */<br>     int       keyframeMin;<br> <br>diff --git a/source/x265cli.cpp b/source/x265cli.cpp<br>index cbb3be593..840ab22c1 100755<br>--- a/source/x265cli.cpp<br>+++ b/source/x265cli.cpp<br>@@ -166,6 +166,7 @@ namespace X265_NS {<br>         H0("   --rdpenalty <0..2>            penalty for 32x32 intra TU in non-I slices. 0:disabled 1:RD-penalty 2:maximum. Default %d\n", param->rdPenalty);<br>         H0("\nSlice decision options:\n");<br>         H0("   --[no-]open-gop               Enable open-GOP, allows I slices to be non-IDR. Default %s\n", OPT(param->bOpenGOP));<br>+          H0("   --cra-nal                     Force nal type to CRA to all frames expect first frame, works only with keyint 1. Default %s\n", OPT(param->craNal));<br>         H0("-I/--keyint <integer>            Max IDR period in frames. -1 for infinite-gop. Default %d\n", param->keyframeMax);<br>         H0("-i/--min-keyint <integer>        Scenecuts closer together than this are coded as I, not IDR. Default: auto\n");<br>         H0("   --gop-lookahead <integer>     Extends gop boundary if a scenecut is found within this from keyint boundary. Default 0\n");<br>diff --git a/source/x265cli.h b/source/x265cli.h<br>index e937f6d77..b5fe327a6 100644<br>--- a/source/x265cli.h<br>+++ b/source/x265cli.h<br>@@ -135,6 +135,7 @@ static const struct option long_options[] =<br>     { "no-fast-intra",        no_argument, NULL, 0 },<br>     { "no-open-gop",          no_argument, NULL, 0 },<br>     { "open-gop",             no_argument, NULL, 0 },<br>+    { "cra-nal",              no_argument, NULL, 0 },<br>     { "keyint",         required_argument, NULL, 'I' },<br>     { "min-keyint",     required_argument, NULL, 'i' },<br>     { "gop-lookahead",  required_argument, NULL, 0 },<br>-- <br>2.40.0.windows.1<br><br></div>