[x265] [PATCH] SEI: Insert buffering period and picture timing SEI messages
kavitha at multicorewareinc.com
kavitha at multicorewareinc.com
Sun Jun 1 18:40:32 CEST 2014
# HG changeset patch
# User Kavitha Sampath <kavitha at multicorewareinc.com>
# Date 1401640530 -19800
# Sun Jun 01 22:05:30 2014 +0530
# Node ID 322bcc4d26dd358d946b9e8da369f52690344af4
# Parent 592ef184549ef631c0fe725cb9fe3cbab8de1db4
SEI: Insert buffering period and picture timing SEI messages
The buffering period SEI message is inserted for every key frame and the
picture timing SEI is inserted for every frame. The commit also computes the
HRD parameters carried in these SEI messages. HRD parameters are signalled by
enabling --hrd.
diff -r 592ef184549e -r 322bcc4d26dd doc/reST/cli.rst
--- a/doc/reST/cli.rst Thu May 29 23:42:16 2014 +0300
+++ b/doc/reST/cli.rst Sun Jun 01 22:05:30 2014 +0530
@@ -846,6 +846,13 @@
to keep the stream headers for you and you want keyframes to be
random access points. Default disabled
+.. option:: --hrd, --no-hrd
+
+ Enable the signalling of HRD parameters to the decoder. The HRD
+ parameters are carried by the Buffering Period SEI messages and
+ Picture Timing SEI messages providing timing information to the
+ decoder. Default disabled
+
.. option:: --aud, --no-aud
Emit an access unit delimiter NAL at the start of each slice access
diff -r 592ef184549e -r 322bcc4d26dd source/CMakeLists.txt
--- a/source/CMakeLists.txt Thu May 29 23:42:16 2014 +0300
+++ b/source/CMakeLists.txt Sun Jun 01 22:05:30 2014 +0530
@@ -19,7 +19,7 @@
include(CheckCXXCompilerFlag)
# X265_BUILD must be incremented each time the public API is changed
-set(X265_BUILD 20)
+set(X265_BUILD 21)
configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
"${PROJECT_BINARY_DIR}/x265.def")
configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
diff -r 592ef184549e -r 322bcc4d26dd source/Lib/TLibCommon/SEI.h
--- a/source/Lib/TLibCommon/SEI.h Thu May 29 23:42:16 2014 +0300
+++ b/source/Lib/TLibCommon/SEI.h Sun Jun 01 22:05:30 2014 +0530
@@ -185,14 +185,7 @@
PayloadType payloadType() const { return PICTURE_TIMING; }
- SEIPictureTiming()
- : m_picStruct(0)
- , m_sourceScanType(0)
- , m_duplicateFlag(false)
- , m_picDpbOutputDuDelay(0)
- , m_numNalusInDuMinus1(NULL)
- , m_duCpbRemovalDelayMinus1(NULL)
- {}
+ SEIPictureTiming() {}
virtual ~SEIPictureTiming()
{
diff -r 592ef184549e -r 322bcc4d26dd source/common/param.cpp
--- a/source/common/param.cpp Thu May 29 23:42:16 2014 +0300
+++ b/source/common/param.cpp Sun Jun 01 22:05:30 2014 +0530
@@ -613,6 +613,7 @@
OPT("hash") p->decodedPictureHashSEI = atoi(value);
OPT("aud") p->bEnableAccessUnitDelimiters = atobool(value);
OPT("b-pyramid") p->bBPyramid = atobool(value);
+ OPT("hrd") p->bEmitHRDSEI = atobool(value);
OPT("aq-mode") p->rc.aqMode = atoi(value);
OPT("aq-strength") p->rc.aqStrength = atof(value);
OPT("vbv-maxrate") p->rc.vbvMaxBitrate = atoi(value);
diff -r 592ef184549e -r 322bcc4d26dd source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Thu May 29 23:42:16 2014 +0300
+++ b/source/encoder/encoder.cpp Sun Jun 01 22:05:30 2014 +0530
@@ -184,6 +184,7 @@
}
}
}
+ m_rateControl->init(&m_frameEncoder[0].m_sps);
m_lookahead->init();
m_encodeStartTime = x265_mdate();
m_totalFrameThreads = param->frameNumThreads;
@@ -1121,8 +1122,8 @@
vui->setFrameFieldInfoPresentFlag(!!param->interlaceMode);
vui->setFieldSeqFlag(!!param->interlaceMode);
- vui->setHrdParametersPresentFlag(false);
- vui->getHrdParameters()->setNalHrdParametersPresentFlag(false);
+ vui->setHrdParametersPresentFlag(param->bEmitHRDSEI);
+ vui->getHrdParameters()->setNalHrdParametersPresentFlag(param->bEmitHRDSEI);
vui->getHrdParameters()->setSubPicHrdParamsPresentFlag(false);
vui->getTimingInfo()->setTimingInfoPresentFlag(true);
@@ -1424,12 +1425,10 @@
m_nonPackedConstraintFlag = false;
m_frameOnlyConstraintFlag = false;
- m_bufferingPeriodSEIEnabled = 0;
m_displayOrientationSEIAngle = 0;
m_gradualDecodingRefreshInfoEnabled = 0;
m_decodingUnitInfoSEIEnabled = 0;
m_useScalingListId = 0;
- m_activeParameterSetsSEIEnabled = 0;
m_minSpatialSegmentationIdc = 0;
m_neutralChromaIndicationFlag = false;
m_pocProportionalToTimingFlag = false;
diff -r 592ef184549e -r 322bcc4d26dd source/encoder/encoder.h
--- a/source/encoder/encoder.h Thu May 29 23:42:16 2014 +0300
+++ b/source/encoder/encoder.h Sun Jun 01 22:05:30 2014 +0530
@@ -82,7 +82,6 @@
int64_t m_firstPts;
int64_t m_bframeDelayTime;
int64_t m_prevReorderedPts[2];
- int64_t m_encodedFrameNum;
ThreadPool* m_threadPool;
Lookahead* m_lookahead;
@@ -157,7 +156,8 @@
bool m_bPCMFilterDisableFlag;
bool m_loopFilterAcrossTilesEnabledFlag;
- int m_bufferingPeriodSEIEnabled;
+ int64_t m_encodedFrameNum;
+ int m_lastBPSEI;
int m_displayOrientationSEIAngle;
int m_gradualDecodingRefreshInfoEnabled;
int m_decodingUnitInfoSEIEnabled;
@@ -168,7 +168,6 @@
bool m_TransquantBypassEnableFlag; ///< transquant_bypass_enable_flag setting in PPS.
bool m_CUTransquantBypassFlagValue; ///< if transquant_bypass_enable_flag, the fixed value to use for the per-CU cu_transquant_bypass_flag.
- int m_activeParameterSetsSEIEnabled; ///< enable active parameter set SEI message
bool m_neutralChromaIndicationFlag;
bool m_pocProportionalToTimingFlag;
diff -r 592ef184549e -r 322bcc4d26dd source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp Thu May 29 23:42:16 2014 +0300
+++ b/source/encoder/frameencoder.cpp Sun Jun 01 22:05:30 2014 +0530
@@ -143,11 +143,17 @@
{
m_sps.setHrdParameters(m_cfg->param->fpsNum, m_cfg->param->fpsDenom, 0, m_cfg->param->rc.bitrate, m_cfg->param->bframes > 0);
}
- if (m_cfg->m_bufferingPeriodSEIEnabled || m_cfg->m_decodingUnitInfoSEIEnabled)
+ if (m_cfg->param->bEmitHRDSEI || m_cfg->m_decodingUnitInfoSEIEnabled)
{
m_sps.getVuiParameters()->setHrdParametersPresentFlag(true);
}
+ // initialize HRD parameters of SPS
+ if (m_cfg->param->bEmitHRDSEI)
+ {
+ top->m_rateControl->initHRD(&m_sps);
+ }
+
m_sps.setTMVPFlagsPresent(true);
// set default slice level flag to the same as SPS level flag
@@ -266,7 +272,7 @@
nalunits[count]->init(nalu);
count++;
- if (m_cfg->m_activeParameterSetsSEIEnabled)
+ if (m_cfg->param->bEmitHRDSEI)
{
SEIActiveParameterSets sei;
sei.activeVPSId = m_top->m_vps.getVPSId();
@@ -275,6 +281,7 @@
sei.numSpsIdsMinus1 = 0;
sei.activeSeqParamSetId = m_sps.getSPSId();
+ nalu.resetToType(NAL_UNIT_PREFIX_SEI);
entropyCoder->setBitstream(&nalu.m_bitstream);
m_seiWriter.writeSEImessage(nalu.m_bitstream, sei, &m_sps);
writeRBSPTrailingBits(nalu.m_bitstream);
@@ -404,6 +411,7 @@
TEncEntropy* entropyCoder = getEntropyCoder(0);
TComSlice* slice = m_pic->getSlice();
int chFmt = slice->getSPS()->getChromaFormatIdc();
+ int totalCoded = (int)m_top->m_encodedFrameNum - 1;
m_nalCount = 0;
entropyCoder->setEntropyCoder(&m_sbacCoder, NULL);
@@ -526,6 +534,34 @@
if (slice->getPic()->m_lowres.bKeyframe)
{
+ if (m_cfg->param->bEmitHRDSEI)
+ {
+ OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
+ SEIBufferingPeriod sei_buffering_period;
+ sei_buffering_period.m_bpSeqParameterSetId = m_sps.getSPSId();
+ sei_buffering_period.m_rapCpbParamsPresentFlag = 0;
+
+ // for the concatenation, it can be set to one during splicing.
+ sei_buffering_period.m_concatenationFlag = 0;
+
+ // since the temporal layer HRD is not ready, we assumed it is fixed
+ sei_buffering_period.m_auCpbRemovalDelayDelta = 1;
+ sei_buffering_period.m_cpbDelayOffset = 0;
+ sei_buffering_period.m_dpbDelayOffset = 0;
+
+ // hrdFullness() calculates the initial CPB removal delay and offset
+ m_top->m_rateControl->hrdFullness(&sei_buffering_period);
+ m_seiWriter.writeSEImessage(nalu.m_bitstream, sei_buffering_period, &m_sps);
+ writeRBSPTrailingBits(nalu.m_bitstream);
+ m_nalList[m_nalCount] = X265_MALLOC(NALUnitEBSP, 1);
+ if (m_nalList[m_nalCount])
+ {
+ m_nalList[m_nalCount]->init(nalu);
+ m_nalCount++;
+ }
+
+ m_top->m_lastBPSEI = totalCoded;
+ }
if (m_cfg->m_gradualDecodingRefreshInfoEnabled && !slice->getRapPicFlag())
{
// Gradual decoding refresh SEI
@@ -568,21 +604,36 @@
}
}
- if (!!m_cfg->param->interlaceMode)
+ if (m_cfg->param->bEmitHRDSEI || !!m_cfg->param->interlaceMode)
{
+ // Picture Timing SEI
OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
+ SEIPictureTiming sei;
- SEIPictureTiming sei;
+ int poc = slice->getPOC();
+ int cpbDelayLength = slice->getSPS()->getVuiParameters()->getHrdParameters()->getCpbRemovalDelayLengthMinus1() + 1;
if (m_cfg->param->interlaceMode == 2)
{
- sei.m_picStruct = (slice->getPOC() & 1) ? 1 /* top */ : 2 /* bottom */;
+ sei.m_picStruct = (poc & 1) ? 1 /* top */ : 2 /* bottom */;
+ }
+ else if (m_cfg->param->interlaceMode == 1)
+ {
+ sei.m_picStruct = (poc & 1) ? 2 /* bottom */ : 1 /* top */;
}
else
{
- sei.m_picStruct = (slice->getPOC() & 1) ? 2 /* bottom */ : 1 /* top */;
+ sei.m_picStruct = 0;
}
sei.m_sourceScanType = 0;
- sei.m_duplicateFlag = 0;
+ sei.m_duplicateFlag = false;
+ sei.m_picDpbOutputDuDelay = 0;
+ sei.m_numNalusInDuMinus1 = NULL;
+ sei.m_duCpbRemovalDelayMinus1 = NULL;
+
+ // The m_aucpbremoval delay specifies how many clock ticks the access unit associated with the picture timing
+ // SEI message has to wait after removal of the access unit with the most recent buffering period SEI message
+ sei.m_auCpbRemovalDelay = X265_MIN(X265_MAX(1, totalCoded - m_top->m_lastBPSEI), (1 << cpbDelayLength));
+ sei.m_picDpbOutputDelay = slice->getSPS()->getNumReorderPics(0) + poc - totalCoded;
entropyCoder->setBitstream(&nalu.m_bitstream);
m_seiWriter.writeSEImessage(nalu.m_bitstream, sei, &m_sps);
diff -r 592ef184549e -r 322bcc4d26dd source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp Thu May 29 23:42:16 2014 +0300
+++ b/source/encoder/ratecontrol.cpp Sun Jun 01 22:05:30 2014 +0530
@@ -27,12 +27,60 @@
#include "encoder.h"
#include "slicetype.h"
#include "ratecontrol.h"
+#include "TLibCommon/SEI.h"
+
+#define BR_SHIFT 6
+#define CPB_SHIFT 4
using namespace x265;
/* Amortize the partial cost of I frames over the next N frames */
const double RateControl::amortizeFraction = 0.85;
const int RateControl::amortizeFrames = 75;
+namespace {
+
+inline int calcScale(uint32_t x)
+{
+ static uint8_t lut[16] = {4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};
+ int y, z = (((x & 0xffff) - 1) >> 27) & 16;
+ x >>= z;
+ z += y = (((x & 0xff) - 1) >> 28) & 8;
+ x >>= y;
+ z += y = (((x & 0xf) - 1) >> 29) & 4;
+ x >>= y;
+ return z + lut[x&0xf];
+}
+
+inline int calcLength(uint32_t x)
+{
+ static uint8_t lut[16] = {4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0};
+ int y, z = (((x >> 16) - 1) >> 27) & 16;
+ x >>= z ^ 16;
+ z += y = ((x - 0x100) >> 28) & 8;
+ x >>= y ^ 8;
+ z += y = ((x - 0x10) >> 29) & 4;
+ x >>= y ^ 4;
+ return z + lut[x];
+}
+
+inline void reduceFraction(int* n, int* d)
+{
+ int a = *n;
+ int b = *d;
+ int c;
+ if (!a || !b)
+ return;
+ c = a % b;
+ while (c)
+ {
+ a = b;
+ b = c;
+ c = a % b;
+ }
+ *n /= b;
+ *d /= b;
+}
+} // end anonymous namespace
/* Compute variance to derive AC energy of each block */
static inline uint32_t acEnergyVar(TComPic *pic, uint64_t sum_ssd, int shift, int i)
@@ -287,40 +335,11 @@
param->rc.vbvMaxBitrate = 0;
}
- isVbv = param->rc.vbvMaxBitrate > 0 && param->rc.vbvBufferSize > 0;
- double fps = (double)param->fpsNum / param->fpsDenom;
- if (isVbv)
- {
- /* We don't support changing the ABR bitrate right now,
- so if the stream starts as CBR, keep it CBR. */
- if (param->rc.vbvBufferSize < (int)(param->rc.vbvMaxBitrate / fps))
- {
- param->rc.vbvBufferSize = (int)(param->rc.vbvMaxBitrate / fps);
- x265_log(param, X265_LOG_WARNING, "VBV buffer size cannot be smaller than one frame, using %d kbit\n",
- param->rc.vbvBufferSize);
- }
- int vbvBufferSize = param->rc.vbvBufferSize * 1000;
- int vbvMaxBitrate = param->rc.vbvMaxBitrate * 1000;
-
- bufferRate = vbvMaxBitrate / fps;
- vbvMaxRate = vbvMaxBitrate;
- bufferSize = vbvBufferSize;
- singleFrameVbv = bufferRate * 1.1 > bufferSize;
-
- if (param->rc.vbvBufferInit > 1.)
- param->rc.vbvBufferInit = Clip3(0.0, 1.0, param->rc.vbvBufferInit / param->rc.vbvBufferSize);
- param->rc.vbvBufferInit = Clip3(0.0, 1.0, X265_MAX(param->rc.vbvBufferInit, bufferRate / bufferSize));
- bufferFillFinal = bufferSize * param->rc.vbvBufferInit;
- isCbr = param->rc.rateControlMode == X265_RC_ABR
- && param->rc.vbvMaxBitrate <= param->rc.bitrate;
- }
-
bframes = param->bframes;
bframeBits = 0;
leadingNoBSatd = 0;
ipOffset = 6.0 * X265_LOG2(param->rc.ipFactor);
pbOffset = 6.0 * X265_LOG2(param->rc.pbFactor);
- init();
/* Adjust the first frame in order to stabilize the quality level compared to the rest */
#define ABR_INIT_QP_MIN (24 + QP_BD_OFFSET)
@@ -347,8 +366,41 @@
lstep = pow(2, param->rc.qpStep / 6.0);
}
-void RateControl::init()
+void RateControl::init(TComSPS *sps)
{
+ isVbv = param->rc.vbvMaxBitrate > 0 && param->rc.vbvBufferSize > 0;
+ double fps = (double)param->fpsNum / param->fpsDenom;
+ if (isVbv)
+ {
+ /* We don't support changing the ABR bitrate right now,
+ so if the stream starts as CBR, keep it CBR. */
+ if (param->rc.vbvBufferSize < (int)(param->rc.vbvMaxBitrate / fps))
+ {
+ param->rc.vbvBufferSize = (int)(param->rc.vbvMaxBitrate / fps);
+ x265_log(param, X265_LOG_WARNING, "VBV buffer size cannot be smaller than one frame, using %d kbit\n",
+ param->rc.vbvBufferSize);
+ }
+ int vbvBufferSize = param->rc.vbvBufferSize * 1000;
+ int vbvMaxBitrate = param->rc.vbvMaxBitrate * 1000;
+
+ TComHRD* hrd = sps->getVuiParameters()->getHrdParameters();
+ if (hrd->getNalHrdParametersPresentFlag())
+ {
+ vbvBufferSize = (hrd->getCpbSizeValueMinus1(0, 0, 0) + 1) << (hrd->getCpbSizeScale() + CPB_SHIFT);
+ vbvMaxBitrate = (hrd->getBitRateValueMinus1(0, 0, 0) + 1) << (hrd->getBitRateScale() + BR_SHIFT);
+ }
+ bufferRate = vbvMaxBitrate / fps;
+ vbvMaxRate = vbvMaxBitrate;
+ bufferSize = vbvBufferSize;
+ singleFrameVbv = bufferRate * 1.1 > bufferSize;
+
+ if (param->rc.vbvBufferInit > 1.)
+ param->rc.vbvBufferInit = Clip3(0.0, 1.0, param->rc.vbvBufferInit / param->rc.vbvBufferSize);
+ param->rc.vbvBufferInit = Clip3(0.0, 1.0, X265_MAX(param->rc.vbvBufferInit, bufferRate / bufferSize));
+ bufferFillFinal = bufferSize * param->rc.vbvBufferInit;
+ isCbr = param->rc.rateControlMode == X265_RC_ABR
+ && param->rc.vbvMaxBitrate <= param->rc.bitrate;
+ }
totalBits = 0;
framesDone = 0;
double tuneCplxFactor = 1;
@@ -373,6 +425,45 @@
predBfromP = pred[0];
}
+void RateControl::initHRD(TComSPS *sps)
+{
+ int vbvBufferSize = param->rc.vbvBufferSize * 1000;
+ int vbvMaxBitrate = param->rc.vbvMaxBitrate * 1000;
+
+ // Init HRD
+ TComHRD* hrd = sps->getVuiParameters()->getHrdParameters();
+ hrd->setCpbCntMinus1(0, 0);
+ hrd->setLowDelayHrdFlag(0, false);
+ hrd->setFixedPicRateFlag(0, 1);
+ hrd->setPicDurationInTcMinus1(0, 0);
+
+ // normalize HRD size and rate to the value / scale notation
+ hrd->setBitRateScale(Clip3(0, 15, calcScale(vbvMaxBitrate) - BR_SHIFT));
+ hrd->setBitRateValueMinus1(0, 0, 0, (vbvMaxBitrate >> (hrd->getBitRateScale() + BR_SHIFT)) - 1);
+
+ hrd->setCpbSizeScale(Clip3(0, 15, calcScale(vbvBufferSize) - CPB_SHIFT));
+ hrd->setCpbSizeValueMinus1(0, 0, 0, (vbvBufferSize >> (hrd->getCpbSizeScale() + CPB_SHIFT)) - 1);
+ int bitRateUnscale = (hrd->getBitRateValueMinus1(0, 0, 0) + 1) << (hrd->getBitRateScale() + BR_SHIFT);
+ int cpbSizeUnscale = (hrd->getCpbSizeValueMinus1(0, 0, 0) + 1) << (hrd->getCpbSizeScale() + CPB_SHIFT);
+
+ // arbitrary
+ #define MAX_DURATION 0.5
+
+ TimingInfo *time = sps->getVuiParameters()->getTimingInfo();
+ int maxCpbOutputDelay = (int)(X265_MIN(param->keyframeMax * MAX_DURATION * time->getTimeScale() / time->getNumUnitsInTick(), INT_MAX));
+ int maxDpbOutputDelay = (int)(sps->getMaxDecPicBuffering(0) * MAX_DURATION * time->getTimeScale() / time->getNumUnitsInTick());
+ int maxDelay = (int)(90000.0 * cpbSizeUnscale / bitRateUnscale + 0.5);
+
+ hrd->setInitialCpbRemovalDelayLengthMinus1(2 + Clip3(4, 22, 32 - calcLength(maxDelay)) - 1);
+ hrd->setCpbRemovalDelayLengthMinus1(Clip3(4, 31, 32 - calcLength(maxCpbOutputDelay)) - 1);
+ hrd->setDpbOutputDelayLengthMinus1(Clip3(4, 31, 32 - calcLength(maxDpbOutputDelay)) - 1);
+
+ #undef MAX_DURATION
+
+ vbvBufferSize = cpbSizeUnscale;
+ vbvMaxBitrate = bitRateUnscale;
+}
+
void RateControl::rateControlStart(TComPic* pic, Lookahead *l, RateControlEntry* rce, Encoder* enc)
{
curSlice = pic->getSlice();
@@ -627,7 +718,7 @@
double underflow = 1.0 + (totalBits - wantedBitsWindow) / abrBuffer;
if (underflow < 0.9 && !isFrameDone)
{
- init();
+ init(NULL);
shortTermCplxSum = rce->lastSatd / (CLIP_DURATION(frameDuration) / BASE_FRAME_DURATION);
shortTermCplxCount = 1;
isAbrReset = true;
@@ -642,6 +733,26 @@
}
}
+void RateControl::hrdFullness(SEIBufferingPeriod *seiBP)
+{
+ TComVUI* vui = curSlice->getSPS()->getVuiParameters();
+ TComHRD* hrd = vui->getHrdParameters();
+ int num = 90000;
+ int denom = (hrd->getBitRateValueMinus1(0, 0, 0) + 1) << (hrd->getBitRateScale() + BR_SHIFT);
+ reduceFraction(&num, &denom);
+ uint64_t cpbState = (uint64_t)bufferFillFinal;
+ uint64_t cpbSize = (uint64_t)((hrd->getCpbSizeValueMinus1(0, 0, 0) + 1) << (hrd->getCpbSizeScale() + CPB_SHIFT));
+
+ if(cpbState < 0 || cpbState > cpbSize)
+ {
+ x265_log(param, X265_LOG_WARNING, "CPB %s: %.0lf bits in a %.0lf-bit buffer\n",
+ cpbState < 0 ? "underflow" : "overflow", (float)cpbState/denom, (float)cpbSize/denom);
+ }
+
+ seiBP->m_initialCpbRemovalDelay[0][0] = (uint32_t)(num * cpbState + denom) / denom;
+ seiBP->m_initialCpbRemovalDelayOffset[0][0] = (uint32_t)(num * cpbSize + denom) / denom - seiBP->m_initialCpbRemovalDelay[0][0];
+}
+
void RateControl::updateVbvPlan(Encoder* enc)
{
bufferFill = bufferFillFinal;
diff -r 592ef184549e -r 322bcc4d26dd source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h Thu May 29 23:42:16 2014 +0300
+++ b/source/encoder/ratecontrol.h Sun Jun 01 22:05:30 2014 +0530
@@ -26,14 +26,14 @@
#ifndef X265_RATECONTROL_H
#define X265_RATECONTROL_H
-#include "TLibCommon/CommonDef.h"
-
namespace x265 {
// encoder namespace
struct Lookahead;
class Encoder;
class TComPic;
+class TComSPS;
+class SEIBufferingPeriod;
#define BASE_FRAME_DURATION 0.04
@@ -129,6 +129,9 @@
void calcAdaptiveQuantFrame(TComPic *pic);
int rateControlEnd(TComPic* pic, int64_t bits, RateControlEntry* rce);
int rowDiagonalVbvRateControl(TComPic* pic, uint32_t row, RateControlEntry* rce, double& qpVbv);
+ void hrdFullness(SEIBufferingPeriod* sei);
+ void init(TComSPS* sps);
+ void initHRD(TComSPS* sps);
protected:
@@ -138,7 +141,6 @@
int residualFrames;
int residualCost;
- void init();
double getQScale(RateControlEntry *rce, double rateFactor);
double rateEstimateQscale(TComPic* pic, RateControlEntry *rce); // main logic for calculating QP based on ABR
void accumPQpUpdate();
diff -r 592ef184549e -r 322bcc4d26dd source/x265.cpp
--- a/source/x265.cpp Thu May 29 23:42:16 2014 +0300
+++ b/source/x265.cpp Sun Jun 01 22:05:30 2014 +0530
@@ -159,6 +159,8 @@
{ "strong-intra-smoothing", no_argument, NULL, 0 },
{ "no-cutree", no_argument, NULL, 0 },
{ "cutree", no_argument, NULL, 0 },
+ { "no-hrd", no_argument, NULL, 0 },
+ { "hrd", no_argument, NULL, 0 },
{ "sar", required_argument, NULL, 0 },
{ "overscan", required_argument, NULL, 0 },
{ "videoformat", required_argument, NULL, 0 },
@@ -386,6 +388,7 @@
H0(" --[no-]cutree Enable cutree for Adaptive Quantization. Default %s\n", OPT(param->rc.cuTree));
H0(" --cbqpoffs <integer> Chroma Cb QP Offset. Default %d\n", param->cbQpOffset);
H0(" --crqpoffs <integer> Chroma Cr QP Offset. Default %d\n", param->crQpOffset);
+ H0(" --[no-]hrd Enable HRD parameters signalling. Default %s\n", OPT(param->bEmitHRDSEI));
H0(" --rd <0..6> Level of RD in mode decision 0:least....6:full RDO. Default %d\n", param->rdLevel);
H0(" --psy-rd <0..2.0> Strength of psycho-visual optimization. Requires slow preset or below. Default %f\n", param->psyRd);
H0(" --[no-]signhide Hide sign bit of one coeff per TU (rdo). Default %s\n", OPT(param->bEnableSignHiding));
diff -r 592ef184549e -r 322bcc4d26dd source/x265.h
--- a/source/x265.h Thu May 29 23:42:16 2014 +0300
+++ b/source/x265.h Sun Jun 01 22:05:30 2014 +0530
@@ -410,6 +410,10 @@
* NAL at the start of every access unit. Default false */
int bEnableAccessUnitDelimiters;
+ /* Enables the buffering period SEI and picture timing SEI to signal the HRD
+ * parameteres. Default is disabled */
+ int bEmitHRDSEI;
+
/*== Coding Unit (CU) definitions ==*/
/* Maxiumum CU width and height in pixels. The size must be 64, 32, or 16.
More information about the x265-devel
mailing list