>From d8dfb330dfdf5704dbf761d43e7814a56927dac5 Mon Sep 17 00:00:00 2001 From: Niranjan <niran...@multicorewareinc.com> Date: Thu, 18 Mar 2021 16:57:24 +0530 Subject: [PATCH] Add: End Of Bitstream and End Of Sequence NAL units
--- doc/reST/cli.rst | 9 +++++++++ source/CMakeLists.txt | 2 +- source/abrEncApp.cpp | 12 ++++++++++++ source/common/param.cpp | 8 ++++++++ source/encoder/api.cpp | 11 +++++++++++ source/encoder/encoder.cpp | 13 +++++++++++++ source/encoder/encoder.h | 2 ++ source/encoder/frameencoder.cpp | 6 ++++++ source/test/regression-tests.txt | 1 + source/x265.h | 8 ++++++++ source/x265cli.cpp | 2 ++ source/x265cli.h | 4 ++++ 12 files changed, 77 insertions(+), 1 deletion(-) diff --git a/doc/reST/cli.rst b/doc/reST/cli.rst index c39fee8..f0f8d2a 100755 --- a/doc/reST/cli.rst +++ b/doc/reST/cli.rst @@ -2529,6 +2529,15 @@ Bitstream options the very first AUD will be skipped since it cannot be placed at the start of the access unit, where it belongs. Default disabled +.. option:: --eob, --no-eob + + Emit an end of bitstream NAL unit at the end of the bitstream. + +.. option:: --eos, --no-eos + + Emit an end of sequence NAL unit at the end of every coded + video sequence. + .. option:: --hrd, --no-hrd Enable the signaling of HRD parameters to the decoder. The HRD diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index a407271..b4e57b5 100755 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -29,7 +29,7 @@ option(NATIVE_BUILD "Target the build CPU" OFF) 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 199) +set(X265_BUILD 200) configure_file("${PROJECT_SOURCE_DIR}/x265.def.in" "${PROJECT_BINARY_DIR}/x265.def") configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in" diff --git a/source/abrEncApp.cpp b/source/abrEncApp.cpp index cd85154..fcb1978 100644 --- a/source/abrEncApp.cpp +++ b/source/abrEncApp.cpp @@ -797,6 +797,18 @@ ret: break; } + if ((m_param->bEnableEndOfBitstream || m_param->bEnableEndOfSequence) && outFrameCount == (uint32_t)m_param->totalFrames) + { + if (api->encoder_end_nal_units(m_encoder, &p_nal, &nal) < 0) + { + x265_log(NULL, X265_LOG_ERROR, "Failure generating end nal units\n"); + m_ret = 3; + goto fail; + } + else + m_cliopt.totalbytes += m_cliopt.output->writeHeaders(p_nal, nal); + } + if (bDolbyVisionRPU) { if (fgetc(m_cliopt.dolbyVisionRpu) != EOF) diff --git a/source/common/param.cpp b/source/common/param.cpp index fb74d75..8a27aae 100755 --- a/source/common/param.cpp +++ b/source/common/param.cpp @@ -145,6 +145,8 @@ void x265_param_default(x265_param* param) param->bAnnexB = 1; param->bRepeatHeaders = 0; param->bEnableAccessUnitDelimiters = 0; + param->bEnableEndOfBitstream = 0; + param->bEnableEndOfSequence = 0; param->bEmitHRDSEI = 0; param->bEmitInfoSEI = 1; param->bEmitHDRSEI = 0; /*Deprecated*/ @@ -1448,6 +1450,8 @@ int x265_param_parse(x265_param* p, const char* name, const char* value) OPT("min-vbv-fullness") p->minVbvFullness = atof(value); OPT("max-vbv-fullness") p->maxVbvFullness = atof(value); OPT("video-signal-type-preset") p->videoSignalTypePreset = strdup(value); + OPT("eob") p->bEnableEndOfBitstream = atobool(value); + OPT("eos") p->bEnableEndOfSequence = atobool(value); else return X265_PARAM_BAD_NAME; } @@ -2130,6 +2134,8 @@ char *x265_param2string(x265_param* p, int padx, int pady) BOOL(p->bRepeatHeaders, "repeat-headers"); BOOL(p->bAnnexB, "annexb"); BOOL(p->bEnableAccessUnitDelimiters, "aud"); + BOOL(p->bEnableEndOfBitstream, "eob"); + BOOL(p->bEnableEndOfSequence, "eos"); BOOL(p->bEmitHRDSEI, "hrd"); BOOL(p->bEmitInfoSEI, "info"); s += sprintf(s, " hash=%d", p->decodedPictureHashSEI); @@ -2444,6 +2450,8 @@ void x265_copy_params(x265_param* dst, x265_param* src) dst->bRepeatHeaders = src->bRepeatHeaders; dst->bAnnexB = src->bAnnexB; dst->bEnableAccessUnitDelimiters = src->bEnableAccessUnitDelimiters; + dst->bEnableEndOfBitstream = src->bEnableEndOfBitstream; + dst->bEnableEndOfSequence = src->bEnableEndOfSequence; dst->bEmitInfoSEI = src->bEmitInfoSEI; dst->decodedPictureHashSEI = src->decodedPictureHashSEI; dst->bEnableTemporalSubLayers = src->bEnableTemporalSubLayers; diff --git a/source/encoder/api.cpp b/source/encoder/api.cpp index a986355..e4eba71 100644 --- a/source/encoder/api.cpp +++ b/source/encoder/api.cpp @@ -295,6 +295,16 @@ int x265_encoder_headers(x265_encoder *enc, x265_nal **pp_nal, uint32_t *pi_nal) return -1; } +int x265_encoder_end_nal_units(x265_encoder *enc, x265_nal **pp_nal, uint32_t *pi_nal) +{ + Encoder *encoder = static_cast<Encoder*>(enc); + Bitstream bs; + encoder->getEndNalUnits(encoder->m_nalList, bs); + *pp_nal = &encoder->m_nalList.m_nal[0]; + if (pi_nal) *pi_nal = encoder->m_nalList.m_numNal; + return encoder->m_nalList.m_occupancy; +} + void x265_encoder_parameters(x265_encoder *enc, x265_param *out) { if (enc && out) @@ -1052,6 +1062,7 @@ static const x265_api libapi = &x265_encoder_reconfig, &x265_encoder_reconfig_zone, &x265_encoder_headers, + &x265_encoder_end_nal_units, &x265_encoder_encode, &x265_encoder_get_stats, &x265_encoder_log, diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp index 19d15fb..c1e1cb4 100644 --- a/source/encoder/encoder.cpp +++ b/source/encoder/encoder.cpp @@ -3374,6 +3374,19 @@ void Encoder::getStreamHeaders(NALList& list, Entropy& sbacCoder, Bitstream& bs) } } +void Encoder::getEndNalUnits(NALList& list, Bitstream& bs) +{ + NALList nalList; + bs.resetBits(); + + if (m_param->bEnableEndOfSequence) + nalList.serialize(NAL_UNIT_EOS, bs); + if (m_param->bEnableEndOfBitstream) + nalList.serialize(NAL_UNIT_EOB, bs); + + list.takeContents(nalList); +} + void Encoder::initVPS(VPS *vps) { /* Note that much of the VPS is initialized by determineLevel() */ diff --git a/source/encoder/encoder.h b/source/encoder/encoder.h index 22a886e..2ee5bda 100644 --- a/source/encoder/encoder.h +++ b/source/encoder/encoder.h @@ -327,6 +327,8 @@ public: void getStreamHeaders(NALList& list, Entropy& sbacCoder, Bitstream& bs); + void getEndNalUnits(NALList& list, Bitstream& bs); + void fetchStats(x265_stats* stats, size_t statsSizeBytes); void printSummary(); diff --git a/source/encoder/frameencoder.cpp b/source/encoder/frameencoder.cpp index efe8528..1b3875a 100644 --- a/source/encoder/frameencoder.cpp +++ b/source/encoder/frameencoder.cpp @@ -467,6 +467,12 @@ void FrameEncoder::compressFrame() * unit) */ Slice* slice = m_frame->m_encData->m_slice; + if (m_param->bEnableEndOfSequence && m_frame->m_lowres.sliceType == X265_TYPE_IDR && m_frame->m_poc) + { + m_bs.resetBits(); + m_nalList.serialize(NAL_UNIT_EOS, m_bs); + } + if (m_param->bEnableAccessUnitDelimiters && (m_frame->m_poc || m_param->bRepeatHeaders)) { m_bs.resetBits(); diff --git a/source/test/regression-tests.txt b/source/test/regression-tests.txt index a4fcab8..971c854 100644 --- a/source/test/regression-tests.txt +++ b/source/test/regression-tests.txt @@ -166,6 +166,7 @@ crowd_run_1920x1080_50.yuv, --preset fast --ctu 64 --rskip 2 --rskip-edge-thresh crowd_run_1920x1080_50.yuv, --preset slow --ctu 32 --rskip 2 --rskip-edge-threshold 5 --hist-scenecut --hist-threshold 0.1 crowd_run_1920x1080_50.yuv, --preset slower --ctu 16 --rskip 2 --rskip-edge-threshold 5 --hist-scenecut --hist-threshold 0.1 --aq-mode 4 crowd_run_1920x1080_50.yuv, --preset ultrafast --video-signal-type-preset BT2100_PQ_YCC:BT2100x108n0005 +crowd_run_1920x1080_50.yuv, --preset ultrafast --eob --eos # Main12 intraCost overflow bug test 720p50_parkrun_ter.y4m,--preset medium diff --git a/source/x265.h b/source/x265.h index 1c51e76..1d52ece 100644 --- a/source/x265.h +++ b/source/x265.h @@ -1956,6 +1956,13 @@ typedef struct x265_param * or color-volume, it will be discarded. */ const char* videoSignalTypePreset; + /* Flag indicating whether the encoder should emit an End of Bitstream + * NAL at the end of bitstream. Default false */ + int bEnableEndOfBitstream; + + /* Flag indicating whether the encoder should emit an End of Sequence + * NAL at the end of every Coded Video Sequence. Default false */ + int bEnableEndOfSequence; } x265_param; /* x265_param_alloc: @@ -2269,6 +2276,7 @@ typedef struct x265_api int (*encoder_reconfig)(x265_encoder*, x265_param*); int (*encoder_reconfig_zone)(x265_encoder*, x265_zone*); int (*encoder_headers)(x265_encoder*, x265_nal**, uint32_t*); + int (*encoder_end_nal_units)(x265_encoder*, x265_nal**, uint32_t*); int (*encoder_encode)(x265_encoder*, x265_nal**, uint32_t*, x265_picture*, x265_picture*); void (*encoder_get_stats)(x265_encoder*, x265_stats*, uint32_t); void (*encoder_log)(x265_encoder*, int, char**); diff --git a/source/x265cli.cpp b/source/x265cli.cpp index e9af67c..bfb6293 100755 --- a/source/x265cli.cpp +++ b/source/x265cli.cpp @@ -351,6 +351,8 @@ namespace X265_NS { H0(" --[no-]idr-recovery-sei Emit recovery point infor SEI at each IDR frame \n"); H0(" --[no-]temporal-layers Enable a temporal sublayer for unreferenced B frames. Default %s\n", OPT(param->bEnableTemporalSubLayers)); H0(" --[no-]aud Emit access unit delimiters at the start of each access unit. Default %s\n", OPT(param->bEnableAccessUnitDelimiters)); + H0(" --[no-]eob Emit end of bitstream nal unit at the end of the bitstream. Default %s\n", OPT(param->bEnableEndOfBitstream)); + H0(" --[no-]eos Emit end of sequence nal unit at the end of every coded video sequence. Default %s\n", OPT(param->bEnableEndOfSequence)); H1(" --hash <integer> Decoded Picture Hash SEI 0: disabled, 1: MD5, 2: CRC, 3: Checksum. Default %d\n", param->decodedPictureHashSEI); H0(" --atc-sei <integer> Emit the alternative transfer characteristics SEI message where the integer is the preferred transfer characteristics. Default disabled\n"); H0(" --pic-struct <integer> Set the picture structure and emits it in the picture timing SEI message. Values in the range 0..12. See D.3.3 of the HEVC spec. for a detailed explanation.\n"); diff --git a/source/x265cli.h b/source/x265cli.h index 9eb571c..46a2b68 100644 --- a/source/x265cli.h +++ b/source/x265cli.h @@ -264,6 +264,10 @@ static const struct option long_options[] = { "repeat-headers", no_argument, NULL, 0 }, { "aud", no_argument, NULL, 0 }, { "no-aud", no_argument, NULL, 0 }, + { "eob", no_argument, NULL, 0 }, + { "no-eob", no_argument, NULL, 0 }, + { "eos", no_argument, NULL, 0 }, + { "no-eos", no_argument, NULL, 0 }, { "info", no_argument, NULL, 0 }, { "no-info", no_argument, NULL, 0 }, { "zones", required_argument, NULL, 0 }, -- 1.8.3.1 -- Thanks & Regards *Niranjan Kumar B* Video Codec Engineer Media & AI Analytics +91 958 511 1449 <https://multicorewareinc.com/>
x265_patch.patch
Description: Binary data
_______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel