>From c867087e91c890d96380b09b0033ab584a17f247 Mon Sep 17 00:00:00 2001 From: AnusuyaKumarasamy <anusuya.kumaras...@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
From 5b8bc2a4a625ac4e254e1616e98e7918cbf90170 Mon Sep 17 00:00:00 2001 From: AnusuyaKumarasamy <anusuya.kumarasamy@multicorewareinc.com> Date: Tue, 30 Jul 2024 15:29:14 +0530 Subject: [PATCH 09/10] 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
_______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel