[x265] [PATCH] CEA 608/708 Support

Indumathi Ravichandran indumathi at multicorewareinc.com
Thu Jun 21 16:50:01 CEST 2018


Okay. Will rename and send the patch tomorrow.

On Wed, Jun 20, 2018 at 8:45 PM, Alex Giladi <alex.giladi at gmail.com> wrote:

> I would rename the "usersei-file" option into something like "nalu-file",
> as the input file format allows arbitrary NAL units rather than only SEIs
> (despite only prefix SEIs being implemented).
>
>
> On Wed, Jun 20, 2018 at 4:43 AM, <indumathi at multicorewareinc.com> wrote:
>
>> # 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_jso
>> n_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 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabc
>> defghijklmnopqrstuvwxyz0123456789+/" */
>> +
>> +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 at videolan.org
>> https://mailman.videolan.org/listinfo/x265-devel
>>
>>
>
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20180621/994c2f69/attachment-0001.html>


More information about the x265-devel mailing list