changeset 12000:b7c8bfabc808 draft

insert SEIRecoveryPoint at IDR frames when --idr-recovery-sei is set
author Aarthi Thirumalai <aarthi@multicorewareinc.com>
date Thu, 08 Mar 2018 15:38:14 +0530
parents 613d9f443769
children 7be938c392b0
files doc/reST/cli.rst source/CMakeLists.txt source/common/param.cpp source/encoder/encoder.cpp source/encoder/frameencoder.cpp source/encoder/sei.h source/x265.h source/x265cli.h
diffstat 8 files changed, 39 insertions(+-), 9 deletions(-) [+]
line wrap: on
line diff
--- a/doc/reST/cli.rst	Mon Mar 05 15:14:34 2018 +0530
+++ b/doc/reST/cli.rst	Thu Mar 08 15:38:14 2018 +0530
@@ -2212,6 +2212,9 @@ Bitstream options
 
 	Only effective at RD levels 5 and 6
 
+.. option:: --idr-recovery-sei, --no-idr-recoveery-sei
+    Emit RecoveryPoint info as sei in bitstream for each IDR frame. Default disabled.
+
 DCT Approximations
 =================
 
--- a/source/CMakeLists.txt	Mon Mar 05 15:14:34 2018 +0530
+++ b/source/CMakeLists.txt	Thu Mar 08 15:38:14 2018 +0530
@@ -29,7 +29,7 @@ option(NATIVE_BUILD "Target the build CP
 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 154)
+set(X265_BUILD 155)
 configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
                "${PROJECT_BINARY_DIR}/x265.def")
 configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
--- a/source/common/param.cpp	Mon Mar 05 15:14:34 2018 +0530
+++ b/source/common/param.cpp	Thu Mar 08 15:38:14 2018 +0530
@@ -133,7 +133,7 @@ void x265_param_default(x265_param* para
     param->bEmitHRDSEI = 0;
     param->bEmitInfoSEI = 1;
     param->bEmitHDRSEI = 0;
-
+    param->bEmitIDRRecoverySEI = 0;
     /* CU definitions */
     param->maxCUSize = 64;
     param->minCUSize = 8;
@@ -982,6 +982,7 @@ int x265_param_parse(x265_param* p, cons
         OPT("limit-sao") p->bLimitSAO = atobool(value);
         OPT("dhdr10-info") p->toneMapFile = strdup(value);
         OPT("dhdr10-opt") p->bDhdr10opt = atobool(value);
+        OPT("idr-recovery-sei") p->bEmitIDRRecoverySEI = atobool(value);
         OPT("const-vbv") p->rc.bEnableConstVbv = atobool(value);
         OPT("ctu-info") p->bCTUInfo = atoi(value);
         OPT("scale-factor") p->scaleFactor = atoi(value);
@@ -1730,6 +1731,7 @@ char *x265_param2string(x265_param* p, i
     BOOL(p->bEmitHDRSEI, "hdr");
     BOOL(p->bHDROpt, "hdr-opt");
     BOOL(p->bDhdr10opt, "dhdr10-opt");
+    BOOL(p->bEmitIDRRecoverySEI, "idr-recovery-sei");
     if (p->analysisSave)
         s += sprintf(s, " analysis-save");
     if (p->analysisLoad)
--- a/source/encoder/encoder.cpp	Mon Mar 05 15:14:34 2018 +0530
+++ b/source/encoder/encoder.cpp	Thu Mar 08 15:38:14 2018 +0530
@@ -2268,7 +2268,7 @@ void Encoder::getStreamHeaders(NALList& 
     list.serialize(NAL_UNIT_SPS, bs);
 
     bs.resetBits();
-    sbacCoder.codePPS( m_pps, (m_param->maxSlices <= 1), m_iPPSQpMinus26);
+    sbacCoder.codePPS(m_pps, (m_param->maxSlices <= 1), m_iPPSQpMinus26);
     bs.writeByteAlignment();
     list.serialize(NAL_UNIT_PPS, bs);
 
@@ -2303,14 +2303,14 @@ void Encoder::getStreamHeaders(NALList& 
         if (opts)
         {
             char *buffer = X265_MALLOC(char, strlen(opts) + strlen(PFX(version_str)) +
-                                             strlen(PFX(build_info_str)) + 200);
+                strlen(PFX(build_info_str)) + 200);
             if (buffer)
             {
                 sprintf(buffer, "x265 (build %d) - %s:%s - H.265/HEVC codec - "
-                        "Copyright 2013-2018 (c) Multicoreware, Inc - "
-                        "http://x265.org - options: %s",
-                        X265_BUILD, PFX(version_str), PFX(build_info_str), opts);
-                
+                    "Copyright 2013-2018 (c) Multicoreware, Inc - "
+                    "http://x265.org - options: %s",
+                    X265_BUILD, PFX(version_str), PFX(build_info_str), opts);
+
                 bs.resetBits();
                 SEIuserDataUnregistered idsei;
                 idsei.m_userData = (uint8_t*)buffer;
--- a/source/encoder/frameencoder.cpp	Mon Mar 05 15:14:34 2018 +0530
+++ b/source/encoder/frameencoder.cpp	Thu Mar 08 15:38:14 2018 +0530
@@ -594,7 +594,6 @@ void FrameEncoder::compressFrame()
 
     /* reset entropy coders and compute slice id */
     m_entropyCoder.load(m_initSliceContext);
-	
     for (uint32_t sliceId = 0; sliceId < m_param->maxSlices; sliceId++)   
         for (uint32_t row = m_sliceBaseRow[sliceId]; row < m_sliceBaseRow[sliceId + 1]; row++)
             m_rows[row].init(m_initSliceContext, sliceId);   
@@ -644,6 +643,19 @@ void FrameEncoder::compressFrame()
 
             m_top->m_lastBPSEI = m_rce.encodeOrder;
         }
+
+        if (m_frame->m_lowres.sliceType == X265_TYPE_IDR && m_param->bEmitIDRRecoverySEI)
+        {
+            /* Recovery Point SEI require the SPS to be "activated" */
+            SEIRecoveryPoint sei;
+            sei.m_recoveryPocCnt = 0;
+            sei.m_exactMatchingFlag = true;
+            sei.m_brokenLinkFlag = false;
+            m_bs.resetBits();
+            sei.write(m_bs, *slice->m_sps);
+            m_bs.writeByteAlignment();
+            m_nalList.serialize(NAL_UNIT_PREFIX_SEI, m_bs);
+        }
     }
 
     if ((m_param->bEmitHRDSEI || !!m_param->interlaceMode))
--- a/source/encoder/sei.h	Mon Mar 05 15:14:34 2018 +0530
+++ b/source/encoder/sei.h	Thu Mar 08 15:38:14 2018 +0530
@@ -253,6 +253,11 @@ public:
 class SEIRecoveryPoint : public SEI
 {
 public:
+    SEIRecoveryPoint()
+    {
+        m_payloadType = RECOVERY_POINT;
+        m_payloadSize = 0;
+    }
     int  m_recoveryPocCnt;
     bool m_exactMatchingFlag;
     bool m_brokenLinkFlag;
--- a/source/x265.h	Mon Mar 05 15:14:34 2018 +0530
+++ b/source/x265.h	Thu Mar 08 15:38:14 2018 +0530
@@ -1557,6 +1557,11 @@ typedef struct x265_param
      * It represents the percentage of maximum AU size used.
      * Default is 1 (which is 100%). Range is 0.5 to 1. */
     double maxAUSizeFactor;
+
+    /* Enables the emission of a Recovery Point SEI with the stream headers
+    * at each IDR frame describing poc of the recovery point, exact matching flag
+    * and broken link flag. Default is disabled. */
+    int       bEmitIDRRecoverySEI;
 } x265_param;
 
 /* x265_param_alloc:
--- a/source/x265cli.h	Mon Mar 05 15:14:34 2018 +0530
+++ b/source/x265cli.h	Thu Mar 08 15:38:14 2018 +0530
@@ -294,6 +294,8 @@ static const struct option long_options[
     { "copy-pic",             no_argument, NULL, 0 },
     { "no-copy-pic",          no_argument, NULL, 0 },
     { "max-ausize-factor", required_argument, NULL, 0 },
+    { "idr-recovery-sei",     no_argument, NULL, 0 },
+    { "no-idr-recovery-sei",  no_argument, NULL, 0 },
     { 0, 0, 0, 0 },
     { 0, 0, 0, 0 },
     { 0, 0, 0, 0 },
@@ -552,6 +554,7 @@ static void showHelp(x265_param *param)
     H0("   --[no-]repeat-headers         Emit SPS and PPS headers at each keyframe. Default %s\n", OPT(param->bRepeatHeaders));
     H0("   --[no-]info                   Emit SEI identifying encoder and parameters. Default %s\n", OPT(param->bEmitInfoSEI));
     H0("   --[no-]hrd                    Enable HRD parameters signaling. Default %s\n", OPT(param->bEmitHRDSEI));
+    H0("   --[no-]idr-recovery-sei      Emit recovery point infor SEI at each IDR frame \n");
     H0("   --[no-]temporal-layers        Enable a temporal sublayer for unreferenced B frames. Default %s\n", OPT(param->bEnableTemporalSubLayers));
     H0("   --[no-]aud                    Emit access unit delimiters at the start of each access unit. Default %s\n", OPT(param->bEnableAccessUnitDelimiters));
     H1("   --hash <integer>              Decoded Picture Hash SEI 0: disabled, 1: MD5, 2: CRC, 3: Checksum. Default %d\n", param->decodedPictureHashSEI);