# HG changeset patch # User Aruna Matheswaran <ar...@multicorewareinc.com> # Date 1571294047 -19800 # Thu Oct 17 12:04:07 2019 +0530 # Node ID b2bb096d9e267df7e71a3464e71da14f663b42db # Parent 971180b100f871ba3635e825feea18662e6bdca8 API: New API to reconfigure zones
diff -r 971180b100f8 -r b2bb096d9e26 doc/reST/api.rst --- a/doc/reST/api.rst Tue Oct 22 20:14:37 2019 +0530 +++ b/doc/reST/api.rst Thu Oct 17 12:04:07 2019 +0530 @@ -191,7 +191,15 @@ * switched out of; using reconfig to switch between ultrafast and other * presets is not recommended without a more fine-grained breakdown of * parameters to take this into account. */ - int x265_encoder_reconfig(x265_encoder *, x265_param *); + int x265_encoder_reconfig(x265_encoder *, x265_param *); + +**x265_encoder_reconfig_zone()** Used to reconfigure rate-contol settings of zones mid-encode:: + + /* x265_encoder_reconfig_zone: + * Properties of the zone will be copied to encoder's param and will be used only to + * influence rate-control decisions of the zone. + * returns 0 on successful copy and negative on failure.*/ + int x265_encoder_reconfig(x265_encoder *, x265_param *); **x265_get_slicetype_poc_and_scenecut()** may be used to fetch slice type, poc and scene cut information mid-encode:: diff -r 971180b100f8 -r b2bb096d9e26 source/CMakeLists.txt --- a/source/CMakeLists.txt Tue Oct 22 20:14:37 2019 +0530 +++ b/source/CMakeLists.txt Thu Oct 17 12:04:07 2019 +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 180) +set(X265_BUILD 181) configure_file("${PROJECT_SOURCE_DIR}/x265.def.in" "${PROJECT_BINARY_DIR}/x265.def") configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in" diff -r 971180b100f8 -r b2bb096d9e26 source/common/param.cpp --- a/source/common/param.cpp Tue Oct 22 20:14:37 2019 +0530 +++ b/source/common/param.cpp Thu Oct 17 12:04:07 2019 +0530 @@ -274,6 +274,8 @@ param->rc.qpMin = 0; param->rc.qpMax = QP_MAX_MAX; param->rc.bEnableConstVbv = 0; + param->bResetZoneConfig = 1; + param->reconfigWindowSize = 0; /* Video Usability Information (VUI) */ param->vui.aspectRatioIdc = 0; @@ -2333,6 +2335,8 @@ dst->rc.bEnableSlowFirstPass = src->rc.bEnableSlowFirstPass; dst->rc.zoneCount = src->rc.zoneCount; dst->rc.zonefileCount = src->rc.zonefileCount; + dst->reconfigWindowSize = src->reconfigWindowSize; + dst->bResetZoneConfig = src->bResetZoneConfig; if (src->rc.zonefileCount && src->rc.zones) { diff -r 971180b100f8 -r b2bb096d9e26 source/encoder/api.cpp --- a/source/encoder/api.cpp Tue Oct 22 20:14:37 2019 +0530 +++ b/source/encoder/api.cpp Thu Oct 17 12:04:07 2019 +0530 @@ -100,7 +100,7 @@ if(param) PARAM_NS::x265_param_default(param); if(latestParam) PARAM_NS::x265_param_default(latestParam); if(zoneParam) PARAM_NS::x265_param_default(zoneParam); - + if (!param || !latestParam || !zoneParam) goto fail; if (p->rc.zoneCount || p->rc.zonefileCount) @@ -191,9 +191,20 @@ encoder->create(); + if (!param->bResetZoneConfig) + { + param->rc.zones = X265_MALLOC(x265_zone, param->rc.zonefileCount); + for (int i = 0; i < param->rc.zonefileCount; i++) + { + param->rc.zones[i].zoneParam = X265_MALLOC(x265_param, 1); + memcpy(param->rc.zones[i].zoneParam, param, sizeof(x265_param)); + } + } + memcpy(zoneParam, param, sizeof(x265_param)); for (int i = 0; i < param->rc.zonefileCount; i++) { + param->rc.zones[i].startFrame = -1; encoder->configureZone(zoneParam, param->rc.zones[i].zoneParam); } @@ -362,6 +373,25 @@ return ret; } + +int x265_encoder_reconfig_zone(x265_encoder* enc, x265_zone* zone_in) +{ + if (!enc || !zone_in) + return -1; + Encoder* encoder = static_cast<Encoder*>(enc); + x265_zone* zone = &(encoder->m_param->rc).zones[encoder->m_zoneIndex]; + x265_param* zoneParam = zone->zoneParam; + + int ret = encoder->reconfigureParam(zoneParam, zone_in->zoneParam); + if (ret) + return -1; + memcpy(zone, zone_in, sizeof(x265_zone)); + + encoder->m_zoneIndex++; + encoder->m_zoneIndex %= encoder->m_param->rc.zonefileCount; + return 0; +} + int x265_encoder_encode(x265_encoder *enc, x265_nal **pp_nal, uint32_t *pi_nal, x265_picture *pic_in, x265_picture *pic_out) { if (!enc) @@ -988,6 +1018,7 @@ &x265_encoder_open, &x265_encoder_parameters, &x265_encoder_reconfig, + &x265_encoder_reconfig_zone, &x265_encoder_headers, &x265_encoder_encode, &x265_encoder_get_stats, diff -r 971180b100f8 -r b2bb096d9e26 source/encoder/dpb.h --- a/source/encoder/dpb.h Tue Oct 22 20:14:37 2019 +0530 +++ b/source/encoder/dpb.h Thu Oct 17 12:04:07 2019 +0530 @@ -52,12 +52,15 @@ m_lastIDR = 0; m_pocCRA = 0; m_bhasLeadingPicture = param->radl; - for (int i = 0; i < param->rc.zonefileCount; i++) + if (param->bResetZoneConfig) { - if (param->rc.zones[i].zoneParam->radl) + for (int i = 0; i < param->rc.zonefileCount ; i++) { - m_bhasLeadingPicture = param->rc.zones[i].zoneParam->radl; - break; + if (param->rc.zones[i].zoneParam->radl) + { + m_bhasLeadingPicture = param->rc.zones[i].zoneParam->radl; + break; + } } } m_bRefreshPending = false; diff -r 971180b100f8 -r b2bb096d9e26 source/encoder/encoder.cpp --- a/source/encoder/encoder.cpp Tue Oct 22 20:14:37 2019 +0530 +++ b/source/encoder/encoder.cpp Thu Oct 17 12:04:07 2019 +0530 @@ -134,6 +134,7 @@ m_prevTonemapPayload.payload = NULL; m_startPoint = 0; m_saveCTUSize = 0; + m_zoneIndex = 0; } inline char *strcatFilename(const char *input, const char *suffix) { @@ -1866,12 +1867,15 @@ frameEnc->m_analysisData.poc = frameEnc->m_poc; if (m_param->rc.bStatRead) readAnalysisFile(&frameEnc->m_analysisData, frameEnc->m_poc, frameEnc->m_lowres.sliceType); - } - - for (int i = 0; i < m_param->rc.zonefileCount; i++) + } + + if (m_param->bResetZoneConfig) { - if (m_param->rc.zones[i].startFrame == frameEnc->m_poc) - x265_encoder_reconfig(this, m_param->rc.zones[i].zoneParam); + for (int i = 0; i < m_param->rc.zonefileCount; i++) + { + if (m_param->rc.zones[i].startFrame == frameEnc->m_poc) + x265_encoder_reconfig(this, m_param->rc.zones[i].zoneParam); + } } if (frameEnc->m_reconfigureRc && m_reconfigureRc) @@ -3066,48 +3070,51 @@ void Encoder::configureZone(x265_param *p, x265_param *zone) { - p->maxNumReferences = zone->maxNumReferences; - p->bEnableFastIntra = zone->bEnableFastIntra; - p->bEnableEarlySkip = zone->bEnableEarlySkip; - p->bEnableRecursionSkip = zone->bEnableRecursionSkip; - p->searchMethod = zone->searchMethod; - p->searchRange = zone->searchRange; - p->subpelRefine = zone->subpelRefine; - p->rdoqLevel = zone->rdoqLevel; - p->rdLevel = zone->rdLevel; - p->bEnableRectInter = zone->bEnableRectInter; - p->maxNumMergeCand = zone->maxNumMergeCand; - p->bIntraInBFrames = zone->bIntraInBFrames; - if(zone->scalingLists) - p->scalingLists = strdup(zone->scalingLists); - - p->rc.aqMode = zone->rc.aqMode; - p->rc.aqStrength = zone->rc.aqStrength; - p->noiseReductionInter = zone->noiseReductionInter; - p->noiseReductionIntra = zone->noiseReductionIntra; - - p->limitModes = zone->limitModes; - p->bEnableSplitRdSkip = zone->bEnableSplitRdSkip; - p->bCULossless = zone->bCULossless; - p->bEnableRdRefine = zone->bEnableRdRefine; - p->limitTU = zone->limitTU; - p->bEnableTSkipFast = zone->bEnableTSkipFast; - p->rdPenalty = zone->rdPenalty; - p->dynamicRd = zone->dynamicRd; - p->bEnableTransformSkip = zone->bEnableTransformSkip; - p->bEnableAMP = zone->bEnableAMP; - - if (m_param->rc.rateControlMode == X265_RC_ABR) - p->rc.bitrate = zone->rc.bitrate; - if (m_param->rc.rateControlMode == X265_RC_CRF) - p->rc.rfConstant = zone->rc.rfConstant; - if (m_param->rc.rateControlMode == X265_RC_CQP) - { - p->rc.qp = zone->rc.qp; - p->rc.aqMode = X265_AQ_NONE; - p->rc.hevcAq = 0; - } - p->radl = zone->radl; + if (m_param->bResetZoneConfig) + { + p->maxNumReferences = zone->maxNumReferences; + p->bEnableFastIntra = zone->bEnableFastIntra; + p->bEnableEarlySkip = zone->bEnableEarlySkip; + p->bEnableRecursionSkip = zone->bEnableRecursionSkip; + p->searchMethod = zone->searchMethod; + p->searchRange = zone->searchRange; + p->subpelRefine = zone->subpelRefine; + p->rdoqLevel = zone->rdoqLevel; + p->rdLevel = zone->rdLevel; + p->bEnableRectInter = zone->bEnableRectInter; + p->maxNumMergeCand = zone->maxNumMergeCand; + p->bIntraInBFrames = zone->bIntraInBFrames; + if (zone->scalingLists) + p->scalingLists = strdup(zone->scalingLists); + + p->rc.aqMode = zone->rc.aqMode; + p->rc.aqStrength = zone->rc.aqStrength; + p->noiseReductionInter = zone->noiseReductionInter; + p->noiseReductionIntra = zone->noiseReductionIntra; + + p->limitModes = zone->limitModes; + p->bEnableSplitRdSkip = zone->bEnableSplitRdSkip; + p->bCULossless = zone->bCULossless; + p->bEnableRdRefine = zone->bEnableRdRefine; + p->limitTU = zone->limitTU; + p->bEnableTSkipFast = zone->bEnableTSkipFast; + p->rdPenalty = zone->rdPenalty; + p->dynamicRd = zone->dynamicRd; + p->bEnableTransformSkip = zone->bEnableTransformSkip; + p->bEnableAMP = zone->bEnableAMP; + + if (m_param->rc.rateControlMode == X265_RC_ABR) + p->rc.bitrate = zone->rc.bitrate; + if (m_param->rc.rateControlMode == X265_RC_CRF) + p->rc.rfConstant = zone->rc.rfConstant; + if (m_param->rc.rateControlMode == X265_RC_CQP) + { + p->rc.qp = zone->rc.qp; + p->rc.aqMode = X265_AQ_NONE; + p->rc.hevcAq = 0; + } + p->radl = zone->radl; + } memcpy(zone, p, sizeof(x265_param)); } @@ -3816,6 +3823,12 @@ x265_log(p, X265_LOG_WARNING, "Turning on repeat - headers for zone encoding\n"); } + if (!m_param->bResetZoneConfig && (p->keyframeMax != p->keyframeMin)) + x265_log(p, X265_LOG_WARNING, "External zone reconfiguration requires a fixed GOP size to enable appropriate signaling of HRD info\n"); + + if (!m_param->bResetZoneConfig && (p->reconfigWindowSize != (uint64_t)p->keyframeMax)) + x265_log(p, X265_LOG_WARNING, "Zone size must be multiple of GOP size to enable appropriate signaling of HRD info\n"); + if (m_param->bEnableHME) { if (m_param->sourceHeight < 540) diff -r 971180b100f8 -r b2bb096d9e26 source/encoder/encoder.h --- a/source/encoder/encoder.h Tue Oct 22 20:14:37 2019 +0530 +++ b/source/encoder/encoder.h Thu Oct 17 12:04:07 2019 +0530 @@ -263,6 +263,8 @@ x265_sei_payload m_prevTonemapPayload; + int m_zoneIndex; + /* Collect frame level feature data */ uint64_t* m_rdCost; uint64_t* m_variance; diff -r 971180b100f8 -r b2bb096d9e26 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Tue Oct 22 20:14:37 2019 +0530 +++ b/source/encoder/ratecontrol.cpp Thu Oct 17 12:04:07 2019 +0530 @@ -1251,7 +1251,8 @@ { m_param = m_param->rc.zones[i].zoneParam; reconfigureRC(); - init(*m_curSlice->m_sps); + if (m_param->bResetZoneConfig) + init(*m_curSlice->m_sps); } } if (m_param->rc.bStatRead) diff -r 971180b100f8 -r b2bb096d9e26 source/encoder/slicetype.cpp --- a/source/encoder/slicetype.cpp Tue Oct 22 20:14:37 2019 +0530 +++ b/source/encoder/slicetype.cpp Thu Oct 17 12:04:07 2019 +0530 @@ -1531,12 +1531,15 @@ if (frm.bIsFadeEnd){ frm.sliceType = m_param->bOpenGOP && m_lastKeyframe >= 0 ? X265_TYPE_I : X265_TYPE_IDR; } - for (int i = 0; i < m_param->rc.zonefileCount; i++) + if (m_param->bResetZoneConfig) { - int curZoneStart = m_param->rc.zones[i].startFrame; - curZoneStart += curZoneStart ? m_param->rc.zones[i].zoneParam->radl : 0; - if (curZoneStart == frm.frameNum) - frm.sliceType = X265_TYPE_IDR; + for (int i = 0; i < m_param->rc.zonefileCount; i++) + { + int curZoneStart = m_param->rc.zones[i].startFrame; + curZoneStart += curZoneStart ? m_param->rc.zones[i].zoneParam->radl : 0; + if (curZoneStart == frm.frameNum) + frm.sliceType = X265_TYPE_IDR; + } } if ((frm.sliceType == X265_TYPE_I && frm.frameNum - m_lastKeyframe >= m_param->keyframeMin) || (frm.frameNum == (m_param->chunkStart - 1)) || (frm.frameNum == m_param->chunkEnd)) { @@ -1554,16 +1557,19 @@ m_lastKeyframe = frm.frameNum; frm.bKeyframe = true; int zoneRadl = 0; - for (int i = 0; i < m_param->rc.zonefileCount; i++) + if (m_param->bResetZoneConfig) { - int zoneStart = m_param->rc.zones[i].startFrame; - zoneStart += zoneStart ? m_param->rc.zones[i].zoneParam->radl : 0; - if (zoneStart == frm.frameNum) + for (int i = 0; i < m_param->rc.zonefileCount; i++) { - zoneRadl = m_param->rc.zones[i].zoneParam->radl; - m_param->radl = 0; - m_param->rc.zones->zoneParam->radl = i < m_param->rc.zonefileCount - 1? m_param->rc.zones[i + 1].zoneParam->radl : 0; - break; + int zoneStart = m_param->rc.zones[i].startFrame; + zoneStart += zoneStart ? m_param->rc.zones[i].zoneParam->radl : 0; + if (zoneStart == frm.frameNum) + { + zoneRadl = m_param->rc.zones[i].zoneParam->radl; + m_param->radl = 0; + m_param->rc.zones->zoneParam->radl = i < m_param->rc.zonefileCount - 1 ? m_param->rc.zones[i + 1].zoneParam->radl : 0; + break; + } } } if (bframes > 0 && !m_param->radl && !zoneRadl) @@ -1854,13 +1860,16 @@ } frames[framecnt + 1] = NULL; - for (int i = 0; i < m_param->rc.zonefileCount; i++) + if (m_param->bResetZoneConfig) { - int curZoneStart = m_param->rc.zones[i].startFrame, nextZoneStart = 0; - curZoneStart += curZoneStart ? m_param->rc.zones[i].zoneParam->radl : 0; - nextZoneStart += (i + 1 < m_param->rc.zonefileCount) ? m_param->rc.zones[i + 1].startFrame + m_param->rc.zones[i + 1].zoneParam->radl : m_param->totalFrames; - if (curZoneStart <= frames[0]->frameNum && nextZoneStart > frames[0]->frameNum) - m_param->keyframeMax = nextZoneStart - curZoneStart; + for (int i = 0; i < m_param->rc.zonefileCount; i++) + { + int curZoneStart = m_param->rc.zones[i].startFrame, nextZoneStart = 0; + curZoneStart += curZoneStart ? m_param->rc.zones[i].zoneParam->radl : 0; + nextZoneStart += (i + 1 < m_param->rc.zonefileCount) ? m_param->rc.zones[i + 1].startFrame + m_param->rc.zones[i + 1].zoneParam->radl : m_param->totalFrames; + if (curZoneStart <= frames[0]->frameNum && nextZoneStart > frames[0]->frameNum) + m_param->keyframeMax = nextZoneStart - curZoneStart; + } } int keylimit = m_param->keyframeMax; if (frames[0]->frameNum < m_param->chunkEnd) @@ -2071,7 +2080,7 @@ frames[numFrames]->sliceType = X265_TYPE_P; } - int zoneRadl = m_param->rc.zonefileCount ? m_param->rc.zones->zoneParam->radl : 0; + int zoneRadl = m_param->rc.zonefileCount && m_param->bResetZoneConfig ? m_param->rc.zones->zoneParam->radl : 0; bool bForceRADL = (m_param->radl || zoneRadl) && !m_param->bOpenGOP; bool bLastMiniGop = (framecnt >= m_param->bframes + 1) ? false : true; int radl = m_param->radl ? m_param->radl : zoneRadl; diff -r 971180b100f8 -r b2bb096d9e26 source/x265.h --- a/source/x265.h Tue Oct 22 20:14:37 2019 +0530 +++ b/source/x265.h Thu Oct 17 12:04:07 2019 +0530 @@ -1819,6 +1819,13 @@ /*Input sequence bit depth. It can be either 8bit, 10bit or 12bit.*/ int sourceBitDepth; + + /*Size of the zone to be reconfigured in frames. Default 0. API only. */ + uint64_t reconfigWindowSize; + + /*Flag to indicate if rate-control history has to be reset during zone reconfiguration. + Default 1 (Enabled). API only. */ + int bResetZoneConfig; } x265_param; /* x265_param_alloc: * Allocates an x265_param instance. The returned param structure is not @@ -1995,6 +2002,12 @@ * parameters to take this into account. */ int x265_encoder_reconfig(x265_encoder *, x265_param *); +/* x265_encoder_reconfig_zone: +* zone settings are copied to the encoder's param. +* Properties of the zone will be used only to re-configure rate-control settings +* of the zone mid-encode. Returns 0 on success on successful copy, negative on failure.*/ +int x265_encoder_reconfig_zone(x265_encoder *, x265_zone *); + /* x265_encoder_get_stats: * returns encoder statistics */ void x265_encoder_get_stats(x265_encoder *encoder, x265_stats *, uint32_t statsSizeBytes); @@ -2123,6 +2136,7 @@ x265_encoder* (*encoder_open)(x265_param*); void (*encoder_parameters)(x265_encoder*, x265_param*); 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_encode)(x265_encoder*, x265_nal**, uint32_t*, x265_picture*, x265_picture*); void (*encoder_get_stats)(x265_encoder*, x265_stats*, uint32_t);
# HG changeset patch # User Aruna Matheswaran <ar...@multicorewareinc.com> # Date 1571294047 -19800 # Thu Oct 17 12:04:07 2019 +0530 # Node ID b2bb096d9e267df7e71a3464e71da14f663b42db # Parent 971180b100f871ba3635e825feea18662e6bdca8 API: New API to reconfigure zones diff -r 971180b100f8 -r b2bb096d9e26 doc/reST/api.rst --- a/doc/reST/api.rst Tue Oct 22 20:14:37 2019 +0530 +++ b/doc/reST/api.rst Thu Oct 17 12:04:07 2019 +0530 @@ -191,7 +191,15 @@ * switched out of; using reconfig to switch between ultrafast and other * presets is not recommended without a more fine-grained breakdown of * parameters to take this into account. */ - int x265_encoder_reconfig(x265_encoder *, x265_param *); + int x265_encoder_reconfig(x265_encoder *, x265_param *); + +**x265_encoder_reconfig_zone()** Used to reconfigure rate-contol settings of zones mid-encode:: + + /* x265_encoder_reconfig_zone: + * Properties of the zone will be copied to encoder's param and will be used only to + * influence rate-control decisions of the zone. + * returns 0 on successful copy and negative on failure.*/ + int x265_encoder_reconfig(x265_encoder *, x265_param *); **x265_get_slicetype_poc_and_scenecut()** may be used to fetch slice type, poc and scene cut information mid-encode:: diff -r 971180b100f8 -r b2bb096d9e26 source/CMakeLists.txt --- a/source/CMakeLists.txt Tue Oct 22 20:14:37 2019 +0530 +++ b/source/CMakeLists.txt Thu Oct 17 12:04:07 2019 +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 180) +set(X265_BUILD 181) configure_file("${PROJECT_SOURCE_DIR}/x265.def.in" "${PROJECT_BINARY_DIR}/x265.def") configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in" diff -r 971180b100f8 -r b2bb096d9e26 source/common/param.cpp --- a/source/common/param.cpp Tue Oct 22 20:14:37 2019 +0530 +++ b/source/common/param.cpp Thu Oct 17 12:04:07 2019 +0530 @@ -274,6 +274,8 @@ param->rc.qpMin = 0; param->rc.qpMax = QP_MAX_MAX; param->rc.bEnableConstVbv = 0; + param->bResetZoneConfig = 1; + param->reconfigWindowSize = 0; /* Video Usability Information (VUI) */ param->vui.aspectRatioIdc = 0; @@ -2333,6 +2335,8 @@ dst->rc.bEnableSlowFirstPass = src->rc.bEnableSlowFirstPass; dst->rc.zoneCount = src->rc.zoneCount; dst->rc.zonefileCount = src->rc.zonefileCount; + dst->reconfigWindowSize = src->reconfigWindowSize; + dst->bResetZoneConfig = src->bResetZoneConfig; if (src->rc.zonefileCount && src->rc.zones) { diff -r 971180b100f8 -r b2bb096d9e26 source/encoder/api.cpp --- a/source/encoder/api.cpp Tue Oct 22 20:14:37 2019 +0530 +++ b/source/encoder/api.cpp Thu Oct 17 12:04:07 2019 +0530 @@ -100,7 +100,7 @@ if(param) PARAM_NS::x265_param_default(param); if(latestParam) PARAM_NS::x265_param_default(latestParam); if(zoneParam) PARAM_NS::x265_param_default(zoneParam); - + if (!param || !latestParam || !zoneParam) goto fail; if (p->rc.zoneCount || p->rc.zonefileCount) @@ -191,9 +191,20 @@ encoder->create(); + if (!param->bResetZoneConfig) + { + param->rc.zones = X265_MALLOC(x265_zone, param->rc.zonefileCount); + for (int i = 0; i < param->rc.zonefileCount; i++) + { + param->rc.zones[i].zoneParam = X265_MALLOC(x265_param, 1); + memcpy(param->rc.zones[i].zoneParam, param, sizeof(x265_param)); + } + } + memcpy(zoneParam, param, sizeof(x265_param)); for (int i = 0; i < param->rc.zonefileCount; i++) { + param->rc.zones[i].startFrame = -1; encoder->configureZone(zoneParam, param->rc.zones[i].zoneParam); } @@ -362,6 +373,25 @@ return ret; } + +int x265_encoder_reconfig_zone(x265_encoder* enc, x265_zone* zone_in) +{ + if (!enc || !zone_in) + return -1; + Encoder* encoder = static_cast<Encoder*>(enc); + x265_zone* zone = &(encoder->m_param->rc).zones[encoder->m_zoneIndex]; + x265_param* zoneParam = zone->zoneParam; + + int ret = encoder->reconfigureParam(zoneParam, zone_in->zoneParam); + if (ret) + return -1; + memcpy(zone, zone_in, sizeof(x265_zone)); + + encoder->m_zoneIndex++; + encoder->m_zoneIndex %= encoder->m_param->rc.zonefileCount; + return 0; +} + int x265_encoder_encode(x265_encoder *enc, x265_nal **pp_nal, uint32_t *pi_nal, x265_picture *pic_in, x265_picture *pic_out) { if (!enc) @@ -988,6 +1018,7 @@ &x265_encoder_open, &x265_encoder_parameters, &x265_encoder_reconfig, + &x265_encoder_reconfig_zone, &x265_encoder_headers, &x265_encoder_encode, &x265_encoder_get_stats, diff -r 971180b100f8 -r b2bb096d9e26 source/encoder/dpb.h --- a/source/encoder/dpb.h Tue Oct 22 20:14:37 2019 +0530 +++ b/source/encoder/dpb.h Thu Oct 17 12:04:07 2019 +0530 @@ -52,12 +52,15 @@ m_lastIDR = 0; m_pocCRA = 0; m_bhasLeadingPicture = param->radl; - for (int i = 0; i < param->rc.zonefileCount; i++) + if (param->bResetZoneConfig) { - if (param->rc.zones[i].zoneParam->radl) + for (int i = 0; i < param->rc.zonefileCount ; i++) { - m_bhasLeadingPicture = param->rc.zones[i].zoneParam->radl; - break; + if (param->rc.zones[i].zoneParam->radl) + { + m_bhasLeadingPicture = param->rc.zones[i].zoneParam->radl; + break; + } } } m_bRefreshPending = false; diff -r 971180b100f8 -r b2bb096d9e26 source/encoder/encoder.cpp --- a/source/encoder/encoder.cpp Tue Oct 22 20:14:37 2019 +0530 +++ b/source/encoder/encoder.cpp Thu Oct 17 12:04:07 2019 +0530 @@ -134,6 +134,7 @@ m_prevTonemapPayload.payload = NULL; m_startPoint = 0; m_saveCTUSize = 0; + m_zoneIndex = 0; } inline char *strcatFilename(const char *input, const char *suffix) { @@ -1866,12 +1867,15 @@ frameEnc->m_analysisData.poc = frameEnc->m_poc; if (m_param->rc.bStatRead) readAnalysisFile(&frameEnc->m_analysisData, frameEnc->m_poc, frameEnc->m_lowres.sliceType); - } - - for (int i = 0; i < m_param->rc.zonefileCount; i++) + } + + if (m_param->bResetZoneConfig) { - if (m_param->rc.zones[i].startFrame == frameEnc->m_poc) - x265_encoder_reconfig(this, m_param->rc.zones[i].zoneParam); + for (int i = 0; i < m_param->rc.zonefileCount; i++) + { + if (m_param->rc.zones[i].startFrame == frameEnc->m_poc) + x265_encoder_reconfig(this, m_param->rc.zones[i].zoneParam); + } } if (frameEnc->m_reconfigureRc && m_reconfigureRc) @@ -3066,48 +3070,51 @@ void Encoder::configureZone(x265_param *p, x265_param *zone) { - p->maxNumReferences = zone->maxNumReferences; - p->bEnableFastIntra = zone->bEnableFastIntra; - p->bEnableEarlySkip = zone->bEnableEarlySkip; - p->bEnableRecursionSkip = zone->bEnableRecursionSkip; - p->searchMethod = zone->searchMethod; - p->searchRange = zone->searchRange; - p->subpelRefine = zone->subpelRefine; - p->rdoqLevel = zone->rdoqLevel; - p->rdLevel = zone->rdLevel; - p->bEnableRectInter = zone->bEnableRectInter; - p->maxNumMergeCand = zone->maxNumMergeCand; - p->bIntraInBFrames = zone->bIntraInBFrames; - if(zone->scalingLists) - p->scalingLists = strdup(zone->scalingLists); - - p->rc.aqMode = zone->rc.aqMode; - p->rc.aqStrength = zone->rc.aqStrength; - p->noiseReductionInter = zone->noiseReductionInter; - p->noiseReductionIntra = zone->noiseReductionIntra; - - p->limitModes = zone->limitModes; - p->bEnableSplitRdSkip = zone->bEnableSplitRdSkip; - p->bCULossless = zone->bCULossless; - p->bEnableRdRefine = zone->bEnableRdRefine; - p->limitTU = zone->limitTU; - p->bEnableTSkipFast = zone->bEnableTSkipFast; - p->rdPenalty = zone->rdPenalty; - p->dynamicRd = zone->dynamicRd; - p->bEnableTransformSkip = zone->bEnableTransformSkip; - p->bEnableAMP = zone->bEnableAMP; - - if (m_param->rc.rateControlMode == X265_RC_ABR) - p->rc.bitrate = zone->rc.bitrate; - if (m_param->rc.rateControlMode == X265_RC_CRF) - p->rc.rfConstant = zone->rc.rfConstant; - if (m_param->rc.rateControlMode == X265_RC_CQP) - { - p->rc.qp = zone->rc.qp; - p->rc.aqMode = X265_AQ_NONE; - p->rc.hevcAq = 0; - } - p->radl = zone->radl; + if (m_param->bResetZoneConfig) + { + p->maxNumReferences = zone->maxNumReferences; + p->bEnableFastIntra = zone->bEnableFastIntra; + p->bEnableEarlySkip = zone->bEnableEarlySkip; + p->bEnableRecursionSkip = zone->bEnableRecursionSkip; + p->searchMethod = zone->searchMethod; + p->searchRange = zone->searchRange; + p->subpelRefine = zone->subpelRefine; + p->rdoqLevel = zone->rdoqLevel; + p->rdLevel = zone->rdLevel; + p->bEnableRectInter = zone->bEnableRectInter; + p->maxNumMergeCand = zone->maxNumMergeCand; + p->bIntraInBFrames = zone->bIntraInBFrames; + if (zone->scalingLists) + p->scalingLists = strdup(zone->scalingLists); + + p->rc.aqMode = zone->rc.aqMode; + p->rc.aqStrength = zone->rc.aqStrength; + p->noiseReductionInter = zone->noiseReductionInter; + p->noiseReductionIntra = zone->noiseReductionIntra; + + p->limitModes = zone->limitModes; + p->bEnableSplitRdSkip = zone->bEnableSplitRdSkip; + p->bCULossless = zone->bCULossless; + p->bEnableRdRefine = zone->bEnableRdRefine; + p->limitTU = zone->limitTU; + p->bEnableTSkipFast = zone->bEnableTSkipFast; + p->rdPenalty = zone->rdPenalty; + p->dynamicRd = zone->dynamicRd; + p->bEnableTransformSkip = zone->bEnableTransformSkip; + p->bEnableAMP = zone->bEnableAMP; + + if (m_param->rc.rateControlMode == X265_RC_ABR) + p->rc.bitrate = zone->rc.bitrate; + if (m_param->rc.rateControlMode == X265_RC_CRF) + p->rc.rfConstant = zone->rc.rfConstant; + if (m_param->rc.rateControlMode == X265_RC_CQP) + { + p->rc.qp = zone->rc.qp; + p->rc.aqMode = X265_AQ_NONE; + p->rc.hevcAq = 0; + } + p->radl = zone->radl; + } memcpy(zone, p, sizeof(x265_param)); } @@ -3816,6 +3823,12 @@ x265_log(p, X265_LOG_WARNING, "Turning on repeat - headers for zone encoding\n"); } + if (!m_param->bResetZoneConfig && (p->keyframeMax != p->keyframeMin)) + x265_log(p, X265_LOG_WARNING, "External zone reconfiguration requires a fixed GOP size to enable appropriate signaling of HRD info\n"); + + if (!m_param->bResetZoneConfig && (p->reconfigWindowSize != (uint64_t)p->keyframeMax)) + x265_log(p, X265_LOG_WARNING, "Zone size must be multiple of GOP size to enable appropriate signaling of HRD info\n"); + if (m_param->bEnableHME) { if (m_param->sourceHeight < 540) diff -r 971180b100f8 -r b2bb096d9e26 source/encoder/encoder.h --- a/source/encoder/encoder.h Tue Oct 22 20:14:37 2019 +0530 +++ b/source/encoder/encoder.h Thu Oct 17 12:04:07 2019 +0530 @@ -263,6 +263,8 @@ x265_sei_payload m_prevTonemapPayload; + int m_zoneIndex; + /* Collect frame level feature data */ uint64_t* m_rdCost; uint64_t* m_variance; diff -r 971180b100f8 -r b2bb096d9e26 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Tue Oct 22 20:14:37 2019 +0530 +++ b/source/encoder/ratecontrol.cpp Thu Oct 17 12:04:07 2019 +0530 @@ -1251,7 +1251,8 @@ { m_param = m_param->rc.zones[i].zoneParam; reconfigureRC(); - init(*m_curSlice->m_sps); + if (m_param->bResetZoneConfig) + init(*m_curSlice->m_sps); } } if (m_param->rc.bStatRead) diff -r 971180b100f8 -r b2bb096d9e26 source/encoder/slicetype.cpp --- a/source/encoder/slicetype.cpp Tue Oct 22 20:14:37 2019 +0530 +++ b/source/encoder/slicetype.cpp Thu Oct 17 12:04:07 2019 +0530 @@ -1531,12 +1531,15 @@ if (frm.bIsFadeEnd){ frm.sliceType = m_param->bOpenGOP && m_lastKeyframe >= 0 ? X265_TYPE_I : X265_TYPE_IDR; } - for (int i = 0; i < m_param->rc.zonefileCount; i++) + if (m_param->bResetZoneConfig) { - int curZoneStart = m_param->rc.zones[i].startFrame; - curZoneStart += curZoneStart ? m_param->rc.zones[i].zoneParam->radl : 0; - if (curZoneStart == frm.frameNum) - frm.sliceType = X265_TYPE_IDR; + for (int i = 0; i < m_param->rc.zonefileCount; i++) + { + int curZoneStart = m_param->rc.zones[i].startFrame; + curZoneStart += curZoneStart ? m_param->rc.zones[i].zoneParam->radl : 0; + if (curZoneStart == frm.frameNum) + frm.sliceType = X265_TYPE_IDR; + } } if ((frm.sliceType == X265_TYPE_I && frm.frameNum - m_lastKeyframe >= m_param->keyframeMin) || (frm.frameNum == (m_param->chunkStart - 1)) || (frm.frameNum == m_param->chunkEnd)) { @@ -1554,16 +1557,19 @@ m_lastKeyframe = frm.frameNum; frm.bKeyframe = true; int zoneRadl = 0; - for (int i = 0; i < m_param->rc.zonefileCount; i++) + if (m_param->bResetZoneConfig) { - int zoneStart = m_param->rc.zones[i].startFrame; - zoneStart += zoneStart ? m_param->rc.zones[i].zoneParam->radl : 0; - if (zoneStart == frm.frameNum) + for (int i = 0; i < m_param->rc.zonefileCount; i++) { - zoneRadl = m_param->rc.zones[i].zoneParam->radl; - m_param->radl = 0; - m_param->rc.zones->zoneParam->radl = i < m_param->rc.zonefileCount - 1? m_param->rc.zones[i + 1].zoneParam->radl : 0; - break; + int zoneStart = m_param->rc.zones[i].startFrame; + zoneStart += zoneStart ? m_param->rc.zones[i].zoneParam->radl : 0; + if (zoneStart == frm.frameNum) + { + zoneRadl = m_param->rc.zones[i].zoneParam->radl; + m_param->radl = 0; + m_param->rc.zones->zoneParam->radl = i < m_param->rc.zonefileCount - 1 ? m_param->rc.zones[i + 1].zoneParam->radl : 0; + break; + } } } if (bframes > 0 && !m_param->radl && !zoneRadl) @@ -1854,13 +1860,16 @@ } frames[framecnt + 1] = NULL; - for (int i = 0; i < m_param->rc.zonefileCount; i++) + if (m_param->bResetZoneConfig) { - int curZoneStart = m_param->rc.zones[i].startFrame, nextZoneStart = 0; - curZoneStart += curZoneStart ? m_param->rc.zones[i].zoneParam->radl : 0; - nextZoneStart += (i + 1 < m_param->rc.zonefileCount) ? m_param->rc.zones[i + 1].startFrame + m_param->rc.zones[i + 1].zoneParam->radl : m_param->totalFrames; - if (curZoneStart <= frames[0]->frameNum && nextZoneStart > frames[0]->frameNum) - m_param->keyframeMax = nextZoneStart - curZoneStart; + for (int i = 0; i < m_param->rc.zonefileCount; i++) + { + int curZoneStart = m_param->rc.zones[i].startFrame, nextZoneStart = 0; + curZoneStart += curZoneStart ? m_param->rc.zones[i].zoneParam->radl : 0; + nextZoneStart += (i + 1 < m_param->rc.zonefileCount) ? m_param->rc.zones[i + 1].startFrame + m_param->rc.zones[i + 1].zoneParam->radl : m_param->totalFrames; + if (curZoneStart <= frames[0]->frameNum && nextZoneStart > frames[0]->frameNum) + m_param->keyframeMax = nextZoneStart - curZoneStart; + } } int keylimit = m_param->keyframeMax; if (frames[0]->frameNum < m_param->chunkEnd) @@ -2071,7 +2080,7 @@ frames[numFrames]->sliceType = X265_TYPE_P; } - int zoneRadl = m_param->rc.zonefileCount ? m_param->rc.zones->zoneParam->radl : 0; + int zoneRadl = m_param->rc.zonefileCount && m_param->bResetZoneConfig ? m_param->rc.zones->zoneParam->radl : 0; bool bForceRADL = (m_param->radl || zoneRadl) && !m_param->bOpenGOP; bool bLastMiniGop = (framecnt >= m_param->bframes + 1) ? false : true; int radl = m_param->radl ? m_param->radl : zoneRadl; diff -r 971180b100f8 -r b2bb096d9e26 source/x265.h --- a/source/x265.h Tue Oct 22 20:14:37 2019 +0530 +++ b/source/x265.h Thu Oct 17 12:04:07 2019 +0530 @@ -1819,6 +1819,13 @@ /*Input sequence bit depth. It can be either 8bit, 10bit or 12bit.*/ int sourceBitDepth; + + /*Size of the zone to be reconfigured in frames. Default 0. API only. */ + uint64_t reconfigWindowSize; + + /*Flag to indicate if rate-control history has to be reset during zone reconfiguration. + Default 1 (Enabled). API only. */ + int bResetZoneConfig; } x265_param; /* x265_param_alloc: * Allocates an x265_param instance. The returned param structure is not @@ -1995,6 +2002,12 @@ * parameters to take this into account. */ int x265_encoder_reconfig(x265_encoder *, x265_param *); +/* x265_encoder_reconfig_zone: +* zone settings are copied to the encoder's param. +* Properties of the zone will be used only to re-configure rate-control settings +* of the zone mid-encode. Returns 0 on success on successful copy, negative on failure.*/ +int x265_encoder_reconfig_zone(x265_encoder *, x265_zone *); + /* x265_encoder_get_stats: * returns encoder statistics */ void x265_encoder_get_stats(x265_encoder *encoder, x265_stats *, uint32_t statsSizeBytes); @@ -2123,6 +2136,7 @@ x265_encoder* (*encoder_open)(x265_param*); void (*encoder_parameters)(x265_encoder*, x265_param*); 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_encode)(x265_encoder*, x265_nal**, uint32_t*, x265_picture*, x265_picture*); void (*encoder_get_stats)(x265_encoder*, x265_stats*, uint32_t);
_______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel