[x265] [PATCH MV-HEVC 09/10] Add support for parsing spatial video with side-by-side and top-bottom format
Anusuya Kumarasamy
anusuya.kumarasamy at multicorewareinc.com
Tue Aug 6 10:50:08 UTC 2024
>From c867087e91c890d96380b09b0033ab584a17f247 Mon Sep 17 00:00:00 2001
From: AnusuyaKumarasamy <anusuya.kumarasamy at multicorewareinc.com>
Date: Tue, 30 Jul 2024 15:29:14 +0530
Subject: [PATCH] Add support for parsing spatial video with side-by-side and
top-bottom format
---
source/abrEncApp.cpp | 12 ++++++++----
source/common/param.cpp | 5 +++++
source/common/picyuv.cpp | 14 ++++++++++----
source/encoder/encoder.cpp | 6 +-----
source/input/input.cpp | 4 ++--
source/input/input.h | 2 +-
source/input/yuv.cpp | 12 ++++++------
source/input/yuv.h | 2 +-
source/x265.h | 2 ++
source/x265cli.cpp | 16 +++++++++-------
source/x265cli.h | 1 +
11 files changed, 46 insertions(+), 30 deletions(-)
diff --git a/source/abrEncApp.cpp b/source/abrEncApp.cpp
index b14db5900..3460dfe78 100644
--- a/source/abrEncApp.cpp
+++ b/source/abrEncApp.cpp
@@ -558,6 +558,7 @@ ret:
pic->planes[1] = srcPic->planes[1];
pic->planes[2] = srcPic->planes[2];
pic->planes[3] = srcPic->planes[3];
+ pic->format = srcPic->format;
if (isAbrLoad)
pic->analysisData = *analysisData;
return true;
@@ -1150,9 +1151,10 @@ ret:
read =
m_parentEnc->m_parent->m_picIdxReadCnt[m_id][writeIdx].waitForChange(read);
}
- for (int view = 0; view < m_parentEnc->m_param->numViews;
view++)
+ for (int view = 0; view < m_parentEnc->m_param->numViews -
!!m_parentEnc->m_param->format; view++)
{
x265_picture* dest =
m_parentEnc->m_parent->m_inputPicBuffer[view][writeIdx];
+ src->format = m_parentEnc->m_param->format;
if (m_input[view]->readPicture(*src))
{
dest->poc = src->poc;
@@ -1169,20 +1171,22 @@ ret:
dest->stride[0] = src->stride[0];
dest->stride[1] = src->stride[1];
dest->stride[2] = src->stride[2];
+ dest->format = src->format;
if (!dest->planes[0])
dest->planes[0] = X265_MALLOC(char,
dest->framesize);
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]);
+ int height = (src->height * (src->format == 2 ? 2 :
1));
+ dest->planes[1] = (char*)dest->planes[0] +
src->stride[0] * height;
+ dest->planes[2] = (char*)dest->planes[1] +
src->stride[1] * (height >> x265_cli_csps[src->colorSpace].height[1]);
#if ENABLE_ALPHA
if (m_parentEnc->m_param->numScalableLayers > 1)
{
dest->planes[3] = (char*)dest->planes[2] +
src->stride[2] * (src->height >> x265_cli_csps[src->colorSpace].height[2]);
}
#endif
- if (view == m_parentEnc->m_param->numViews - 1)
+ if (view == m_parentEnc->m_param->numViews - 1 -
!!m_parentEnc->m_param->format)
m_parentEnc->m_parent->m_picWriteCnt[m_id].incr();
}
else
diff --git a/source/common/param.cpp b/source/common/param.cpp
index 8b7d268d2..c310a7b4c 100755
--- a/source/common/param.cpp
+++ b/source/common/param.cpp
@@ -406,6 +406,7 @@ void x265_param_default(x265_param* param)
/* Multi-View Encoding*/
param->numViews = 1;
+ param->format = 1;
param->numLayers = 1;
}
@@ -1464,6 +1465,8 @@ int x265_param_parse(x265_param* p, const char* name,
const char* value)
}
#endif
#if ENABLE_MULTIVIEW
+ OPT("format")
+ p->format = atoi(value);
OPT("num-views")
{
p->numViews = atoi(value);
@@ -2389,6 +2392,7 @@ char *x265_param2string(x265_param* p, int padx, int
pady)
#endif
#if ENABLE_MULTIVIEW
s += sprintf(s, " num-views=%d", p->numViews);
+ s += sprintf(s, " format=%d", p->format);
#endif
BOOL(p->bEnableSBRC, "sbrc");
#undef BOOL
@@ -2917,6 +2921,7 @@ void x265_copy_params(x265_param* dst, x265_param*
src)
#endif
#if ENABLE_MULTIVIEW
dst->numViews = src->numViews;
+ dst->format = src->format;
#endif
dst->numLayers = src->numLayers;
diff --git a/source/common/picyuv.cpp b/source/common/picyuv.cpp
index bd5690d3e..e4911b19a 100644
--- a/source/common/picyuv.cpp
+++ b/source/common/picyuv.cpp
@@ -321,10 +321,13 @@ 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
{
- if (isBase)
+ if (isBase || param.numViews > 1)
{
+ int offsetX, offsetY;
+ offsetX = (!isBase && pic.format == 1 ? width : 0);
+ offsetY = (!isBase && pic.format == 2 ? width * height :
0);
pixel *yPixel = m_picOrg[0];
- uint8_t *yChar = (uint8_t*)pic.planes[0];
+ uint8_t* yChar = (uint8_t*)pic.planes[0] + offsetX +
offsetY;
for (int r = 0; r < height; r++)
{
@@ -336,11 +339,14 @@ void PicYuv::copyFromPicture(const x265_picture& pic,
const x265_param& param, i
if (param.internalCsp != X265_CSP_I400)
{
+ offsetX = offsetX >> m_hChromaShift;
+ offsetY = offsetY >> (m_hChromaShift * 2);
+
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];
+ uint8_t* uChar = (uint8_t*)pic.planes[1] + offsetX +
offsetY;
+ uint8_t* vChar = (uint8_t*)pic.planes[2] + offsetX +
offsetY;
for (int r = 0; r < height >> m_vChromaShift; r++)
{
diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
index 7f4e4b3eb..5fb822c8a 100644
--- a/source/encoder/encoder.cpp
+++ b/source/encoder/encoder.cpp
@@ -1701,11 +1701,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture** pic_out)
}
/* Copy input picture into a Frame and PicYuv, send to
lookahead */
-#if ENABLE_ALPHA
- inFrame[layer]->m_fencPic->copyFromPicture(*inputPic[layer],
*m_param, m_sps.conformanceWindow.rightOffset,
m_sps.conformanceWindow.bottomOffset, !layer);
-#else
- inFrame[layer]->m_fencPic->copyFromPicture(*inputPic[layer],
*m_param, m_sps.conformanceWindow.rightOffset,
m_sps.conformanceWindow.bottomOffset);
-#endif
+
inFrame[layer]->m_fencPic->copyFromPicture(*inputPic[!m_param->format ?
layer : 0], *m_param, m_sps.conformanceWindow.rightOffset,
m_sps.conformanceWindow.bottomOffset, !layer);
inFrame[layer]->m_poc = (!layer) ? (++m_pocLast) : m_pocLast;
inFrame[layer]->m_userData = inputPic[0]->userData;
diff --git a/source/input/input.cpp b/source/input/input.cpp
index 889c0ba5e..43734c978 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, bool alpha)
+InputFile* InputFile::open(InputFileInfo& info, bool bForceY4m, bool
alpha, int format)
{
const char * s = strrchr(info.filename, '.');
if (bForceY4m || (s && !strcmp(s, ".y4m")))
return new Y4MInput(info, alpha);
else
- return new YUVInput(info, alpha);
+ return new YUVInput(info, alpha, format);
}
diff --git a/source/input/input.h b/source/input/input.h
index 96a5734c6..8836eb9bf 100644
--- a/source/input/input.h
+++ b/source/input/input.h
@@ -66,7 +66,7 @@ public:
InputFile() {}
- static InputFile* open(InputFileInfo& info, bool bForceY4m, bool
alpha);
+ static InputFile* open(InputFileInfo& info, bool bForceY4m, bool
alpha, int format);
virtual void startReader() = 0;
diff --git a/source/input/yuv.cpp b/source/input/yuv.cpp
index 878075ec8..65d696c48 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, bool alpha)
+YUVInput::YUVInput(InputFileInfo& info, bool alpha, int format)
{
for (int i = 0; i < QUEUE_SIZE; i++)
buf[i] = NULL;
@@ -57,8 +57,8 @@ YUVInput::YUVInput(InputFileInfo& info, bool alpha)
framesize = 0;
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];
+ int32_t w = (width * (format == 1 ? 2 : 1)) >>
x265_cli_csps[colorSpace].width[i];
+ uint32_t h = (height * (format == 2 ? 2 : 1)) >>
x265_cli_csps[colorSpace].height[i];
framesize += w * h * pixelbytes;
}
@@ -206,12 +206,12 @@ bool YUVInput::readPicture(x265_picture& pic)
pic.framesize = framesize;
pic.height = height;
pic.width = width;
- pic.stride[0] = width * pixelbytes;
+ pic.stride[0] = width * pixelbytes * (pic.format == 1 ? 2 : 1);
pic.stride[1] = pic.stride[0] >>
x265_cli_csps[colorSpace].width[1];
pic.stride[2] = pic.stride[0] >>
x265_cli_csps[colorSpace].width[2];
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]);
+ pic.planes[1] = (char*)pic.planes[0] + pic.stride[0] * (height *
(pic.format == 2 ? 2 : 1));
+ pic.planes[2] = (char*)pic.planes[1] + pic.stride[1] * ((height *
(pic.format == 2 ? 2 : 1)) >> x265_cli_csps[colorSpace].height[1]);
#if ENABLE_ALPHA
if (alphaAvailable)
{
diff --git a/source/input/yuv.h b/source/input/yuv.h
index 2c104a4cc..8cab97d74 100644
--- a/source/input/yuv.h
+++ b/source/input/yuv.h
@@ -63,7 +63,7 @@ protected:
public:
- YUVInput(InputFileInfo& info, bool alpha);
+ YUVInput(InputFileInfo& info, bool alpha, int format);
virtual ~YUVInput();
void release();
diff --git a/source/x265.h b/source/x265.h
index 1b685e3c1..fb06372af 100644
--- a/source/x265.h
+++ b/source/x265.h
@@ -494,6 +494,7 @@ typedef struct x265_picture
int width;
int layerID;
+ int format;
} x265_picture;
typedef enum
@@ -2304,6 +2305,7 @@ typedef struct x265_param
/*Multi View Encoding*/
int numViews;
+ int format;
int numLayers;
} x265_param;
diff --git a/source/x265cli.cpp b/source/x265cli.cpp
index cd42a3bfa..c0c70b78b 100755
--- a/source/x265cli.cpp
+++ b/source/x265cli.cpp
@@ -379,6 +379,7 @@ namespace X265_NS {
#endif
#if ENABLE_MULTIVIEW
H0(" --num-views Number of Views for Multiview
Encoding. Default %d\n", param->numViews);
+ H0(" --format Format of the input video 0 :
normal, 1 : side-by-side, 2 : over-under Default %d\n", param->format);
H0(" --multiview-config Configuration file for
Multiview Encoding\n");
#endif
#ifdef SVT_HEVC
@@ -864,7 +865,7 @@ namespace X265_NS {
}
#endif
InputFileInfo info[MAX_VIEWS];
- for (int i = 0; i < param->numViews; i++)
+ for (int i = 0; i < param->numViews - !!param->format; i++)
{
info[i].filename = inputfn[i];
info[i].depth = inputBitDepth;
@@ -879,7 +880,7 @@ namespace X265_NS {
info[i].frameCount = 0;
getParamAspectRatio(param, info[i].sarWidth,
info[i].sarHeight);
- this->input[i] = InputFile::open(info[i], this->bForceY4m,
param->numScalableLayers > 1);
+ this->input[i] = InputFile::open(info[i], this->bForceY4m,
param->numScalableLayers > 1, param->format);
if (!this->input[i] || this->input[i]->isFail())
{
x265_log_file(param, X265_LOG_ERROR, "unable to open input
file <%s>\n", inputfn[i]);
@@ -957,11 +958,11 @@ namespace X265_NS {
else
sprintf(buf + p, " frames %u - %d of %d", this->seek,
this->seek + this->framesToBeEncoded - 1, info[0].frameCount);
- for (int view = 0; view < param->numViews; view++)
+ for (int view = 0; view < param->numViews - !!param->format;
view++)
general_log(param, input[view]->getName(), X265_LOG_INFO,
"%s\n", buf);
}
- for (int view = 0; view < param->numViews; view++)
+ for (int view = 0; view < param->numViews - !!param->format;
view++)
this->input[view]->startReader();
if (reconfn[0])
@@ -982,7 +983,7 @@ namespace X265_NS {
}
}
#endif
- for (int i = 0; i < param->numLayers; i++)
+ for (int i = 0; i < param->numLayers - !!param->format; i++)
{
this->recon[i] = ReconFile::open(reconfn[i],
param->sourceWidth, param->sourceHeight, reconFileBitDepth,
param->fpsNum, param->fpsDenom, param->internalCsp,
param->sourceBitDepth);
@@ -1387,6 +1388,7 @@ namespace X265_NS {
#define OPT(STR) else if (!strcmp(name, STR))
if (0);
OPT("num-views") param->numViews = x265_atoi(optarg,
bError);
+ OPT("format") param->format = x265_atoi(optarg,
bError);
if (param->numViews > 1)
{
if (0);
@@ -1419,9 +1421,9 @@ namespace X265_NS {
}
linenum++;
}
- if (numInput != param->numViews)
+ if (numInput != (param->format ? 1 : param->numViews))
{
- x265_log(NULL, X265_LOG_WARNING, "Input file missing for given
number of views<%d>\n", param->numViews);
+ x265_log(NULL, X265_LOG_WARNING, "Number of Input files does
not match with the given format <%d>\n", param->format);
if (api)
api->param_free(param);
exit(1);
diff --git a/source/x265cli.h b/source/x265cli.h
index 49a88d084..7ae9877d7 100644
--- a/source/x265cli.h
+++ b/source/x265cli.h
@@ -364,6 +364,7 @@ static const struct option long_options[] =
#if ENABLE_MULTIVIEW
{ "num-views", required_argument, NULL, 0 },
{ "multiview-config", required_argument, NULL, 0 },
+ { "format", required_argument, NULL, 0 },
#endif
#ifdef SVT_HEVC
{ "svt", no_argument, NULL, 0 },
--
2.36.0.windows.1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240806/96af8d92/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0009-Add-support-for-parsing-spatial-video-with-side-by-s.patch
Type: application/x-patch
Size: 14996 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240806/96af8d92/attachment-0001.bin>
More information about the x265-devel
mailing list