[x265] [PATCH] analysis: introduce analysis refinement level for analysis save/load feature
sagar at multicorewareinc.com
sagar at multicorewareinc.com
Tue Apr 12 14:35:50 CEST 2016
# HG changeset patch
# User Sagar Kotecha<sagar at multicorewareinc.com>
# Date 1460440996 -19800
# Tue Apr 12 11:33:16 2016 +0530
# Node ID 710856d0242825e49b7dbf967d9b715c4b0e8c39
# Parent 40afead3177d7c128066334bfe075042388e86b0
analysis: introduce analysis refinement level for analysis save/load feature
Amount of information stored/reused is distributed across levels.
Higher the value, Lesser the information stored/reused.
diff -r 40afead3177d -r 710856d02428 doc/reST/cli.rst
--- a/doc/reST/cli.rst Sat Apr 09 19:32:28 2016 +0530
+++ b/doc/reST/cli.rst Tue Apr 12 11:33:16 2016 +0530
@@ -791,6 +791,27 @@
**Values:** off(0), save(1): dump analysis data, load(2): read analysis data
+.. option:: --analysis-refine-level <1..5>
+
+ Amount of information stored/reused in :option:`--analysis-mode` is distributed across levels.
+ Higher the value, Lesser the information stored/reused, Slower the encode. Default 5.
+
+ Note that --analysis-refine-level must be paired with analysis-mode.
+
+ +-------+---------------------------------------------------------------+
+ | Level | Description |
+ +=======+===============================================================+
+ | 1 | Currently same as 3 |
+ +-------+---------------------------------------------------------------+
+ | 2 | Currently same as 3 |
+ +-------+---------------------------------------------------------------+
+ | 3 | Lookahead information, Intra and inter modes, ref's, rect-amp |
+ +-------+---------------------------------------------------------------+
+ | 4 | Lookahead information, Intra and inter modes, ref's |
+ +-------+---------------------------------------------------------------+
+ | 5 | Lookahead information |
+ +-------+---------------------------------------------------------------+
+
.. option:: --analysis-file <filename>
Specify a filename for analysis data (see :option:`--analysis-mode`)
diff -r 40afead3177d -r 710856d02428 source/CMakeLists.txt
--- a/source/CMakeLists.txt Sat Apr 09 19:32:28 2016 +0530
+++ b/source/CMakeLists.txt Tue Apr 12 11:33:16 2016 +0530
@@ -30,7 +30,7 @@
mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)
# X265_BUILD must be incremented each time the public API is changed
-set(X265_BUILD 83)
+set(X265_BUILD 84)
configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
"${PROJECT_BINARY_DIR}/x265.def")
configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
diff -r 40afead3177d -r 710856d02428 source/common/param.cpp
--- a/source/common/param.cpp Sat Apr 09 19:32:28 2016 +0530
+++ b/source/common/param.cpp Tue Apr 12 11:33:16 2016 +0530
@@ -188,6 +188,7 @@
param->psyRd = 2.0;
param->psyRdoq = 0.0;
param->analysisMode = 0;
+ param->analysisRefineLevel = 0;
param->analysisFileName = NULL;
param->bIntraInBFrames = 0;
param->bLossless = 0;
@@ -787,6 +788,7 @@
OPT("me") p->searchMethod = parseName(value, x265_motion_est_names, bError);
OPT("cutree") p->rc.cuTree = atobool(value);
OPT("slow-firstpass") p->rc.bEnableSlowFirstPass = atobool(value);
+ OPT("analysis-refine-level") p->analysisRefineLevel = atoi(value);
OPT("strict-cbr")
{
p->rc.bStrictCbr = atobool(value);
@@ -1202,6 +1204,7 @@
"Strict-cbr cannot be applied without specifying target bitrate or vbv bufsize");
CHECK(param->analysisMode && (param->analysisMode < X265_ANALYSIS_OFF || param->analysisMode > X265_ANALYSIS_LOAD),
"Invalid analysis mode. Analysis mode 0: OFF 1: SAVE : 2 LOAD");
+ CHECK((param->analysisMode == X265_ANALYSIS_OFF) && param->analysisRefineLevel, "Provide analysis mode");
return check_failed;
}
diff -r 40afead3177d -r 710856d02428 source/encoder/analysis.cpp
--- a/source/encoder/analysis.cpp Sat Apr 09 19:32:28 2016 +0530
+++ b/source/encoder/analysis.cpp Tue Apr 12 11:33:16 2016 +0530
@@ -142,15 +142,18 @@
m_modeDepth[0].fencYuv.copyFromPicYuv(*m_frame->m_fencPic, ctu.m_cuAddr, 0);
uint32_t numPartition = ctu.m_numPartitions;
- if (m_param->analysisMode && m_slice->m_sliceType != I_SLICE)
+ if (m_param->analysisRefineLevel != 5 && m_param->analysisMode && m_slice->m_sliceType != I_SLICE)
{
int numPredDir = m_slice->isInterP() ? 1 : 2;
m_reuseInterDataCTU = (analysis_inter_data*)m_frame->m_analysisData.interData;
m_reuseRef = &m_reuseInterDataCTU->ref[ctu.m_cuAddr * X265_MAX_PRED_MODE_PER_CTU * numPredDir];
- m_reuseDepth = &m_reuseInterDataCTU->depth[ctu.m_cuAddr * ctu.m_numPartitions];
+ m_reuseDepth = &m_reuseInterDataCTU->depth[ctu.m_cuAddr * ctu.m_numPartitions];
m_reuseModes = &m_reuseInterDataCTU->modes[ctu.m_cuAddr * ctu.m_numPartitions];
- m_reusePartSize = &m_reuseInterDataCTU->partSize[ctu.m_cuAddr * ctu.m_numPartitions];
- m_reuseMergeFlag = &m_reuseInterDataCTU->mergeFlag[ctu.m_cuAddr * ctu.m_numPartitions];
+ if (m_param->analysisRefineLevel < 4)
+ {
+ m_reusePartSize = &m_reuseInterDataCTU->partSize[ctu.m_cuAddr * ctu.m_numPartitions];
+ m_reuseMergeFlag = &m_reuseInterDataCTU->mergeFlag[ctu.m_cuAddr * ctu.m_numPartitions];
+ }
if (m_param->analysisMode == X265_ANALYSIS_SAVE)
for (int i = 0; i < X265_MAX_PRED_MODE_PER_CTU * numPredDir; i++)
m_reuseRef[i] = -1;
@@ -160,7 +163,7 @@
if (m_slice->m_sliceType == I_SLICE)
{
analysis_intra_data* intraDataCTU = (analysis_intra_data*)m_frame->m_analysisData.intraData;
- if (m_param->analysisMode == X265_ANALYSIS_LOAD)
+ if (m_param->analysisRefineLevel != 5 && m_param->analysisMode == X265_ANALYSIS_LOAD)
{
memcpy(ctu.m_cuDepth, &intraDataCTU->depth[ctu.m_cuAddr * numPartition], sizeof(uint8_t) * numPartition);
memcpy(ctu.m_lumaIntraDir, &intraDataCTU->modes[ctu.m_cuAddr * numPartition], sizeof(uint8_t) * numPartition);
@@ -905,7 +908,7 @@
}
bool foundSkip = false;
- if (m_param->analysisMode == X265_ANALYSIS_LOAD)
+ if (m_param->analysisRefineLevel != 5 && m_param->analysisMode == X265_ANALYSIS_LOAD)
{
if (mightNotSplit && depth == m_reuseDepth[cuGeom.absPartIdx])
{
@@ -919,7 +922,8 @@
if (m_param->rdLevel)
earlyskip = md.bestMode && m_param->bEnableEarlySkip;
}
- if (m_reusePartSize[cuGeom.absPartIdx] == SIZE_2Nx2N)
+
+ if ((m_param->analysisRefineLevel < 4) && m_reusePartSize[cuGeom.absPartIdx] == SIZE_2Nx2N)
{
if (m_reuseModes[cuGeom.absPartIdx] != MODE_INTRA && m_reuseModes[cuGeom.absPartIdx] != 4)
{
@@ -1410,7 +1414,7 @@
md.pred[PRED_2Nx2N].rdCost = 0;
}
- if (m_param->analysisMode == X265_ANALYSIS_LOAD)
+ if (m_param->analysisRefineLevel != 5 && m_param->analysisMode == X265_ANALYSIS_LOAD)
{
if (mightNotSplit && depth == m_reuseDepth[cuGeom.absPartIdx])
{
@@ -1423,7 +1427,7 @@
foundSkip = true;
earlyskip = !!m_param->bEnableEarlySkip;
}
- if (m_reusePartSize[cuGeom.absPartIdx] == SIZE_2Nx2N)
+ if (m_param->analysisRefineLevel < 4 && m_reusePartSize[cuGeom.absPartIdx] == SIZE_2Nx2N)
skipRectAmp = true && !!md.bestMode;
}
}
@@ -2106,7 +2110,7 @@
interMode.cu.setPredModeSubParts(MODE_INTER);
int numPredDir = m_slice->isInterP() ? 1 : 2;
- if (m_param->analysisMode == X265_ANALYSIS_LOAD && m_reuseInterDataCTU)
+ if (m_param->analysisRefineLevel != 5 && m_param->analysisMode == X265_ANALYSIS_LOAD && m_reuseInterDataCTU)
{
int refOffset = cuGeom.geomRecurId * 16 * numPredDir + partSize * numPredDir * 2;
int index = 0;
@@ -2133,7 +2137,7 @@
}
interMode.sa8dCost = m_rdCost.calcRdSADCost((uint32_t)interMode.distortion, interMode.sa8dBits);
- if (m_param->analysisMode == X265_ANALYSIS_SAVE && m_reuseInterDataCTU)
+ if (m_param->analysisRefineLevel != 5 && m_param->analysisMode == X265_ANALYSIS_SAVE && m_reuseInterDataCTU)
{
int refOffset = cuGeom.geomRecurId * 16 * numPredDir + partSize * numPredDir * 2;
int index = 0;
@@ -2155,7 +2159,7 @@
interMode.cu.setPredModeSubParts(MODE_INTER);
int numPredDir = m_slice->isInterP() ? 1 : 2;
- if (m_param->analysisMode == X265_ANALYSIS_LOAD && m_reuseInterDataCTU)
+ if (m_param->analysisRefineLevel != 5 && m_param->analysisMode == X265_ANALYSIS_LOAD && m_reuseInterDataCTU)
{
int refOffset = cuGeom.geomRecurId * 16 * numPredDir + partSize * numPredDir * 2;
int index = 0;
@@ -2173,7 +2177,7 @@
/* predInterSearch sets interMode.sa8dBits, but this is ignored */
encodeResAndCalcRdInterCU(interMode, cuGeom);
- if (m_param->analysisMode == X265_ANALYSIS_SAVE && m_reuseInterDataCTU)
+ if (m_param->analysisRefineLevel != 5 && m_param->analysisMode == X265_ANALYSIS_SAVE && m_reuseInterDataCTU)
{
int refOffset = cuGeom.geomRecurId * 16 * numPredDir + partSize * numPredDir * 2;
int index = 0;
diff -r 40afead3177d -r 710856d02428 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Sat Apr 09 19:32:28 2016 +0530
+++ b/source/encoder/encoder.cpp Tue Apr 12 11:33:16 2016 +0530
@@ -328,6 +328,9 @@
x265_log(NULL, X265_LOG_ERROR, "Analysis load/save: failed to open file %s\n", name);
m_aborted = true;
}
+
+ if (!m_param->analysisRefineLevel)
+ m_param->analysisRefineLevel = 5;
}
m_bZeroLatency = !m_param->bframes && !m_param->lookaheadDepth && m_param->frameNumThreads == 1;
@@ -1863,6 +1866,7 @@
if (p->bDistributeModeAnalysis && p->analysisMode)
{
p->analysisMode = X265_ANALYSIS_OFF;
+ p->analysisRefineLevel = 0;
x265_log(p, X265_LOG_WARNING, "Analysis save and load mode not supported for distributed mode analysis\n");
}
if (p->bEnableRdRefine && (p->rdLevel < 5 || !p->rc.aqMode))
@@ -1977,26 +1981,38 @@
{
X265_CHECK(analysis->sliceType, "invalid slice type\n");
analysis->interData = analysis->intraData = NULL;
+
+
if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
{
- analysis_intra_data *intraData = (analysis_intra_data*)analysis->intraData;
- CHECKED_MALLOC_ZERO(intraData, analysis_intra_data, 1);
- CHECKED_MALLOC(intraData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
- CHECKED_MALLOC(intraData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
- CHECKED_MALLOC(intraData->partSizes, char, analysis->numPartitions * analysis->numCUsInFrame);
- CHECKED_MALLOC(intraData->chromaModes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
- analysis->intraData = intraData;
+ if (m_param->analysisRefineLevel != 5)
+ {
+ analysis_intra_data *intraData = (analysis_intra_data*)analysis->intraData;
+ CHECKED_MALLOC_ZERO(intraData, analysis_intra_data, 1);
+ CHECKED_MALLOC(intraData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ CHECKED_MALLOC(intraData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ CHECKED_MALLOC(intraData->partSizes, char, analysis->numPartitions * analysis->numCUsInFrame);
+ CHECKED_MALLOC(intraData->chromaModes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ analysis->intraData = intraData;
+ }
}
else
{
+
int numDir = analysis->sliceType == X265_TYPE_P ? 1 : 2;
analysis_inter_data *interData = (analysis_inter_data*)analysis->interData;
CHECKED_MALLOC_ZERO(interData, analysis_inter_data, 1);
- CHECKED_MALLOC_ZERO(interData->ref, int32_t, analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir);
- CHECKED_MALLOC(interData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
- CHECKED_MALLOC(interData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
- CHECKED_MALLOC(interData->partSize, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
- CHECKED_MALLOC(interData->mergeFlag, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ if (m_param->analysisRefineLevel != 5)
+ {
+ CHECKED_MALLOC_ZERO(interData->ref, int32_t, analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir);
+ CHECKED_MALLOC(interData->depth, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ CHECKED_MALLOC(interData->modes, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ if (m_param->analysisRefineLevel < 4)
+ {
+ CHECKED_MALLOC(interData->partSize, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ CHECKED_MALLOC(interData->mergeFlag, uint8_t, analysis->numPartitions * analysis->numCUsInFrame);
+ }
+ }
CHECKED_MALLOC_ZERO(interData->wt, WeightParam, 3 * numDir);
analysis->interData = interData;
}
@@ -2017,7 +2033,7 @@
X265_FREE(((analysis_intra_data*)analysis->intraData)->chromaModes);
X265_FREE(analysis->intraData);
}
- else
+ else if (analysis->interData)
{
X265_FREE(((analysis_inter_data*)analysis->interData)->ref);
X265_FREE(((analysis_inter_data*)analysis->interData)->depth);
@@ -2035,10 +2051,10 @@
#define X265_FREAD(val, size, readSize, fileOffset)\
if (fread(val, size, readSize, fileOffset) != readSize)\
{\
- x265_log(NULL, X265_LOG_ERROR, "Error reading analysis data\n");\
- freeAnalysis(analysis);\
- m_aborted = true;\
- return;\
+ x265_log(NULL, X265_LOG_ERROR, "Error reading analysis data\n"); \
+ freeAnalysis(analysis); \
+ m_aborted = true; \
+ return; \
}\
static uint64_t consumedBytes = 0;
@@ -2046,7 +2062,8 @@
uint32_t depthBytes = 0;
fseeko(m_analysisFile, totalConsumedBytes, SEEK_SET);
- int poc; uint32_t frameRecordSize;
+ int poc, refineLevel;
+ uint32_t frameRecordSize;
X265_FREAD(&frameRecordSize, sizeof(uint32_t), 1, m_analysisFile);
X265_FREAD(&depthBytes, sizeof(uint32_t), 1, m_analysisFile);
X265_FREAD(&poc, sizeof(int), 1, m_analysisFile);
@@ -2078,63 +2095,96 @@
X265_FREAD(&analysis->satdCost, sizeof(int64_t), 1, m_analysisFile);
X265_FREAD(&analysis->numCUsInFrame, sizeof(int), 1, m_analysisFile);
X265_FREAD(&analysis->numPartitions, sizeof(int), 1, m_analysisFile);
+ X265_FREAD(&refineLevel, sizeof(int), 1, m_analysisFile);
+
+ if (refineLevel != m_param->analysisRefineLevel)
+ {
+ x265_log(NULL, X265_LOG_ERROR, "analysis refine level between save-load must match\n");
+ freeAnalysis(analysis);
+ m_aborted = true;
+ return;
+ }
+
+ int numDir;
+ if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
+ {
+ numDir = 0;
+ consumedBytes += frameRecordSize;
+ }
+ else
+ numDir = analysis->sliceType == X265_TYPE_P ? 1 : 2;
/* Memory is allocated for inter and intra analysis data based on the slicetype */
allocAnalysis(analysis);
- if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
+ if (!numDir)
{
- uint8_t *tempBuf = NULL, *depthBuf = NULL, *modeBuf = NULL, *partSizes = NULL;
+ if (refineLevel < 5)
+ {
+ uint8_t *tempBuf = NULL, *depthBuf = NULL, *modeBuf = NULL, *partSizes = NULL;
- tempBuf = X265_MALLOC(uint8_t, depthBytes * 3);
- X265_FREAD(tempBuf, sizeof(uint8_t), depthBytes * 3, m_analysisFile);
+ tempBuf = X265_MALLOC(uint8_t, depthBytes * 3);
+ X265_FREAD(tempBuf, sizeof(uint8_t), depthBytes * 3, m_analysisFile);
- depthBuf = tempBuf;
- modeBuf = tempBuf + depthBytes;
- partSizes = tempBuf + 2 * depthBytes;
+ depthBuf = tempBuf;
+ modeBuf = tempBuf + depthBytes;
+ partSizes = tempBuf + 2 * depthBytes;
- size_t count = 0;
- for (uint32_t d = 0; d < depthBytes; d++)
+ size_t count = 0;
+ for (uint32_t d = 0; d < depthBytes; d++)
+ {
+ int bytes = analysis->numPartitions >> (depthBuf[d] * 2);
+ memset(&((analysis_intra_data *)analysis->intraData)->depth[count], depthBuf[d], bytes);
+ memset(&((analysis_intra_data *)analysis->intraData)->chromaModes[count], modeBuf[d], bytes);
+ memset(&((analysis_intra_data *)analysis->intraData)->partSizes[count], partSizes[d], bytes);
+ count += bytes;
+ }
+ X265_FREAD(((analysis_intra_data *)analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFile);
+ X265_FREE(tempBuf);
+ }
+ analysis->sliceType = X265_TYPE_I;
+ }
+ else
+ {
+ if (refineLevel < 5)
{
- int bytes = analysis->numPartitions >> (depthBuf[d] * 2);
- memset(&((analysis_intra_data *)analysis->intraData)->depth[count], depthBuf[d], bytes);
- memset(&((analysis_intra_data *)analysis->intraData)->chromaModes[count], modeBuf[d], bytes);
- memset(&((analysis_intra_data *)analysis->intraData)->partSizes[count], partSizes[d], bytes);
- count += bytes;
+ int numSharedData = 4;
+ if (m_param->analysisRefineLevel == 4)
+ numSharedData = 2;
+ uint8_t *tempBuf = NULL, *depthBuf = NULL, *modeBuf = NULL, *partSize = NULL, *mergeFlag = NULL;
+
+ tempBuf = X265_MALLOC(uint8_t, depthBytes * numSharedData);
+ X265_FREAD(tempBuf, sizeof(uint8_t), depthBytes * numSharedData, m_analysisFile);
+
+ depthBuf = tempBuf;
+ modeBuf = tempBuf + depthBytes;
+
+ if (m_param->analysisRefineLevel < 4)
+ {
+ partSize = modeBuf + depthBytes;
+ mergeFlag = partSize + depthBytes;
+ }
+
+ size_t count = 0;
+ for (uint32_t d = 0; d < depthBytes; d++)
+ {
+ int bytes = analysis->numPartitions >> (depthBuf[d] * 2);
+ memset(&((analysis_inter_data *)analysis->interData)->depth[count], depthBuf[d], bytes);
+ memset(&((analysis_inter_data *)analysis->interData)->modes[count], modeBuf[d], bytes);
+ if (m_param->analysisRefineLevel < 4)
+ {
+ memset(&((analysis_inter_data *)analysis->interData)->partSize[count], partSize[d], bytes);
+ memset(&((analysis_inter_data *)analysis->interData)->mergeFlag[count], mergeFlag[d], bytes);
+ }
+ count += bytes;
+ }
+ X265_FREE(tempBuf);
+ X265_FREAD(((analysis_inter_data *)analysis->interData)->ref, sizeof(int32_t), analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir, m_analysisFile);
}
- X265_FREAD(((analysis_intra_data *)analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFile);
- X265_FREE(tempBuf);
- analysis->sliceType = X265_TYPE_I;
- consumedBytes += frameRecordSize;
}
- else
+ if (numDir)
{
- uint8_t *tempBuf = NULL, *depthBuf = NULL, *modeBuf = NULL, *partSize = NULL, *mergeFlag = NULL;
-
- tempBuf = X265_MALLOC(uint8_t, depthBytes * 4);
- X265_FREAD(tempBuf, sizeof(uint8_t), depthBytes * 4, m_analysisFile);
-
- depthBuf = tempBuf;
- modeBuf = tempBuf + depthBytes;
- partSize = modeBuf + depthBytes;
- mergeFlag = partSize + depthBytes;
-
- size_t count = 0;
- for (uint32_t d = 0; d < depthBytes; d++)
- {
- int bytes = analysis->numPartitions >> (depthBuf[d] * 2);
- memset(&((analysis_inter_data *)analysis->interData)->depth[count], depthBuf[d], bytes);
- memset(&((analysis_inter_data *)analysis->interData)->modes[count], modeBuf[d], bytes);
- memset(&((analysis_inter_data *)analysis->interData)->partSize[count], partSize[d], bytes);
- memset(&((analysis_inter_data *)analysis->interData)->mergeFlag[count], mergeFlag[d], bytes);
- count += bytes;
- }
-
- X265_FREE(tempBuf);
-
- int numDir = analysis->sliceType == X265_TYPE_P ? 1 : 2;
- X265_FREAD(((analysis_inter_data *)analysis->interData)->ref, sizeof(int32_t), analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir, m_analysisFile);
uint32_t numPlanes = m_param->internalCsp == X265_CSP_I400 ? 1 : 3;
X265_FREAD(((analysis_inter_data *)analysis->interData)->wt, sizeof(WeightParam), numPlanes * numDir, m_analysisFile);
consumedBytes += frameRecordSize;
@@ -2156,80 +2206,91 @@
return;\
}\
+ int numDir;
+ if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
+ numDir = 0;
+ else
+ numDir = analysis->sliceType == X265_TYPE_P ? 1 : 2;
+
uint32_t depthBytes = 0;
- if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
+ analysis->frameRecordSize = sizeof(analysis->frameRecordSize) + sizeof(depthBytes)+sizeof(analysis->poc) + sizeof(analysis->sliceType) +
+ sizeof(analysis->numCUsInFrame) + sizeof(analysis->numPartitions) + sizeof(analysis->bScenecut) + sizeof(analysis->satdCost) + sizeof(m_param->analysisRefineLevel);
+
+ int numSharedData = 4;
+ if (m_param->analysisRefineLevel == 4)
+ numSharedData = 2;
+
+ if (m_param->analysisRefineLevel != 5)
{
- for (uint32_t cuAddr = 0; cuAddr < analysis->numCUsInFrame; cuAddr++)
+ if (!numDir)
{
- uint8_t depth = 0;
- uint8_t mode = 0;
- uint8_t partSize = 0;
+ for (uint32_t cuAddr = 0; cuAddr < analysis->numCUsInFrame; cuAddr++)
+ {
+ uint8_t depth = 0;
+ uint8_t mode = 0;
+ uint8_t partSize = 0;
- CUData* ctu = curEncData.getPicCTU(cuAddr);
- analysis_intra_data* intraDataCTU = (analysis_intra_data*)analysis->intraData;
+ CUData* ctu = curEncData.getPicCTU(cuAddr);
+ analysis_intra_data* intraDataCTU = (analysis_intra_data*)analysis->intraData;
- for (uint32_t absPartIdx = 0; absPartIdx < ctu->m_numPartitions; depthBytes++)
+ for (uint32_t absPartIdx = 0; absPartIdx < ctu->m_numPartitions; depthBytes++)
+ {
+ depth = ctu->m_cuDepth[absPartIdx];
+ intraDataCTU->depth[depthBytes] = depth;
+
+ mode = ctu->m_chromaIntraDir[absPartIdx];
+ intraDataCTU->chromaModes[depthBytes] = mode;
+
+ partSize = ctu->m_partSize[absPartIdx];
+ intraDataCTU->partSizes[depthBytes] = partSize;
+
+ absPartIdx += ctu->m_numPartitions >> (depth * 2);
+ }
+ memcpy(&intraDataCTU->modes[ctu->m_cuAddr * ctu->m_numPartitions], ctu->m_lumaIntraDir, sizeof(uint8_t)* ctu->m_numPartitions);
+ }
+ analysis->frameRecordSize += sizeof(uint8_t)* analysis->numCUsInFrame * analysis->numPartitions + depthBytes * 3;
+ }
+ else
+ {
+ for (uint32_t cuAddr = 0; cuAddr < analysis->numCUsInFrame; cuAddr++)
{
- depth = ctu->m_cuDepth[absPartIdx];
- intraDataCTU->depth[depthBytes] = depth;
+ uint8_t depth = 0;
+ uint8_t predMode = 0;
+ uint8_t partSize = 0;
+ uint8_t mergeFlag = 0;
- mode = ctu->m_chromaIntraDir[absPartIdx];
- intraDataCTU->chromaModes[depthBytes] = mode;
+ CUData* ctu = curEncData.getPicCTU(cuAddr);
+ analysis_inter_data* interDataCTU = (analysis_inter_data*)analysis->interData;
- partSize = ctu->m_partSize[absPartIdx];
- intraDataCTU->partSizes[depthBytes] = partSize;
+ for (uint32_t absPartIdx = 0; absPartIdx < ctu->m_numPartitions; depthBytes++)
+ {
+ depth = ctu->m_cuDepth[absPartIdx];
+ interDataCTU->depth[depthBytes] = depth;
- absPartIdx += ctu->m_numPartitions >> (depth * 2);
+ predMode = ctu->m_predMode[absPartIdx];
+ if (ctu->m_refIdx[1][absPartIdx] != -1)
+ predMode = 4; // used as indiacator if the block is coded as bidir
+
+ interDataCTU->modes[depthBytes] = predMode;
+
+ if (m_param->analysisRefineLevel < 4)
+ {
+ partSize = ctu->m_partSize[absPartIdx];
+ interDataCTU->partSize[depthBytes] = partSize;
+
+ mergeFlag = ctu->m_mergeFlag[absPartIdx];
+ interDataCTU->mergeFlag[depthBytes] = mergeFlag;
+ }
+
+ absPartIdx += ctu->m_numPartitions >> (depth * 2);
+ }
}
- memcpy(&intraDataCTU->modes[ctu->m_cuAddr * ctu->m_numPartitions], ctu->m_lumaIntraDir, sizeof(uint8_t)* ctu->m_numPartitions);
+ analysis->frameRecordSize += depthBytes * numSharedData;
+ analysis->frameRecordSize += sizeof(int32_t)* analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir;
}
- }
- else
- {
- for (uint32_t cuAddr = 0; cuAddr < analysis->numCUsInFrame; cuAddr++)
- {
- uint8_t depth = 0;
- uint8_t predMode = 0;
- uint8_t partSize = 0;
- uint8_t mergeFlag = 0;
+ }
+ analysis->frameRecordSize += sizeof(WeightParam) * 3 * numDir;
- CUData* ctu = curEncData.getPicCTU(cuAddr);
- analysis_inter_data* interDataCTU = (analysis_inter_data*)analysis->interData;
-
- for (uint32_t absPartIdx = 0; absPartIdx < ctu->m_numPartitions; depthBytes++)
- {
- depth = ctu->m_cuDepth[absPartIdx];
- interDataCTU->depth[depthBytes] = depth;
-
- predMode = ctu->m_predMode[absPartIdx];
- if (ctu->m_refIdx[1][absPartIdx] != -1)
- predMode = 4; // used as indiacator if the block is coded as bidir
-
- interDataCTU->modes[depthBytes] = predMode;
-
- partSize = ctu->m_partSize[absPartIdx];
- interDataCTU->partSize[depthBytes] = partSize;
-
- mergeFlag = ctu->m_mergeFlag[absPartIdx];
- interDataCTU->mergeFlag[depthBytes] = mergeFlag;
-
- absPartIdx += ctu->m_numPartitions >> (depth * 2);
- }
- }
- }
-
- /* calculate frameRecordSize */
- analysis->frameRecordSize = sizeof(analysis->frameRecordSize) + sizeof(depthBytes) + sizeof(analysis->poc) + sizeof(analysis->sliceType) +
- sizeof(analysis->numCUsInFrame) + sizeof(analysis->numPartitions) + sizeof(analysis->bScenecut) + sizeof(analysis->satdCost);
- if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
- analysis->frameRecordSize += sizeof(uint8_t)* analysis->numCUsInFrame * analysis->numPartitions + depthBytes * 3;
- else
- {
- int numDir = (analysis->sliceType == X265_TYPE_P) ? 1 : 2;
- analysis->frameRecordSize += depthBytes * 4;
- analysis->frameRecordSize += sizeof(int32_t)* analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir;
- analysis->frameRecordSize += sizeof(WeightParam)* 3 * numDir;
- }
X265_FWRITE(&analysis->frameRecordSize, sizeof(uint32_t), 1, m_analysisFile);
X265_FWRITE(&depthBytes, sizeof(uint32_t), 1, m_analysisFile);
X265_FWRITE(&analysis->poc, sizeof(int), 1, m_analysisFile);
@@ -2238,25 +2299,36 @@
X265_FWRITE(&analysis->satdCost, sizeof(int64_t), 1, m_analysisFile);
X265_FWRITE(&analysis->numCUsInFrame, sizeof(int), 1, m_analysisFile);
X265_FWRITE(&analysis->numPartitions, sizeof(int), 1, m_analysisFile);
+ X265_FWRITE(&m_param->analysisRefineLevel, sizeof(int), 1, m_analysisFile);
- if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
+ if (m_param->analysisRefineLevel != 5)
{
- X265_FWRITE(((analysis_intra_data*)analysis->intraData)->depth, sizeof(uint8_t), depthBytes, m_analysisFile);
- X265_FWRITE(((analysis_intra_data*)analysis->intraData)->chromaModes, sizeof(uint8_t), depthBytes, m_analysisFile);
- X265_FWRITE(((analysis_intra_data*)analysis->intraData)->partSizes, sizeof(char), depthBytes, m_analysisFile);
- X265_FWRITE(((analysis_intra_data*)analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFile);
+ if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)
+ {
+ X265_FWRITE(((analysis_intra_data*)analysis->intraData)->depth, sizeof(uint8_t), depthBytes, m_analysisFile);
+ X265_FWRITE(((analysis_intra_data*)analysis->intraData)->chromaModes, sizeof(uint8_t), depthBytes, m_analysisFile);
+ X265_FWRITE(((analysis_intra_data*)analysis->intraData)->partSizes, sizeof(char), depthBytes, m_analysisFile);
+ X265_FWRITE(((analysis_intra_data*)analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFile);
+ }
+ else
+ {
+ X265_FWRITE(((analysis_inter_data*)analysis->interData)->depth, sizeof(uint8_t), depthBytes, m_analysisFile);
+ X265_FWRITE(((analysis_inter_data*)analysis->interData)->modes, sizeof(uint8_t), depthBytes, m_analysisFile);
+ if (m_param->analysisRefineLevel < 4)
+ {
+ X265_FWRITE(((analysis_inter_data*)analysis->interData)->partSize, sizeof(uint8_t), depthBytes, m_analysisFile);
+ X265_FWRITE(((analysis_inter_data*)analysis->interData)->mergeFlag, sizeof(uint8_t), depthBytes, m_analysisFile);
+ }
+ X265_FWRITE(((analysis_inter_data*)analysis->interData)->ref, sizeof(int32_t), analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir, m_analysisFile);
+ }
}
- else
+
+ if (numDir)
{
- int numDir = analysis->sliceType == X265_TYPE_P ? 1 : 2;
- X265_FWRITE(((analysis_inter_data*)analysis->interData)->depth, sizeof(uint8_t), depthBytes, m_analysisFile);
- X265_FWRITE(((analysis_inter_data*)analysis->interData)->modes, sizeof(uint8_t), depthBytes, m_analysisFile);
- X265_FWRITE(((analysis_inter_data*)analysis->interData)->partSize, sizeof(uint8_t), depthBytes, m_analysisFile);
- X265_FWRITE(((analysis_inter_data*)analysis->interData)->mergeFlag, sizeof(uint8_t), depthBytes, m_analysisFile);
- X265_FWRITE(((analysis_inter_data*)analysis->interData)->ref, sizeof(int32_t), analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * numDir, m_analysisFile);
uint32_t numPlanes = m_param->internalCsp == X265_CSP_I400 ? 1 : 3;
X265_FWRITE(((analysis_inter_data*)analysis->interData)->wt, sizeof(WeightParam), numPlanes * numDir, m_analysisFile);
}
+
#undef X265_FWRITE
}
diff -r 40afead3177d -r 710856d02428 source/encoder/search.cpp
--- a/source/encoder/search.cpp Sat Apr 09 19:32:28 2016 +0530
+++ b/source/encoder/search.cpp Tue Apr 12 11:33:16 2016 +0530
@@ -2083,7 +2083,7 @@
cu.getNeighbourMV(puIdx, pu.puAbsPartIdx, interMode.interNeighbours);
/* Uni-directional prediction */
- if (m_param->analysisMode == X265_ANALYSIS_LOAD)
+ if (m_param->analysisRefineLevel != 5 && m_param->analysisMode == X265_ANALYSIS_LOAD)
{
for (int list = 0; list < numPredDir; list++)
{
diff -r 40afead3177d -r 710856d02428 source/x265.h
--- a/source/x265.h Sat Apr 09 19:32:28 2016 +0530
+++ b/source/x265.h Tue Apr 12 11:33:16 2016 +0530
@@ -992,6 +992,11 @@
* the encoder must perform. Default X265_ANALYSIS_OFF */
int analysisMode;
+ /* A value between 1 and 5 (both inclusive) which determines the level of
+ * information stored/reused between save and load mode. Higher the analysis refine
+ * level lesser the informtion stored/reused. Default is 5 */
+ int analysisRefineLevel;
+
/* Filename for analysisMode save/load. Default name is "x265_analysis.dat" */
const char* analysisFileName;
diff -r 40afead3177d -r 710856d02428 source/x265cli.h
--- a/source/x265cli.h Sat Apr 09 19:32:28 2016 +0530
+++ b/source/x265cli.h Tue Apr 12 11:33:16 2016 +0530
@@ -222,6 +222,7 @@
{ "slow-firstpass", no_argument, NULL, 0 },
{ "no-slow-firstpass", no_argument, NULL, 0 },
{ "analysis-mode", required_argument, NULL, 0 },
+ { "analysis-refine-level", required_argument, NULL, 0 },
{ "analysis-file", required_argument, NULL, 0 },
{ "strict-cbr", no_argument, NULL, 0 },
{ "temporal-layers", no_argument, NULL, 0 },
@@ -375,6 +376,7 @@
H0(" --[no-]slow-firstpass Enable a slow first pass in a multipass rate control mode. Default %s\n", OPT(param->rc.bEnableSlowFirstPass));
H0(" --[no-]strict-cbr Enable stricter conditions and tolerance for bitrate deviations in CBR mode. Default %s\n", OPT(param->rc.bStrictCbr));
H0(" --analysis-mode <string|int> save - Dump analysis info into file, load - Load analysis buffers from the file. Default %d\n", param->analysisMode);
+ H0(" --analysis-refine-level <1..5>Level of information stored/reused in analysis save/load mode 1:least....5:most. Default %d\n", param->analysisRefineLevel);
H0(" --analysis-file <filename> Specify file name used for either dumping or reading analysis data.\n");
H0(" --aq-mode <integer> Mode for Adaptive Quantization - 0:none 1:uniform AQ 2:auto variance 3:auto variance with bias to dark scenes. Default %d\n", param->rc.aqMode);
H0(" --aq-strength <float> Reduces blocking and blurring in flat and textured areas (0 to 3.0). Default %.2f\n", param->rc.aqStrength);
More information about the x265-devel
mailing list