[x265] [PATCH] CEA 608/708 Support
indumathi at multicorewareinc.com
indumathi at multicorewareinc.com
Wed Jun 20 10:43:37 CEST 2018
# HG changeset patch
# User indumathi at multicorewareinc.com
# Date 1528726491 -19800
# Mon Jun 11 19:44:51 2018 +0530
# Node ID e1dd8424a3bd5f9f61f4a73aec6f2aee27591772
# Parent a8a5ccf5aaf7e04e439a216e5c396991c6b76999
CEA 608/708 Support
Parse the SEI messages from text file and insert it into the userSEI with cli option.
diff -r a8a5ccf5aaf7 -r e1dd8424a3bd doc/reST/cli.rst
--- a/doc/reST/cli.rst Wed Jun 13 09:54:27 2018 +0530
+++ b/doc/reST/cli.rst Mon Jun 11 19:44:51 2018 +0530
@@ -2135,6 +2135,12 @@
Maximum luma value allowed for input pictures. Any values above max-luma
are clipped. No default.
+
+.. option:: --usersei-file <filename>
+
+ Text file containing userSEI in POC order : <POC><space><PREFIX><space><NAL UNIT TYPE>/<SEI TYPE><space><SEI Payload>
+ Parse the input file specified and inserts SEI messages into the bitstream.
+ Currently, we support only PREFIX SEI messages. This is an "application-only" feature.
.. option:: --atc-sei <integer>
diff -r a8a5ccf5aaf7 -r e1dd8424a3bd source/CMakeLists.txt
--- a/source/CMakeLists.txt Wed Jun 13 09:54:27 2018 +0530
+++ b/source/CMakeLists.txt Mon Jun 11 19:44:51 2018 +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 161)
+set(X265_BUILD 162)
configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
"${PROJECT_BINARY_DIR}/x265.def")
configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
diff -r a8a5ccf5aaf7 -r e1dd8424a3bd source/common/param.cpp
--- a/source/common/param.cpp Wed Jun 13 09:54:27 2018 +0530
+++ b/source/common/param.cpp Mon Jun 11 19:44:51 2018 +0530
@@ -302,6 +302,7 @@
param->bDisableLookahead = 0;
param->bCopyPicToFrame = 1;
param->maxAUSizeFactor = 1;
+ param->userSeiFile = NULL;
/* DCT Approximations */
param->bLowPassDct = 0;
@@ -1048,6 +1049,7 @@
OPT("pic-struct") p->pictureStructure = atoi(value);
OPT("chunk-start") p->chunkStart = atoi(value);
OPT("chunk-end") p->chunkEnd = atoi(value);
+ OPT("usersei-file") p->userSeiFile = strdup(value);
else
return X265_PARAM_BAD_NAME;
}
diff -r a8a5ccf5aaf7 -r e1dd8424a3bd source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Wed Jun 13 09:54:27 2018 +0530
+++ b/source/encoder/encoder.cpp Mon Jun 11 19:44:51 2018 +0530
@@ -79,6 +79,7 @@
m_threadPool = NULL;
m_analysisFileIn = NULL;
m_analysisFileOut = NULL;
+ m_seiFile = NULL;
m_offsetEmergency = NULL;
m_iFrameNum = 0;
m_iPPSQpMinus26 = 0;
@@ -412,6 +413,20 @@
m_emitCLLSEI = p->maxCLL || p->maxFALL;
+ if (m_param->userSeiFile)
+ {
+ m_seiFile = x265_fopen(m_param->userSeiFile, "r");
+ if (!m_seiFile)
+ {
+ x265_log_file(NULL, X265_LOG_ERROR, "%s file not found or Failed to open\n", m_param->userSeiFile);
+ m_aborted = true;
+ }
+ else
+ m_enableUserSei = 1;
+ }
+ else
+ m_enableUserSei = 0;
+
#if ENABLE_HDR10_PLUS
if (m_bToneMap)
m_numCimInfo = m_hdr10plus_api->hdr10plus_json_to_movie_cim(m_param->toneMapFile, m_cim);
@@ -782,6 +797,8 @@
}
X265_FREE(temp);
}
+ if (m_seiFile)
+ fclose(m_seiFile);
if (m_param)
{
if (m_param->csvfpt)
@@ -922,7 +939,14 @@
}
}
#endif
-
+/* seiMsg will contain SEI messages specified in a fixed file format in POC order.
+* Format of the file : <POC><space><PREFIX><space><NAL UNIT TYPE>/<SEI TYPE><space><SEI Payload> */
+ x265_sei_payload seiMsg;
+ seiMsg.payload = NULL;
+ if (m_enableUserSei)
+ {
+ seiMsg = readUserSeiFile(m_pocLast);
+ }
if (pic_in->bitDepth < 8 || pic_in->bitDepth > 16)
{
x265_log(m_param, X265_LOG_ERROR, "Input bit depth (%d) must be between 8 and 16\n",
@@ -1008,6 +1032,8 @@
if (m_bToneMap && toneMap.payload)
toneMapEnable = 1;
int numPayloads = pic_in->userSEI.numPayloads + toneMapEnable;
+ if (m_enableUserSei && seiMsg.payload)
+ numPayloads += m_enableUserSei;
inFrame->m_userSEI.numPayloads = numPayloads;
if (inFrame->m_userSEI.numPayloads)
@@ -1023,6 +1049,8 @@
x265_sei_payload input;
if ((i == (numPayloads - 1)) && toneMapEnable)
input = toneMap;
+ else if (m_enableUserSei)
+ input = seiMsg;
else
input = pic_in->userSEI.payloads[i];
int size = inFrame->m_userSEI.payloads[i].payloadSize = input.payloadSize;
@@ -1033,6 +1061,8 @@
}
if (toneMap.payload)
x265_free(toneMap.payload);
+ if (seiMsg.payload)
+ x265_free(seiMsg.payload);
}
if (pic_in->quantOffsets != NULL)
@@ -4706,6 +4736,55 @@
TOOLCMP(oldParam->rc.rfConstant, newParam->rc.rfConstant, "crf=%f to %f\n");
}
+x265_sei_payload Encoder::readUserSeiFile(int curPoc)
+{
+ x265_sei_payload seiMsg;
+ seiMsg.payload = NULL;
+ char line[1024];
+ while (!feof(m_seiFile))
+ {
+ fgets(line, sizeof(line), m_seiFile);
+ int poc = atoi(strtok(line, " "));
+ char *prefix = strtok(NULL, " ");
+ int nalType = atoi(strtok(NULL, "/"));
+ int payloadType = atoi(strtok(NULL, " "));
+ char *base64Encode = strtok(NULL, "\n");
+ int base64EncodeLength = (int)strlen(base64Encode);
+ char *base64Decode = SEI::base64Decode(base64Encode, base64EncodeLength);
+ if (nalType == NAL_UNIT_PREFIX_SEI && (!strcmp(prefix, "PREFIX")))
+ {
+ int currentPOC = curPoc + 1;
+ if (currentPOC == poc)
+ {
+ seiMsg.payloadSize = (base64EncodeLength / 4) * 3;
+ seiMsg.payload = (uint8_t*)x265_malloc(sizeof(uint8_t) * seiMsg.payloadSize);
+ if (!seiMsg.payload)
+ {
+ x265_log(m_param, X265_LOG_ERROR, "Unable to allocate memory for SEI payload\n");
+ break;
+ }
+ if (payloadType == 4)
+ seiMsg.payloadType = USER_DATA_REGISTERED_ITU_T_T35;
+ else if (payloadType == 5)
+ seiMsg.payloadType = USER_DATA_UNREGISTERED;
+ else
+ {
+ x265_log(m_param, X265_LOG_WARNING, "Unsupported SEI payload Type for frame %d\n", poc);
+ break;
+ }
+ memcpy(seiMsg.payload, base64Decode, seiMsg.payloadSize);
+ return seiMsg;
+ }
+ }
+ else
+ {
+ x265_log(m_param, X265_LOG_WARNING, "SEI message for frame %d is not inserted. Will support only PREFIX SEI messages.\n", poc);
+ break;
+ }
+ }
+ return seiMsg;
+}
+
bool Encoder::computeSPSRPSIndex()
{
RPS* rpsInSPS = m_sps.spsrps;
diff -r a8a5ccf5aaf7 -r e1dd8424a3bd source/encoder/encoder.h
--- a/source/encoder/encoder.h Wed Jun 13 09:54:27 2018 +0530
+++ b/source/encoder/encoder.h Mon Jun 11 19:44:51 2018 +0530
@@ -169,6 +169,7 @@
Frame* m_exportedPic;
FILE* m_analysisFileIn;
FILE* m_analysisFileOut;
+ FILE* m_seiFile;
x265_param* m_param;
x265_param* m_latestParam; // Holds latest param during a reconfigure
RateControl* m_rateControl;
@@ -212,6 +213,7 @@
double m_cR;
int m_bToneMap; // Enables tone-mapping
+ int m_enableUserSei;
#ifdef ENABLE_HDR10_PLUS
const hdr10plus_api *m_hdr10plus_api;
@@ -299,6 +301,8 @@
int validateAnalysisData(x265_analysis_data* analysis, int readWriteFlag);
+ x265_sei_payload readUserSeiFile(int poc);
+
void calcRefreshInterval(Frame* frameEnc);
void initRefIdx();
diff -r a8a5ccf5aaf7 -r e1dd8424a3bd source/encoder/sei.cpp
--- a/source/encoder/sei.cpp Wed Jun 13 09:54:27 2018 +0530
+++ b/source/encoder/sei.cpp Mon Jun 11 19:44:51 2018 +0530
@@ -90,3 +90,63 @@
{
m_payloadSize = size;
}
+
+/* charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" */
+
+char* SEI::base64Decode(char encodedString[], int base64EncodeLength)
+{
+ char* decodedString;
+ decodedString = (char*)malloc(sizeof(char) * ((base64EncodeLength / 4) * 3));
+ int i, j, k = 0;
+ // stores the bitstream
+ int bitstream = 0;
+ // countBits stores current number of bits in bitstream
+ int countBits = 0;
+ // selects 4 characters from encodedString at a time. Find the position of each encoded character in charSet and stores in bitstream
+ for (i = 0; i < base64EncodeLength; i += 4)
+ {
+ bitstream = 0, countBits = 0;
+ for (j = 0; j < 4; j++)
+ {
+ // make space for 6 bits
+ if (encodedString[i + j] != '=')
+ {
+ bitstream = bitstream << 6;
+ countBits += 6;
+ }
+ // Finding the position of each encoded character in charSet and storing in bitstream, use OR '|' operator to store bits
+
+ if (encodedString[i + j] >= 'A' && encodedString[i + j] <= 'Z')
+ bitstream = bitstream | (encodedString[i + j] - 'A');
+
+ else if (encodedString[i + j] >= 'a' && encodedString[i + j] <= 'z')
+ bitstream = bitstream | (encodedString[i + j] - 'a' + 26);
+
+ else if (encodedString[i + j] >= '0' && encodedString[i + j] <= '9')
+ bitstream = bitstream | (encodedString[i + j] - '0' + 52);
+
+ // '+' occurs in 62nd position in charSet
+ else if (encodedString[i + j] == '+')
+ bitstream = bitstream | 62;
+
+ // '/' occurs in 63rd position in charSet
+ else if (encodedString[i + j] == '/')
+ bitstream = bitstream | 63;
+
+ // to delete appended bits during encoding
+ else
+ {
+ bitstream = bitstream >> 2;
+ countBits -= 2;
+ }
+ }
+
+ while (countBits != 0)
+ {
+ countBits -= 8;
+ decodedString[k++] = (bitstream >> countBits) & 255;
+ }
+ }
+ return decodedString;
+}
+
diff -r a8a5ccf5aaf7 -r e1dd8424a3bd source/encoder/sei.h
--- a/source/encoder/sei.h Wed Jun 13 09:54:27 2018 +0530
+++ b/source/encoder/sei.h Mon Jun 11 19:44:51 2018 +0530
@@ -41,6 +41,7 @@
void alignAndSerialize(Bitstream& bs, int lastSei, int isSingleSei, NalUnitType nalUnitType, NALList& list);
int countPayloadSize(const SPS& sps);
void setSize(uint32_t size);
+ static char* base64Decode(char encodedString[], int base64EncodeLength);
virtual ~SEI() {}
protected:
SEIPayloadType m_payloadType;
diff -r a8a5ccf5aaf7 -r e1dd8424a3bd source/x265.h
--- a/source/x265.h Wed Jun 13 09:54:27 2018 +0530
+++ b/source/x265.h Mon Jun 11 19:44:51 2018 +0530
@@ -1641,6 +1641,8 @@
* used in taking lookahead decisions, but, they will not be encoded.
* Default 0 (disabled). */
int chunkEnd;
+ /* File containing base64 encoded SEI messages in POC order */
+ const char* userSeiFile;
} x265_param;
diff -r a8a5ccf5aaf7 -r e1dd8424a3bd source/x265cli.h
--- a/source/x265cli.h Wed Jun 13 09:54:27 2018 +0530
+++ b/source/x265cli.h Mon Jun 11 19:44:51 2018 +0530
@@ -304,6 +304,7 @@
{ "no-single-sei", no_argument, NULL, 0 },
{ "atc-sei", required_argument, NULL, 0 },
{ "pic-struct", required_argument, NULL, 0 },
+ { "usersei-file", required_argument, NULL, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
@@ -354,6 +355,7 @@
H0(" --dhdr10-info <filename> JSON file containing the Creative Intent Metadata to be encoded as Dynamic Tone Mapping\n");
H0(" --[no-]dhdr10-opt Insert tone mapping SEI only for IDR frames and when the tone mapping information changes. Default disabled\n");
#endif
+ H0(" --usersei-file <filename> Text file containing SEI messages in the following format : <POC><space><PREFIX><space><NAL UNIT TYPE>/<SEI TYPE><space><SEI Payload>\n");
H0("-f/--frames <integer> Maximum number of frames to encode. Default all\n");
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");
-------------- next part --------------
A non-text attachment was scrubbed...
Name: x265.patch
Type: text/x-patch
Size: 12873 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20180620/ae73f2e2/attachment.bin>
More information about the x265-devel
mailing list