[x265] [PATCH] Add CLI option to enable or disable picture copy to internal frame buffer

kavitha at multicorewareinc.com kavitha at multicorewareinc.com
Tue Nov 14 11:11:04 CET 2017


# HG changeset patch
# User Kavitha Sampath <kavitha at multicorewareinc.com>
# Date 1510637409 -19800
#      Tue Nov 14 11:00:09 2017 +0530
# Node ID dd9772385d152528201d335efbc6f75fdc43b08c
# Parent  6ac1b12bcde91b691ef1de8bb936e23c0f29b6ff
Add CLI option to enable or disable picture copy to internal frame buffer

diff -r 6ac1b12bcde9 -r dd9772385d15 doc/reST/cli.rst
--- a/doc/reST/cli.rst	Fri Nov 10 19:02:48 2017 +0530
+++ b/doc/reST/cli.rst	Tue Nov 14 11:00:09 2017 +0530
@@ -399,6 +399,18 @@
 
 	Default: 1 slice per frame. **Experimental feature**
 
+.. option:: --copy-pic, --no-copy-pic
+
+	Allow encoder to copy input x265 pictures to internal frame buffers. When disabled,
+	x265 will not make an internal copy of the input picture and will work with the
+	application's buffers. While this allows for deeper integration, it is the responsbility
+	of the application to (a) ensure that the allocated picture has extra space for padding
+	that will be done by the library, and (b) the buffers aren't recycled until the library
+	has completed encoding this frame (which can be figured out by tracking NALs output by x265)
+
+	Default: enabled
+
+
 Input/Output File Options
 =========================
 
diff -r 6ac1b12bcde9 -r dd9772385d15 source/CMakeLists.txt
--- a/source/CMakeLists.txt	Fri Nov 10 19:02:48 2017 +0530
+++ b/source/CMakeLists.txt	Tue Nov 14 11:00:09 2017 +0530
@@ -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 144)
+set(X265_BUILD 145)
 configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
                "${PROJECT_BINARY_DIR}/x265.def")
 configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
diff -r 6ac1b12bcde9 -r dd9772385d15 source/common/frame.cpp
--- a/source/common/frame.cpp	Fri Nov 10 19:02:48 2017 +0530
+++ b/source/common/frame.cpp	Tue Nov 14 11:00:09 2017 +0530
@@ -85,7 +85,7 @@
         m_analysis2Pass.analysisFramedata = NULL;
     }
 
-    if (m_fencPic->create(param) && m_lowres.create(m_fencPic, param->bframes, !!param->rc.aqMode || !!param->bAQMotion, param->rc.qgSize))
+    if (m_fencPic->create(param, !!m_param->bCopyPicToFrame) && m_lowres.create(m_fencPic, param->bframes, !!param->rc.aqMode || !!param->bAQMotion, param->rc.qgSize))
     {
         X265_CHECK((m_reconColCount == NULL), "m_reconColCount was initialized");
         m_numRows = (m_fencPic->m_picHeight + param->maxCUSize - 1)  / param->maxCUSize;
@@ -158,7 +158,8 @@
 
     if (m_fencPic)
     {
-        m_fencPic->destroy();
+        if (m_param->bCopyPicToFrame)
+            m_fencPic->destroy();
         delete m_fencPic;
         m_fencPic = NULL;
     }
diff -r 6ac1b12bcde9 -r dd9772385d15 source/common/param.cpp
--- a/source/common/param.cpp	Fri Nov 10 19:02:48 2017 +0530
+++ b/source/common/param.cpp	Tue Nov 14 11:00:09 2017 +0530
@@ -290,6 +290,7 @@
     param->csvfpt = NULL;
     param->forceFlush = 0;
     param->bDisableLookahead = 0;
+    param->bCopyPicToFrame = 1;
 
     /* DCT Approximations */
     param->bLowPassDct = 0;
@@ -987,6 +988,7 @@
 		OPT("lowpass-dct") p->bLowPassDct = atobool(value);
         OPT("vbv-end") p->vbvBufferEnd = atof(value);
         OPT("vbv-end-fr-adj") p->vbvEndFrameAdjust = atof(value);
+        OPT("copy-pic") p->bCopyPicToFrame = atobool(value);
         OPT("refine-mv-type")
         {
             if (strcmp(strdup(value), "avc") == 0)
@@ -1718,6 +1720,7 @@
     s += sprintf(s, " ctu-info=%d", p->bCTUInfo);
     BOOL(p->bLowPassDct, "lowpass-dct");
     s += sprintf(s, " refine-mv-type=%d", p->bMVType);
+    s += sprintf(s, " copy-pic=%d", p->bCopyPicToFrame);
 #undef BOOL
     return buf;
 }
diff -r 6ac1b12bcde9 -r dd9772385d15 source/common/picyuv.cpp
--- a/source/common/picyuv.cpp	Fri Nov 10 19:02:48 2017 +0530
+++ b/source/common/picyuv.cpp	Tue Nov 14 11:00:09 2017 +0530
@@ -69,7 +69,7 @@
     m_vChromaShift = 0;
 }
 
-bool PicYuv::create(x265_param* param, pixel *pixelbuf)
+bool PicYuv::create(x265_param* param, bool picAlloc, pixel *pixelbuf)
 {
     m_param = param;
     uint32_t picWidth = m_param->sourceWidth;
@@ -93,8 +93,11 @@
         m_picOrg[0] = pixelbuf;
     else
     {
-        CHECKED_MALLOC(m_picBuf[0], pixel, m_stride * (maxHeight + (m_lumaMarginY * 2)));
-        m_picOrg[0] = m_picBuf[0] + m_lumaMarginY * m_stride + m_lumaMarginX;
+        if (picAlloc)
+        {
+            CHECKED_MALLOC(m_picBuf[0], pixel, m_stride * (maxHeight + (m_lumaMarginY * 2)));
+            m_picOrg[0] = m_picBuf[0] + m_lumaMarginY * m_stride + m_lumaMarginX;
+        }
     }
 
     if (picCsp != X265_CSP_I400)
@@ -102,12 +105,14 @@
         m_chromaMarginX = m_lumaMarginX;  // keep 16-byte alignment for chroma CTUs
         m_chromaMarginY = m_lumaMarginY >> m_vChromaShift;
         m_strideC = ((numCuInWidth * m_param->maxCUSize) >> m_hChromaShift) + (m_chromaMarginX * 2);
+        if (picAlloc)
+        {
+            CHECKED_MALLOC(m_picBuf[1], pixel, m_strideC * ((maxHeight >> m_vChromaShift) + (m_chromaMarginY * 2)));
+            CHECKED_MALLOC(m_picBuf[2], pixel, m_strideC * ((maxHeight >> m_vChromaShift) + (m_chromaMarginY * 2)));
 
-        CHECKED_MALLOC(m_picBuf[1], pixel, m_strideC * ((maxHeight >> m_vChromaShift) + (m_chromaMarginY * 2)));
-        CHECKED_MALLOC(m_picBuf[2], pixel, m_strideC * ((maxHeight >> m_vChromaShift) + (m_chromaMarginY * 2)));
-
-        m_picOrg[1] = m_picBuf[1] + m_chromaMarginY * m_strideC + m_chromaMarginX;
-        m_picOrg[2] = m_picBuf[2] + m_chromaMarginY * m_strideC + m_chromaMarginX;
+            m_picOrg[1] = m_picBuf[1] + m_chromaMarginY * m_strideC + m_chromaMarginX;
+            m_picOrg[2] = m_picBuf[2] + m_chromaMarginY * m_strideC + m_chromaMarginX;
+        }
     }
     else
     {
@@ -236,8 +241,10 @@
     uint64_t crSum;
     lumaSum = cbSum = crSum = 0;
 
-    if (pic.bitDepth == 8)
+    if (m_param->bCopyPicToFrame)
     {
+        if (pic.bitDepth == 8)
+        {
 #if (X265_DEPTH > 8)
         {
             pixel *yPixel = m_picOrg[0];
@@ -260,7 +267,7 @@
             }
         }
 #else /* Case for (X265_DEPTH == 8) */
-        // TODO: Does we need this path? may merge into above in future
+            // TODO: Does we need this path? may merge into above in future
         {
             pixel *yPixel = m_picOrg[0];
             uint8_t *yChar = (uint8_t*)pic.planes[0];
@@ -294,47 +301,54 @@
             }
         }
 #endif /* (X265_DEPTH > 8) */
-    }
-    else /* pic.bitDepth > 8 */
-    {
-        /* defensive programming, mask off bits that are supposed to be zero */
-        uint16_t mask = (1 << X265_DEPTH) - 1;
-        int shift = abs(pic.bitDepth - X265_DEPTH);
-        pixel *yPixel = m_picOrg[0];
-
-        uint16_t *yShort = (uint16_t*)pic.planes[0];
-
-        if (pic.bitDepth > X265_DEPTH)
+        }
+        else /* pic.bitDepth > 8 */
         {
-            /* shift right and mask pixels to final size */
-            primitives.planecopy_sp(yShort, pic.stride[0] / sizeof(*yShort), yPixel, m_stride, width, height, shift, mask);
-        }
-        else /* Case for (pic.bitDepth <= X265_DEPTH) */
-        {
-            /* shift left and mask pixels to final size */
-            primitives.planecopy_sp_shl(yShort, pic.stride[0] / sizeof(*yShort), yPixel, m_stride, width, height, shift, mask);
-        }
+            /* defensive programming, mask off bits that are supposed to be zero */
+            uint16_t mask = (1 << X265_DEPTH) - 1;
+            int shift = abs(pic.bitDepth - X265_DEPTH);
+            pixel *yPixel = m_picOrg[0];
 
-        if (param.internalCsp != X265_CSP_I400)
-        {
-            pixel *uPixel = m_picOrg[1];
-            pixel *vPixel = m_picOrg[2];
-
-            uint16_t *uShort = (uint16_t*)pic.planes[1];
-            uint16_t *vShort = (uint16_t*)pic.planes[2];
+            uint16_t *yShort = (uint16_t*)pic.planes[0];
 
             if (pic.bitDepth > X265_DEPTH)
             {
-                primitives.planecopy_sp(uShort, pic.stride[1] / sizeof(*uShort), uPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
-                primitives.planecopy_sp(vShort, pic.stride[2] / sizeof(*vShort), vPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
+                /* shift right and mask pixels to final size */
+                primitives.planecopy_sp(yShort, pic.stride[0] / sizeof(*yShort), yPixel, m_stride, width, height, shift, mask);
             }
             else /* Case for (pic.bitDepth <= X265_DEPTH) */
             {
-                primitives.planecopy_sp_shl(uShort, pic.stride[1] / sizeof(*uShort), uPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
-                primitives.planecopy_sp_shl(vShort, pic.stride[2] / sizeof(*vShort), vPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
+                /* shift left and mask pixels to final size */
+                primitives.planecopy_sp_shl(yShort, pic.stride[0] / sizeof(*yShort), yPixel, m_stride, width, height, shift, mask);
+            }
+
+            if (param.internalCsp != X265_CSP_I400)
+            {
+                pixel *uPixel = m_picOrg[1];
+                pixel *vPixel = m_picOrg[2];
+
+                uint16_t *uShort = (uint16_t*)pic.planes[1];
+                uint16_t *vShort = (uint16_t*)pic.planes[2];
+
+                if (pic.bitDepth > X265_DEPTH)
+                {
+                    primitives.planecopy_sp(uShort, pic.stride[1] / sizeof(*uShort), uPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
+                    primitives.planecopy_sp(vShort, pic.stride[2] / sizeof(*vShort), vPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
+                }
+                else /* Case for (pic.bitDepth <= X265_DEPTH) */
+                {
+                    primitives.planecopy_sp_shl(uShort, pic.stride[1] / sizeof(*uShort), uPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
+                    primitives.planecopy_sp_shl(vShort, pic.stride[2] / sizeof(*vShort), vPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
+                }
             }
         }
     }
+    else
+    {
+        m_picOrg[0] = (pixel*)pic.planes[0];
+        m_picOrg[1] = (pixel*)pic.planes[1];
+        m_picOrg[2] = (pixel*)pic.planes[2];
+    }
 
     pixel *Y = m_picOrg[0];
     pixel *U = m_picOrg[1];
diff -r 6ac1b12bcde9 -r dd9772385d15 source/common/picyuv.h
--- a/source/common/picyuv.h	Fri Nov 10 19:02:48 2017 +0530
+++ b/source/common/picyuv.h	Tue Nov 14 11:00:09 2017 +0530
@@ -76,7 +76,7 @@
 
     PicYuv();
 
-    bool  create(x265_param* param, pixel *pixelbuf = NULL);
+    bool  create(x265_param* param, bool picAlloc = true, pixel *pixelbuf = NULL);
     bool  createOffsets(const SPS& sps);
     void  destroy();
     int   getLumaBufLen(uint32_t picWidth, uint32_t picHeight, uint32_t picCsp);
diff -r 6ac1b12bcde9 -r dd9772385d15 source/x265.h
--- a/source/x265.h	Fri Nov 10 19:02:48 2017 +0530
+++ b/source/x265.h	Tue Nov 14 11:00:09 2017 +0530
@@ -1531,6 +1531,9 @@
 
     /* Reuse MV information obtained through API */
     int       bMVType;
+
+    /* Allow the encoder to have a copy of the planes of x265_picture in Frame */
+    int       bCopyPicToFrame;
 } x265_param;
 
 /* x265_param_alloc:
diff -r 6ac1b12bcde9 -r dd9772385d15 source/x265cli.h
--- a/source/x265cli.h	Fri Nov 10 19:02:48 2017 +0530
+++ b/source/x265cli.h	Tue Nov 14 11:00:09 2017 +0530
@@ -286,6 +286,8 @@
     { "no-splitrd-skip",      no_argument, NULL, 0 },
     { "lowpass-dct",          no_argument, NULL, 0 },
     { "refine-mv-type", required_argument, NULL, 0 },
+    { "copy-pic",             no_argument, NULL, 0 },
+    { "no-copy-pic",          no_argument, NULL, 0 },
     { 0, 0, 0, 0 },
     { 0, 0, 0, 0 },
     { 0, 0, 0, 0 },
@@ -339,6 +341,7 @@
     H0("   --seek <integer>              First frame to encode\n");
     H1("   --[no-]interlace <bff|tff>    Indicate input pictures are interlace fields in temporal order. Default progressive\n");
     H1("   --dither                      Enable dither if downscaling to 8 bit pixels. Default disabled\n");
+    H0("   --[no-]copy-pic               Copy buffers of input picture in frame. Default %s\n", OPT(param->bCopyPicToFrame));
     H0("\nQuality reporting metrics:\n");
     H0("   --[no-]ssim                   Enable reporting SSIM metric scores. Default %s\n", OPT(param->bEnableSsim));
     H0("   --[no-]psnr                   Enable reporting PSNR metric scores. Default %s\n", OPT(param->bEnablePsnr));


More information about the x265-devel mailing list