[x265] [PATCH] encoder:auto-padding to min CU size and set conformance window
Gopu Govindaswamy
gopu at multicorewareinc.com
Tue Oct 22 09:10:22 CEST 2013
# HG changeset patch
# User Gopu Govindaswamy <gopu at multicorewareinc.com>
# Date 1382425812 -19800
# Node ID 857cae26a3544d3c711c22c354f7592b63ec23a9
# Parent 9245a882ccee89fc1d158b501587bac7d6e081e4
encoder:auto-padding to min CU size and set conformance window
diff -r 9245a882ccee -r 857cae26a354 source/Lib/TLibCommon/TComPicYuv.cpp
--- a/source/Lib/TLibCommon/TComPicYuv.cpp Mon Oct 21 22:45:55 2013 -0500
+++ b/source/Lib/TLibCommon/TComPicYuv.cpp Tue Oct 22 12:40:12 2013 +0530
@@ -357,7 +357,7 @@
* Upscale pixels from 8bits to 16 bits when required, but do not modify pixels.
* This new routine is GPL
*/
-void TComPicYuv::copyFromPicture(const x265_picture_t& pic)
+void TComPicYuv::copyFromPicture(const x265_picture_t& pic, int *pad)
{
Pel *Y = getLumaAddr();
Pel *U = getCbAddr();
@@ -367,15 +367,22 @@
uint8_t *u = (uint8_t*)pic.planes[1];
uint8_t *v = (uint8_t*)pic.planes[2];
+ int padx = pad[0];
+ int pady = pad[1];
+
#if HIGH_BIT_DEPTH
if (sizeof(Pel) * 8 > pic.bitDepth)
{
assert(pic.bitDepth == 8);
+ /* width and height - without padsize */
+ int width = m_picWidth - padx;
+ int height = m_picHeight - pady;
+
// Manually copy pixels to up-size them
- for (int r = 0; r < m_picHeight; r++)
+ for (int r = 0; r < height; r++)
{
- for (int c = 0; c < m_picWidth; c++)
+ for (int c = 0; c < width; c++)
{
Y[c] = (Pel)y[c];
}
@@ -384,9 +391,9 @@
y += pic.stride[0];
}
- for (int r = 0; r < m_picHeight >> 1; r++)
+ for (int r = 0; r < height >> 1; r++)
{
- for (int c = 0; c < m_picWidth >> 1; c++)
+ for (int c = 0; c < width >> 1; c++)
{
U[c] = (Pel)u[c];
V[c] = (Pel)v[c];
@@ -397,30 +404,108 @@
u += pic.stride[1];
v += pic.stride[2];
}
+
+ /* Extend the right if width is not multiple of minimum CU size */
+
+ if (padx)
+ {
+ Y = getLumaAddr();
+ U = getCbAddr();
+ V = getCrAddr();
+
+ for (int r = 0; r < height; r++)
+ {
+ for (int x = 0; x < padx; x++)
+ Y[width + x] = Y[width - 1];
+ Y += getStride();
+ }
+
+ for (int r = 0; r < height >> 1; r++)
+ {
+ for (int x = 0; x < padx >> 1; x++)
+ {
+ U[(width >> 1) + x] = U[(width >> 1) - 1];
+ V[(width >> 1) + x] = V[(width >> 1) - 1];
+ }
+ U += getCStride();
+ V += getCStride();
+ }
+ }
+
+ /* extend the bottom if height is not multiple of the minimum CU size */
+ if (pady)
+ {
+ width = m_picWidth;
+ Y = getLumaAddr() + (height - 1) * getStride();
+ U = getCbAddr() + ((height >> 1) - 1) * getCStride();
+ V = getCrAddr() + ((height >> 1) - 1) * getCStride();
+
+ for (uint32_t i = 1; i <= pady; i++)
+ memcpy(Y + i * getStride(), Y, width * sizeof(Pel));
+
+ for (uint32_t j = 1; j <= pady >> 1; j++)
+ {
+ memcpy(U + j * getCStride(), U, (width >> 1) * sizeof(Pel));
+ memcpy(V + j * getCStride(), V, (width >> 1) * sizeof(Pel));
+ }
+ }
}
else
#endif // if HIGH_BIT_DEPTH
{
- int width = m_picWidth * (pic.bitDepth > 8 ? 2 : 1);
+
+ /* width and height - without padsize */
+ int width = (m_picWidth * (pic.bitDepth > 8 ? 2 : 1)) - padx;
+ int height = m_picHeight - pady;
// copy pixels by row into encoder's buffer
- for (int r = 0; r < m_picHeight; r++)
+ for (int r = 0; r < height; r++)
{
memcpy(Y, y, width);
+ /* extend the right if width is not multiple of the minimum CU size */
+ if (padx)
+ ::memset(Y + width, Y[width - 1], padx);
+
Y += getStride();
y += pic.stride[0];
+
}
- for (int r = 0; r < m_picHeight >> 1; r++)
+ for (int r = 0; r < height >> 1; r++)
{
memcpy(U, u, width >> 1);
memcpy(V, v, width >> 1);
+ /* extend the right if width is not multiple of the minimum CU size */
+ if (padx)
+ {
+ ::memset(U + (width >> 1), U[(width >> 1) - 1], padx >> 1);
+ ::memset(V + (width >> 1), V[(width >> 1) - 1], padx >> 1);
+ }
+
U += getCStride();
V += getCStride();
u += pic.stride[1];
v += pic.stride[2];
}
+
+ /* extend the bottom if height is not multiple of the minimum CU size */
+ if (pady)
+ {
+ width = m_picWidth;
+ Y = getLumaAddr() + (height - 1) * getStride();
+ U = getCbAddr() + ((height >> 1) - 1) * getCStride();
+ V = getCrAddr() + ((height >> 1) - 1) * getCStride();
+
+ for (uint32_t i = 1; i <= pady; i++)
+ memcpy(Y + i * getStride(), Y, width * sizeof(pixel));
+
+ for (uint32_t j = 1; j <= pady >> 1; j++)
+ {
+ memcpy(U + j * getCStride(), U, (width >> 1) * sizeof(pixel));
+ memcpy(V + j * getCStride(), V, (width >> 1) * sizeof(pixel));
+ }
+ }
}
}
diff -r 9245a882ccee -r 857cae26a354 source/Lib/TLibCommon/TComPicYuv.h
--- a/source/Lib/TLibCommon/TComPicYuv.h Mon Oct 21 22:45:55 2013 -0500
+++ b/source/Lib/TLibCommon/TComPicYuv.h Tue Oct 22 12:40:12 2013 +0530
@@ -178,7 +178,7 @@
void copyToPicLuma(TComPicYuv* destYuv);
void copyToPicCb(TComPicYuv* destYuv);
void copyToPicCr(TComPicYuv* destYuv);
- void copyFromPicture(const x265_picture_t&);
+ void copyFromPicture(const x265_picture_t&, int *pad);
MotionReference* generateMotionReference(wpScalingParam *w);
diff -r 9245a882ccee -r 857cae26a354 source/common/common.cpp
--- a/source/common/common.cpp Mon Oct 21 22:45:55 2013 -0500
+++ b/source/common/common.cpp Tue Oct 22 12:40:12 2013 +0530
@@ -259,10 +259,6 @@
"Minimum partition width size should be larger than or equal to 8");
CHECK(param->maxCUSize < 16,
"Maximum partition width size should be larger than or equal to 16");
- CHECK((param->sourceWidth % (param->maxCUSize >> (maxCUDepth - 1))) != 0,
- "Resulting coded frame width must be a multiple of the minimum CU size");
- CHECK((param->sourceHeight % (param->maxCUSize >> (maxCUDepth - 1))) != 0,
- "Resulting coded frame height must be a multiple of the minimum CU size");
CHECK((1u << tuQTMaxLog2Size) > param->maxCUSize,
"QuadtreeTULog2MaxSize must be log2(maxCUSize) or smaller.");
diff -r 9245a882ccee -r 857cae26a354 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Mon Oct 21 22:45:55 2013 -0500
+++ b/source/encoder/encoder.cpp Tue Oct 22 12:40:12 2013 +0530
@@ -180,7 +180,7 @@
/* Copy input picture into a TComPic, send to lookahead */
pic->getSlice()->setPOC(++m_pocLast);
- pic->getPicYuvOrg()->copyFromPicture(*pic_in);
+ pic->getPicYuvOrg()->copyFromPicture(*pic_in, m_pad);
pic->m_userData = pic_in->userData;
pic->m_pts = pic_in->pts;
@@ -973,7 +973,7 @@
m_maxNumOffsetsPerPic = 2048;
m_log2ParallelMergeLevelMinus2 = 0;
- //========= set default confirmation window ==================================
+ //========= set default Display window ==================================
m_defaultDisplayWindow.m_enabledFlag = true;
m_defaultDisplayWindow.m_winRightOffset = 0;
m_defaultDisplayWindow.m_winTopOffset = 0;
@@ -981,6 +981,36 @@
m_defaultDisplayWindow.m_winLeftOffset = 0;
m_pad[0] = m_pad[1] = 0;
+ //======== set pad size if width is not multiple of the minimum CU size =========
+ uint32_t maxCUDepth = (uint32_t)g_convertToBit[_param->maxCUSize];
+ uint32_t minCUDepth = (_param->maxCUSize >> (maxCUDepth - 1));
+ if ((_param->sourceWidth % minCUDepth) != 0)
+ {
+ uint32_t padsize = 0;
+ uint32_t rem = _param->sourceWidth % minCUDepth;
+ padsize = minCUDepth - rem;
+ _param->sourceWidth += padsize;
+ m_pad[0] = padsize; //pad width
+
+ /* set the confirmation window offsets */
+ m_conformanceWindow.m_enabledFlag = true;
+ m_conformanceWindow.m_winRightOffset = m_pad[0];
+ }
+
+ //======== set pad size if height is not multiple of the minimum CU size =========
+ if ((_param->sourceHeight % minCUDepth) != 0)
+ {
+ uint32_t padsize = 0;
+ uint32_t rem = _param->sourceHeight % minCUDepth;
+ padsize = minCUDepth - rem;
+ _param->sourceHeight += padsize;
+ m_pad[1] = padsize; //pad height
+
+ /* set the confirmation window offsets */
+ m_conformanceWindow.m_enabledFlag = true;
+ m_conformanceWindow.m_winBottomOffset = m_pad[1];
+ }
+
m_progressiveSourceFlag = true;
m_interlacedSourceFlag = false;
m_nonPackedConstraintFlag = false;
More information about the x265-devel
mailing list