Please ignore this patch. I will resend with some changes. Thanks, Indumathi R
On Wed, Jun 20, 2018 at 2:13 PM, <induma...@multicorewareinc.com> wrote: > # HG changeset patch > # User induma...@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 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcd > efghijklmnopqrstuvwxyz0123456789+/" */ > + > +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"); >
_______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel