pushed Thanks, Kalyan Goswami, PhD Video Architect @ MulticoreWare http: <http://www.multicorewareinc.com/>//www.multicorewareinc.com <http://www.multicorewareinc.com/> +91 9884989331
On Mon, Dec 10, 2018 at 3:29 PM Aruna Matheswaran < [email protected]> wrote: > # HG changeset patch > # User Aruna Matheswaran <[email protected]> > # Date 1538037975 -19800 > # Thu Sep 27 14:16:15 2018 +0530 > # Node ID e50f803e26fb3926dc695e0aeea39681fe1eacbd > # Parent b748ee9f44657a9468b9d62c85d02dfafcbc4039 > Add support for Dolby Vision RPU muxing > > diff -r b748ee9f4465 -r e50f803e26fb doc/reST/cli.rst > --- a/doc/reST/cli.rst Fri Sep 28 10:45:23 2018 +0530 > +++ b/doc/reST/cli.rst Thu Sep 27 14:16:15 2018 +0530 > @@ -2208,6 +2208,15 @@ > > Currently only profile 5 enabled, Default 0 (disabled) > > +.. option:: --dolby-vision-rpu > + > + File containing Dolby Vision RPU metadata. If given, x265's Dolby > Vision > + metadata parser will fill the RPU field of input pictures with the > metadata > + read from the file. The library will interleave access units with > RPUs in the > + bitstream. Default NULL (disabled). > + > + **CLI ONLY** > + > .. option:: --info, --no-info > > Emit an informational SEI with the stream headers which describes > diff -r b748ee9f4465 -r e50f803e26fb source/CMakeLists.txt > --- a/source/CMakeLists.txt Fri Sep 28 10:45:23 2018 +0530 > +++ b/source/CMakeLists.txt Thu Sep 27 14:16:15 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 166) > +set(X265_BUILD 167) > configure_file("${PROJECT_SOURCE_DIR}/x265.def.in" > "${PROJECT_BINARY_DIR}/x265.def") > configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in" > diff -r b748ee9f4465 -r e50f803e26fb source/common/frame.cpp > --- a/source/common/frame.cpp Fri Sep 28 10:45:23 2018 +0530 > +++ b/source/common/frame.cpp Thu Sep 27 14:16:15 2018 +0530 > @@ -44,6 +44,8 @@ > m_param = NULL; > m_userSEI.numPayloads = 0; > m_userSEI.payloads = NULL; > + m_rpu.payloadSize = 0; > + m_rpu.payload = NULL; > memset(&m_lowres, 0, sizeof(m_lowres)); > m_rcData = NULL; > m_encodeStartTime = 0; > diff -r b748ee9f4465 -r e50f803e26fb source/common/frame.h > --- a/source/common/frame.h Fri Sep 28 10:45:23 2018 +0530 > +++ b/source/common/frame.h Thu Sep 27 14:16:15 2018 +0530 > @@ -98,6 +98,7 @@ > > float* m_quantOffsets; // points to > quantOffsets in x265_picture > x265_sei m_userSEI; > + x265_dolby_vision_rpu m_rpu; > > /* Frame Parallelism - notification between FrameEncoders of > available motion reference rows */ > ThreadSafeInteger* m_reconRowFlag; // flag of CTU rows > completely reconstructed and extended for motion reference > diff -r b748ee9f4465 -r e50f803e26fb source/encoder/api.cpp > --- a/source/encoder/api.cpp Fri Sep 28 10:45:23 2018 +0530 > +++ b/source/encoder/api.cpp Thu Sep 27 14:16:15 2018 +0530 > @@ -598,6 +598,8 @@ > pic->quantOffsets = NULL; > pic->userSEI.payloads = NULL; > pic->userSEI.numPayloads = 0; > + pic->rpu.payloadSize = 0; > + pic->rpu.payload = NULL; > > if ((param->analysisSave || param->analysisLoad) || (param->bMVType > == AVC_INFO)) > { > @@ -612,6 +614,8 @@ > > void x265_picture_free(x265_picture *p) > { > + if (p->rpu.payload) > + X265_FREE(p->rpu.payload); > return x265_free(p); > } > > diff -r b748ee9f4465 -r e50f803e26fb source/encoder/encoder.cpp > --- a/source/encoder/encoder.cpp Fri Sep 28 10:45:23 2018 +0530 > +++ b/source/encoder/encoder.cpp Thu Sep 27 14:16:15 2018 +0530 > @@ -1075,6 +1075,14 @@ > > copyUserSEIMessages(inFrame, pic_in); > > + /*Copy Dolby Vision RPU from pic_in to frame*/ > + if (pic_in->rpu.payloadSize) > + { > + inFrame->m_rpu.payloadSize = pic_in->rpu.payloadSize; > + inFrame->m_rpu.payload = new uint8_t[pic_in->rpu.payloadSize]; > + memcpy(inFrame->m_rpu.payload, pic_in->rpu.payload, > pic_in->rpu.payloadSize); > + } > + > if (pic_in->quantOffsets != NULL) > { > int cuCount; > @@ -2362,6 +2370,13 @@ > { > sbacCoder.setBitstream(&bs); > > + if (m_param->dolbyProfile && !m_param->bRepeatHeaders) > + { > + bs.resetBits(); > + bs.write(0x10, 8); > + list.serialize(NAL_UNIT_ACCESS_UNIT_DELIMITER, bs); > + } > + > /* headers for start of bitstream */ > bs.resetBits(); > sbacCoder.codeVPS(m_vps); > diff -r b748ee9f4465 -r e50f803e26fb source/encoder/frameencoder.cpp > --- a/source/encoder/frameencoder.cpp Fri Sep 28 10:45:23 2018 +0530 > +++ b/source/encoder/frameencoder.cpp Thu Sep 27 14:16:15 2018 +0530 > @@ -1063,6 +1063,14 @@ > m_accessUnitBits = bytes << 3; > } > > + if (m_frame->m_rpu.payloadSize) > + { > + m_bs.resetBits(); > + for (int i = 0; i < m_frame->m_rpu.payloadSize; i++) > + m_bs.write(m_frame->m_rpu.payload[i], 8); > + m_nalList.serialize(NAL_UNIT_UNSPECIFIED, m_bs); > + } > + > m_endCompressTime = x265_mdate(); > > /* Decrement referenced frame reference counts, allow them to be > recycled */ > diff -r b748ee9f4465 -r e50f803e26fb source/encoder/nal.cpp > --- a/source/encoder/nal.cpp Fri Sep 28 10:45:23 2018 +0530 > +++ b/source/encoder/nal.cpp Thu Sep 27 14:16:15 2018 +0530 > @@ -97,7 +97,7 @@ > /* Will write size later */ > bytes += 4; > } > - else if (!m_numNal || nalUnitType == NAL_UNIT_VPS || nalUnitType == > NAL_UNIT_SPS || nalUnitType == NAL_UNIT_PPS) > + else if (!m_numNal || nalUnitType == NAL_UNIT_VPS || nalUnitType == > NAL_UNIT_SPS || nalUnitType == NAL_UNIT_PPS || nalUnitType == > NAL_UNIT_UNSPECIFIED) > { > memcpy(out, startCodePrefix, 4); > bytes += 4; > @@ -124,7 +124,7 @@ > * - 0x000002 */ > for (uint32_t i = 0; i < payloadSize; i++) > { > - if (i > 2 && !out[bytes - 2] && !out[bytes - 3] && out[bytes - 1] > <= 0x03) > + if (i > 2 && !out[bytes - 2] && !out[bytes - 3] && out[bytes - 1] > <= 0x03 && nalUnitType != NAL_UNIT_UNSPECIFIED) > { > /* inject 0x03 to prevent emulating a start code */ > out[bytes] = out[bytes - 1]; > diff -r b748ee9f4465 -r e50f803e26fb source/encoder/sei.cpp > --- a/source/encoder/sei.cpp Fri Sep 28 10:45:23 2018 +0530 > +++ b/source/encoder/sei.cpp Thu Sep 27 14:16:15 2018 +0530 > @@ -66,7 +66,8 @@ > > if (!isNested) > { > - bs.writeByteAlignment(); > + if (nalUnitType != NAL_UNIT_UNSPECIFIED) > + bs.writeByteAlignment(); > list.serialize(nalUnitType, bs); > } > } > diff -r b748ee9f4465 -r e50f803e26fb source/x265.cpp > --- a/source/x265.cpp Fri Sep 28 10:45:23 2018 +0530 > +++ b/source/x265.cpp Thu Sep 27 14:16:15 2018 +0530 > @@ -65,6 +65,8 @@ > { > b_ctrl_c = 1; > } > +#define START_CODE 0x00000001 > +#define START_CODE_BYTES 4 > > struct CLIOptions > { > @@ -72,6 +74,7 @@ > ReconFile* recon; > OutputFile* output; > FILE* qpfile; > + FILE* dolbyVisionRpu; /* File containing Dolby Vision BL RPU > metadata */ > const char* reconPlayCmd; > const x265_api* api; > x265_param* param; > @@ -94,6 +97,7 @@ > recon = NULL; > output = NULL; > qpfile = NULL; > + dolbyVisionRpu = NULL; > reconPlayCmd = NULL; > api = NULL; > param = NULL; > @@ -124,6 +128,9 @@ > if (qpfile) > fclose(qpfile); > qpfile = NULL; > + if (dolbyVisionRpu) > + fclose(dolbyVisionRpu); > + dolbyVisionRpu = NULL; > if (output) > output->release(); > output = NULL; > @@ -311,6 +318,15 @@ > if (!this->qpfile) > x265_log_file(param, X265_LOG_ERROR, "%s qpfile not > found or error in opening qp file\n", optarg); > } > + OPT("dolby-vision-rpu") > + { > + this->dolbyVisionRpu = x265_fopen(optarg, "rb"); > + if (!this->dolbyVisionRpu) > + { > + x265_log_file(param, X265_LOG_ERROR, "Dolby Vision > RPU metadata file %s not found or error in opening file\n", optarg); > + return true; > + } > + } > OPT("fullhelp") > { > param->logLevel = X265_LOG_FULL; > @@ -552,6 +568,59 @@ > } > #endif > > +/* Parse the RPU file and extract the RPU corresponding to the current > picture > + * and fill the rpu field of the input picture */ > +static int rpuParser(x265_picture * pic, FILE * ptr) > +{ > + uint8_t byte; > + uint32_t code = 0; > + int bytesRead = 0; > + pic->rpu.payloadSize = 0; > + > + if (!pic->pts) > + { > + while (bytesRead++ < 4 && fread(&byte, sizeof(uint8_t), 1, ptr)) > + code = (code << 8) | byte; > + > + if (code != START_CODE) > + { > + x265_log(NULL, X265_LOG_ERROR, "Invalid Dolby Vision RPU > startcode in POC %d\n", pic->pts); > + return 1; > + } > + } > + > + bytesRead = 0; > + while (fread(&byte, sizeof(uint8_t), 1, ptr)) > + { > + code = (code << 8) | byte; > + if (bytesRead++ < 3) > + continue; > + if (bytesRead >= 1024) > + { > + x265_log(NULL, X265_LOG_ERROR, "Invalid Dolby Vision RPU size > in POC %d\n", pic->pts); > + return 1; > + } > + > + if (code != START_CODE) > + pic->rpu.payload[pic->rpu.payloadSize++] = (code >> (3 * 8)) > & 0xFF; > + else > + return 0; > + } > + > + int ShiftBytes = START_CODE_BYTES - (bytesRead - > pic->rpu.payloadSize); > + int bytesLeft = bytesRead - pic->rpu.payloadSize; > + code = (code << ShiftBytes * 8); > + for (int i = 0; i < bytesLeft; i++) > + { > + pic->rpu.payload[pic->rpu.payloadSize++] = (code >> (3 * 8)) & > 0xFF; > + code = (code << 8); > + } > + if (!pic->rpu.payloadSize) > + x265_log(NULL, X265_LOG_WARNING, "Dolby Vision RPU not found for > POC %d\n", pic->pts); > + return 0; > +} > + > + > /* CLI return codes: > * > * 0 - encode successful > @@ -630,8 +699,10 @@ > x265_stats stats; > uint32_t nal; > int16_t *errorBuf = NULL; > + bool bDolbyVisionRPU = false; > int ret = 0; > > + > if (!param->bRepeatHeaders) > { > if (api->encoder_headers(encoder, &p_nal, &nal) < 0) > @@ -646,6 +717,13 @@ > > api->picture_init(param, pic_in); > > + if (param->dolbyProfile && cliopt.dolbyVisionRpu) > + { > + pic_in->rpu.payload = X265_MALLOC(uint8_t, 1024); > + if (pic_in->rpu.payload) > + bDolbyVisionRPU = true; > + } > + > if (cliopt.bDither) > { > errorBuf = X265_MALLOC(int16_t, param->sourceWidth + 1); > @@ -685,8 +763,13 @@ > } > /* Overwrite PTS */ > pic_in->pts = pic_in->poc; > + > + if (bDolbyVisionRPU) > + { > + if (rpuParser(pic_in, cliopt.dolbyVisionRpu) > 0) > + goto fail; > + } > } > - > int numEncoded = api->encoder_encode(encoder, &p_nal, &nal, > pic_in, pic_recon); > if (numEncoded < 0) > { > @@ -749,6 +832,13 @@ > break; > } > > + if (bDolbyVisionRPU) > + { > + if(fgetc(cliopt.dolbyVisionRpu) != EOF) > + x265_log(NULL, X265_LOG_WARNING, "Dolby Vision RPU count is > greater than frame count\n"); > + x265_log(NULL, X265_LOG_INFO, "VES muxing with Dolby Vision RPU > file successful\n"); > + } > + > /* clear progress report */ > if (cliopt.bProgress) > fprintf(stderr, "%*s\r", 80, " "); > diff -r b748ee9f4465 -r e50f803e26fb source/x265.h > --- a/source/x265.h Fri Sep 28 10:45:23 2018 +0530 > +++ b/source/x265.h Thu Sep 27 14:16:15 2018 +0530 > @@ -81,6 +81,7 @@ > NAL_UNIT_FILLER_DATA, > NAL_UNIT_PREFIX_SEI, > NAL_UNIT_SUFFIX_SEI, > + NAL_UNIT_UNSPECIFIED = 62, > NAL_UNIT_INVALID = 64, > } NalUnitType; > > @@ -360,6 +361,12 @@ > x265_sei_payload *payloads; > } x265_sei; > > +typedef struct x265_dolby_vision_rpu > +{ > + int payloadSize; > + uint8_t* payload; > +}x265_dolby_vision_rpu; > + > /* Used to pass pictures into the encoder, and to get picture data back > out of > * the encoder. The input and output semantics are different */ > typedef struct x265_picture > @@ -445,6 +452,9 @@ > > // pts is reordered in the order of encoding. > int64_t reorderedPts; > + > + //Dolby Vision RPU metadata > + x265_dolby_vision_rpu rpu; > } x265_picture; > > typedef enum > diff -r b748ee9f4465 -r e50f803e26fb source/x265cli.h > --- a/source/x265cli.h Fri Sep 28 10:45:23 2018 +0530 > +++ b/source/x265cli.h Thu Sep 27 14:16:15 2018 +0530 > @@ -306,6 +306,7 @@ > { "atc-sei", required_argument, NULL, 0 }, > { "pic-struct", required_argument, NULL, 0 }, > { "nalu-file", required_argument, NULL, 0 }, > + { "dolby-vision-rpu", required_argument, NULL, 0 }, > { 0, 0, 0, 0 }, > { 0, 0, 0, 0 }, > { 0, 0, 0, 0 }, > @@ -357,6 +358,8 @@ > H0(" --[no-]dhdr10-opt Insert tone mapping SEI only for > IDR frames and when the tone mapping information changes. Default > disabled\n"); > #endif > H0(" --dolby-vision-profile <float|integer> Specifies Dolby Vision > profile ID. Currently only profile 5 enabled. Specified as '5' or '50'. > Default 0 (disabled).\n"); > + H0(" --dolby-vision-rpu <filename> File containing Dolby Vision RPU > metadata.\n" > + " If given, x265's Dolby Vision > metadata parser will fill the RPU field of input pictures with the metadata > read from the file. Default NULL(disabled).\n"); > H0(" --nalu-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"); > > _______________________________________________ > x265-devel mailing list > [email protected] > https://mailman.videolan.org/listinfo/x265-devel >
_______________________________________________ x265-devel mailing list [email protected] https://mailman.videolan.org/listinfo/x265-devel
