<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Apr 2, 2018 at 6:31 PM, <span dir="ltr"><<a href="mailto:santhoshini@multicorewareinc.com" target="_blank">santhoshini@multicorewareinc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br>
# User Santhoshini Sekar <<a href="mailto:santhoshini@multicorewareinc.com">santhoshini@multicorewareinc.<wbr>com</a>><br>
# Date 1522673234 -19800<br>
# Mon Apr 02 18:17:14 2018 +0530<br>
# Node ID 6337356c86a4f5a49f275eb466d6fa<wbr>e32e6eb145<br>
# Parent 946f82dbf4e80cb272f43a32a78ba2<wbr>b186469845<br>
introduce new CLI single-sei to write all SEI messages in one single NAL<br>
<br>
diff --git a/doc/reST/cli.rst b/doc/reST/cli.rst<br>
--- a/doc/reST/cli.rst<br>
+++ b/doc/reST/cli.rst<br>
@@ -2221,6 +2221,10 @@<br>
.. option:: --idr-recovery-sei, --no-idr-recoveery-sei<br>
Emit RecoveryPoint info as sei in bitstream for each IDR frame. Default disabled.<br>
<br>
+.. option:: --single-sei, --no-single-sei<br>
+ Emit SEI messages in a single NAL unit instead of multiple NALs. Default disabled.<br>
+ When HRD SEI is enabled the HM decoder will throw a warning.<br>
+<br>
DCT Approximations<br>
=================<br>
<br>
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt<br>
--- a/source/CMakeLists.txt<br>
+++ b/source/CMakeLists.txt<br>
@@ -29,7 +29,7 @@<br>
option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)<br>
mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)<br>
# X265_BUILD must be incremented each time the public API is changed<br>
-set(X265_BUILD 156)<br>
+set(X265_BUILD 157)<br>
configure_file("${PROJECT_<wbr>SOURCE_DIR}/<a href="http://x265.def.in" rel="noreferrer" target="_blank">x265.def.in</a>"<br>
"${PROJECT_BINARY_DIR}/x265.<wbr>def")<br>
configure_file("${PROJECT_<wbr>SOURCE_DIR}/<a href="http://x265_config.h.in" rel="noreferrer" target="_blank">x265_config.h.in</a>"<br>
diff --git a/source/common/param.cpp b/source/common/param.cpp<br>
--- a/source/common/param.cpp<br>
+++ b/source/common/param.cpp<br>
@@ -301,6 +301,7 @@<br>
/* DCT Approximations */<br>
param->bLowPassDct = 0;<br>
param->bMVType = 0;<br>
+ param->bSingleSeiNal = 0;<br>
}<br>
<br>
int x265_param_default_preset(<wbr>x265_param* param, const char* preset, const char* tune)<br>
@@ -1017,6 +1018,7 @@<br>
OPT("radl") p->radl = atoi(value);<br>
OPT("max-ausize-factor") p->maxAUSizeFactor = atof(value);<br>
OPT("dynamic-refine") p->bDynamicRefine = atobool(value);<br>
+ OPT("single-sei") p->bSingleSeiNal = atobool(value);<br>
else<br>
return X265_PARAM_BAD_NAME;<br>
}<br>
@@ -1382,6 +1384,14 @@<br>
if (param-><wbr>masteringDisplayColorVolume || param->maxFALL || param->maxCLL)<br>
param->bEmitHDRSEI = 1;<br>
<br>
+ bool isSingleSEI = ((param->bEmitHRDSEI || param->bEmitInfoSEI || param->decodedPictureHashSEI ||<br>
+ param-><wbr>masteringDisplayColorVolume || param->maxCLL || param->maxFALL ||<br>
+ param->bEmitHDRSEI || param->bEmitIDRRecoverySEI) && param->bSingleSeiNal);<br>
+ if (!isSingleSEI)<br>
+ {<br>
+ param->bSingleSeiNal = 0;<br>
+ x265_log(param, X265_LOG_WARNING, "None of the SEI messages are enabled. Diabling Single SEI NAL\n");<br>
+ }<br>
return check_failed;<br>
}<br>
<br>
@@ -1528,6 +1538,7 @@<br>
TOOLOPT(!param-><wbr>bSaoNonDeblocked && param->bEnableSAO, "sao");<br>
TOOLOPT(param->rc.bStatWrite, "stats-write");<br>
TOOLOPT(param->rc.bStatRead, "stats-read");<br>
+ TOOLOPT(param->bSingleSeiNal, "single-sei");<br>
#if ENABLE_HDR10_PLUS<br>
TOOLOPT(param->toneMapFile != NULL, "dhdr10-info");<br>
#endif<br>
@@ -1751,6 +1762,7 @@<br>
s += sprintf(s, " copy-pic=%d", p->bCopyPicToFrame);<br>
s += sprintf(s, " max-ausize-factor=%.1f", p->maxAUSizeFactor);<br>
BOOL(p->bDynamicRefine, "dynamic-refine");<br>
+ BOOL(p->bSingleSeiNal, "single-sei");<br>
#undef BOOL<br>
return buf;<br>
}<br>
diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp<br>
--- a/source/encoder/encoder.cpp<br>
+++ b/source/encoder/encoder.cpp<br>
@@ -2289,26 +2289,26 @@<br>
sbacCoder.codePPS(m_pps, (m_param->maxSlices <= 1), m_iPPSQpMinus26);<br>
bs.writeByteAlignment();<br>
list.serialize(NAL_UNIT_PPS, bs);<br>
-<br>
+ if (m_param->bSingleSeiNal)<br>
+ bs.resetBits();<br>
if (m_param->bEmitHDRSEI)<br>
{<br>
SEIContentLightLevel cllsei;<br>
cllsei.max_content_light_level = m_param->maxCLL;<br>
cllsei.max_pic_average_light_<wbr>level = m_param->maxFALL;<br>
- bs.resetBits();<br>
+ if (!m_param->bSingleSeiNal)<br>
+ bs.resetBits();<br>
cllsei.write(bs, m_sps);<br>
- bs.writeByteAlignment();<br>
- list.serialize(NAL_UNIT_<wbr>PREFIX_SEI, bs);<br>
-<br>
+ cllsei.alignAndSerialize(bs, false, m_param->bSingleSeiNal, NAL_UNIT_PREFIX_SEI, list);<br>
if (m_param-><wbr>masteringDisplayColorVolume)<br>
{<br>
SEIMasteringDisplayColorVolume mdsei;<br>
if (mdsei.parse(m_param-><wbr>masteringDisplayColorVolume))<br>
{<br>
- bs.resetBits();<br>
+ if (!m_param->bSingleSeiNal)<br>
+ bs.resetBits();<br>
mdsei.write(bs, m_sps);<br>
- bs.writeByteAlignment();<br>
- list.serialize(NAL_UNIT_<wbr>PREFIX_SEI, bs);<br>
+ mdsei.alignAndSerialize(bs, false, m_param->bSingleSeiNal, NAL_UNIT_PREFIX_SEI, list);<br>
}<br>
else<br>
x265_log(m_param, X265_LOG_WARNING, "unable to parse mastering display color volume info\n");<br>
@@ -2328,15 +2328,13 @@<br>
"Copyright 2013-2018 (c) Multicoreware, Inc - "<br>
"<a href="http://x265.org" rel="noreferrer" target="_blank">http://x265.org</a> - options: %s",<br>
X265_BUILD, PFX(version_str), PFX(build_info_str), opts);<br>
-<br>
- bs.resetBits();<br>
+ if (!m_param->bSingleSeiNal)<br>
+ bs.resetBits();<br>
SEIuserDataUnregistered idsei;<br>
idsei.m_userData = (uint8_t*)buffer;<br>
idsei.setSize((uint32_t)<wbr>strlen(buffer));<br>
idsei.write(bs, m_sps);<br>
- bs.writeByteAlignment();<br>
- list.serialize(NAL_UNIT_<wbr>PREFIX_SEI, bs);<br>
-<br>
+ idsei.alignAndSerialize(bs, false, m_param->bSingleSeiNal, NAL_UNIT_PREFIX_SEI, list);<br>
X265_FREE(buffer);<br>
}<br>
<br>
@@ -2350,12 +2348,12 @@<br>
SEIActiveParameterSets sei;<br>
sei.m_selfContainedCvsFlag = true;<br>
sei.m_noParamSetUpdateFlag = true;<br>
- bs.resetBits();<br>
+ if (!m_param->bSingleSeiNal)<br>
+ bs.resetBits();<br>
int payloadSize = sei.countPayloadSize(m_sps);<br>
sei.setSize(payloadSize);<br>
sei.write(bs, m_sps);<br>
- bs.writeByteAlignment();<br>
- list.serialize(NAL_UNIT_<wbr>PREFIX_SEI, bs);<br>
+ sei.alignAndSerialize(bs, false, m_param->bSingleSeiNal, NAL_UNIT_PREFIX_SEI, list);<br>
}<br>
}<br>
<br>
diff --git a/source/encoder/frameencoder.<wbr>cpp b/source/encoder/frameencoder.<wbr>cpp<br>
--- a/source/encoder/frameencoder.<wbr>cpp<br>
+++ b/source/encoder/frameencoder.<wbr>cpp<br>
@@ -393,6 +393,7 @@<br>
* not repeating headers (since AUD is supposed to be the first NAL in the access<br>
* unit) */<br>
Slice* slice = m_frame->m_encData->m_slice;<br>
+<br>
if (m_param-><wbr>bEnableAccessUnitDelimiters && (m_frame->m_poc || m_param->bRepeatHeaders))<br>
{<br>
m_bs.resetBits();<br>
@@ -400,6 +401,8 @@<br>
m_entropyCoder.codeAUD(*slice)<wbr>;<br>
m_bs.writeByteAlignment();<br>
m_nalList.serialize(NAL_UNIT_<wbr>ACCESS_UNIT_DELIMITER, m_bs);<br>
+ if (m_param->bSingleSeiNal)<br>
+ m_bs.resetBits();<br>
}<br>
if (m_frame->m_lowres.bKeyframe && m_param->bRepeatHeaders)<br>
{<br>
@@ -527,7 +530,7 @@<br>
}<br>
<br>
bool isIDR = m_frame->m_lowres.sliceType == X265_TYPE_IDR;<br>
- writeSei = payloadChange || isIDR;<br>
+ writeSei = (payloadChange || isIDR);<br>
}<br>
}<br>
}<br>
@@ -633,12 +636,12 @@<br>
bpSei->m_dpbDelayOffset = 0;<br>
// hrdFullness() calculates the initial CPB removal delay and offset<br>
m_top->m_rateControl-><wbr>hrdFullness(bpSei);<br>
- m_bs.resetBits();<br>
+ if (!m_param->bSingleSeiNal)<br>
+ m_bs.resetBits();<br>
int payloadSize = bpSei->countPayloadSize(*<wbr>slice->m_sps);<br>
bpSei->setSize(payloadSize);<br>
bpSei->write(m_bs, *slice->m_sps);<br>
- m_bs.writeByteAlignment();<br>
- m_nalList.serialize(NAL_UNIT_<wbr>PREFIX_SEI, m_bs);<br>
+ bpSei->alignAndSerialize(m_bs, false, m_param->bSingleSeiNal, NAL_UNIT_PREFIX_SEI, m_nalList);<br>
<br>
m_top->m_lastBPSEI = m_rce.encodeOrder;<br>
}<br>
@@ -650,11 +653,11 @@<br>
sei.m_recoveryPocCnt = 0;<br>
sei.m_exactMatchingFlag = true;<br>
sei.m_brokenLinkFlag = false;<br>
- m_bs.resetBits();<br>
+ if (!m_param->bSingleSeiNal)<br>
+ m_bs.resetBits();<br>
sei.setSize(sei.<wbr>countPayloadSize(*slice->m_<wbr>sps));<br>
sei.write(m_bs, *slice->m_sps);<br>
- m_bs.writeByteAlignment();<br>
- m_nalList.serialize(NAL_UNIT_<wbr>PREFIX_SEI, m_bs);<br>
+ sei.alignAndSerialize(m_bs, false, m_param->bSingleSeiNal, NAL_UNIT_PREFIX_SEI, m_nalList);<br>
}<br>
}<br>
<br>
@@ -686,12 +689,12 @@<br>
sei->m_auCpbRemovalDelay = X265_MIN(X265_MAX(1, m_rce.encodeOrder - prevBPSEI), (1 << hrd->cpbRemovalDelayLength));<br>
sei->m_picDpbOutputDelay = slice->m_sps->numReorderPics + poc - m_rce.encodeOrder;<br>
}<br>
- m_bs.resetBits();<br>
+ if (!m_param->bSingleSeiNal)<br>
+ m_bs.resetBits();<br>
int payloadSize = sei->countPayloadSize(*slice-><wbr>m_sps);<br>
sei->setSize(payloadSize);<br>
sei->write(m_bs, *slice->m_sps);<br>
- m_bs.writeByteAlignment();<br>
- m_nalList.serialize(NAL_UNIT_<wbr>PREFIX_SEI, m_bs);<br>
+ sei->alignAndSerialize(m_bs, false, m_param->bSingleSeiNal, NAL_UNIT_PREFIX_SEI, m_nalList);<br>
}<br>
<br>
/* Write user SEI */<br>
@@ -702,11 +705,11 @@<br>
{<br>
SEIuserDataUnregistered sei;<br>
sei.m_userData = payload->payload;<br>
- m_bs.resetBits();<br>
+ if (!m_param->bSingleSeiNal)<br>
+ m_bs.resetBits();<br>
sei.setSize(payload-><wbr>payloadSize);<br>
sei.write(m_bs, *slice->m_sps);<br>
- m_bs.writeByteAlignment();<br>
- m_nalList.serialize(NAL_UNIT_<wbr>PREFIX_SEI, m_bs);<br>
+ sei.alignAndSerialize(m_bs, false, m_param->bSingleSeiNal, NAL_UNIT_PREFIX_SEI, m_nalList);<br>
}<br>
else if (payload->payloadType == USER_DATA_REGISTERED_ITU_T_<wbr>T35)<br>
{<br>
@@ -717,13 +720,21 @@<br>
m_bs.resetBits();<br>
sei.setSize(payload-><wbr>payloadSize);<br>
sei.write(m_bs, *slice->m_sps);<br>
- m_bs.writeByteAlignment();<br>
- m_nalList.serialize(NAL_UNIT_<wbr>PREFIX_SEI, m_bs);<br>
+ sei.alignAndSerialize(m_bs, true, m_param->bSingleSeiNal, NAL_UNIT_PREFIX_SEI, m_nalList);<br>
}<br>
}<br>
else<br>
x265_log(m_param, X265_LOG_ERROR, "Unrecognized SEI type\n");<br>
}<br>
+ bool isSei = (m_frame->m_lowres.bKeyframe &&<br>
+ (m_param->bRepeatHeaders || m_param->bEmitHRDSEI<br>
+ || !!m_param->interlaceMode || m_param->bEmitIDRRecoverySEI))<wbr>;<br>
+<br>
+ if (isSei && m_param->bSingleSeiNal)<br>
+ {<br>
+ m_bs.writeByteAlignment();<br>
+ m_nalList.serialize(NAL_UNIT_<wbr>PREFIX_SEI, m_bs);<br>
+ }<br>
/* CQP and CRF (without capped VBV) doesn't use mid-frame statistics to<br>
* tune RateControl parameters for other frames.<br>
* Hence, for these modes, update m_startEndOrder and unlock RC for previous threads waiting in<br>
@@ -1055,7 +1066,8 @@<br>
<br>
m_nalList.serialize(slice->m_<wbr>nalUnitType, m_bs);<br>
}<br>
-<br>
+ if (isSei && m_param->bSingleSeiNal)<br>
+ m_bs.resetBits();<br>
<br>
if (m_param-><wbr>decodedPictureHashSEI)<br>
{<br>
@@ -1085,8 +1097,7 @@<br>
m_bs.resetBits();<br>
m_seiReconPictureDigest.<wbr>setSize(payloadSize);<br>
m_seiReconPictureDigest.write(<wbr>m_bs, *slice->m_sps);<br>
- m_bs.writeByteAlignment();<br>
- m_nalList.serialize(NAL_UNIT_<wbr>SUFFIX_SEI, m_bs);<br>
+ m_seiReconPictureDigest.<wbr>alignAndSerialize(m_bs, true, m_param->bSingleSeiNal, NAL_UNIT_SUFFIX_SEI, m_nalList);<br>
}<br>
<br>
uint64_t bytes = 0;<br>
diff --git a/source/encoder/sei.cpp b/source/encoder/sei.cpp<br>
--- a/source/encoder/sei.cpp<br>
+++ b/source/encoder/sei.cpp<br>
@@ -44,6 +44,15 @@<br>
return count;<br>
}<br>
<br>
+void SEI::alignAndSerialize(<wbr>Bitstream& bs, int lastSei, int isSingleSei, NalUnitType nalUnitType, NALList& list)<br>
+{<br>
+ if (lastSei || !isSingleSei)<br>
+ {<br>
+ bs.writeByteAlignment();<br>
+ list.serialize(nalUnitType, bs);<br>
+ }<br>
+}<br>
+<br>
/* marshal a single SEI message sei, storing the marshalled representation<br>
* in bitstream bs */<br>
void SEI::write(Bitstream& bs, const SPS& sps)<br>
diff --git a/source/encoder/sei.h b/source/encoder/sei.h<br>
--- a/source/encoder/sei.h<br>
+++ b/source/encoder/sei.h<br>
@@ -27,6 +27,7 @@<br>
#include "common.h"<br>
#include "bitstream.h"<br>
#include "slice.h"<br>
+#include "nal.h"<br>
<br>
namespace X265_NS {<br>
// private namespace<br>
@@ -37,6 +38,7 @@<br>
/* SEI users call write() to marshal an SEI to a bitstream.<br>
* The write() method calls writeSEI() which encodes the header */<br>
void write(Bitstream& bs, const SPS& sps);<br>
+ void alignAndSerialize(Bitstream& bs, int lastSei, int isSingleSei, NalUnitType nalUnitType, NALList& list);<br>
int countPayloadSize(const SPS& sps);<br>
void setSize(uint32_t size);<br>
virtual ~SEI() {}<br>
diff --git a/source/x265.h b/source/x265.h<br>
--- a/source/x265.h<br>
+++ b/source/x265.h<br>
@@ -1563,6 +1563,9 @@<br>
<br>
/* Dynamically change refine-inter at block level*/<br>
int bDynamicRefine;<br>
+<br>
+ /* Enable writing all SEI messgaes in one single NAL instead of mul*/<br>
+ int bSingleSeiNal;<br>
} x265_param;<br>
<br>
/* x265_param_alloc:<br>
diff --git a/source/x265cli.h b/source/x265cli.h<br>
--- a/source/x265cli.h<br>
+++ b/source/x265cli.h<br>
@@ -298,6 +298,8 @@<br>
{ "max-ausize-factor", required_argument, NULL, 0 },<br>
{ "idr-recovery-sei", no_argument, NULL, 0 },<br>
{ "no-idr-recovery-sei", no_argument, NULL, 0 },<br>
+ { "single-sei", no_argument, NULL, 0 },<br>
+ { "no-single-sei", no_argument, NULL, 0 },<br>
{ 0, 0, 0, 0 },<br>
{ 0, 0, 0, 0 },<br>
{ 0, 0, 0, 0 },<br>
<br>______________________________<wbr>_________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/<wbr>listinfo/x265-devel</a><br>
<br></blockquote></div><br></div><div class="gmail_extra">Pushed.</div></div>