# HG changeset patch # User Kavitha Sampath <kavi...@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)); _______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel