Hi, Pradeep, I have resend the patch to x265 mail list by using a new email " [email protected]" and sending patch with ubuntu(china's network has many problems when connected to foreign), and this time i have test download the patch and import it, it work well. Please check it again.
2016-10-25 12:06 GMT+08:00 Pradeep Ramachandran < [email protected]>: > 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 <[email protected]> > 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 < >> [email protected]>: >> >>> 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 <[email protected] >>> > wrote: >>> >>>> # HG changeset patch >>>> # User ZhengWang <[email protected]> >>>> # 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->numberOfPictures; >>>> + 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 >>>> [email protected] >>>> https://mailman.videolan.org/listinfo/x265-devel >>>> >>>> >>> >>> _______________________________________________ >>> x265-devel mailing list >>> [email protected] >>> https://mailman.videolan.org/listinfo/x265-devel >>> >>> >> >> >> -- >> Thanks, >> Zheng Wang. >> >> _______________________________________________ >> x265-devel mailing list >> [email protected] >> https://mailman.videolan.org/listinfo/x265-devel >> >> > > _______________________________________________ > x265-devel mailing list > [email protected] > https://mailman.videolan.org/listinfo/x265-devel > > -- Thanks, Zheng Wang.
_______________________________________________ x265-devel mailing list [email protected] https://mailman.videolan.org/listinfo/x265-devel
