[x265] [PATCH Alpha 02/20] Add support for parsing YUVA input
Anusuya Kumarasamy
anusuya.kumarasamy at multicorewareinc.com
Mon Aug 5 10:51:16 UTC 2024
>From bd724606c1d75491b9789aa77ba13b9c999a6c3c Mon Sep 17 00:00:00 2001
From: AnusuyaKumarasamy <anusuya.kumarasamy at multicorewareinc.com>
Date: Tue, 2 Jul 2024 14:47:32 +0530
Subject: [PATCH] Add support for parsing YUVA input
---
source/abrEncApp.cpp | 7 +++++
source/common/picyuv.cpp | 64 +++++++++++++++++++++++++++-----------
source/common/picyuv.h | 2 +-
source/encoder/encoder.cpp | 4 ++-
source/input/input.cpp | 6 ++--
source/input/input.h | 2 +-
source/input/y4m.cpp | 10 ++++--
source/input/y4m.h | 4 ++-
source/input/yuv.cpp | 10 ++++--
source/input/yuv.h | 4 ++-
source/x265.h | 10 +++---
source/x265cli.cpp | 3 +-
12 files changed, 90 insertions(+), 36 deletions(-)
diff --git a/source/abrEncApp.cpp b/source/abrEncApp.cpp
index 94644a1c0..d8b9f8e3b 100644
--- a/source/abrEncApp.cpp
+++ b/source/abrEncApp.cpp
@@ -499,6 +499,7 @@ ret:
pic->planes[0] = srcPic->planes[0];
pic->planes[1] = srcPic->planes[1];
pic->planes[2] = srcPic->planes[2];
+ pic->planes[3] = srcPic->planes[3];
if (isAbrLoad)
pic->analysisData = *analysisData;
return true;
@@ -1097,6 +1098,12 @@ ret:
memcpy(dest->planes[0], src->planes[0], src->framesize *
sizeof(char));
dest->planes[1] = (char*)dest->planes[0] + src->stride[0]
* src->height;
dest->planes[2] = (char*)dest->planes[1] + src->stride[1]
* (src->height >> x265_cli_csps[src->colorSpace].height[1]);
+
+ if (m_parentEnc->m_param->bEnableAlpha)
+ {
+ dest->planes[3] = (char*)dest->planes[2] +
src->stride[2] * (src->height >> x265_cli_csps[src->colorSpace].height[2]);
+ }
+
m_parentEnc->m_parent->m_picWriteCnt[m_id].incr();
}
else
diff --git a/source/common/picyuv.cpp b/source/common/picyuv.cpp
index 58426a613..8e0b44455 100644
--- a/source/common/picyuv.cpp
+++ b/source/common/picyuv.cpp
@@ -258,7 +258,7 @@ void PicYuv::destroy()
/* Copy pixels from an x265_picture into internal PicYuv instance.
* Shift pixels as necessary, mask off bits above X265_DEPTH for safety. */
-void PicYuv::copyFromPicture(const x265_picture& pic, const x265_param&
param, int padx, int pady)
+void PicYuv::copyFromPicture(const x265_picture& pic, const x265_param&
param, int padx, int pady, bool isBase)
{
/* m_picWidth is the width that is being encoded, padx indicates how
many
* of those pixels are padding to reach multiple of MinCU(4) size.
@@ -321,34 +321,62 @@ void PicYuv::copyFromPicture(const x265_picture& pic,
const x265_param& param, i
#else /* Case for (X265_DEPTH == 8) */
// 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];
-
- for (int r = 0; r < height; r++)
+ if (isBase)
{
- memcpy(yPixel, yChar, width * sizeof(pixel));
+ pixel *yPixel = m_picOrg[0];
+ uint8_t *yChar = (uint8_t*)pic.planes[0];
- yPixel += m_stride;
- yChar += pic.stride[0] / sizeof(*yChar);
- }
+ for (int r = 0; r < height; r++)
+ {
+ memcpy(yPixel, yChar, width * sizeof(pixel));
- if (param.internalCsp != X265_CSP_I400)
+ yPixel += m_stride;
+ yChar += pic.stride[0] / sizeof(*yChar);
+ }
+
+ if (param.internalCsp != X265_CSP_I400)
+ {
+ pixel *uPixel = m_picOrg[1];
+ pixel *vPixel = m_picOrg[2];
+
+ uint8_t *uChar = (uint8_t*)pic.planes[1];
+ uint8_t *vChar = (uint8_t*)pic.planes[2];
+
+ for (int r = 0; r < height >> m_vChromaShift; r++)
+ {
+ memcpy(uPixel, uChar, (width >> m_hChromaShift) *
sizeof(pixel));
+ memcpy(vPixel, vChar, (width >> m_hChromaShift) *
sizeof(pixel));
+
+ uPixel += m_strideC;
+ vPixel += m_strideC;
+ uChar += pic.stride[1] / sizeof(*uChar);
+ vChar += pic.stride[2] / sizeof(*vChar);
+ }
+ }
+ }
+ if (!isBase && param.bEnableAlpha)
{
- pixel *uPixel = m_picOrg[1];
- pixel *vPixel = m_picOrg[2];
+ pixel* aPixel = m_picOrg[0];
+ uint8_t* aChar = (uint8_t*)pic.planes[3];
- uint8_t *uChar = (uint8_t*)pic.planes[1];
- uint8_t *vChar = (uint8_t*)pic.planes[2];
+ for (int r = 0; r < height; r++)
+ {
+ memcpy(aPixel, aChar, width * sizeof(pixel));
+
+ aPixel += m_stride;
+ aChar += pic.stride[0] / sizeof(*aChar);
+ }
+
+ pixel* uPixel = m_picOrg[1];
+ pixel* vPixel = m_picOrg[2];
for (int r = 0; r < height >> m_vChromaShift; r++)
{
- memcpy(uPixel, uChar, (width >> m_hChromaShift) *
sizeof(pixel));
- memcpy(vPixel, vChar, (width >> m_hChromaShift) *
sizeof(pixel));
+ memset(uPixel, 128, (width >> m_hChromaShift) *
sizeof(pixel));
+ memset(vPixel, 128, (width >> m_hChromaShift) *
sizeof(pixel));
uPixel += m_strideC;
vPixel += m_strideC;
- uChar += pic.stride[1] / sizeof(*uChar);
- vChar += pic.stride[2] / sizeof(*vChar);
}
}
}
diff --git a/source/common/picyuv.h b/source/common/picyuv.h
index ba448567a..ec9ff69c2 100644
--- a/source/common/picyuv.h
+++ b/source/common/picyuv.h
@@ -83,7 +83,7 @@ public:
void destroy();
int getLumaBufLen(uint32_t picWidth, uint32_t picHeight, uint32_t
picCsp);
- void copyFromPicture(const x265_picture&, const x265_param& param,
int padx, int pady);
+ void copyFromPicture(const x265_picture&, const x265_param& param,
int padx, int pady, bool isBase);
void copyFromFrame(PicYuv* source);
intptr_t getChromaAddrOffset(uint32_t ctuAddr, uint32_t absPartIdx)
const { return m_cuOffsetC[ctuAddr] + m_buOffsetC[absPartIdx]; }
diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
index 0f188e626..dc09be6dc 100644
--- a/source/encoder/encoder.cpp
+++ b/source/encoder/encoder.cpp
@@ -1359,6 +1359,8 @@ void Encoder::copyPicture(x265_picture *dest, const
x265_picture *src)
memcpy(dest->planes[0], src->planes[0], src->framesize * sizeof(char));
dest->planes[1] = (char*)dest->planes[0] + src->stride[0] *
src->height;
dest->planes[2] = (char*)dest->planes[1] + src->stride[1] *
(src->height >> x265_cli_csps[src->colorSpace].height[1]);
+ if(m_param->bEnableAlpha)
+ dest->planes[3] = (char*)dest->planes[2] + src->stride[2] *
(src->height >> x265_cli_csps[src->colorSpace].height[2]);
}
bool Encoder::isFilterThisframe(uint8_t sliceTypeConfig, int curSliceType)
@@ -1642,7 +1644,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
}
/* Copy input picture into a Frame and PicYuv, send to lookahead */
- inFrame->m_fencPic->copyFromPicture(*inputPic, *m_param,
m_sps.conformanceWindow.rightOffset, m_sps.conformanceWindow.bottomOffset);
+ inFrame->m_fencPic->copyFromPicture(*inputPic, *m_param,
m_sps.conformanceWindow.rightOffset, m_sps.conformanceWindow.bottomOffset,
true);
inFrame->m_poc = ++m_pocLast;
inFrame->m_userData = inputPic->userData;
diff --git a/source/input/input.cpp b/source/input/input.cpp
index 32264212c..889c0ba5e 100644
--- a/source/input/input.cpp
+++ b/source/input/input.cpp
@@ -27,12 +27,12 @@
using namespace X265_NS;
-InputFile* InputFile::open(InputFileInfo& info, bool bForceY4m)
+InputFile* InputFile::open(InputFileInfo& info, bool bForceY4m, bool alpha)
{
const char * s = strrchr(info.filename, '.');
if (bForceY4m || (s && !strcmp(s, ".y4m")))
- return new Y4MInput(info);
+ return new Y4MInput(info, alpha);
else
- return new YUVInput(info);
+ return new YUVInput(info, alpha);
}
diff --git a/source/input/input.h b/source/input/input.h
index 7a001c9c5..96a5734c6 100644
--- a/source/input/input.h
+++ b/source/input/input.h
@@ -66,7 +66,7 @@ public:
InputFile() {}
- static InputFile* open(InputFileInfo& info, bool bForceY4m);
+ static InputFile* open(InputFileInfo& info, bool bForceY4m, bool
alpha);
virtual void startReader() = 0;
diff --git a/source/input/y4m.cpp b/source/input/y4m.cpp
index bb55b6417..eedbf991c 100644
--- a/source/input/y4m.cpp
+++ b/source/input/y4m.cpp
@@ -40,13 +40,14 @@
using namespace X265_NS;
using namespace std;
static const char header[] = {'F','R','A','M','E'};
-Y4MInput::Y4MInput(InputFileInfo& info)
+Y4MInput::Y4MInput(InputFileInfo& info, bool alpha)
{
for (int i = 0; i < QUEUE_SIZE; i++)
buf[i] = NULL;
threadActive = false;
colorSpace = info.csp;
+ alphaAvailable = alpha;
sarWidth = info.sarWidth;
sarHeight = info.sarHeight;
width = info.width;
@@ -69,7 +70,7 @@ Y4MInput::Y4MInput(InputFileInfo& info)
if (ifs && !ferror(ifs) && parseHeader())
{
int pixelbytes = depth > 8 ? 2 : 1;
- for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)
+ for (int i = 0; i < x265_cli_csps[colorSpace].planes +
alphaAvailable; i++)
{
int stride = (width >> x265_cli_csps[colorSpace].width[i]) *
pixelbytes;
framesize += (stride * (height >>
x265_cli_csps[colorSpace].height[i]));
@@ -396,6 +397,11 @@ bool Y4MInput::readPicture(x265_picture& pic)
pic.planes[0] = buf[read % QUEUE_SIZE];
pic.planes[1] = (char*)pic.planes[0] + pic.stride[0] * height;
pic.planes[2] = (char*)pic.planes[1] + pic.stride[1] * (height >>
x265_cli_csps[colorSpace].height[1]);
+ if (alphaAvailable)
+ {
+ pic.stride[3] = pic.stride[0] >>
x265_cli_csps[colorSpace].width[3];
+ pic.planes[3] = (char*)pic.planes[2] + pic.stride[2] * (height
>> x265_cli_csps[colorSpace].height[2]);
+ }
readCount.incr();
return true;
}
diff --git a/source/input/y4m.h b/source/input/y4m.h
index f22938fb6..37992bb66 100644
--- a/source/input/y4m.h
+++ b/source/input/y4m.h
@@ -55,6 +55,8 @@ protected:
int colorSpace;
+ bool alphaAvailable;
+
bool threadActive;
ThreadSafeInteger readCount;
@@ -69,7 +71,7 @@ protected:
public:
- Y4MInput(InputFileInfo& info);
+ Y4MInput(InputFileInfo& info, bool alpha);
virtual ~Y4MInput();
void release();
diff --git a/source/input/yuv.cpp b/source/input/yuv.cpp
index 0856a7217..670dae1ab 100644
--- a/source/input/yuv.cpp
+++ b/source/input/yuv.cpp
@@ -40,7 +40,7 @@
using namespace X265_NS;
using namespace std;
-YUVInput::YUVInput(InputFileInfo& info)
+YUVInput::YUVInput(InputFileInfo& info, bool alpha)
{
for (int i = 0; i < QUEUE_SIZE; i++)
buf[i] = NULL;
@@ -49,12 +49,13 @@ YUVInput::YUVInput(InputFileInfo& info)
width = info.width;
height = info.height;
colorSpace = info.csp;
+ alphaAvailable = alpha;
threadActive = false;
ifs = NULL;
uint32_t pixelbytes = depth > 8 ? 2 : 1;
framesize = 0;
- for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)
+ for (int i = 0; i < x265_cli_csps[colorSpace].planes + alphaAvailable;
i++)
{
uint32_t w = width >> x265_cli_csps[colorSpace].width[i];
uint32_t h = height >> x265_cli_csps[colorSpace].height[i];
@@ -211,6 +212,11 @@ bool YUVInput::readPicture(x265_picture& pic)
pic.planes[0] = buf[read % QUEUE_SIZE];
pic.planes[1] = (char*)pic.planes[0] + pic.stride[0] * height;
pic.planes[2] = (char*)pic.planes[1] + pic.stride[1] * (height >>
x265_cli_csps[colorSpace].height[1]);
+ if (alphaAvailable)
+ {
+ pic.stride[3] = pic.stride[0] >>
x265_cli_csps[colorSpace].width[3];
+ pic.planes[3] = (char*)pic.planes[2] + pic.stride[2] * (height
>> x265_cli_csps[colorSpace].height[2]);
+ }
readCount.incr();
return true;
}
diff --git a/source/input/yuv.h b/source/input/yuv.h
index c5e74f1e9..2c104a4cc 100644
--- a/source/input/yuv.h
+++ b/source/input/yuv.h
@@ -47,6 +47,8 @@ protected:
uint32_t framesize;
+ bool alphaAvailable;
+
bool threadActive;
ThreadSafeInteger readCount;
@@ -61,7 +63,7 @@ protected:
public:
- YUVInput(InputFileInfo& info);
+ YUVInput(InputFileInfo& info, bool alpha);
virtual ~YUVInput();
void release();
diff --git a/source/x265.h b/source/x265.h
index b6e410435..48ec30bc7 100644
--- a/source/x265.h
+++ b/source/x265.h
@@ -410,10 +410,10 @@ typedef struct x265_picture
/* Must be specified on input pictures, the number of planes is
determined
* by the colorSpace value */
- void* planes[3];
+ void* planes[4];
/* Stride is the number of bytes between row starts */
- int stride[3];
+ int stride[4];
/* Must be specified on input pictures. x265_picture_init() will set
it to
* the encoder's internal bit depth, but this field must describe the
depth
@@ -623,13 +623,15 @@ typedef enum
#define X265_MAX_GOP_LENGTH 16
#define MAX_T_LAYERS 7
+#define MAX_SCALABLE_LAYERS 2
+
#define X265_IPRATIO_STRENGTH 1.43
typedef struct x265_cli_csp
{
int planes;
- int width[3];
- int height[3];
+ int width[4];
+ int height[4];
} x265_cli_csp;
static const x265_cli_csp x265_cli_csps[] =
diff --git a/source/x265cli.cpp b/source/x265cli.cpp
index 2f8a150d4..ce7af9533 100755
--- a/source/x265cli.cpp
+++ b/source/x265cli.cpp
@@ -832,8 +832,7 @@ namespace X265_NS {
info.frameCount = 0;
getParamAspectRatio(param, info.sarWidth, info.sarHeight);
-
- this->input = InputFile::open(info, this->bForceY4m);
+ this->input = InputFile::open(info, this->bForceY4m,
param->bEnableAlpha);
if (!this->input || this->input->isFail())
{
x265_log_file(param, X265_LOG_ERROR, "unable to open input
file <%s>\n", inputfn);
--
2.36.0.windows.1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240805/1d197bc9/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-Add-support-for-parsing-YUVA-input.patch
Type: application/octet-stream
Size: 14714 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240805/1d197bc9/attachment-0001.obj>
More information about the x265-devel
mailing list