Thanks Zheng. Interestingly this worked from clipboard but when I went to patchwork to download the patch ( https://patches.videolan.org/project/x265-devel/list/), it didn't work. Pradeep.
On Tue, Oct 25, 2016 at 8:39 AM, Zheng Wang <zh...@multicorewareinc.com> wrote: > Hi Pradeep, > > I have check the x265 code, and now i can pull the newlist code version is > "(0e9e52640546) limitTU: fix energy calculation used in limiting TU > recursion …" > My patch is base on this: > # Node ID 19d3c5ea8bc10d3728ba2ae06190d188fe6093a3 > # Parent 0e9e5264054606a38a3fe6c87272a1737b340b1a > Store commonly-used RPS in SPS in 2 pass mode. > > I also try to import my patch base on version "(0e9e52640546)“, it success > by "Import from Clipboard" using TortoiseHg. > > If there are some problem, please tell me the detailed info about it. > > > 2016-10-24 19:33 GMT+08:00 Pradeep Ramachandran < > prad...@multicorewareinc.com>: > >> This patch doesn't apply at current x265 tip. Please fix and resend. >> Pradeep. >> >> On Mon, Oct 24, 2016 at 12:27 PM, Zheng Wang <zh...@multicorewareinc.com> >> wrote: >> >>> # HG changeset patch >>> # User ZhengWang <zh...@multicorewareinc.com> >>> # Date 1477292081 -28800 >>> # Mon Oct 24 14:54:41 2016 +0800 >>> # Node ID 19d3c5ea8bc10d3728ba2ae06190d188fe6093a3 >>> # Parent 0e9e5264054606a38a3fe6c87272a1737b340b1a >>> Store commonly-used RPS in SPS in 2 pass mode. >>> Add new param --[no]-multi-pass-opt-rps to control it, default disabled. >>> >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 doc/reST/cli.rst >>> --- a/doc/reST/cli.rst Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/doc/reST/cli.rst Mon Oct 24 14:54:41 2016 +0800 >>> @@ -1852,6 +1852,10 @@ >>> Discard optional VUI HRD info from bitstream. Default enabled when >>> :option:`--hrd` is enabled. >>> >>> +.. option:: --[no]-multi-pass-opt-rps >>> + >>> + Enable storing commonly RPS in SPS in multi pass mode. Default >>> disabled. >>> + >>> >>> Debugging options >>> ================= >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/CMakeLists.txt >>> --- a/source/CMakeLists.txt Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/CMakeLists.txt Mon Oct 24 14:54:41 2016 +0800 >>> @@ -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 98) >>> +set(X265_BUILD 99) >>> configure_file("${PROJECT_SOURCE_DIR}/x265.def.in" >>> "${PROJECT_BINARY_DIR}/x265.def") >>> configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in" >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/common/common.h >>> --- a/source/common/common.h Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/common/common.h Mon Oct 24 14:54:41 2016 +0800 >>> @@ -312,6 +312,7 @@ >>> >>> #define MAX_NUM_REF_PICS 16 // max. number of pictures used >>> for reference >>> #define MAX_NUM_REF 16 // max. number of entries in >>> picture reference list >>> +#define MAX_NUM_SHORT_TERM_RPS 64 // max. number of short term >>> reference picture set in SPS >>> >>> #define REF_NOT_VALID -1 >>> >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/common/framedata.cpp >>> --- a/source/common/framedata.cpp Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/common/framedata.cpp Mon Oct 24 14:54:41 2016 +0800 >>> @@ -37,6 +37,9 @@ >>> m_slice = new Slice; >>> m_picCTU = new CUData[sps.numCUsInFrame]; >>> m_picCsp = csp; >>> + m_spsrpsIdx = -1; >>> + if (param.rc.bStatWrite) >>> + m_spsrps = const_cast<RPS*>(sps.spsrps); >>> >>> m_cuMemPool.create(0, param.internalCsp, sps.numCUsInFrame); >>> for (uint32_t ctuAddr = 0; ctuAddr < sps.numCUsInFrame; ctuAddr++) >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/common/framedata.h >>> --- a/source/common/framedata.h Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/common/framedata.h Mon Oct 24 14:54:41 2016 +0800 >>> @@ -106,6 +106,9 @@ >>> CUDataMemPool m_cuMemPool; >>> CUData* m_picCTU; >>> >>> + RPS* m_spsrps; >>> + int m_spsrpsIdx; >>> + >>> /* Rate control data used during encode and by references */ >>> struct RCStatCU >>> { >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/common/param.cpp >>> --- a/source/common/param.cpp Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/common/param.cpp Mon Oct 24 14:54:41 2016 +0800 >>> @@ -198,6 +198,7 @@ >>> param->bCULossless = 0; >>> param->bEnableTemporalSubLayers = 0; >>> param->bEnableRdRefine = 0; >>> + param->bMultiPassOptRPS = 0; >>> >>> /* Rate control options */ >>> param->rc.vbvMaxBitrate = 0; >>> @@ -915,6 +916,8 @@ >>> OPT("limit-tu") p->limitTU = atoi(value); >>> OPT("opt-qp-pps") p->bOptQpPPS = atobool(value); >>> OPT("opt-ref-list-length-pps") p->bOptRefListLengthPPS = >>> atobool(value); >>> + OPT("multi-pass-opt-rps") p->bMultiPassOptRPS = atobool(value); >>> + >>> else >>> return X265_PARAM_BAD_NAME; >>> } >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/common/slice.h >>> --- a/source/common/slice.h Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/common/slice.h Mon Oct 24 14:54:41 2016 +0800 >>> @@ -239,6 +239,10 @@ >>> uint32_t maxLatencyIncrease; >>> int numReorderPics; >>> >>> + RPS spsrps[MAX_NUM_SHORT_TERM_RPS]; >>> + int spsrpsNum; >>> + int numGOPBegin; >>> + >>> bool bUseSAO; // use param >>> bool bUseAMP; // use param >>> bool bUseStrongIntraSmoothing; // use param >>> @@ -337,6 +341,7 @@ >>> int m_sliceQp; >>> int m_poc; >>> int m_lastIDR; >>> + int m_rpsIdx; >>> >>> uint32_t m_colRefIdx; // never modified >>> >>> @@ -352,6 +357,7 @@ >>> >>> int m_iPPSQpMinus26; >>> int numRefIdxDefault[2]; >>> + int m_iNumRPSInSPS; >>> >>> Slice() >>> { >>> @@ -365,6 +371,7 @@ >>> m_iPPSQpMinus26 = 0; >>> numRefIdxDefault[0] = 1; >>> numRefIdxDefault[1] = 1; >>> + m_rpsIdx = -1; >>> } >>> >>> void disableWeights(); >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/encoder/api.cpp >>> --- a/source/encoder/api.cpp Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/encoder/api.cpp Mon Oct 24 14:54:41 2016 +0800 >>> @@ -141,6 +141,11 @@ >>> Encoder *encoder = static_cast<Encoder*>(enc); >>> Entropy sbacCoder; >>> Bitstream bs; >>> + if (encoder->m_param->rc.bStatRead && >>> encoder->m_param->bMultiPassOptRPS) >>> + { >>> + if (!encoder->computeSPSRPSIndex()) >>> + return -1; >>> + } >>> encoder->getStreamHeaders(encoder->m_nalList, sbacCoder, bs); >>> *pp_nal = &encoder->m_nalList.m_nal[0]; >>> if (pi_nal) *pi_nal = encoder->m_nalList.m_numNal; >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/encoder/encoder.cpp >>> --- a/source/encoder/encoder.cpp Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/encoder/encoder.cpp Mon Oct 24 14:54:41 2016 +0800 >>> @@ -77,6 +77,7 @@ >>> m_iFrameNum = 0; >>> m_iPPSQpMinus26 = 0; >>> m_iLastSliceQp = 0; >>> + m_rpsInSpsCount = 0; >>> for (int i = 0; i < X265_MAX_FRAME_THREADS; i++) >>> m_frameEncoder[i] = NULL; >>> >>> @@ -905,6 +906,7 @@ >>> frameEnc->m_encData->m_slice->m_iPPSQpMinus26 = >>> m_iPPSQpMinus26; >>> frameEnc->m_encData->m_slice->numRefIdxDefault[0] = >>> m_pps.numRefIdxDefault[0]; >>> frameEnc->m_encData->m_slice->numRefIdxDefault[1] = >>> m_pps.numRefIdxDefault[1]; >>> + frameEnc->m_encData->m_slice->m_iNumRPSInSPS = >>> m_sps.spsrpsNum; >>> >>> curEncoder->m_rce.encodeOrder = frameEnc->m_encodeOrder = >>> m_encodedFrameNum++; >>> if (m_bframeDelay) >>> @@ -1068,6 +1070,13 @@ >>> >>> x265_log(m_param, X265_LOG_INFO, "lossless compression ratio >>> %.2f::1\n", uncompressed / m_analyzeAll.m_accBits); >>> } >>> + if (m_param->bMultiPassOptRPS && m_param->rc.bStatRead) >>> + { >>> + x265_log(m_param, X265_LOG_INFO, "RPS in SPS: %d frames >>> (%.2f%%), RPS not in SPS: %d frames (%.2f%%)\n", >>> + m_rpsInSpsCount, (float)100.0 * m_rpsInSpsCount / >>> m_rateControl->m_numEntries, >>> + m_rateControl->m_numEntries - m_rpsInSpsCount, >>> + (float)100.0 * (m_rateControl->m_numEntries - >>> m_rpsInSpsCount) / m_rateControl->m_numEntries); >>> + } >>> >>> if (m_analyzeAll.m_numPics) >>> { >>> @@ -2433,3 +2442,203 @@ >>> TOOLCMP(oldParam->maxNumMergeCand, newParam->maxNumMergeCand, >>> "max-merge=%d to %d\n"); >>> TOOLCMP(oldParam->bIntraInBFrames, newParam->bIntraInBFrames, >>> "b-intra=%d to %d\n"); >>> } >>> + >>> +bool Encoder::computeSPSRPSIndex() >>> +{ >>> + RPS* rpsInSPS = m_sps.spsrps; >>> + int* rpsNumInPSP = &m_sps.spsrpsNum; >>> + int beginNum = m_sps.numGOPBegin; >>> + int endNum; >>> + RPS* rpsInRec; >>> + RPS* rpsInIdxList; >>> + RPS* thisRpsInSPS; >>> + RPS* thisRpsInList; >>> + RPSListNode* headRpsIdxList = NULL; >>> + RPSListNode* tailRpsIdxList = NULL; >>> + RPSListNode* rpsIdxListIter = NULL; >>> + RateControlEntry *rce2Pass = m_rateControl->m_rce2Pass; >>> + int numEntries = m_rateControl->m_numEntries; >>> + RateControlEntry *rce; >>> + int idx = 0; >>> + int pos = 0; >>> + int resultIdx[64]; >>> + memset(rpsInSPS, 0, sizeof(RPS) * MAX_NUM_SHORT_TERM_RPS); >>> + >>> + // find out all RPS date in current GOP >>> + beginNum++; >>> + endNum = beginNum; >>> + if (!m_param->bRepeatHeaders) >>> + { >>> + endNum = numEntries; >>> + } >>> + else >>> + { >>> + while (endNum < numEntries) >>> + { >>> + rce = &rce2Pass[endNum]; >>> + if (rce->sliceType == I_SLICE) >>> + { >>> + break; >>> + } >>> + endNum++; >>> + } >>> + } >>> + m_sps.numGOPBegin = endNum; >>> + >>> + // find out all kinds of RPS >>> + for (int i = beginNum; i < endNum; i++) >>> + { >>> + rce = &rce2Pass[i]; >>> + rpsInRec = &rce->rpsData; >>> + rpsIdxListIter = headRpsIdxList; >>> + // i frame don't recode RPS info >>> + if (rce->sliceType != I_SLICE) >>> + { >>> + while (rpsIdxListIter) >>> + { >>> + rpsInIdxList = rpsIdxListIter->rps; >>> + if (rpsInRec->numberOfPictures == >>> rpsInIdxList->numberOfPictures >>> + && rpsInRec->numberOfNegativePictures == >>> rpsInIdxList->numberOfNegativePictures >>> + && rpsInRec->numberOfPositivePictures == >>> rpsInIdxList->numberOfPositivePictures) >>> + { >>> + for (pos = 0; pos < rpsInRec->numberOfPictures; >>> pos++) >>> + { >>> + if (rpsInRec->deltaPOC[pos] != >>> rpsInIdxList->deltaPOC[pos] >>> + || rpsInRec->bUsed[pos] != >>> rpsInIdxList->bUsed[pos]) >>> + break; >>> + } >>> + if (pos == rpsInRec->numberOfPictures) // if >>> this type of RPS has exist >>> + { >>> + rce->rpsIdx = rpsIdxListIter->idx; >>> + rpsIdxListIter->count++; >>> + // sort RPS type link after reset RPS type >>> count. >>> + RPSListNode* next = rpsIdxListIter->next; >>> + RPSListNode* prior = rpsIdxListIter->prior; >>> + RPSListNode* iter = prior; >>> + if (iter) >>> + { >>> + while (iter) >>> + { >>> + if (iter->count > rpsIdxListIter->count) >>> + break; >>> + iter = iter->prior; >>> + } >>> + if (iter) >>> + { >>> + prior->next = next; >>> + if (next) >>> + next->prior = prior; >>> + else >>> + tailRpsIdxList = prior; >>> + rpsIdxListIter->next = iter->next; >>> + rpsIdxListIter->prior = iter; >>> + iter->next->prior = rpsIdxListIter; >>> + iter->next = rpsIdxListIter; >>> + } >>> + else >>> + { >>> + prior->next = next; >>> + if (next) >>> + next->prior = prior; >>> + else >>> + tailRpsIdxList = prior; >>> + headRpsIdxList->prior = rpsIdxListIter; >>> + rpsIdxListIter->next = headRpsIdxList; >>> + rpsIdxListIter->prior = NULL; >>> + headRpsIdxList = rpsIdxListIter; >>> + } >>> + } >>> + break; >>> + } >>> + } >>> + rpsIdxListIter = rpsIdxListIter->next; >>> + } >>> + if (!rpsIdxListIter) // add new type of RPS >>> + { >>> + RPSListNode* newIdxNode = new RPSListNode(); >>> + if (newIdxNode == NULL) >>> + goto fail; >>> + newIdxNode->rps = rpsInRec; >>> + newIdxNode->idx = idx++; >>> + newIdxNode->count = 1; >>> + newIdxNode->next = NULL; >>> + newIdxNode->prior = NULL; >>> + if (!tailRpsIdxList) >>> + tailRpsIdxList = headRpsIdxList = newIdxNode; >>> + else >>> + { >>> + tailRpsIdxList->next = newIdxNode; >>> + newIdxNode->prior = tailRpsIdxList; >>> + tailRpsIdxList = newIdxNode; >>> + } >>> + rce->rpsIdx = newIdxNode->idx; >>> + } >>> + } >>> + else >>> + { >>> + rce->rpsIdx = -1; >>> + } >>> + } >>> + >>> + // get commonly RPS set >>> + memset(resultIdx, 0, sizeof(resultIdx)); >>> + if (idx > MAX_NUM_SHORT_TERM_RPS) >>> + idx = MAX_NUM_SHORT_TERM_RPS; >>> + >>> + *rpsNumInPSP = idx; >>> + rpsIdxListIter = headRpsIdxList; >>> + for (int i = 0; i < idx; i++) >>> + { >>> + resultIdx[i] = rpsIdxListIter->idx; >>> + m_rpsInSpsCount += rpsIdxListIter->count; >>> + thisRpsInSPS = rpsInSPS + i; >>> + thisRpsInList = rpsIdxListIter->rps; >>> + thisRpsInSPS->numberOfPictures = thisRpsInList->numberOfPicture >>> s; >>> + thisRpsInSPS->numberOfNegativePictures = >>> thisRpsInList->numberOfNegativePictures; >>> + thisRpsInSPS->numberOfPositivePictures = >>> thisRpsInList->numberOfPositivePictures; >>> + for (pos = 0; pos < thisRpsInList->numberOfPictures; pos++) >>> + { >>> + thisRpsInSPS->deltaPOC[pos] = thisRpsInList->deltaPOC[pos]; >>> + thisRpsInSPS->bUsed[pos] = thisRpsInList->bUsed[pos]; >>> + } >>> + rpsIdxListIter = rpsIdxListIter->next; >>> + } >>> + >>> + //reset every frame's RPS index >>> + for (int i = beginNum; i < endNum; i++) >>> + { >>> + int j; >>> + rce = &rce2Pass[i]; >>> + for (j = 0; j < idx; j++) >>> + { >>> + if (rce->rpsIdx == resultIdx[j]) >>> + { >>> + rce->rpsIdx = j; >>> + break; >>> + } >>> + } >>> + >>> + if (j == idx) >>> + rce->rpsIdx = -1; >>> + } >>> + >>> + rpsIdxListIter = headRpsIdxList; >>> + while (rpsIdxListIter) >>> + { >>> + RPSListNode* freeIndex = rpsIdxListIter; >>> + rpsIdxListIter = rpsIdxListIter->next; >>> + delete freeIndex; >>> + } >>> + return true; >>> + >>> +fail: >>> + rpsIdxListIter = headRpsIdxList; >>> + while (rpsIdxListIter) >>> + { >>> + RPSListNode* freeIndex = rpsIdxListIter; >>> + rpsIdxListIter = rpsIdxListIter->next; >>> + delete freeIndex; >>> + } >>> + return false; >>> +} >>> + >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/encoder/encoder.h >>> --- a/source/encoder/encoder.h Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/encoder/encoder.h Mon Oct 24 14:54:41 2016 +0800 >>> @@ -79,6 +79,15 @@ >>> int numRefIdxl1[MAX_NUM_REF_IDX]; >>> }; >>> >>> +struct RPSListNode >>> +{ >>> + int idx; >>> + int count; >>> + RPS* rps; >>> + RPSListNode* next; >>> + RPSListNode* prior; >>> +}; >>> + >>> class FrameEncoder; >>> class DPB; >>> class Lookahead; >>> @@ -156,6 +165,9 @@ >>> Lock m_sliceRefIdxLock; >>> RefIdxLastGOP m_refIdxLastGOP; >>> >>> + Lock m_rpsInSpsLock; >>> + int m_rpsInSpsCount; >>> + >>> Encoder(); >>> ~Encoder() {} >>> >>> @@ -196,6 +208,7 @@ >>> void initRefIdx(); >>> void analyseRefIdx(int *numRefIdx); >>> void updateRefIdx(); >>> + bool computeSPSRPSIndex(); >>> >>> protected: >>> >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/encoder/entropy.cpp >>> --- a/source/encoder/entropy.cpp Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/encoder/entropy.cpp Mon Oct 24 14:54:41 2016 +0800 >>> @@ -312,7 +312,9 @@ >>> WRITE_FLAG(sps.bUseSAO, "sample_adaptive_offset_enabled_flag"); >>> >>> WRITE_FLAG(0, "pcm_enabled_flag"); >>> - WRITE_UVLC(0, "num_short_term_ref_pic_sets"); >>> + WRITE_UVLC(sps.spsrpsNum, "num_short_term_ref_pic_sets"); >>> + for (int i = 0; i < sps.spsrpsNum; i++) >>> + codeShortTermRefPicSet(sps.spsrps[i], i); >>> WRITE_FLAG(0, "long_term_ref_pics_present_flag"); >>> >>> WRITE_FLAG(sps.bTemporalMVPEnabled, "sps_temporal_mvp_enable_flag" >>> ); >>> @@ -614,8 +616,21 @@ >>> } >>> #endif >>> >>> - WRITE_FLAG(0, "short_term_ref_pic_set_sps_flag"); >>> - codeShortTermRefPicSet(slice.m_rps); >>> + if (slice.m_rpsIdx < 0) >>> + { >>> + WRITE_FLAG(0, "short_term_ref_pic_set_sps_flag"); >>> + codeShortTermRefPicSet(slice.m_rps, >>> slice.m_sps->spsrpsNum); >>> + } >>> + else >>> + { >>> + WRITE_FLAG(1, "short_term_ref_pic_set_sps_flag"); >>> + int numBits = 0; >>> + while ((1 << numBits) < slice.m_iNumRPSInSPS) >>> + numBits++; >>> + >>> + if (numBits > 0) >>> + WRITE_CODE(slice.m_rpsIdx, numBits, >>> "short_term_ref_pic_set_idx"); >>> + } >>> >>> if (slice.m_sps->bTemporalMVPEnabled) >>> WRITE_FLAG(1, "slice_temporal_mvp_enable_flag"); >>> @@ -707,8 +722,11 @@ >>> WRITE_CODE(substreamSizes[i] - 1, offsetLen, >>> "entry_point_offset_minus1"); >>> } >>> >>> -void Entropy::codeShortTermRefPicSet(const RPS& rps) >>> +void Entropy::codeShortTermRefPicSet(const RPS& rps, int idx) >>> { >>> + if (idx > 0) >>> + WRITE_FLAG(0, "inter_ref_pic_set_prediction_flag"); >>> + >>> WRITE_UVLC(rps.numberOfNegativePictures, "num_negative_pics"); >>> WRITE_UVLC(rps.numberOfPositivePictures, "num_positive_pics"); >>> int prev = 0; >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/encoder/entropy.h >>> --- a/source/encoder/entropy.h Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/encoder/entropy.h Mon Oct 24 14:54:41 2016 +0800 >>> @@ -149,7 +149,7 @@ >>> >>> void codeSliceHeader(const Slice& slice, FrameData& encData, >>> uint32_t slice_addr, uint32_t slice_addr_bits, int sliceQp); >>> void codeSliceHeaderWPPEntryPoints(const uint32_t *substreamSizes, >>> uint32_t numSubStreams, uint32_t maxOffset); >>> - void codeShortTermRefPicSet(const RPS& rps); >>> + void codeShortTermRefPicSet(const RPS& rps, int idx); >>> void finishSlice() { encodeBinTrm(1); finish(); >>> dynamic_cast<Bitstream*>(m_bitIf)->writeByteAlignment(); } >>> >>> void encodeCTU(const CUData& cu, const CUGeom& cuGeom); >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/encoder/frameencoder.cpp >>> --- a/source/encoder/frameencoder.cpp Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/encoder/frameencoder.cpp Mon Oct 24 14:54:41 2016 +0800 >>> @@ -359,9 +359,23 @@ >>> ScopedLock refIdxLock(m_top->m_sliceRefIdxLock); >>> m_top->updateRefIdx(); >>> } >>> - m_top->getStreamHeaders(m_nalList, m_entropyCoder, m_bs); >>> + if (m_top->m_param->rc.bStatRead && >>> m_top->m_param->bMultiPassOptRPS) >>> + { >>> + ScopedLock refIdxLock(m_top->m_rpsInSpsLock); >>> + if (!m_top->computeSPSRPSIndex()) >>> + { >>> + x265_log(m_param, X265_LOG_ERROR, "compute commonly RPS >>> failed!\n"); >>> + m_top->m_aborted = true; >>> + } >>> + m_top->getStreamHeaders(m_nalList, m_entropyCoder, m_bs); >>> + } >>> + else >>> + m_top->getStreamHeaders(m_nalList, m_entropyCoder, m_bs); >>> } >>> >>> + if (m_top->m_param->rc.bStatRead && m_top->m_param->bMultiPassOptR >>> PS) >>> + m_frame->m_encData->m_slice->m_rpsIdx = >>> (m_top->m_rateControl->m_rce2Pass + m_frame->m_encodeOrder)->rpsIdx; >>> + >>> // Weighted Prediction parameters estimation. >>> bool bUseWeightP = slice->m_sliceType == P_SLICE && >>> slice->m_pps->bUseWeightPred; >>> bool bUseWeightB = slice->m_sliceType == B_SLICE && >>> slice->m_pps->bUseWeightedBiPred; >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/encoder/ratecontrol.cpp >>> --- a/source/encoder/ratecontrol.cpp Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/encoder/ratecontrol.cpp Mon Oct 24 14:54:41 2016 +0800 >>> @@ -544,10 +544,27 @@ >>> } >>> rce = &m_rce2Pass[encodeOrder]; >>> m_encOrder[frameNumber] = encodeOrder; >>> - e += sscanf(p, " in:%*d out:%*d type:%c q:%lf q-aq:%lf >>> q-noVbv:%lf q-Rceq:%lf tex:%d mv:%d misc:%d icu:%lf pcu:%lf scu:%lf", >>> - &picType, &qpRc, &qpAq, &qNoVbv, &qRceq, >>> &rce->coeffBits, >>> - &rce->mvBits, &rce->miscBits, &rce->iCuCount, >>> &rce->pCuCount, >>> - &rce->skipCuCount); >>> + if (!m_param->bMultiPassOptRPS) >>> + { >>> + e += sscanf(p, " in:%*d out:%*d type:%c q:%lf >>> q-aq:%lf q-noVbv:%lf q-Rceq:%lf tex:%d mv:%d misc:%d icu:%lf pcu:%lf >>> scu:%lf", >>> + &picType, &qpRc, &qpAq, &qNoVbv, &qRceq, >>> &rce->coeffBits, >>> + &rce->mvBits, &rce->miscBits, &rce->iCuCount, >>> &rce->pCuCount, >>> + &rce->skipCuCount); >>> + } >>> + else >>> + { >>> + char deltaPOC[128]; >>> + char bUsed[40]; >>> + memset(deltaPOC, 0, sizeof(deltaPOC)); >>> + memset(bUsed, 0, sizeof(bUsed)); >>> + e += sscanf(p, " in:%*d out:%*d type:%c q:%lf >>> q-aq:%lf q-noVbv:%lf q-Rceq:%lf tex:%d mv:%d misc:%d icu:%lf pcu:%lf >>> scu:%lf nump:%d numnegp:%d numposp:%d deltapoc:%s bused:%s", >>> + &picType, &qpRc, &qpAq, &qNoVbv, &qRceq, >>> &rce->coeffBits, >>> + &rce->mvBits, &rce->miscBits, &rce->iCuCount, >>> &rce->pCuCount, >>> + &rce->skipCuCount, >>> &rce->rpsData.numberOfPictures, &rce->rpsData.numberOfNegativePictures, >>> &rce->rpsData.numberOfPositivePictures, deltaPOC, bUsed); >>> + splitdeltaPOC(deltaPOC, rce); >>> + splitbUsed(bUsed, rce); >>> + rce->rpsIdx = -1; >>> + } >>> rce->keptAsRef = true; >>> rce->isIdr = false; >>> if (picType == 'b' || picType == 'p') >>> @@ -2632,18 +2649,55 @@ >>> char cType = rce->sliceType == I_SLICE ? >>> (curFrame->m_lowres.sliceType == X265_TYPE_IDR ? 'I' : 'i') >>> : rce->sliceType == P_SLICE ? 'P' >>> : IS_REFERENCED(curFrame) ? 'B' : 'b'; >>> - if (fprintf(m_statFileOut, >>> - "in:%d out:%d type:%c q:%.2f q-aq:%.2f q-noVbv:%.2f >>> q-Rceq:%.2f tex:%d mv:%d misc:%d icu:%.2f pcu:%.2f scu:%.2f ;\n", >>> - rce->poc, rce->encodeOrder, >>> - cType, curEncData.m_avgQpRc, curEncData.m_avgQpAq, >>> - rce->qpNoVbv, rce->qRceq, >>> - curFrame->m_encData->m_frameStats.coeffBits, >>> - curFrame->m_encData->m_frameStats.mvBits, >>> - curFrame->m_encData->m_frameStats.miscBits, >>> - curFrame->m_encData->m_frameStats.percent8x8Intra * >>> m_ncu, >>> - curFrame->m_encData->m_frameStats.percent8x8Inter * >>> m_ncu, >>> - curFrame->m_encData->m_frameStats.percent8x8Skip * >>> m_ncu) < 0) >>> - goto writeFailure; >>> + >>> + if (!curEncData.m_param->bMultiPassOptRPS) >>> + { >>> + if (fprintf(m_statFileOut, >>> + "in:%d out:%d type:%c q:%.2f q-aq:%.2f q-noVbv:%.2f >>> q-Rceq:%.2f tex:%d mv:%d misc:%d icu:%.2f pcu:%.2f scu:%.2f ;\n", >>> + rce->poc, rce->encodeOrder, >>> + cType, curEncData.m_avgQpRc, curEncData.m_avgQpAq, >>> + rce->qpNoVbv, rce->qRceq, >>> + curFrame->m_encData->m_frameStats.coeffBits, >>> + curFrame->m_encData->m_frameStats.mvBits, >>> + curFrame->m_encData->m_frameStats.miscBits, >>> + curFrame->m_encData->m_frameStats.percent8x8Intra * m_ncu, >>> + curFrame->m_encData->m_frameStats.percent8x8Inter * m_ncu, >>> + curFrame->m_encData->m_frameStats.percent8x8Skip * m_ncu) >>> < 0) >>> + goto writeFailure; >>> + } >>> + else{ >>> + RPS* rpsWriter = &curFrame->m_encData->m_slice->m_rps; >>> + int i, num = rpsWriter->numberOfPictures; >>> + char deltaPOC[128]; >>> + char bUsed[40]; >>> + memset(deltaPOC, 0, sizeof(deltaPOC)); >>> + memset(bUsed, 0, sizeof(bUsed)); >>> + sprintf(deltaPOC, "deltapoc:~"); >>> + sprintf(bUsed, "bused:~"); >>> + >>> + for (i = 0; i < num; i++) >>> + { >>> + sprintf(deltaPOC, "%s%d~", deltaPOC, >>> rpsWriter->deltaPOC[i]); >>> + sprintf(bUsed, "%s%d~", bUsed, rpsWriter->bUsed[i]); >>> + } >>> + >>> + if (fprintf(m_statFileOut, >>> + "in:%d out:%d type:%c q:%.2f q-aq:%.2f q-noVbv:%.2f >>> q-Rceq:%.2f tex:%d mv:%d misc:%d icu:%.2f pcu:%.2f scu:%.2f nump:%d >>> numnegp:%d numposp:%d %s %s ;\n", >>> + rce->poc, rce->encodeOrder, >>> + cType, curEncData.m_avgQpRc, curEncData.m_avgQpAq, >>> + rce->qpNoVbv, rce->qRceq, >>> + curFrame->m_encData->m_frameStats.coeffBits, >>> + curFrame->m_encData->m_frameStats.mvBits, >>> + curFrame->m_encData->m_frameStats.miscBits, >>> + curFrame->m_encData->m_frameStats.percent8x8Intra * m_ncu, >>> + curFrame->m_encData->m_frameStats.percent8x8Inter * m_ncu, >>> + curFrame->m_encData->m_frameStats.percent8x8Skip * m_ncu, >>> + rpsWriter->numberOfPictures, >>> + rpsWriter->numberOfNegativePictures, >>> + rpsWriter->numberOfPositivePictures, >>> + deltaPOC, bUsed) < 0) >>> + goto writeFailure; >>> + } >>> /* Don't re-write the data in multi-pass mode. */ >>> if (m_param->rc.cuTree && IS_REFERENCED(curFrame) && >>> !m_param->rc.bStatRead) >>> { >>> @@ -2736,3 +2790,48 @@ >>> X265_FREE(m_param->rc.zones); >>> } >>> >>> +void RateControl::splitdeltaPOC(char deltapoc[], RateControlEntry *rce) >>> +{ >>> + int idx = 0, length = 0; >>> + char tmpStr[128]; >>> + char* src = deltapoc; >>> + char* buf = strstr(src, "~"); >>> + while (buf) >>> + { >>> + memset(tmpStr, 0, sizeof(tmpStr)); >>> + length = (int)(buf - src); >>> + if (length != 0) >>> + { >>> + strncpy(tmpStr, src, length); >>> + rce->rpsData.deltaPOC[idx] = atoi(tmpStr); >>> + idx++; >>> + if (idx == rce->rpsData.numberOfPictures) >>> + break; >>> + } >>> + src += (length + 1); >>> + buf = strstr(src, "~"); >>> + } >>> +} >>> + >>> +void RateControl::splitbUsed(char bused[], RateControlEntry *rce) >>> +{ >>> + int idx = 0, length = 0; >>> + char tmpStr[128]; >>> + char* src = bused; >>> + char* buf = strstr(src, "~"); >>> + while (buf) >>> + { >>> + memset(tmpStr, 0, sizeof(tmpStr)); >>> + length = (int)(buf - src); >>> + if (length != 0) >>> + { >>> + strncpy(tmpStr, src, length); >>> + rce->rpsData.bUsed[idx] = atoi(tmpStr) > 0; >>> + idx++; >>> + if (idx == rce->rpsData.numberOfPictures) >>> + break; >>> + } >>> + src += (length + 1); >>> + buf = strstr(src, "~"); >>> + } >>> +} >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/encoder/ratecontrol.h >>> --- a/source/encoder/ratecontrol.h Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/encoder/ratecontrol.h Mon Oct 24 14:54:41 2016 +0800 >>> @@ -111,6 +111,8 @@ >>> bool isIdr; >>> SEIPictureTiming *picTimingSEI; >>> HRDTiming *hrdTiming; >>> + int rpsIdx; >>> + RPS rpsData; >>> }; >>> >>> class RateControl >>> @@ -282,6 +284,8 @@ >>> bool findUnderflow(double *fills, int *t0, int *t1, int over, int >>> framesCount); >>> bool fixUnderflow(int t0, int t1, double adjustment, double >>> qscaleMin, double qscaleMax); >>> double tuneQScaleForGrain(double rcOverflow); >>> + void splitdeltaPOC(char deltapoc[], RateControlEntry *rce); >>> + void splitbUsed(char deltapoc[], RateControlEntry *rce); >>> }; >>> } >>> #endif // ifndef X265_RATECONTROL_H >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/x265.h >>> --- a/source/x265.h Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/x265.h Mon Oct 24 14:54:41 2016 +0800 >>> @@ -1323,6 +1323,9 @@ >>> /* Opitmize ref list length in PPS based on stats from previous >>> GOP*/ >>> int bOptRefListLengthPPS; >>> >>> + /* Enable storing commonly RPS in SPS in multi pass mode */ >>> + int bMultiPassOptRPS; >>> + >>> } x265_param; >>> >>> /* x265_param_alloc: >>> diff -r 0e9e52640546 -r 19d3c5ea8bc1 source/x265cli.h >>> --- a/source/x265cli.h Wed Oct 12 17:58:49 2016 +0530 >>> +++ b/source/x265cli.h Mon Oct 24 14:54:41 2016 +0800 >>> @@ -236,6 +236,8 @@ >>> { "pass", required_argument, NULL, 0 }, >>> { "slow-firstpass", no_argument, NULL, 0 }, >>> { "no-slow-firstpass", no_argument, NULL, 0 }, >>> + { "multi-pass-opt-rps", no_argument, NULL, 0 }, >>> + { "no-multi-pass-opt-rps", no_argument, NULL, 0 }, >>> { "analysis-mode", required_argument, NULL, 0 }, >>> { "analysis-file", required_argument, NULL, 0 }, >>> { "strict-cbr", no_argument, NULL, 0 }, >>> @@ -460,6 +462,7 @@ >>> H0(" --[no-]vui-hrd-info Discard optional HRD timing >>> information from the bistream. Default %s\n", OPT(param->bEmitVUIHRDInfo)); >>> H0(" --[no-]opt-qp-pps Discard optional HRD timing >>> information from the bistream. Default %s\n", OPT(param->bOptQpPPS)); >>> H0(" --[no-]opt-ref-list-length-pps Discard optional HRD timing >>> information from the bistream. Default %s\n", OPT(param->bOptRefListLengthPP >>> S)); >>> + H0(" --[no-]multi-pass-opt-rps Enable storing commonly RPS in >>> SPS in multi pass mode. Default %s\n", OPT(param->bMultiPassOptRPS)); >>> H1("\nReconstructed video options (debugging):\n"); >>> H1("-r/--recon <filename> Reconstructed raw image YUV or >>> Y4M output file name\n"); >>> H1(" --recon-depth <integer> Bit-depth of reconstructed raw >>> image file. Defaults to input bit depth, or 8 if Y4M\n"); >>> >>> >>> _______________________________________________ >>> x265-devel mailing list >>> x265-devel@videolan.org >>> https://mailman.videolan.org/listinfo/x265-devel >>> >>> >> >> _______________________________________________ >> x265-devel mailing list >> x265-devel@videolan.org >> https://mailman.videolan.org/listinfo/x265-devel >> >> > > > -- > Thanks, > Zheng Wang. > > _______________________________________________ > x265-devel mailing list > x265-devel@videolan.org > https://mailman.videolan.org/listinfo/x265-devel > >
_______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel