[x265] Fwd: Fix build issues
# HG changeset patch # User Radhakrishnan # Date 1527845200 -19800 # Fri Jun 01 14:56:40 2018 +0530 # Node ID ef02ddaad3dcc07a7750989b21878f82cd6c2f97 # Parent 9cde2c278464be0db96d41f9605a2dc7a3137165 Fixes cmake error "cannot find x265.pdb" when installing files for static debug build provided enable_cli is off. diff -r 9cde2c278464 -r ef02ddaad3dc source/CMakeLists.txt --- a/source/CMakeLists.txt Wed May 30 20:54:07 2018 +0530 +++ b/source/CMakeLists.txt Fri Jun 01 14:56:40 2018 +0530 @@ -554,7 +554,7 @@ ARCHIVE DESTINATION ${LIB_INSTALL_DIR}) endif() install(FILES x265.h "${PROJECT_BINARY_DIR}/x265_config.h" DESTINATION include) -if(WIN32) +if((WIN32 AND ENABLE_CLI) OR (WIN32 AND ENABLE_SHARED)) if(MSVC_IDE) install(FILES "${PROJECT_BINARY_DIR}/Debug/x265.pdb" DESTINATION ${BIN_INSTALL_DIR} CONFIGURATIONS Debug) install(FILES "${PROJECT_BINARY_DIR}/RelWithDebInfo/x265.pdb" DESTINATION ${BIN_INSTALL_DIR} CONFIGURATIONS RelWithDebInfo) fix-install-error-x265.patch Description: Binary data ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
Re: [x265] [PATCH] Fix payload size for SEIRecoveryPoint
Yeah but I didn't add it to that flag as this is not a hrd related parameter. But I will clean up this function and resend the patch. pls ignore this Aarthi Priya Thirumalai Technical Lead, UHDkit Multicoreware Inc On Fri, Mar 16, 2018 at 5:35 PM, Ashok Kumar Mishra < as...@multicorewareinc.com> wrote: > > > On Fri, Mar 16, 2018 at 4:24 PM, <aar...@multicorewareinc.com> wrote: > >> # HG changeset patch >> # User Aarthi Thirumalai <aar...@multicorewareinc.com> >> # Date 1521028474 -19800 >> # Wed Mar 14 17:24:34 2018 +0530 >> # Node ID 265d516af978a209bd22a6ae43487cecd01c4503 >> # Parent d7c26df32fae052b7e895fee9bda1c22b24cc44b >> Fix payload size for SEIRecoveryPoint >> >> diff -r d7c26df32fae -r 265d516af978 source/encoder/sei.cpp >> --- a/source/encoder/sei.cppTue Mar 13 13:40:13 2018 +0530 >> +++ b/source/encoder/sei.cppWed Mar 14 17:24:34 2018 +0530 >> @@ -41,8 +41,9 @@ >> uint32_t type = m_payloadType; >> m_bitIf = >> BitCounter count; >> +uint32_t payloadSize = m_payloadSize; >> bool hrdTypes = (m_payloadType == ACTIVE_PARAMETER_SETS || >> m_payloadType == PICTURE_TIMING || m_payloadType == BUFFERING_PERIOD); >> > > I think it is not required to check the condition "m_payloadType == > RECOVERY_POINT" in other places > if you add this in above flag hrdTypes. > > >> -if (hrdTypes) >> +if (hrdTypes || m_payloadType == RECOVERY_POINT) >> { >> m_bitIf = >> /* virtual writeSEI method, write to bit counter to determine >> size */ >> @@ -53,10 +54,10 @@ >> WRITE_CODE(0xff, 8, "payload_type"); >> } >> WRITE_CODE(type, 8, "payload_type"); >> -uint32_t payloadSize; >> -if (hrdTypes || m_payloadType == USER_DATA_UNREGISTERED || >> m_payloadType == USER_DATA_REGISTERED_ITU_T_T35) >> +if (hrdTypes || m_payloadType == USER_DATA_UNREGISTERED || >> m_payloadType == USER_DATA_REGISTERED_ITU_T_T35 || >> +m_payloadType == RECOVERY_POINT) >> { >> -if (hrdTypes) >> +if (hrdTypes || m_payloadType == RECOVERY_POINT) >> { >> X265_CHECK(0 == (count.getNumberOfWrittenBits() & 7), >> "payload unaligned\n"); >> payloadSize = count.getNumberOfWrittenBits() >> 3; >> @@ -65,13 +66,10 @@ >> payloadSize = m_payloadSize + 16; >> else >> payloadSize = m_payloadSize; >> - >> -for (; payloadSize >= 0xff; payloadSize -= 0xff) >> -WRITE_CODE(0xff, 8, "payload_size"); >> -WRITE_CODE(payloadSize, 8, "payload_size"); >> } >> -else >> -WRITE_CODE(m_payloadSize, 8, "payload_size"); >> +for (; payloadSize >= 0xff; payloadSize -= 0xff) >> +WRITE_CODE(0xff, 8, "payload_size"); >> +WRITE_CODE(payloadSize, 8, "payload_size"); >> /* virtual writeSEI method, write to bs */ >> writeSEI(sps); >> } >> >> ___ >> 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 > > ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
Re: [x265] [PATCH] encoder: expose BREF slice type in pic_out sliceType
In finishFrameStats, the pic_out->frameData->sliceType is getting set as I/P/B. For this, we combine the B/BREF from lowres.sliceType and set it as 'B' But the pic_out->sliceType is set to lowres.sliceType which is an enum with 5 values. I can see the lowres.sliceTypes able to differentiate between BREF(4) and B(5). Can you pls provide your test cli if you are not able to see this in lowres.sliceType. Since we use it in other places as well, this can be a bigger problem if lowres.sliceType does not indicate BREF. Aarthi Priya Thirumalai Technical Lead, UHDkit Multicoreware Inc On Mon, Nov 20, 2017 at 9:12 PM, John Stebbins <stebb...@jetheaddev.com> wrote: > BREF is not set in lowres.SliceType. Only B slice type is getting set in > pic_out sliceType. A similar test is already performed in finishFrameStats > because lowres.sliceType does not distinguish. > > On 11/19/2017 10:15 PM, Aarthi Priya Thirumalai wrote: > > I think this change is not necessary since the sliceType in pic_out is > already set from m_lowres.sliceType. > So, if the B frame is a B_REF, this is reflected from the lowres.sliceType > already. > > Is there any reason, you are explicitly setting it again? > > On Fri, Nov 17, 2017 at 4:41 AM, John Stebbins <stebb...@jetheaddev.com> > wrote: > >> # HG changeset patch >> # User John Stebbins <jstebbins...@gmail.com> >> # Date 1510861637 28800 >> # Thu Nov 16 11:47:17 2017 -0800 >> # Branch stable >> # Node ID 5b61fc79bfa2d2bf85f8796001d711e5eed1fa1c >> # Parent 0b3ba15b33eaed5681f639697024525e9460bb31 >> encoder: expose BREF slice type in pic_out sliceType >> >> The AppleTV 4K requires accurate frame dependency information in the >> mp4 sdtp box in order to play 2160p60 content. >> >> diff -r 0b3ba15b33ea -r 5b61fc79bfa2 source/encoder/encoder.cpp >> --- a/source/encoder/encoder.cppTue Sep 05 11:21:24 2017 +0530 >> +++ b/source/encoder/encoder.cppThu Nov 16 11:47:17 2017 -0800 >> @@ -857,6 +857,9 @@ >> pic_out->pts = outFrame->m_pts; >> pic_out->dts = outFrame->m_dts; >> pic_out->sliceType = outFrame->m_lowres.sliceType; >> +if (pic_out->sliceType == X265_TYPE_B && >> +IS_REFERENCED(outFrame)) >> +pic_out->sliceType = X265_TYPE_BREF; >> pic_out->planes[0] = recpic->m_picOrg[0]; >> pic_out->stride[0] = (int)(recpic->m_stride * >> sizeof(pixel)); >> if (m_param->internalCsp != X265_CSP_I400) >> ___ >> x265-devel mailing list >> x265-devel@videolan.org >> https://mailman.videolan.org/listinfo/x265-devel >> > > > > ___ > x265-devel mailing > listx265-devel@videolan.orghttps://mailman.videolan.org/listinfo/x265-devel > > > -- > John GnuPG fingerprint: D0EC B3DB C372 D1F1 0B01 83F0 49F1 D7B2 60D4 > D0F7 > > > ___ > 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
Re: [x265] [PATCH] encoder: expose BREF slice type in pic_out sliceType
I think this change is not necessary since the sliceType in pic_out is already set from m_lowres.sliceType. So, if the B frame is a B_REF, this is reflected from the lowres.sliceType already. Is there any reason, you are explicitly setting it again? On Fri, Nov 17, 2017 at 4:41 AM, John Stebbinswrote: > # HG changeset patch > # User John Stebbins > # Date 1510861637 28800 > # Thu Nov 16 11:47:17 2017 -0800 > # Branch stable > # Node ID 5b61fc79bfa2d2bf85f8796001d711e5eed1fa1c > # Parent 0b3ba15b33eaed5681f639697024525e9460bb31 > encoder: expose BREF slice type in pic_out sliceType > > The AppleTV 4K requires accurate frame dependency information in the > mp4 sdtp box in order to play 2160p60 content. > > diff -r 0b3ba15b33ea -r 5b61fc79bfa2 source/encoder/encoder.cpp > --- a/source/encoder/encoder.cppTue Sep 05 11:21:24 2017 +0530 > +++ b/source/encoder/encoder.cppThu Nov 16 11:47:17 2017 -0800 > @@ -857,6 +857,9 @@ > pic_out->pts = outFrame->m_pts; > pic_out->dts = outFrame->m_dts; > pic_out->sliceType = outFrame->m_lowres.sliceType; > +if (pic_out->sliceType == X265_TYPE_B && > +IS_REFERENCED(outFrame)) > +pic_out->sliceType = X265_TYPE_BREF; > pic_out->planes[0] = recpic->m_picOrg[0]; > pic_out->stride[0] = (int)(recpic->m_stride * > sizeof(pixel)); > if (m_param->internalCsp != X265_CSP_I400) > ___ > 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
Re: [x265] [PATCH] Add dynamic rate-control reconfiguration
On Tue, Apr 4, 2017 at 6:34 PM,wrote: > # HG changeset patch > # User Aruna Matheswaran > # Date 1487757265 -19800 > # Wed Feb 22 15:24:25 2017 +0530 > # Node ID 576ad673d9b352c45853b7ffeeacce7d23268bb8 > # Parent 08a05ca9fd16c9f5efb1ce4d8389bda8a63f5f7d > Add dynamic rate-control reconfiguration > > diff -r 08a05ca9fd16 -r 576ad673d9b3 source/common/frame.cpp > --- a/source/common/frame.cpp Mon Mar 27 12:35:20 2017 +0530 > +++ b/source/common/frame.cpp Wed Feb 22 15:24:25 2017 +0530 > @@ -47,6 +47,7 @@ > memset(_lowres, 0, sizeof(m_lowres)); > m_rcData = NULL; > m_encodeStartTime = 0; > +m_reconfigureRc = false; > } > > bool Frame::create(x265_param *param, float* quantOffsets) > diff -r 08a05ca9fd16 -r 576ad673d9b3 source/common/frame.h > --- a/source/common/frame.h Mon Mar 27 12:35:20 2017 +0530 > +++ b/source/common/frame.h Wed Feb 22 15:24:25 2017 +0530 > @@ -84,6 +84,7 @@ > Lowres m_lowres; > bool m_lowresInit; // lowres init complete > (pre-analysis) > bool m_bChromaExtended;// orig chroma planes > motion extended for weight analysis > +bool m_reconfigureRc; > > float* m_quantOffsets; // points to > quantOffsets in x265_picture > x265_sei m_userSEI; > diff -r 08a05ca9fd16 -r 576ad673d9b3 source/encoder/api.cpp > --- a/source/encoder/api.cppMon Mar 27 12:35:20 2017 +0530 > +++ b/source/encoder/api.cppWed Feb 22 15:24:25 2017 +0530 > @@ -171,7 +171,7 @@ > > x265_param save; > Encoder* encoder = static_cast (enc); > -if (encoder->m_reconfigure) /* Reconfigure in progress */ > +if (encoder->m_reconfigure || encoder->m_reconfigureRc) /* > Reconfigure in progress */ > return 1; > memcpy(, encoder->m_latestParam, sizeof(x265_param)); > int ret = encoder->reconfigureParam(encoder->m_latestParam, > param_in); > @@ -197,7 +197,22 @@ > return -1; > } > } > -encoder->m_reconfigure = true; > +if (encoder->m_reconfigureRc) > +{ > +VPS saveVPS; > +memcpy(, >m_vps.ptl, > sizeof(saveVPS.ptl)); > +determineLevel(*encoder->m_latestParam, encoder->m_vps); > +if (saveVPS.ptl.profileIdc != encoder->m_vps.ptl.profileIdc > || saveVPS.ptl.levelIdc != encoder->m_vps.ptl.levelIdc > +|| saveVPS.ptl.tierFlag != encoder->m_vps.ptl.tierFlag) > +{ > +x265_log(encoder->m_param, X265_LOG_WARNING, > "Profile/Level/Tier has changed from %d/%d/%s to %d/%d/%s.Cannot > reconfigure rate-control.\n", > + saveVPS.ptl.profileIdc, saveVPS.ptl.levelIdc, > saveVPS.ptl.tierFlag ? "High" : "Main", encoder->m_vps.ptl.profileIdc, > + encoder->m_vps.ptl.levelIdc, > encoder->m_vps.ptl.tierFlag ? "High" : "Main"); > +encoder->m_reconfigureRc = false; > +} > +} > +else > +encoder->m_reconfigure = true; > why set only m_reconfigure as true, where are you setting m_reconfigureRc to true? > encoder->printReconfigureParams(); > } > return ret; > diff -r 08a05ca9fd16 -r 576ad673d9b3 source/encoder/encoder.cpp > --- a/source/encoder/encoder.cppMon Mar 27 12:35:20 2017 +0530 > +++ b/source/encoder/encoder.cppWed Feb 22 15:24:25 2017 +0530 > @@ -56,6 +56,7 @@ > { > m_aborted = false; > m_reconfigure = false; > +m_reconfigureRc = false; > m_encodedFrameNum = 0; > m_pocLast = -1; > m_curEncoder = 0; > @@ -607,7 +608,7 @@ > { > inFrame = new Frame; > inFrame->m_encodeStartTime = x265_mdate(); > -x265_param* p = m_reconfigure ? m_latestParam : m_param; > no need for this change - when reconfigureRc is true, m_reconfigure will also be true..so dont need to change these > +x265_param* p = (m_reconfigure || m_reconfigureRc) ? > m_latestParam : m_param; > if (inFrame->create(p, pic_in->quantOffsets)) > { > /* the first PicYuv created is asked to generate the CU > and block unit offset > @@ -674,7 +675,7 @@ > inFrame->m_userData = pic_in->userData; > inFrame->m_pts = pic_in->pts; > inFrame->m_forceqp = pic_in->forceqp; > -inFrame->m_param = m_reconfigure ? m_latestParam : m_param; > same as above. for any reconfigure, set m_reconfigure to true, additionally, set m_reconfigureRc to true for Rate control reconfigure changes. no need for the above change then > +inFrame->m_param = (m_reconfigure || m_reconfigureRc) ? > m_latestParam : m_param; > > if (pic_in->userSEI.numPayloads) > { > @@ -740,6 +741,8 @@ > inFrame->m_lowres.bScenecut = !!inFrame->m_analysisData. >
Re: [x265] [PATCH] Set frame as keyint if scalinglist reconfigure
On Wed, Dec 21, 2016 at 10:15 AM,wrote: > # HG changeset patch > # User Vignesh Vijayakumar > # Date 1482232112 -19800 > # Tue Dec 20 16:38:32 2016 +0530 > # Node ID 97d011cd7fe2b7dc1ecd2cebb887e1536b810052 > # Parent 88285bf550a4f88bb09ff5b49ec46b81140a025d > Set frame as keyint if scalinglist reconfigure > > diff -r 88285bf550a4 -r 97d011cd7fe2 source/encoder/encoder.cpp > --- a/source/encoder/encoder.cppTue Dec 20 16:35:53 2016 +0530 > +++ b/source/encoder/encoder.cppTue Dec 20 16:38:32 2016 +0530 > @@ -78,6 +78,7 @@ > m_iPPSQpMinus26 = 0; > m_iLastSliceQp = 0; > m_rpsInSpsCount = 0; > +m_reconfigureScalingLists = false; > for (int i = 0; i < X265_MAX_FRAME_THREADS; i++) > m_frameEncoder[i] = NULL; > > @@ -842,6 +843,12 @@ > frameEnc = m_lookahead->getDecidedPicture(); > if (frameEnc && !pass) > { > You can't make it a keyframe this way. A keyframe can't be of any slicetype. It needs to be IDR. You need to change the slicetype as well. You need to set the m_reconfigureScalingLists to true while you are reconfiguring the scaling List inside the x265_encoder_reconfig() and based on this, you need to set the next incoming frame's slice type to I/IDR and set it as keyframe during the slicetype analysis of that frame. It will in turn change the slice types of the following frames accordingly. Else, reconfigure scaling list only at every keyframe interval - this is what I would recommend. +if (m_param->bRepeatHeaders && m_reconfigure && m_latestParam > != NULL && (m_latestParam->scalingLists != m_param->scalingLists) && > !m_reconfigureScalingLists) > +{ > +frameEnc->m_lowres.bKeyframe = true; > +m_reconfigureScalingLists = true; > +} > + > if (curEncoder->m_reconfigure) > { > /* One round robin cycle of FE reconfigure is complete */ > diff -r 88285bf550a4 -r 97d011cd7fe2 source/encoder/encoder.h > --- a/source/encoder/encoder.h Tue Dec 20 16:35:53 2016 +0530 > +++ b/source/encoder/encoder.h Tue Dec 20 16:38:32 2016 +0530 > @@ -150,6 +150,7 @@ > bool m_bZeroLatency; // x265_encoder_encode() > returns NALs for the input picture, zero lag > bool m_aborted; // fatal error detected > bool m_reconfigure; // Encoder reconfigure in > progress > +bool m_reconfigureScalingLists;// Change in > scalinglists > > /* Begin intra refresh when one not in progress or else begin one as > soon as the current > * one is done. Requires bIntraRefresh to be set.*/ > ___ > 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
[x265] [PATCH] Set up separate threadpool for lookahead
# HG changeset patch # User Aarthi Priya Thirumalai <aar...@multicorewareinc.com> # Date 1481274360 -19800 # Fri Dec 09 14:36:00 2016 +0530 # Node ID e8152da7aa0e03a27f01a2a95aedf914248fe577 # Parent 78e1e1354a25d287f17359ed489833e46bf177f1 Set up separate threadpool for lookahead The user can allocate specific number of threads for lookahead by specifying --lookahead-threads , creating a separate lookahead pool for these threads. This will improve performance when lookahead becomes a bottle neck. THe threads for lookahead must be ideally less than half the total number of available worker threads. diff -r 78e1e1354a25 -r e8152da7aa0e doc/reST/cli.rst --- a/doc/reST/cli.rst Fri Dec 09 10:45:12 2016 +0530 +++ b/doc/reST/cli.rst Fri Dec 09 14:36:00 2016 +0530 @@ -1227,8 +1227,18 @@ Default: 8 for ultrafast, superfast, faster, fast, medium 4 for slow, slower disabled for veryslow, slower + +.. option:: --lookahead-threads +Use multiple worker threads dedicated to doing only lookahead instead of sharing +the worker threads with frame Encoders. A dedicated lookahead threadpool is created with the +specified number of worker threads. This can range from 0 upto half the +hardware threads available for encoding. Using too many threads for lookahead can starve +resources for frame Encoder and can harm performance. Default is 0 - disabled, Lookahead + shares worker threads with other FrameEncoders . +**Values:** 0 - disabled(default). Max - Half of available hardware threads. + .. option:: --b-adapt Set the level of effort in determining B frame placement. diff -r 78e1e1354a25 -r e8152da7aa0e source/CMakeLists.txt --- a/source/CMakeLists.txt Fri Dec 09 10:45:12 2016 +0530 +++ b/source/CMakeLists.txt Fri Dec 09 14:36:00 2016 +0530 @@ -28,9 +28,8 @@ option(NATIVE_BUILD "Target the build CPU" OFF) 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 102) +set(X265_BUILD 103) configure_file("${PROJECT_SOURCE_DIR}/x265.def.in" "${PROJECT_BINARY_DIR}/x265.def") configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in" diff -r 78e1e1354a25 -r e8152da7aa0e source/common/param.cpp --- a/source/common/param.cpp Fri Dec 09 10:45:12 2016 +0530 +++ b/source/common/param.cpp Fri Dec 09 14:36:00 2016 +0530 @@ -149,8 +149,8 @@ param->bBPyramid = 1; param->scenecutThreshold = 40; /* Magic number pulled in from x264 */ param->lookaheadSlices = 8; +param->lookaheadThreads = 0; param->scenecutBias = 5.0; - /* Intra Coding Tools */ param->bEnableConstrainedIntra = 0; param->bEnableStrongIntraSmoothing = 1; @@ -919,7 +919,7 @@ OPT("opt-ref-list-length-pps") p->bOptRefListLengthPPS = atobool(value); OPT("multi-pass-opt-rps") p->bMultiPassOptRPS = atobool(value); OPT("scenecut-bias") p->scenecutBias = atof(value); - +OPT("lookahead-threads") p->lookaheadThreads = atoi(value); else return X265_PARAM_BAD_NAME; } @@ -1412,6 +1412,7 @@ TOOLOPT(param->bEnableFastIntra, "fast-intra"); TOOLOPT(param->bEnableStrongIntraSmoothing, "strong-intra-smoothing"); TOOLVAL(param->lookaheadSlices, "lslices=%d"); +TOOLVAL(param->lookaheadThreads, "lthreads=%d") if (param->maxSlices > 1) TOOLVAL(param->maxSlices, "slices=%d"); if (param->bEnableLoopFilter) diff -r 78e1e1354a25 -r e8152da7aa0e source/common/threadpool.cpp --- a/source/common/threadpool.cpp Fri Dec 09 10:45:12 2016 +0530 +++ b/source/common/threadpool.cpp Fri Dec 09 14:36:00 2016 +0530 @@ -244,8 +244,7 @@ return bondCount; } - -ThreadPool* ThreadPool::allocThreadPools(x265_param* p, int& numPools) +ThreadPool* ThreadPool::allocThreadPools(x265_param* p, int& numPools, bool isThreadsReserved) { enum { MAX_NODE_NUM = 127 }; int cpusPerNode[MAX_NODE_NUM + 1]; @@ -397,17 +396,32 @@ x265_log(p, X265_LOG_DEBUG, "Reducing number of thread pools for frame thread count\n"); numPools = X265_MAX(p->frameNumThreads / 2, 1); } - +if (isThreadsReserved) +numPools = 1; ThreadPool *pools = new ThreadPool[numPools]; if (pools) { -int maxProviders = (p->frameNumThreads + numPools - 1) / numPools + 1; /* +1 is Lookahead, always assigned to threadpool 0 */ +int maxProviders = (p->frameNumThreads + numPools - 1) / numPools + !isThreadsReserved; /* +1 is Lookahead, always assigned to threadpool 0 */ int node = 0;
[x265] [PATCH] rcStats: add more fields to rcStats
# HG changeset patch # User Aarthi Priya Thirumalai <aar...@multicorewareinc.com> # Date 1468235606 -19800 # Mon Jul 11 16:43:26 2016 +0530 # Node ID b8c3278330fdd67dc2d3d6ea32ec2b6b8bebe00b # Parent a932b4366235ab6597c8d124c1569dade6ff790a rcStats: add more fields to rcStats diff -r a932b4366235 -r b8c3278330fd source/common/frame.h --- a/source/common/frame.h Mon Jul 04 21:25:59 2016 +0530 +++ b/source/common/frame.h Mon Jul 11 16:43:26 2016 +0530 @@ -49,6 +49,9 @@ double pCuCount; double skipCuCount; double qScale; +double cumulativePQp; +double cumulativePNorm; +double lastQScaleFor[3]; int mvBits; int miscBits; int coeffBits; diff -r a932b4366235 -r b8c3278330fd source/encoder/encoder.cpp --- a/source/encoder/encoder.cppMon Jul 04 21:25:59 2016 +0530 +++ b/source/encoder/encoder.cppMon Jul 11 16:43:26 2016 +0530 @@ -777,7 +777,7 @@ if (m_rateControl->writeRateControlFrameStats(outFrame, >m_rce)) m_aborted = true; -if (pic_out && m_param->rc.bStatWrite) +if (pic_out) { /* m_rcData is allocated for every frame */ pic_out->rcData = outFrame->m_rcData; diff -r a932b4366235 -r b8c3278330fd source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cppMon Jul 04 21:25:59 2016 +0530 +++ b/source/encoder/ratecontrol.cppMon Jul 11 16:43:26 2016 +0530 @@ -1223,6 +1223,10 @@ /* copy value of lastRceq into thread local rce struct *to be used in RateControlEnd() */ rce->qRceq = m_lastRceq; accumPQpUpdate(); +curFrame->m_rcData->cumulativePQp = m_accumPQp; +curFrame->m_rcData->cumulativePNorm = m_accumPNorm; +for (int i = 0; i < 3; i++) +curFrame->m_rcData->lastQScaleFor[i] = m_lastQScaleFor[i]; } else // CQP { ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
[x265] [PATCH] fix warnings in sao
# HG changeset patch # User Aarthi Priya Thirumalai <aar...@multicorewareinc.com> # Date 1466746115 -19800 # Fri Jun 24 10:58:35 2016 +0530 # Node ID 9b1ef8bf4ec4cbeb19cbc15b584893310bbed2e2 # Parent 626fcbac7ffba723dabd3a9f0507c4c80f3e7bc9 fix warnings in sao diff -r 626fcbac7ffb -r 9b1ef8bf4ec4 source/encoder/sao.cpp --- a/source/encoder/sao.cppThu Jun 16 12:57:38 2016 +0530 +++ b/source/encoder/sao.cppFri Jun 24 10:58:35 2016 +0530 @@ -1398,7 +1398,7 @@ while (offset != 0) { // Calculate the bits required for signalling the offset -int rate = (typeIdx == SAO_BO) ? (abs(offset) + 2) : (abs(offset) + 1); +uint32_t rate = (typeIdx == SAO_BO) ? (abs(offset) + 2) : (abs(offset) + 1); if (abs(offset) == OFFSET_THRESH - 1) rate--; ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
[x265] Birthday off today
Hi all, I will be taking the day off on the occasion of my birthday. ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
Re: [x265] [PATCH] rc: fix Rate Control for grainy content
# HG changeset patch # User Aarthi Thirumalai # Date 1452501832 -19800 # Mon Jan 11 14:13:52 2016 +0530 # Node ID cee55e38a09310c1c3384ee72e548bd72a00a4e7 # Parent f548abe8eae8fb75513a85d1b09233e706c7b5ba rc: fix Rate Control for grainy content optimize params for tune grain, reduce frequent qp fluctions to prevent grain loss diff -r f548abe8eae8 -r cee55e38a093 source/common/param.cpp --- a/source/common/param.cpp Wed Jan 20 18:27:42 2016 +0530 +++ b/source/common/param.cpp Mon Jan 11 14:13:52 2016 +0530 @@ -454,16 +454,11 @@ } else if (!strcmp(tune, "grain")) { -param->deblockingFilterBetaOffset = -2; -param->deblockingFilterTCOffset = -2; -param->bIntraInBFrames = 0; -param->rdoqLevel = 2; -param->psyRdoq = 10.0; -param->psyRd = 0.5; param->rc.ipFactor = 1.1; -param->rc.pbFactor = 1.1; -param->rc.aqStrength = 0.3; -param->rc.qCompress = 0.8; +param->rc.pbFactor = 1.0; +param->rc.cuTree = 0; +param->rc.aqMode = 0; +param->rc.qpStep = 1.0; } else return -1; diff -r f548abe8eae8 -r cee55e38a093 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Wed Jan 20 18:27:42 2016 +0530 +++ b/source/encoder/ratecontrol.cpp Mon Jan 11 14:13:52 2016 +0530 @@ -190,6 +190,8 @@ m_numEntries = 0; m_isSceneTransition = false; m_lastPredictorReset = 0; +m_avgPFrameQp = 0; +m_isFirstMiniGop = false; if (m_param->rc.rateControlMode == X265_RC_CRF) { m_param->rc.qp = (int)m_param->rc.rfConstant; @@ -288,9 +290,13 @@ m_ipOffset = 6.0 * X265_LOG2(m_param->rc.ipFactor); m_pbOffset = 6.0 * X265_LOG2(m_param->rc.pbFactor); +for (int i = 0; i < QP_MAX_MAX; i++) +m_qpToEncodedBits[i] = 0; + /* Adjust the first frame in order to stabilize the quality level compared to the rest */ #define ABR_INIT_QP_MIN (24) #define ABR_INIT_QP_MAX (40) +#define ABR_INIT_QP_GRAIN_MAX (32) #define ABR_SCENECUT_INIT_QP_MIN (12) #define CRF_INIT_QP (int)m_param->rc.rfConstant for (int i = 0; i < 3; i++) @@ -361,6 +367,7 @@ m_amortizeFraction = 0.85; m_amortizeFrames = m_param->totalFrames / 2; } + for (int i = 0; i < s_slidingWindowFrames; i++) { m_satdCostWindow[i] = 0; @@ -370,15 +377,19 @@ m_isPatternPresent = false; m_numBframesInPattern = 0; +m_isGrainEnabled = false; +if(m_param->rc.pbFactor <= 1.1 && !m_param->rc.cuTree) // tune for grainy content OR equal p-b frame sizes +m_isGrainEnabled = true; + /* 720p videos seem to be a good cutoff for cplxrSum */ -double tuneCplxFactor = (m_param->rc.cuTree && m_ncu > 3600) ? 2.5 : 1; - +double tuneCplxFactor = (m_ncu > 3600 && m_param->rc.cuTree) ? 2.5 : m_isGrainEnabled ? 1.9 : 1; /* estimated ratio that produces a reasonable QP for the first I-frame */ m_cplxrSum = .01 * pow(7.0e5, m_qCompress) * pow(m_ncu, 0.5) * tuneCplxFactor; m_wantedBitsWindow = m_bitrate * m_frameDuration; m_accumPNorm = .01; m_accumPQp = (m_param->rc.rateControlMode == X265_RC_CRF ? CRF_INIT_QP : ABR_INIT_QP_MIN) * m_accumPNorm; + /* Frame Predictors used in vbv */ initFramePredictors(); if (!m_statFileOut && (m_param->rc.bStatWrite || m_param->rc.bStatRead)) @@ -1049,12 +1060,12 @@ } m_pred[0].coeff = m_pred[3].coeff = 0.75; m_pred[0].coeffMin = m_pred[3].coeffMin = 0.75 / 4; -if (m_param->rc.qCompress >= 0.8) // when tuned for grain +if (m_isGrainEnabled) // when tuned for grain { m_pred[1].coeffMin = 0.75 / 4; m_pred[1].coeff = 0.75; -m_pred[0].coeff = m_pred[3].coeff = 0.5; -m_pred[0].coeffMin = m_pred[3].coeffMin = 0.5 / 4; +m_pred[0].coeff = m_pred[3].coeff = 0.75; +m_pred[0].coeffMin = m_pred[3].coeffMin = 0.75 / 4; } } @@ -1089,10 +1100,12 @@ } rce->isActive = true; bool isRefFrameScenecut = m_sliceType!= I_SLICE && m_curSlice->m_refFrameList[0][0]->m_lowres.bScenecut; +m_isFirstMiniGop = m_sliceType == I_SLICE ? true : m_isFirstMiniGop; if (curFrame->m_lowres.bScenecut) { m_isSceneTransition = true; m_lastPredictorReset = rce->encodeOrder; + initFramePredictors(); } else if (m_sliceType != B_SLICE && !isRefFrameScenecut) @@ -1197,7 +1210,7 @@ double q = x265_qScale2qp(rateEstimateQscale(curFrame, rce)); q = x265_clip3((double)QP_MIN, (double)QP_MAX_MAX, q); m_qp = int(q + 0.5); -rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq = q; +rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq = int(q + 0.5); /* copy value of lastRceq into thread local rce struct *to be used in RateControlEnd() */ rce->qRceq = m_lastRceq; accumPQpUpdate(); @@
[x265] [PATCH] rc: fix rate factor values recorded in csv
# HG changeset patch # User Aarthi Priya Thirumalai <aar...@multicorewareinc.com> # Date 1449763621 -19800 # Thu Dec 10 21:37:01 2015 +0530 # Node ID c401ace41d5d8d2eef8f82d625465de7f9b47b0e # Parent d72c79721e88cbd6e471d50351b46111918871ba rc: fix rate factor values recorded in csv diff -r d72c79721e88 -r c401ace41d5d source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cppThu Dec 10 10:07:17 2015 +0530 +++ b/source/encoder/ratecontrol.cppThu Dec 10 21:37:01 2015 +0530 @@ -144,6 +144,7 @@ rce->sliceType = rce2Pass->sliceType; rce->qpNoVbv = rce2Pass->qpNoVbv; rce->newQp = rce2Pass->newQp; +rce->qRceq = rce2Pass->qRceq; } } // end anonymous namespace /* Returns the zone for the current frame */ @@ -517,7 +518,7 @@ char picType; int e; char *next; -double qpRc, qpAq, qNoVbv; +double qpRc, qpAq, qNoVbv, qRceq; next = strstr(p, ";"); if (next) *next++ = 0; @@ -529,8 +530,8 @@ } rce = _rce2Pass[encodeOrder]; m_encOrder[frameNumber] = encodeOrder; -e += sscanf(p, " in:%*d out:%*d type:%c q:%lf q-aq:%lf q-noVbv:%lf tex:%d mv:%d misc:%d icu:%lf pcu:%lf scu:%lf", - , , , , >coeffBits, +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", + , , , , , >coeffBits, >mvBits, >miscBits, >iCuCount, >pCuCount, >skipCuCount); rce->keptAsRef = true; @@ -554,6 +555,7 @@ rce->qpNoVbv = qNoVbv; rce->qpaRc = qpRc; rce->qpAq = qpAq; +rce->qRceq = qRceq; p = next; } X265_FREE(statsBuf); @@ -1142,6 +1144,7 @@ } if (!m_isAbr && m_2pass && m_param->rc.rateControlMode == X265_RC_CRF) { +rce->qpPrev = x265_qScale2qp(rce->qScale); rce->qScale = rce->newQScale; rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq = x265_qScale2qp(rce->newQScale); m_qp = int(rce->qpaRc + 0.5); @@ -2347,20 +2350,31 @@ { if (m_param->rc.rateControlMode == X265_RC_ABR && !m_param->rc.bStatRead) checkAndResetABR(rce, true); - -if (m_param->rc.rateControlMode == X265_RC_CRF) +} +if (m_param->rc.rateControlMode == X265_RC_CRF) +{ +double crfVal, qpRef = curEncData.m_avgQpRc; +bool is2passCrfChange = false; +if (m_2pass) { -if (int(curEncData.m_avgQpRc + 0.5) == slice->m_sliceQp) -curEncData.m_rateFactor = m_rateFactorConstant; -else +if (abs(curEncData.m_avgQpRc - rce->qpPrev) > 0.1) { -/* If vbv changed the frame QP recalculate the rate-factor */ -double baseCplx = m_ncu * (m_param->bframes ? 120 : 80); -double mbtree_offset = m_param->rc.cuTree ? (1.0 - m_param->rc.qCompress) * 13.5 : 0; -curEncData.m_rateFactor = pow(baseCplx, 1 - m_qCompress) / -x265_qp2qScale(int(curEncData.m_avgQpRc + 0.5) + mbtree_offset); +qpRef = rce->qpPrev; +is2passCrfChange = true; } } +if (is2passCrfChange || abs(qpRef - rce->qpNoVbv) > 0.5) +{ +double crfFactor = rce->qRceq /x265_qp2qScale(qpRef); +double baseCplx = m_ncu * (m_param->bframes ? 120 : 80); +double mbtree_offset = m_param->rc.cuTree ? (1.0 - m_param->rc.qCompress) * 13.5 : 0; +crfVal = x265_qScale2qp(pow(baseCplx, 1 - m_qCompress) / crfFactor) - mbtree_offset; +} +else +crfVal = rce->sliceType == I_SLICE ? m_param->rc.rfConstant - m_ipOffset : +(rce->sliceType == B_SLICE ? m_param->rc.rfConstant + m_pbOffset : m_param->rc.rfConstant); + +curEncData.m_rateFactor = crfVal; } if (m_isAbr && !m_isAbrReset) @@ -2454,10 +2468,10 @@ : 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 tex:%d mv:%d misc:%d icu:%.2f pcu:%.2f scu:%.2f ;\n", +"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, +
Re: [x265] [PATCH] rc: fix rate factor values recorded in csv
pls ignore.. sending revised patch for this On Thu, Dec 10, 2015 at 10:48 PM, Aarthi Priya Thirumalai < aar...@multicorewareinc.com> wrote: > # HG changeset patch > # User Aarthi Priya Thirumalai <aar...@multicorewareinc.com> > # Date 1449763621 -19800 > # Thu Dec 10 21:37:01 2015 +0530 > # Node ID 721d60a7988b85083f72832b58e5e98f42d5a678 > # Parent 33d04da2f68830ac51151cfbda8f38fb9a7e8bb9 > rc: fix rate factor values recorded in csv > > diff -r 33d04da2f688 -r 721d60a7988b source/encoder/ratecontrol.cpp > --- a/source/encoder/ratecontrol.cppWed Dec 09 22:24:25 2015 +0530 > +++ b/source/encoder/ratecontrol.cppThu Dec 10 21:37:01 2015 +0530 > @@ -142,6 +142,7 @@ > rce->expectedVbv = rce2Pass->expectedVbv; > rce->blurredComplexity = rce2Pass->blurredComplexity; > rce->sliceType = rce2Pass->sliceType; > +rce->qRceq = rce2Pass->qRceq; > } > > } // end anonymous namespace > @@ -509,7 +510,7 @@ > char picType; > int e; > char *next; > -double qpRc, qpAq, qNoVbv; > +double qpRc, qpAq, qNoVbv, qRceq; > next = strstr(p, ";"); > if (next) > *next++ = 0; > @@ -520,8 +521,8 @@ > return false; > } > rce = _rce2Pass[frameNumber]; > -e += sscanf(p, " in:%*d out:%*d type:%c q:%lf q-aq:%lf > q-noVbv:%lf tex:%d mv:%d misc:%d icu:%lf pcu:%lf scu:%lf", > - , , , , >coeffBits, > +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", > + , , , , , > >coeffBits, > >mvBits, >miscBits, >iCuCount, > >pCuCount, > >skipCuCount); > rce->keptAsRef = true; > @@ -545,6 +546,7 @@ > rce->qpNoVbv = qNoVbv; > rce->qpaRc = qpRc; > rce->qpAq = qpAq; > +rce->qRceq = qRceq; > p = next; > } > X265_FREE(statsBuf); > @@ -2239,20 +2241,32 @@ > { > if (m_param->rc.rateControlMode == X265_RC_ABR && > !m_param->rc.bStatRead) > checkAndResetABR(rce, true); > +} > +if (m_param->rc.rateControlMode == X265_RC_CRF) > +{ > +double crfVal; > +if (m_2pass || abs(curEncData.m_avgQpRc - rce->qpNoVbv) > 0.5) > +{ > +double qpRef = curEncData.m_avgQpRc; > +if (m_2pass) > +{ > +double qpPrev = x265_qScale2qp(rce->qScale); > +qpRef = abs(curEncData.m_avgQpRc - qpPrev) > 0.1 ? > curEncData.m_avgQpRc : qpPrev; > +} > +double crfFactor = rce->qRceq /x265_qp2qScale(qpRef); > +if(rce->sliceType == I_SLICE) > +crfFactor /= m_param->rc.ipFactor; > +else if (rce->sliceType == B_SLICE) > +crfFactor *= m_param->rc.pbFactor; > +double baseCplx = m_ncu * (m_param->bframes ? 120 : 80); > +double mbtree_offset = m_param->rc.cuTree ? (1.0 - > m_param->rc.qCompress) * 13.5 : 0; > +crfVal = x265_qScale2qp(pow(baseCplx, 1 - m_qCompress) / > crfFactor) - mbtree_offset; > +} > +else > +crfVal = rce->sliceType == I_SLICE ? m_param->rc.rfConstant - > m_ipOffset : > +(rce->sliceType == B_SLICE ? m_param->rc.rfConstant + > m_pbOffset : m_param->rc.rfConstant); > > -if (m_param->rc.rateControlMode == X265_RC_CRF) > -{ > -if (int(curEncData.m_avgQpRc + 0.5) == slice->m_sliceQp) > -curEncData.m_rateFactor = m_rateFactorConstant; > -else > -{ > -/* If vbv changed the frame QP recalculate the > rate-factor */ > -double baseCplx = m_ncu * (m_param->bframes ? 120 : 80); > -double mbtree_offset = m_param->rc.cuTree ? (1.0 - > m_param->rc.qCompress) * 13.5 : 0; > -curEncData.m_rateFactor = pow(baseCplx, 1 - m_qCompress) / > -x265_qp2qScale(int(curEncData.m_avgQpRc + 0.5) + > mbtree_offset); > -} > -} > +curEncData.m_rateFactor = crfVal; > } > > if (m_isAbr && !m_isAbrReset) > @@ -2346,10 +2360,10 @@ > : rce->sliceType == P_SLICE ? 'P' > : IS_REFE
Re: [x265] [PATCH] rc: fix rate factor values recorded in csv
CRF is right now printed as a RateFactor value that is used internally in the calculation of Rate Control, that is not in the same scale as the user inputs. We are changing the crf printed in teh csv to reflect the scale of (0-51) -> what the user selects in the cli. In case of VBV changing the qp from whatever is decided for the given CRF, we recompute the CRF corresponding to the updated qp at the end and print it out. Similarly, for 2 pass when qp is changed from 1st pass, we recompute the CRF and print it out in the csv. On Fri, Dec 11, 2015 at 8:25 PM, Deepthi Nandakumar < deep...@multicorewareinc.com> wrote: > Thanks Aarthi. Can you quickly jog my memory on what we discussed about > CRF calculations? > > On Fri, Dec 11, 2015 at 8:17 PM, Aarthi Priya Thirumalai < > aar...@multicorewareinc.com> wrote: > >> # HG changeset patch >> # User Aarthi Priya Thirumalai <aar...@multicorewareinc.com> >> # Date 1449763621 -19800 >> # Thu Dec 10 21:37:01 2015 +0530 >> # Node ID c401ace41d5d8d2eef8f82d625465de7f9b47b0e >> # Parent d72c79721e88cbd6e471d50351b46111918871ba >> rc: fix rate factor values recorded in csv >> >> diff -r d72c79721e88 -r c401ace41d5d source/encoder/ratecontrol.cpp >> --- a/source/encoder/ratecontrol.cppThu Dec 10 10:07:17 2015 +0530 >> +++ b/source/encoder/ratecontrol.cppThu Dec 10 21:37:01 2015 +0530 >> @@ -144,6 +144,7 @@ >> rce->sliceType = rce2Pass->sliceType; >> rce->qpNoVbv = rce2Pass->qpNoVbv; >> rce->newQp = rce2Pass->newQp; >> +rce->qRceq = rce2Pass->qRceq; >> } >> } // end anonymous namespace >> /* Returns the zone for the current frame */ >> @@ -517,7 +518,7 @@ >> char picType; >> int e; >> char *next; >> -double qpRc, qpAq, qNoVbv; >> +double qpRc, qpAq, qNoVbv, qRceq; >> next = strstr(p, ";"); >> if (next) >> *next++ = 0; >> @@ -529,8 +530,8 @@ >> } >> rce = _rce2Pass[encodeOrder]; >> m_encOrder[frameNumber] = encodeOrder; >> -e += sscanf(p, " in:%*d out:%*d type:%c q:%lf q-aq:%lf >> q-noVbv:%lf tex:%d mv:%d misc:%d icu:%lf pcu:%lf scu:%lf", >> - , , , , >coeffBits, >> +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", >> + , , , , , >> >coeffBits, >> >mvBits, >miscBits, >iCuCount, >> >pCuCount, >> >skipCuCount); >> rce->keptAsRef = true; >> @@ -554,6 +555,7 @@ >> rce->qpNoVbv = qNoVbv; >> rce->qpaRc = qpRc; >> rce->qpAq = qpAq; >> +rce->qRceq = qRceq; >> p = next; >> } >> X265_FREE(statsBuf); >> @@ -1142,6 +1144,7 @@ >> } >> if (!m_isAbr && m_2pass && m_param->rc.rateControlMode == >> X265_RC_CRF) >> { >> +rce->qpPrev = x265_qScale2qp(rce->qScale); >> rce->qScale = rce->newQScale; >> rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq = >> x265_qScale2qp(rce->newQScale); >> m_qp = int(rce->qpaRc + 0.5); >> @@ -2347,20 +2350,31 @@ >> { >> if (m_param->rc.rateControlMode == X265_RC_ABR && >> !m_param->rc.bStatRead) >> checkAndResetABR(rce, true); >> - >> -if (m_param->rc.rateControlMode == X265_RC_CRF) >> +} >> +if (m_param->rc.rateControlMode == X265_RC_CRF) >> +{ >> +double crfVal, qpRef = curEncData.m_avgQpRc; >> +bool is2passCrfChange = false; >> +if (m_2pass) >> { >> -if (int(curEncData.m_avgQpRc + 0.5) == slice->m_sliceQp) >> -curEncData.m_rateFactor = m_rateFactorConstant; >> -else >> +if (abs(curEncData.m_avgQpRc - rce->qpPrev) > 0.1) >> { >> -/* If vbv changed the frame QP recalculate the >> rate-factor */ >> -double baseCplx = m_ncu * (m_param->bframes ? 120 : 80); >> -double mbtree_offset = m_param->rc.cuTree ? (1.0 - >> m_param->rc.qCompress) * 13.5 : 0; >>
[x265] [PATCH] rc: fix rate factor values recorded in csv
# HG changeset patch # User Aarthi Priya Thirumalai <aar...@multicorewareinc.com> # Date 1449763621 -19800 # Thu Dec 10 21:37:01 2015 +0530 # Node ID 721d60a7988b85083f72832b58e5e98f42d5a678 # Parent 33d04da2f68830ac51151cfbda8f38fb9a7e8bb9 rc: fix rate factor values recorded in csv diff -r 33d04da2f688 -r 721d60a7988b source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cppWed Dec 09 22:24:25 2015 +0530 +++ b/source/encoder/ratecontrol.cppThu Dec 10 21:37:01 2015 +0530 @@ -142,6 +142,7 @@ rce->expectedVbv = rce2Pass->expectedVbv; rce->blurredComplexity = rce2Pass->blurredComplexity; rce->sliceType = rce2Pass->sliceType; +rce->qRceq = rce2Pass->qRceq; } } // end anonymous namespace @@ -509,7 +510,7 @@ char picType; int e; char *next; -double qpRc, qpAq, qNoVbv; +double qpRc, qpAq, qNoVbv, qRceq; next = strstr(p, ";"); if (next) *next++ = 0; @@ -520,8 +521,8 @@ return false; } rce = _rce2Pass[frameNumber]; -e += sscanf(p, " in:%*d out:%*d type:%c q:%lf q-aq:%lf q-noVbv:%lf tex:%d mv:%d misc:%d icu:%lf pcu:%lf scu:%lf", - , , , , >coeffBits, +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", + , , , , , >coeffBits, >mvBits, >miscBits, >iCuCount, >pCuCount, >skipCuCount); rce->keptAsRef = true; @@ -545,6 +546,7 @@ rce->qpNoVbv = qNoVbv; rce->qpaRc = qpRc; rce->qpAq = qpAq; +rce->qRceq = qRceq; p = next; } X265_FREE(statsBuf); @@ -2239,20 +2241,32 @@ { if (m_param->rc.rateControlMode == X265_RC_ABR && !m_param->rc.bStatRead) checkAndResetABR(rce, true); +} +if (m_param->rc.rateControlMode == X265_RC_CRF) +{ +double crfVal; +if (m_2pass || abs(curEncData.m_avgQpRc - rce->qpNoVbv) > 0.5) +{ +double qpRef = curEncData.m_avgQpRc; +if (m_2pass) +{ +double qpPrev = x265_qScale2qp(rce->qScale); +qpRef = abs(curEncData.m_avgQpRc - qpPrev) > 0.1 ? curEncData.m_avgQpRc : qpPrev; +} +double crfFactor = rce->qRceq /x265_qp2qScale(qpRef); +if(rce->sliceType == I_SLICE) +crfFactor /= m_param->rc.ipFactor; +else if (rce->sliceType == B_SLICE) +crfFactor *= m_param->rc.pbFactor; +double baseCplx = m_ncu * (m_param->bframes ? 120 : 80); +double mbtree_offset = m_param->rc.cuTree ? (1.0 - m_param->rc.qCompress) * 13.5 : 0; +crfVal = x265_qScale2qp(pow(baseCplx, 1 - m_qCompress) / crfFactor) - mbtree_offset; +} +else +crfVal = rce->sliceType == I_SLICE ? m_param->rc.rfConstant - m_ipOffset : +(rce->sliceType == B_SLICE ? m_param->rc.rfConstant + m_pbOffset : m_param->rc.rfConstant); -if (m_param->rc.rateControlMode == X265_RC_CRF) -{ -if (int(curEncData.m_avgQpRc + 0.5) == slice->m_sliceQp) -curEncData.m_rateFactor = m_rateFactorConstant; -else -{ -/* If vbv changed the frame QP recalculate the rate-factor */ -double baseCplx = m_ncu * (m_param->bframes ? 120 : 80); -double mbtree_offset = m_param->rc.cuTree ? (1.0 - m_param->rc.qCompress) * 13.5 : 0; -curEncData.m_rateFactor = pow(baseCplx, 1 - m_qCompress) / -x265_qp2qScale(int(curEncData.m_avgQpRc + 0.5) + mbtree_offset); -} -} +curEncData.m_rateFactor = crfVal; } if (m_isAbr && !m_isAbrReset) @@ -2346,10 +2360,10 @@ : 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 tex:%d mv:%d misc:%d icu:%.2f pcu:%.2f scu:%.2f ;\n", +"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->qpNoVbv, rce->qRceq, curFrame->m_encData->m_frameStats.coeffBits, curFrame->m_encData->m_frameStats.mvBits, curFrame->m_encData->m_frameStats.miscBits, ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
Re: [x265] [PATCH] rc: record RF details in csv for 2 pass CRF
# HG changeset patch # User Aarthi Thirumalai# Date 1448384595 -19800 # Tue Nov 24 22:33:15 2015 +0530 # Node ID 7b84524dc44236071ba33f5858a6c38a909162d2 # Parent e90c2d74de88459dd18837765a310a462d9679ec rc: record RF details in csv for 2 pass CRF diff -r e90c2d74de88 -r 7b84524dc442 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Mon Nov 23 12:26:45 2015 +0530 +++ b/source/encoder/ratecontrol.cpp Tue Nov 24 22:33:15 2015 +0530 @@ -2239,10 +2239,11 @@ { if (m_param->rc.rateControlMode == X265_RC_ABR && !m_param->rc.bStatRead) checkAndResetABR(rce, true); +} -if (m_param->rc.rateControlMode == X265_RC_CRF) + if (m_param->rc.rateControlMode == X265_RC_CRF) { -if (int(curEncData.m_avgQpRc + 0.5) == slice->m_sliceQp) +if (curEncData.m_avgQpRc - rce->qpNoVbv < 1) curEncData.m_rateFactor = m_rateFactorConstant; else { @@ -2253,7 +2254,6 @@ x265_qp2qScale(int(curEncData.m_avgQpRc + 0.5) + mbtree_offset); } } -} if (m_isAbr && !m_isAbrReset) { On Wed, Nov 25, 2015 at 12:33 PM, Deepthi Nandakumar < deep...@multicorewareinc.com> wrote: > can you resend this patch, conflicts with your earlier one. > > On Tue, Nov 24, 2015 at 11:47 PM, wrote: > >> # HG changeset patch >> # User Aarthi Thirumalai >> # Date 1448384595 -19800 >> # Tue Nov 24 22:33:15 2015 +0530 >> # Branch stable >> # Node ID d17f491e06152f4627152a36169c272651bd5e3d >> # Parent 0c49c9cc75e4c1ef9534a28b49b97b9107636f5d >> rc: record RF details in csv for 2 pass CRF >> >> diff -r 0c49c9cc75e4 -r d17f491e0615 source/encoder/ratecontrol.cpp >> --- a/source/encoder/ratecontrol.cppMon Nov 23 14:06:10 2015 +0530 >> +++ b/source/encoder/ratecontrol.cppTue Nov 24 22:33:15 2015 +0530 >> @@ -1141,6 +1141,7 @@ >> } >> if (!m_isAbr && m_2pass && m_param->rc.rateControlMode == >> X265_RC_CRF) >> { >> +rce->oldQScale = rce->qScale; >> rce->qScale = rce->newQScale; >> rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq = >> x265_qScale2qp(rce->newQScale); >> m_qp = int(rce->qpaRc + 0.5); >> @@ -1704,6 +1705,7 @@ >> bool isFrameAfterScenecut = m_sliceType!= I_SLICE && >> m_curSlice->m_refPicList[0][0]->m_lowres.bScenecut; >> if (!m_2pass && m_isVbv && isFrameAfterScenecut) >> q = x265_clip3(lqmin, lqmax, q); >> +rce->qScale = q; >> } >> m_lastQScaleFor[m_sliceType] = q; >> if ((m_curSlice->m_poc == 0 || m_lastQScaleFor[P_SLICE] < q) && >> !(m_2pass && !m_isVbv)) >> @@ -2337,10 +2339,12 @@ >> { >> if (m_param->rc.rateControlMode == X265_RC_ABR && >> !m_param->rc.bStatRead) >> checkAndResetABR(rce, true); >> +} >> >> -if (m_param->rc.rateControlMode == X265_RC_CRF) >> + if (m_param->rc.rateControlMode == X265_RC_CRF) >> { >> -if (int(curEncData.m_avgQpRc + 0.5) == slice->m_sliceQp) >> +if ((int(curEncData.m_avgQpRc + 0.5) == slice->m_sliceQp && >> !m_2pass) || >> +(rce->oldQScale == rce->qScale)) >> curEncData.m_rateFactor = m_rateFactorConstant; >> else >> { >> @@ -2351,7 +2355,6 @@ >> x265_qp2qScale(int(curEncData.m_avgQpRc + 0.5) + >> mbtree_offset); >> } >> } >> -} >> >> if (m_isAbr && !m_isAbrReset) >> { >> diff -r 0c49c9cc75e4 -r d17f491e0615 source/encoder/ratecontrol.h >> --- a/source/encoder/ratecontrol.h Mon Nov 23 14:06:10 2015 +0530 >> +++ b/source/encoder/ratecontrol.h Tue Nov 24 22:33:15 2015 +0530 >> @@ -101,6 +101,7 @@ >> double qScale; >> double newQScale; >> double newQp; >> +double oldQScale; >> int mvBits; >> int miscBits; >> int coeffBits; >> ___ >> x265-devel mailing list >> x265-devel@videolan.org >> https://mailman.videolan.org/listinfo/x265-devel >> > > > > -- > Deepthi Nandakumar > Engineering Manager, x265 > Multicoreware, Inc > > ___ > 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
Re: [x265] [PATCH 2 of 2] rc: implement 2 pass CRF, when vbv is enabled
pls ignore the previous patch. It has a few bugs while merging. here is the fixed one : # HG changeset patch # User Divya Manivannan# Date 1448267770 -19800 # Mon Nov 23 14:06:10 2015 +0530 # Branch stable # Node ID 0c49c9cc75e4c1ef9534a28b49b97b9107636f5d # Parent 6b308775b6f065ea5002a76a40aa6f5d81e8ee50 rc: implement 2 pass CRF, when vbv is enabled. Allow CRF with VBV in 2nd pass to increase the quality of capped CRF in the first pass. diff -r 6b308775b6f0 -r 0c49c9cc75e4 source/common/param.cpp --- a/source/common/param.cpp Mon Nov 23 12:26:45 2015 +0530 +++ b/source/common/param.cpp Mon Nov 23 14:06:10 2015 +0530 @@ -1170,7 +1170,7 @@ CHECK(0 > param->noiseReductionIntra || param->noiseReductionIntra > 2000, "Valid noise reduction range 0 - 2000"); if (param->noiseReductionInter) CHECK(0 > param->noiseReductionInter || param->noiseReductionInter > 2000, "Valid noise reduction range 0 - 2000"); -CHECK(param->rc.rateControlMode == X265_RC_CRF && param->rc.bStatRead, +CHECK(param->rc.rateControlMode == X265_RC_CRF && param->rc.bStatRead && param->rc.vbvMaxBitrate == 0, "Constant rate-factor is incompatible with 2pass"); CHECK(param->rc.rateControlMode == X265_RC_CQP && param->rc.bStatRead, "Constant QP is incompatible with 2pass"); diff -r 6b308775b6f0 -r 0c49c9cc75e4 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Mon Nov 23 12:26:45 2015 +0530 +++ b/source/encoder/ratecontrol.cpp Mon Nov 23 14:06:10 2015 +0530 @@ -142,6 +142,8 @@ rce->expectedVbv = rce2Pass->expectedVbv; rce->blurredComplexity = rce2Pass->blurredComplexity; rce->sliceType = rce2Pass->sliceType; +rce->qpNoVbv = rce2Pass->qpNoVbv; +rce->newQp = rce2Pass->newQp; } } // end anonymous namespace @@ -205,7 +207,7 @@ m_rateFactorMaxDecrement = m_param->rc.rfConstant - m_param->rc.rfConstantMin; } m_isAbr = m_param->rc.rateControlMode != X265_RC_CQP && !m_param->rc.bStatRead; -m_2pass = m_param->rc.rateControlMode == X265_RC_ABR && m_param->rc.bStatRead; +m_2pass = (m_param->rc.rateControlMode == X265_RC_ABR || m_param->rc.vbvMaxBitrate > 0) && m_param->rc.bStatRead; m_bitrate = m_param->rc.bitrate * 1000; m_frameDuration = (double)m_param->fpsDenom / m_param->fpsNum; m_qp = m_param->rc.qp; @@ -488,6 +490,12 @@ x265_log(m_param, X265_LOG_ERROR, "Rce Entries for 2 pass cannot be allocated\n"); return false; } +m_encOrder = X265_MALLOC(int, m_numEntries); +if (!m_encOrder) +{ +x265_log(m_param, X265_LOG_ERROR, "Encode order for 2 pass cannot be allocated\n"); +return false; +} /* init all to skipped p frames */ for (int i = 0; i < m_numEntries; i++) { @@ -504,6 +512,7 @@ { RateControlEntry *rce; int frameNumber; +int encodeOrder; char picType; int e; char *next; @@ -511,13 +520,14 @@ next = strstr(p, ";"); if (next) *next++ = 0; -e = sscanf(p, " in:%d ", ); +e = sscanf(p, " in:%d out:%d", , ); if (frameNumber < 0 || frameNumber >= m_numEntries) { x265_log(m_param, X265_LOG_ERROR, "bad frame number (%d) at stats line %d\n", frameNumber, i); return false; } -rce = _rce2Pass[frameNumber]; +rce = _rce2Pass[encodeOrder]; +m_encOrder[frameNumber] = encodeOrder; e += sscanf(p, " in:%*d out:%*d type:%c q:%lf q-aq:%lf q-noVbv:%lf tex:%d mv:%d misc:%d icu:%lf pcu:%lf scu:%lf", , , , , >coeffBits, >mvBits, >miscBits, >iCuCount, >pCuCount, @@ -538,7 +548,7 @@ x265_log(m_param, X265_LOG_ERROR, "statistics are damaged at line %d, parser out=%d\n", i, e); return false; } -rce->qScale = x265_qp2qScale(qpRc); +rce->qScale = rce->newQScale = x265_qp2qScale(qpRc); totalQpAq += qpAq; rce->qpNoVbv = qNoVbv; rce->qpaRc = qpRc; @@ -546,8 +556,7 @@ p = next; } X265_FREE(statsBuf); - -if (m_param->rc.rateControlMode == X265_RC_ABR) +if (m_param->rc.rateControlMode == X265_RC_ABR || m_param->rc.vbvMaxBitrate > 0) { if (!initPass2()) return false; @@ -630,11 +639,8 @@ #undef MAX_DURATION } - -bool RateControl::initPass2() +bool RateControl::analyseABR2Pass(int startIndex, int endIndex, uint64_t allAvailableBits) { -uint64_t allConstBits = 0; -uint64_t
Re: [x265] [PATCH] rc: improve loop in clipQscale
LGTM On Nov 6, 2015 1:41 PM, "Ximing Cheng"wrote: > # HG changeset patch > # User Ximing Cheng > # Date 1446797063 -28800 > # Fri Nov 06 16:04:23 2015 +0800 > # Node ID f11b17b4656a85a15dc82fd04485fbf920848e4d > # Parent 45ea73c63c12c66e5e5e777e80853c8b3cadf101 > rc: improve loop in clipQscale > > diff -r 45ea73c63c12 -r f11b17b4656a source/encoder/ratecontrol.cpp > --- a/source/encoder/ratecontrol.cppFri Nov 06 11:55:27 2015 +0530 > +++ b/source/encoder/ratecontrol.cppFri Nov 06 16:04:23 2015 +0800 > @@ -1756,6 +1756,7 @@ > * is in a reasonable state by the end of the lookahead. */ > int loopTerminate = 0; > /* Avoid an infinite loop. */ > +double pSliceFactor = m_sliceType == I_SLICE ? > m_param->rc.ipFactor : (m_sliceType == B_SLICE ? 1 / m_param->rc.pbFactor : > 1); > for (int iterations = 0; iterations < 1000 && loopTerminate > != 3; iterations++) > { > double frameQ[3]; > @@ -1764,7 +1765,7 @@ > double bufferFillCur = m_bufferFill - curBits; > double targetFill; > double totalDuration = m_frameDuration; > -frameQ[P_SLICE] = m_sliceType == I_SLICE ? q * > m_param->rc.ipFactor : (m_sliceType == B_SLICE ? q / m_param->rc.pbFactor : > q); > +frameQ[P_SLICE] = q * pSliceFactor; > frameQ[B_SLICE] = frameQ[P_SLICE] * m_param->rc.pbFactor; > frameQ[I_SLICE] = frameQ[P_SLICE] / m_param->rc.ipFactor; > /* Loop over the planned future frames. */ > @@ -1798,12 +1799,15 @@ > continue; > } > /* Try to get the buffer not more than 80% filled, but > don't set an impossible goal. */ > -targetFill = x265_clip3(m_bufferSize * (1 - 0.2 * > finalDur), m_bufferSize, m_bufferFill - totalDuration * m_vbvMaxRate * 0.5); > -if (m_isCbr && bufferFillCur > targetFill && > !m_isSceneTransition) > +if (m_isCbr && !m_isSceneTransition) > { > -q /= 1.01; > -loopTerminate |= 2; > -continue; > +targetFill = x265_clip3(m_bufferSize * (1 - 0.2 * > finalDur), m_bufferSize, m_bufferFill - totalDuration * m_vbvMaxRate * 0.5); > +if (bufferFillCur > targetFill) > +{ > +q /= 1.01; > +loopTerminate |= 2; > +continue; > +} > } > break; > } > @@ -1857,7 +1861,7 @@ > if (m_rateFactorMaxIncrement) > { > double qpNoVbv = x265_qScale2qp(q0); > -double qmax = X265_MIN(MAX_MAX_QPSCALE,x265_qp2qScale(qpNoVbv > + m_rateFactorMaxIncrement)); > +double qmax = X265_MIN(MAX_MAX_QPSCALE, > x265_qp2qScale(qpNoVbv + m_rateFactorMaxIncrement)); > return x265_clip3(MIN_QPSCALE, qmax, q); > } > } > > > ___ > 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
Re: [x265] P-frames referencing B-frames, Generalised B-frames in HEVC
Hi, When b-pyramid is on, then b slices can refer to both B , P and I slices. We are creating a hierarchy among B frames, that is some B frames can be used as reference for other b frames. Regards Aarthi On Oct 26, 2015 3:23 AM, "Roshantha Mendis"wrote: > Hi, > > When --b-pyramid is set to true, can P-SLICES refer to B-SLICES ? > > I haven't come across a video sequence that this happens, but just want to > know if this can happen. > > Also if this situation can occur, then is it valid according to the HEVC > specs ? > > Many thanks > > -- > Rosh Mendis > Research Student - EngD in LSCITS > Dept. of Computer Science > University of York > > Disclaimer: http://www.york.ac.uk/docs/disclaimer/email.htm > > ___ > 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
Re: [x265] Under VBV rc mode , increasing the vbv-maxrate or vbv-bufsize has no or very little effect on the final result
Adding to Mario's points, changing the vbv-maxrate and vbv-bufsize , while keeping the target bitrate the same - will have a heavier impact on the moving average bitrate rather than the overall bitrate. Increasing the vbv buffer, while keeping the rest constant roughly means the buffer can handle a larger fluctuation in the per second bitrate. Similary, decreasing the vbv buffer size will drive the encoder to a stick to a constant bitrate for every second. At this point the vbv restrictions will kick in to decrease the bitrate hikes in between, and the quality for that portion of scene might go down. So, I suggest you plot the distribution of bitrates for each of your test case to see the impact . Regards Aarthi On Tue, Oct 20, 2015 at 11:53 AM, Mario *LigH* Rohkrämerwrote: > I believe the reason is the relation between the three values. You can > fill the buffer faster than the video target bitrate, so it needs only few > seconds to fill a previously empty buffer, and even less if the buffer was > already pre-filled. And then you compare it to a case where you can fill it > even faster than before, so there is even less problem; the encoder is > almost unrestricted by the VBV, only restricted by the target bitrate. > > You will certainly see a difference in cases where filling the buffer > would take longer, and the video bitrate would exceed this fill rate for a > longer duration if it was not limited by the fill rate: Then the encoder > needs to reduce its target bitrate and spend less than the optimum for the > desired quality. > > From my experience as DVD Video author, we had cases of close to optimum > utilizations of videos just even rejected by the authoring tool, where the > analysis of the scene in question revealed per GOP spikes of 13-14 Mbps > (VBV max fill rate of DVD Video is 9.8 Mbps) which the VBV simulator of the > encoder found acceptable, but the VBV simulator in the authoring tool could > not accept (possibly due to an unfortunate burst of subtitles). Agerage > bitrates tell little, their distribution over the VBV filling duration > makes the difference. > > One of the most demanding scenes ever was the beginning of "Cruel > Intentions" with a flight over a graveyard, filmed downwards: Several > seconds of heavy motion right at the start. It revealed a few rare DVD > player models which possibly had less than the specified 224 KB of decoding > buffer built in. > > > > Am 20.10.2015, 04:59 Uhr, schrieb fangzhen : > > Recently, I am testing the x265 codes and mostly on VBV rc mode.\ >> But, I find an strange problem. For instance, I set up the following test >> circumstance: >> resolution: 1920x1080 >> bitrate=1000kbps, vbv-bufsize=3000kbit >> when I set vbv-maxbitrate>1250kbps, I get almost the same result, like >> the same psnr, the almost same bitrate. >> I get the same result for vbv-bufsize where the vbv-maxbitrate is fixed, >> like 3000kbps. >> So I wonder why this situation exists? Can anybody give me some >> explanation? Thanks so much in advance. >> > > > -- > > Fun and success! > Mario *LigH* Rohkrämer > mailto:cont...@ligh.de > > ___ > 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
Re: [x265] [PATCH 2 of 2] rc: Remove the redundant calculation on slidingWindow
On Fri, Oct 16, 2015 at 1:50 PM, Ximing Chengwrote: > This patch reduce the calculation by saving the SATD moving sum last > time (frame), then the next frame can calculate its SATD moving sum by > the last moving sum and the replaced value in the slidingWindow, so > that each frame in rate ctrl does not need to do a loop for at most > s_slidingWindowFrames times to calculate its SATD moving sum. > > Suppose slidingWindow size is 6, value is x y z a b c > > rc frame (m_sliderPos)moving sum > 0 0 > 1 0.5x > 2 0.5^2x+0.5y > 3 0.5^3x+0.5^2y+0.5z > 4 0.5^4x+0.5^3y+0.5^2z+0.5a > 5 > 0.5^5x+0.5^4y+0.5^3z+0.5^2a+0.5b > 6 > 0.5^5x+0.5^4y+0.5^3z+0.5^2a+0.5b+c > 7 0.5 > (0.5^4y+0.5^3z+0.5^2a+0.5b+c)+x_1 == 0.5 > (0.5^5x+0.5^4y+0.5^3z+0.5^2a+0.5b+c - 0.5^5x) + x_1 > > which x_1 is the replaced value of x > > On Mon, Oct 12, 2015 at 10:26 AM, Ximing Cheng > wrote: > > # HG changeset patch > > # User Ximing Cheng > > # Date 1444616617 -28800 > > # Mon Oct 12 10:23:37 2015 +0800 > > # Node ID 0d1cfbb2716edcf9ba5b8ccc8b0fd585f4de59d7 > > # Parent 667253981f61f18c36bf5c7f607fbf6ea8cc6474 > > rc: Remove the redundant calculation on slidingWindow > > > > diff -r 667253981f61 -r 0d1cfbb2716e source/encoder/ratecontrol.cpp > > --- a/source/encoder/ratecontrol.cppMon Oct 12 10:18:55 2015 +0800 > > +++ b/source/encoder/ratecontrol.cppMon Oct 12 10:23:37 2015 +0800 > > @@ -219,6 +219,7 @@ > > m_cutreeStatFileOut = m_cutreeStatFileIn = NULL; > > m_rce2Pass = NULL; > > m_lastBsliceSatdCost = 0; > > +m_movingAvgSum = 0.0; > > > > // vbv initialization > > m_param->rc.vbvBufferSize = x265_clip3(0, 200, > m_param->rc.vbvBufferSize); > > @@ -1347,18 +1348,28 @@ > > { > > if (m_isAbr) > > { > > -double slidingWindowCplxSum = 0; > > -int start = m_sliderPos > s_slidingWindowFrames ? > m_sliderPos : 0; > > -for (int cnt = 0; cnt < s_slidingWindowFrames; cnt++, > start++) > > +int pos = m_sliderPos % s_slidingWindowFrames; > > +int addPos = (pos + s_slidingWindowFrames - 1) % > s_slidingWindowFrames; > > +if (m_sliderPos > s_slidingWindowFrames) > > { > > -int pos = start % s_slidingWindowFrames; > > -slidingWindowCplxSum *= 0.5; > > -if (!m_satdCostWindow[pos]) > > -break; > > -slidingWindowCplxSum += m_satdCostWindow[pos]; > > +const static double base = pow(0.5, > s_slidingWindowFrames - 1); > > +m_movingAvgSum -= m_lastRemovedSatdCost * base; > > +m_movingAvgSum *= 0.5; > > +m_movingAvgSum += m_satdCostWindow[addPos]; > > } > > -rce->movingAvgSum = slidingWindowCplxSum; > > -m_satdCostWindow[m_sliderPos % s_slidingWindowFrames] = > rce->lastSatd; > > +else if (m_sliderPos == s_slidingWindowFrames) > > +{ > > +m_movingAvgSum += m_satdCostWindow[addPos]; > > +} > > +else if (m_sliderPos > 0) > > +{ > > +m_movingAvgSum += m_satdCostWindow[addPos]; > > +m_movingAvgSum *= 0.5; > > +} > > + > > +rce->movingAvgSum = m_movingAvgSum; > > +m_lastRemovedSatdCost = m_satdCostWindow[pos]; > > +m_satdCostWindow[pos] = rce->lastSatd; > > m_sliderPos++; > > } > > } > should the m_lastRemovedSatdCost be taken after incrementing the m_sliderPos ? because at the position = s_slidingWindowFrames, it should delete the data written in m_satdCostWindow but the lastRemovedSatdCost would not be pointing to that yet - can you check this once. > diff -r 667253981f61 -r 0d1cfbb2716e source/encoder/ratecontrol.h > > --- a/source/encoder/ratecontrol.h Mon Oct 12 10:18:55 2015 +0800 > > +++ b/source/encoder/ratecontrol.h Mon Oct 12 10:23:37 2015 +0800 > > @@ -167,6 +167,8 @@ > > int64_t m_satdCostWindow[50]; > > int64_t m_encodedBitsWindow[50]; > > int m_sliderPos; > > +int64_t m_lastRemovedSatdCost; > > +double m_movingAvgSum; > > > > /* To detect a pattern of low detailed static frames in single pass > ABR using satdcosts */ > > int64_t m_lastBsliceSatdCost; > > > > > > ___ > > x265-devel mailing list > > x265-devel@videolan.org > > https://mailman.videolan.org/listinfo/x265-devel > ___ > x265-devel mailing list > x265-devel@videolan.org >
Re: [x265] [PATCH 1 of 2] rc: don't update predictors from previous frames, after reset at scenecut
No. We will re init vbv predictors and apply the scenecut transition related controls from the scene that begins the scene change which is signaled by bScenecut flag. and revert the operation at the next mini-gop. On Mon, Sep 28, 2015 at 5:03 PM, Deepthi Nandakumar < deep...@multicorewareinc.com> wrote: > > > On Thu, Sep 24, 2015 at 1:56 PM,wrote: > >> # HG changeset patch >> # User Aarthi Thirumalai >> # Date 1442909407 -19800 >> # Tue Sep 22 13:40:07 2015 +0530 >> # Branch stable >> # Node ID c44b32bc7c906456ad242dd237831ec96c1f5c3d >> # Parent 69d55d4c53ebff6d98e4431e0f8fe6103705b8ec >> rc: don't update predictors from previous frames, after reset at scenecut. >> >> diff -r 69d55d4c53eb -r c44b32bc7c90 source/encoder/ratecontrol.cpp >> --- a/source/encoder/ratecontrol.cppTue Sep 22 13:33:13 2015 +0530 >> +++ b/source/encoder/ratecontrol.cppTue Sep 22 13:40:07 2015 +0530 >> @@ -182,6 +182,7 @@ >> m_finalFrameCount = 0; >> m_numEntries = 0; >> m_isSceneTransition = false; >> +m_lastPredictorReset = 0; >> if (m_param->rc.rateControlMode == X265_RC_CRF) >> { >> m_param->rc.qp = (int)m_param->rc.rfConstant; >> @@ -370,20 +371,8 @@ >> m_accumPNorm = .01; >> m_accumPQp = (m_param->rc.rateControlMode == X265_RC_CRF ? >> CRF_INIT_QP : ABR_INIT_QP_MIN) * m_accumPNorm; >> >> -/* Frame Predictors and Row predictors used in vbv */ >> -for (int i = 0; i < 4; i++) >> -{ >> -m_pred[i].coeff = 1.0; >> -m_pred[i].count = 1.0; >> -m_pred[i].decay = 0.5; >> -m_pred[i].offset = 0.0; >> -} >> -m_pred[0].coeff = m_pred[3].coeff = 0.75; >> -if (m_param->rc.qCompress >= 0.8) // when tuned for grain >> -{ >> -m_pred[1].coeff = 0.75; >> -m_pred[0].coeff = m_pred[3].coeff = 0.50; >> -} >> +/* Frame Predictors used in vbv */ >> +initFramePredictors(); >> if (!m_statFileOut && (m_param->rc.bStatWrite || >> m_param->rc.bStatRead)) >> { >> /* If the user hasn't defined the stat filename, use the default >> value */ >> @@ -932,6 +921,24 @@ >> return X265_TYPE_AUTO; >> } >> >> +void RateControl::initFramePredictors() >> +{ >> +/* Frame Predictors used in vbv */ >> +for (int i = 0; i < 4; i++) >> +{ >> +m_pred[i].coeff = 1.0; >> +m_pred[i].count = 1.0; >> +m_pred[i].decay = 0.5; >> +m_pred[i].offset = 0.0; >> +} >> +m_pred[0].coeff = m_pred[3].coeff = 0.75; >> +if (m_param->rc.qCompress >= 0.8) // when tuned for grain >> +{ >> +m_pred[1].coeff = 0.75; >> +m_pred[0].coeff = m_pred[3].coeff = 0.50; >> +} >> +} >> + >> int RateControl::rateControlStart(Frame* curFrame, RateControlEntry* >> rce, Encoder* enc) >> { >> int orderValue = m_startEndOrder.get(); >> @@ -961,23 +968,21 @@ >> copyRceData(rce, _rce2Pass[rce->poc]); >> } >> rce->isActive = true; >> -bool isframeAfterKeyframe = m_sliceType != I_SLICE && >> m_curSlice->m_refPicList[0][0]->m_encData->m_slice->m_sliceType == I_SLICE; >> +bool isRefFrameScenecut = m_sliceType!= I_SLICE && >> m_curSlice->m_refPicList[0][0]->m_lowres.bScenecut == 1; >> if (curFrame->m_lowres.bScenecut) >> { >> > > This should be if (isRefFrameScenecut)? > > >> m_isSceneTransition = true; >> -/* Frame Predictors and Row predictors used in vbv */ >> -for (int i = 0; i < 4; i++) >> -{ >> -m_pred[i].coeff = 1.0; >> -m_pred[i].count = 1.0; >> -m_pred[i].decay = 0.5; >> -m_pred[i].offset = 0.0; >> -} >> -m_pred[0].coeff = m_pred[3].coeff = 0.75; >> +m_lastPredictorReset = rce->encodeOrder; >> +initFramePredictors(); >> } >> -else if (m_sliceType != B_SLICE && !isframeAfterKeyframe) >> +else if (m_sliceType != B_SLICE && !isRefFrameScenecut) >> m_isSceneTransition = false; >> >> +if (rce->encodeOrder < m_lastPredictorReset + >> m_param->frameNumThreads) >> +{ >> +rce->rowPreds[0][0].count = 0; >> +} >> + >> rce->bLastMiniGopBFrame = curFrame->m_lowres.bLastMiniGopBFrame; >> rce->bufferRate = m_bufferRate; >> rce->rowCplxrSum = 0.0; >> @@ -2149,7 +2154,7 @@ >> { >> int predType = rce->sliceType; >> predType = rce->sliceType == B_SLICE && rce->keptAsRef ? 3 : >> predType; >> -if (rce->lastSatd >= m_ncu) >> +if (rce->lastSatd >= m_ncu && rce->encodeOrder >= >> m_lastPredictorReset) >> updatePredictor(_pred[predType], x265_qp2qScale(rce->qpaRc), >> (double)rce->lastSatd, (double)bits); >> if (!m_isVbv) >> return; >> diff -r 69d55d4c53eb -r c44b32bc7c90 source/encoder/ratecontrol.h >> --- a/source/encoder/ratecontrol.h Tue Sep 22 13:33:13 2015 +0530 >> +++ b/source/encoder/ratecontrol.h Tue Sep 22 13:40:07 2015 +0530 >> @@ -173,6 +173,7 @@ >> int
Re: [x265] [PATCH 1 of 2] slicetype: Modify Scenecut algorithm to detect scene transition points
# HG changeset patch # User Aarthi Thirumalai # Date 1437505166 -19800 # Wed Jul 22 00:29:26 2015 +0530 # Node ID cea0ce5bf57d5decc14743aa69234a1dfe84996b # Parent d56b2466c04459205287e1581d8a36eebf372ba6 slicetype: Modify Scenecut algorithm to detect scene transition points to improve Rate Control (refs #160). identify scene trasitions, fade-ins, fadeouts, sceneCuts and signal the flag bSceneCut in Lowres structure. This flag will be used by RateControl to adjust the qp during scene cuts. diff -r d56b2466c044 -r cea0ce5bf57d source/common/lowres.cpp --- a/source/common/lowres.cpp Wed Aug 12 18:12:20 2015 +0530 +++ b/source/common/lowres.cpp Wed Jul 22 00:29:26 2015 +0530 @@ -126,7 +126,7 @@ void Lowres::init(PicYuv *origPic, int poc) { bLastMiniGopBFrame = false; -bScenecut = true; // could be a scene-cut, until ruled out by flash detection +bScenecut = false; // could be a scene-cut, until ruled out by flash detection bKeyframe = false; // Not a keyframe unless identified by lookahead frameNum = poc; leadingBframes = 0; diff -r d56b2466c044 -r cea0ce5bf57d source/encoder/slicetype.cpp --- a/source/encoder/slicetype.cpp Wed Aug 12 18:12:20 2015 +0530 +++ b/source/encoder/slicetype.cpp Wed Jul 22 00:29:26 2015 +0530 @@ -483,6 +483,7 @@ m_pool = pool; m_lastNonB = NULL; +m_isSceneTransition = false; m_scratch = NULL; m_tld = NULL; m_filled = false; @@ -1267,10 +1268,16 @@ int numBFrames = 0; int numAnalyzed = numFrames; -if (m_param-scenecutThreshold scenecut(frames, 0, 1, true, origNumFrames, maxSearch)) + +if (m_param-bFrameAdaptive) { -frames[1]-sliceType = X265_TYPE_I; -return; +bool isScenecut = scenecut(frames, 0, 1, true, origNumFrames); +/* When scenecut threshold is set, use scenecut detection for I frame placements */ +if (!m_param-scenecutThreshold isScenecut) +{ +frames[1]-sliceType = X265_TYPE_I; +return; +} } if (m_param-bframes) @@ -1357,14 +1364,13 @@ /* Check scenecut on the first minigop. */ for (int j = 1; j numBFrames + 1; j++) { -if (m_param-scenecutThreshold scenecut(frames, j, j + 1, false, origNumFrames, maxSearch)) +if (m_param-scenecutThreshold scenecut(frames, j, j + 1, false, origNumFrames)) { frames[j]-sliceType = X265_TYPE_P; numAnalyzed = j; break; } } - resetStart = bKeyframe ? 1 : X265_MIN(numBFrames + 2, numAnalyzed + 1); } else @@ -1388,46 +1394,94 @@ if (bIsVbvLookahead) vbvLookahead(frames, numFrames, bKeyframe); + int maxp1 = X265_MIN(m_param-bframes + 1, origNumFrames); /* Restore frame types for all frames that haven't actually been decided yet. */ for (int j = resetStart; j = numFrames; j++) +{ frames[j]-sliceType = X265_TYPE_AUTO; +/* If any frame marked as scenecut is being restarted for sliceDecision, + * undo scene Transition flag */ +if (j = maxp1 frames[j]-bScenecut m_isSceneTransition) +m_isSceneTransition = false; +} } -bool Lookahead::scenecut(Lowres **frames, int p0, int p1, bool bRealScenecut, int numFrames, int maxSearch) +bool Lookahead::scenecut(Lowres **frames, int p0, int p1, bool bRealScenecut, int numFrames) { /* Only do analysis during a normal scenecut check. */ if (bRealScenecut m_param-bframes) { int origmaxp1 = p0 + 1; /* Look ahead to avoid coding short flashes as scenecuts. */ -if (m_param-bFrameAdaptive == X265_B_ADAPT_TRELLIS) -/* Don't analyse any more frames than the trellis would have covered. */ -origmaxp1 += m_param-bframes; -else -origmaxp1++; +origmaxp1 += m_param-bframes; int maxp1 = X265_MIN(origmaxp1, numFrames); - +bool fluctuate = false; +bool noScenecuts = false; +int64_t avgSatdCost = 0; +if (frames[0]-costEst[1][0] -1) +avgSatdCost = frames[0]-costEst[1][0]; +int cnt = 1; /* Where A and B are scenes: AABBBAA * If BBB is shorter than (maxp1-p0), it is detected as a flash * and not considered a scenecut. */ for (int cp1 = p1; cp1 = maxp1; cp1++) { if (!scenecutInternal(frames, p0, cp1, false)) +{ /* Any frame in between p0 and cur_p1 cannot be a real scenecut. */ for (int i = cp1; i p0; i--) +{ frames[i]-bScenecut = false; +noScenecuts = false; +} +} +else if (scenecutInternal(frames, cp1 - 1, cp1, false)) +{ +/* If current frame is a Scenecut from p0 frame as well as Scenecut from + *
Re: [x265] [PATCH 2 of 2] rc: adjust qp for scene transitions and fade ins to avoid quality loss with vbv
ignore the previous patch - contains a build error. Sending the corrected version here: # HG changeset patch # User Aarthi Thirumalai # Date 1439287054 -19800 # Tue Aug 11 15:27:34 2015 +0530 # Node ID 4f5109967676d983d8ccc4f5f410f96f5f30a5cb # Parent cea0ce5bf57d5decc14743aa69234a1dfe84996b rc: adjust qp for scene transitions and fade ins to avoid quality loss with vbv diff -r cea0ce5bf57d -r 4f5109967676 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Wed Jul 22 00:29:26 2015 +0530 +++ b/source/encoder/ratecontrol.cpp Tue Aug 11 15:27:34 2015 +0530 @@ -181,6 +181,7 @@ m_bTerminated = false; m_finalFrameCount = 0; m_numEntries = 0; +m_isSceneTransition = false; if (m_param-rc.rateControlMode == X265_RC_CRF) { m_param-rc.qp = (int)m_param-rc.rfConstant; @@ -273,7 +274,6 @@ if(m_param-rc.bStrictCbr) m_rateTolerance = 0.7; -m_leadingBframes = m_param-bframes; m_bframeBits = 0; m_leadingNoBSatd = 0; m_ipOffset = 6.0 * X265_LOG2(m_param-rc.ipFactor); @@ -282,6 +282,7 @@ /* Adjust the first frame in order to stabilize the quality level compared to the rest */ #define ABR_INIT_QP_MIN (24) #define ABR_INIT_QP_MAX (40) +#define ABR_SCENECUT_INIT_QP_MIN (12) #define CRF_INIT_QP (int)m_param-rc.rfConstant for (int i = 0; i 3; i++) m_lastQScaleFor[i] = x265_qp2qScale(m_param-rc.rateControlMode == X265_RC_CRF ? CRF_INIT_QP : ABR_INIT_QP_MIN); @@ -960,10 +961,22 @@ copyRceData(rce, m_rce2Pass[rce-poc]); } rce-isActive = true; -if (m_sliceType == B_SLICE) -rce-bframes = m_leadingBframes; -else -m_leadingBframes = curFrame-m_lowres.leadingBframes; +bool isframeAfterKeyframe = m_sliceType != I_SLICE m_curSlice-m_refFrameList[0][0]-m_encData-m_slice-m_sliceType == I_SLICE; +if (curFrame-m_lowres.bScenecut) +{ +m_isSceneTransition = true; +/* Frame Predictors and Row predictors used in vbv */ +for (int i = 0; i 4; i++) +{ +m_pred[i].coeff = 1.0; +m_pred[i].count = 1.0; +m_pred[i].decay = 0.5; +m_pred[i].offset = 0.0; +} +m_pred[0].coeff = m_pred[3].coeff = 0.75; +} +else if (m_sliceType != B_SLICE !isframeAfterKeyframe) +m_isSceneTransition = false; rce-bLastMiniGopBFrame = curFrame-m_lowres.bLastMiniGopBFrame; rce-bufferRate = m_bufferRate; @@ -1040,6 +1053,10 @@ } } } +/* For a scenecut that occurs within the mini-gop, enable scene transition + * switch until the next mini-gop to ensure a min qp for all the frames within + * the scene-transition mini-gop */ + double q = x265_qScale2qp(rateEstimateQscale(curFrame, rce)); q = x265_clip3((double)QP_MIN, (double)QP_MAX_MAX, q); m_qp = int(q + 0.5); @@ -1382,6 +1399,13 @@ else q += m_pbOffset; +/* Set a min qp at scenechanges and transitions */ +if (m_isSceneTransition) +{ +q = X265_MAX(ABR_SCENECUT_INIT_QP_MIN, q); +double minScenecutQscale =x265_qp2qScale(ABR_SCENECUT_INIT_QP_MIN); +m_lastQScaleFor[P_SLICE] = X265_MAX(minScenecutQscale, m_lastQScaleFor[P_SLICE]); +} double qScale = x265_qp2qScale(q); rce-qpNoVbv = q; double lmin = 0, lmax = 0; @@ -1544,6 +1568,13 @@ q = X265_MIN(lqmax, q); } q = x265_clip3(MIN_QPSCALE, MAX_MAX_QPSCALE, q); +/* Set a min qp at scenechanges and transitions */ +if (m_isSceneTransition) +{ + double minScenecutQscale =x265_qp2qScale(ABR_SCENECUT_INIT_QP_MIN); + q = X265_MAX(minScenecutQscale, q); + m_lastQScaleFor[P_SLICE] = X265_MAX(minScenecutQscale, m_lastQScaleFor[P_SLICE]); +} rce-qpNoVbv = x265_qScale2qp(q); q = clipQscale(curFrame, rce, q); /* clip qp to permissible range after vbv-lookahead estimation to avoid possible @@ -1750,7 +1781,7 @@ } /* Try to get the buffer not more than 80% filled, but don't set an impossible goal. */ targetFill = x265_clip3(m_bufferSize * (1 - 0.2 * finalDur), m_bufferSize, m_bufferFill - totalDuration * m_vbvMaxRate * 0.5); -if (m_isCbr bufferFillCur targetFill) +if (m_isCbr bufferFillCur targetFill !m_isSceneTransition) { q /= 1.01; loopTerminate |= 2; diff -r cea0ce5bf57d -r 4f5109967676 source/encoder/ratecontrol.h --- a/source/encoder/ratecontrol.h Wed Jul 22 00:29:26 2015 +0530 +++ b/source/encoder/ratecontrol.h Tue Aug 11 15:27:34 2015 +0530 @@ -147,7 +147,6 @@ double m_pbOffset; int64_t m_bframeBits; int64_t m_currentSatd; -int m_leadingBframes; int
Re: [x265] [PATCH] slicetype: Modify Scenecut algorithm to detect scene transition points
Currently during scene change transitions, esp slow gradual fadeins/fadeouts every frame changes vastly in luma intensity and hence passes as a scenecut but these are treated as a series of flashes in scenecut() . So, none of the frames gets marked as scencut during such transitions. It would be better if we can signal the first frame of such transition flashes as sceneChange for RateControl. so that the rate control can set a minimum qp for such frames. This would help the bitrate spikes at fade ins where the qp can be really low. The patch mainly fixes the place in scenecut() where the flash detection happens and the first frame in a series of flash is signaled as sceneChange. Changing bias or modifying scenecutInterval doesn't help here as those frames are already ,marked as scenecuts from those function. Only scencut() flash detection part reverts the flashes as non-scenecuts which we are changing. the slicetype decision is not changed as I am signalling these scene changes with a different flag that Ratecontrol would be using. On Wed, Jul 22, 2015 at 10:10 PM, Deepthi Nandakumar deep...@multicorewareinc.com wrote: The intention was to separate slicetype decision from scene change detection, where scene change detection would also account for transitions (like fade-ins, fade-outs etc), in addition to the abrupt scene change. It is not clear to me how this is being done without modifying scenecutInternal. On Wed, Jul 22, 2015 at 9:59 PM, Steve Borho st...@borho.org wrote: On 07/22, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1437505166 -19800 # Wed Jul 22 00:29:26 2015 +0530 # Node ID f134920ac855af45f052ccd6d3c239d39940a100 # Parent 46152345eb6ff261fd90272f7a0712300d6324c0 slicetype: Modify Scenecut algorithm to detect scene transition points to improve Rate Control. identify scene trasitions, fade-ins, fadeouts, sceneCuts and signal the flag bSceneChange in Lowres structure. This flag will be used by RateControl to adjust the wps during scene cuts. No changes in sliceType decisions or I frame placement. I could nitpick a few coding style issues, but my main question is whether you tried disabling the keyframe distance bias during flash detection and arrived at this approach, or whether this is an orthogonal change? diff -r 46152345eb6f -r f134920ac855 source/common/lowres.cpp --- a/source/common/lowres.cppMon Jul 20 17:18:54 2015 -0700 +++ b/source/common/lowres.cppWed Jul 22 00:29:26 2015 +0530 @@ -127,6 +127,7 @@ { bLastMiniGopBFrame = false; bScenecut = true; // could be a scene-cut, until ruled out by flash detection +bSceneChange = true; bKeyframe = false; // Not a keyframe unless identified by lookahead frameNum = poc; leadingBframes = 0; diff -r 46152345eb6f -r f134920ac855 source/common/lowres.h --- a/source/common/lowres.h Mon Jul 20 17:18:54 2015 -0700 +++ b/source/common/lowres.h Wed Jul 22 00:29:26 2015 +0530 @@ -115,6 +115,7 @@ intleadingBframes; // number of leading B frames for P or I bool bScenecut;// Set to false if the frame cannot possibly be part of a real scenecut. +bool bSceneChange; bool bKeyframe; bool bLastMiniGopBFrame; diff -r 46152345eb6f -r f134920ac855 source/encoder/slicetype.cpp --- a/source/encoder/slicetype.cppMon Jul 20 17:18:54 2015 -0700 +++ b/source/encoder/slicetype.cppWed Jul 22 00:29:26 2015 +0530 @@ -462,6 +462,7 @@ m_pool = pool; m_lastNonB = NULL; +m_isSceneTransition = false; m_scratch = NULL; m_tld = NULL; m_filled = false; @@ -1375,6 +1376,8 @@ bool Lookahead::scenecut(Lowres **frames, int p0, int p1, bool bRealScenecut, int numFrames, int maxSearch) { /* Only do analysis during a normal scenecut check. */ +int64_t avgSatdCost = 0; +int cnt = 0; if (bRealScenecut m_param-bframes) { int origmaxp1 = p0 + 1; @@ -1392,11 +1395,45 @@ for (int cp1 = p1; cp1 = maxp1; cp1++) { if (!scenecutInternal(frames, p0, cp1, false)) +{ /* Any frame in between p0 and cur_p1 cannot be a real scenecut. */ for (int i = cp1; i p0; i--) +{ frames[i]-bScenecut = false; +frames[i]-bSceneChange = false; +} +} +else if (!scenecutInternal(frames,cp1 - 1, cp1, false)) +{ +/* Prevent false flashes. */ +frames[cp1]-bSceneChange = false; +} +else +{ +/* compute average satdcost of flashes of scenecuts to confirm + * bwhether a scene transition is possible within the segment. */ +
Re: [x265] [PATCH 6 of 6 REV2] analysis: always configure quant QP directly after setting RD lambda
We may remove the qp offset calculations from there but may need to use it for collecting cu level intra and inter satdcosts from lowres data for row vbv encodes. On Sun, Apr 26, 2015 at 11:17 PM, Steve Borho st...@borho.org wrote: On Sun, Apr 26, 2015 at 12:21 PM, Steve Borho st...@borho.org wrote: # HG changeset patch # User Steve Borho st...@borho.org # Date 1429943995 18000 # Sat Apr 25 01:39:55 2015 -0500 # Node ID 68a13226d586b335c02cade9311e093f0149c42a # Parent 6a0a37c01cff03cadd44691a0fe447d17ec0b14f analysis: always configure quant QP directly after setting RD lambda Basically, everywhere we adjust or assign QP we set quant QP immediately. This removes a great many ad-hoc calls to setQPforQuant() and hopefully makes it impossible to miss quant being configured properly. This patch fixes a layering violation where the frame encoder was setting the RDO lambdas directly, but only when delta-QP was not enabled. diff -r 6a0a37c01cff -r 68a13226d586 source/common/quant.cpp --- a/source/common/quant.cpp Sat Apr 25 00:39:48 2015 -0500 +++ b/source/common/quant.cpp Sat Apr 25 01:39:55 2015 -0500 @@ -225,16 +225,15 @@ X265_FREE(m_fencShortBuf); } -void Quant::setQPforQuant(const CUData cu) +void Quant::setQPforQuant(const CUData ctu, int qp) { -m_tqBypass = !!cu.m_tqBypass[0]; +m_tqBypass = !!ctu.m_tqBypass[0]; if (m_tqBypass) return; -m_nr = m_frameNr ? m_frameNr[cu.m_encData-m_frameEncoderID] : NULL; -int qpy = cu.m_qp[0]; -m_qpParam[TEXT_LUMA].setQpParam(qpy + QP_BD_OFFSET); -setChromaQP(qpy + cu.m_slice-m_pps-chromaQpOffset[0], TEXT_CHROMA_U, cu.m_chromaFormat); -setChromaQP(qpy + cu.m_slice-m_pps-chromaQpOffset[1], TEXT_CHROMA_V, cu.m_chromaFormat); +m_nr = m_frameNr ? m_frameNr[ctu.m_encData-m_frameEncoderID] : NULL; +m_qpParam[TEXT_LUMA].setQpParam(qp + QP_BD_OFFSET); +setChromaQP(qp + ctu.m_slice-m_pps-chromaQpOffset[0], TEXT_CHROMA_U, ctu.m_chromaFormat); +setChromaQP(qp + ctu.m_slice-m_pps-chromaQpOffset[1], TEXT_CHROMA_V, ctu.m_chromaFormat); } void Quant::setChromaQP(int qpin, TextType ttype, int chFmt) diff -r 6a0a37c01cff -r 68a13226d586 source/common/quant.h --- a/source/common/quant.h Sat Apr 25 00:39:48 2015 -0500 +++ b/source/common/quant.h Sat Apr 25 01:39:55 2015 -0500 @@ -103,7 +103,7 @@ bool allocNoiseReduction(const x265_param param); /* CU setup */ -void setQPforQuant(const CUData cu); +void setQPforQuant(const CUData ctu, int qp); uint32_t transformNxN(const CUData cu, const pixel* fenc, uint32_t fencStride, const int16_t* residual, uint32_t resiStride, coeff_t* coeff, uint32_t log2TrSize, TextType ttype, uint32_t absPartIdx, bool useTransformSkip); diff -r 6a0a37c01cff -r 68a13226d586 source/encoder/analysis.cpp --- a/source/encoder/analysis.cpp Sat Apr 25 00:39:48 2015 -0500 +++ b/source/encoder/analysis.cpp Sat Apr 25 01:39:55 2015 -0500 @@ -146,18 +146,16 @@ if (m_slice-m_pps-bUseDQP) { -m_aqQP[0] = calculateQpforCuSize(ctu, cuGeom); -setLambdaFromQP(*m_slice, m_aqQP[0]); -m_aqQP[0] = x265_clip3(QP_MIN, QP_MAX_SPEC, m_aqQP[0]); -ctu.setQPSubParts((int8_t)m_aqQP[0], 0, 0); +m_aqQP[0] = setLambdaFromQP(ctu, calculateQpforCuSize(ctu, cuGeom)); if (m_slice-m_pps-maxCuDQPDepth) initAqQPs(1, ctu, cuGeom + 1); } else -m_aqQP[0] = m_slice-m_sliceQp; +/* adaptive quant disabled, CTU QP is always slice QP, and within spec range */ +m_aqQP[0] = setLambdaFromQP(ctu, m_slice-m_sliceQp); -m_quant.setQPforQuant(ctu); +ctu.setQPSubParts((int8_t)m_aqQP[0], 0, 0); m_rqt[0].cur.load(initialContext); m_modeDepth[0].fencYuv.copyFromPicYuv(*m_frame-m_fencPic, ctu.m_cuAddr, 0); @@ -231,20 +229,24 @@ return; else if (md.bestMode-cu.isIntra(0)) { +m_quant.m_tqBypass = true; md.pred[PRED_LOSSLESS].initCosts(); md.pred[PRED_LOSSLESS].cu.initLosslessCU(md.bestMode-cu, cuGeom); PartSize size = (PartSize)md.pred[PRED_LOSSLESS].cu.m_partSize[0]; uint8_t* modes = md.pred[PRED_LOSSLESS].cu.m_lumaIntraDir; checkIntra(md.pred[PRED_LOSSLESS], cuGeom, size, modes, NULL); checkBestMode(md.pred[PRED_LOSSLESS], cuGeom.depth); +m_quant.m_tqBypass = false; } else { +m_quant.m_tqBypass = true; md.pred[PRED_LOSSLESS].initCosts(); md.pred[PRED_LOSSLESS].cu.initLosslessCU(md.bestMode-cu, cuGeom); md.pred[PRED_LOSSLESS].predYuv.copyFromYuv(md.bestMode-predYuv); encodeResAndCalcRdInterCU(md.pred[PRED_LOSSLESS], cuGeom); checkBestMode(md.pred[PRED_LOSSLESS], cuGeom.depth); +
Re: [x265] [PATCH 2 of 2] rc: tune initial predictor values for better frame size predictions in vbv lookahead
On Thu, Apr 9, 2015 at 12:09 AM, Steve Borho st...@borho.org wrote: On 04/08, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1426487738 -19800 # Mon Mar 16 12:05:38 2015 +0530 # Node ID b4646bdaf2202748d3a3b159b9bc8e3cfcd272de # Parent 6f159ec858f4eec484d722916c41911e3e4540f9 rc: tune initial predictor values for better frame size predictions in vbv lookahead an overall improvement in ssim of around .05-.1 db can be seen. Also, improves visual quality at the start of the encode. SteamLocomotiveTrain_2560x1600_60_10bit_crop.yuv --bitrate 9000 --vbv-bufsize 9000 --strict-cbr Bitrate Y PSNR U PSNR V PSNR Global PSNR SSIM SSIM (dB) before 9168.43 39.689 45.096 45.152 41.048 0.93176 11.66 after 9106.16 39.864 45.16945.19941.194 0.93518 11.883 do these pair of commits belong on stable? Yes, they belong on the stable diff -r 6f159ec858f4 -r b4646bdaf220 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Tue Mar 31 22:16:21 2015 +0530 +++ b/source/encoder/ratecontrol.cpp Mon Mar 16 12:05:38 2015 +0530 @@ -372,12 +372,17 @@ /* Frame Predictors and Row predictors used in vbv */ for (int i = 0; i 4; i++) { -m_pred[i].coeff = 1.5; +m_pred[i].coeff = 1.0; m_pred[i].count = 1.0; m_pred[i].decay = 0.5; m_pred[i].offset = 0.0; } -m_pred[0].coeff = 1.0; +m_pred[0].coeff = m_pred[3].coeff = 0.75; +if (m_param-rc.qCompress = 0.8) // when tuned for grain +{ +m_pred[1].coeff = 0.75; +m_pred[0].coeff = m_pred[3].coeff = 0.50; +} if (!m_statFileOut (m_param-rc.bStatWrite || m_param-rc.bStatRead)) { /* If the user hasn't defined the stat filename, use the default value */ @@ -1797,8 +1802,11 @@ double pbits = predictSize(m_pred[m_predType], q, (double)m_currentSatd); if (pbits rce-frameSizeMaximum) q *= pbits / rce-frameSizeMaximum; - -if (!m_isCbr || (m_isAbr m_currentSatd = rce-movingAvgSum q = q0 / 2)) +/* To detect frames that are more complex in SATD costs compared to prev window, yet + * lookahead vbv reduces its qscale by half its value. Be on safer side and avoid drastic + * qscale reductions for frames high in complexity */ +bool mispredCheck = rce-movingAvgSum m_currentSatd = rce-movingAvgSum q = q0 / 2; +if (!m_isCbr || (m_isAbr mispredCheck)) q = X265_MAX(q0, q); if (m_rateFactorMaxIncrement) ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel -- Steve Borho ___ 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
Re: [x265] [PATCH 1 of 2] rc: separate frame bits predictor objects for BRef and B frames
# HG changeset patch # User Aarthi Thirumalai # Date 1428573257 -19800 # Thu Apr 09 15:24:17 2015 +0530 # Node ID c87e15a9a353bc13036bb33a4a1932ebdb7dfb1a # Parent 4d3bfacc276362175f5f0b4a5844ec640c8871f0 rc: add helper function to decide the VBV predictor type for each frame diff -r 4d3bfacc2763 -r c87e15a9a353 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Mon Mar 16 12:05:38 2015 +0530 +++ b/source/encoder/ratecontrol.cpp Thu Apr 09 15:24:17 2015 +0530 @@ -952,7 +952,7 @@ rce-sliceType = m_sliceType; if (!m_2pass) rce-keptAsRef = IS_REFERENCED(curFrame); -m_predType = m_sliceType == B_SLICE rce-keptAsRef ? 3 : m_sliceType; +m_predType = getPredictorType(curFrame-m_lowres.sliceType, m_sliceType); rce-poc = m_curSlice-m_poc; if (m_param-rc.bStatRead) { @@ -1113,6 +1113,14 @@ m_accumPQp += m_qp; } +int RateControl::getPredictorType(int lowresSliceType, int sliceType) +{ +/* Use a different predictor for B Ref and B frames for vbv frame size predictions */ +if (lowresSliceType == X265_TYPE_BREF) +return 3; +return sliceType; +} + double RateControl::getDiffLimitedQScale(RateControlEntry *rce, double q) { // force I/B quants as a function of P quants @@ -1734,7 +1742,7 @@ bufferFillCur += wantedFrameSize; int64_t satd = curFrame-m_lowres.plannedSatd[j] (X265_DEPTH - 8); type = IS_X265_TYPE_I(type) ? I_SLICE : IS_X265_TYPE_B(type) ? B_SLICE : P_SLICE; -int predType = curFrame-m_lowres.plannedType[j] == X265_TYPE_BREF ? 3 : type; +int predType = getPredictorType(curFrame-m_lowres.plannedType[j], type); curBits = predictSize(m_pred[predType], frameQ[type], (double)satd); bufferFillCur -= curBits; } diff -r 4d3bfacc2763 -r c87e15a9a353 source/encoder/ratecontrol.h --- a/source/encoder/ratecontrol.h Mon Mar 16 12:05:38 2015 +0530 +++ b/source/encoder/ratecontrol.h Thu Apr 09 15:24:17 2015 +0530 @@ -264,7 +264,7 @@ double rateEstimateQscale(Frame* pic, RateControlEntry *rce); // main logic for calculating QP based on ABR double tuneAbrQScaleFromFeedback(double qScale); void accumPQpUpdate(); - +intgetPredictorType(int lowresSliceType, int sliceType); void updateVbv(int64_t bits, RateControlEntry* rce); void updatePredictor(Predictor *p, double q, double var, double bits); double clipQscale(Frame* pic, RateControlEntry* rce, double q); On Thu, Apr 9, 2015 at 12:08 AM, Steve Borho st...@borho.org wrote: On 04/08, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1427820381 -19800 # Tue Mar 31 22:16:21 2015 +0530 # Node ID 6f159ec858f4eec484d722916c41911e3e4540f9 # Parent 3e416dec8024b8339b18568cf65e48eb3448bed1 rc: separate frame bits predictor objects for BRef and B frames improves frame size prediction for BRef frames in VBV. this probably deserves a follow up commit introducing an inline helper method that maps from Slice* to predictor type, so we can be sure the logic stays consistent going forward and is self-documenting diff -r 3e416dec8024 -r 6f159ec858f4 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Tue Apr 07 16:00:39 2015 -0500 +++ b/source/encoder/ratecontrol.cpp Tue Mar 31 22:16:21 2015 +0530 @@ -370,7 +370,7 @@ m_accumPQp = (m_param-rc.rateControlMode == X265_RC_CRF ? CRF_INIT_QP : ABR_INIT_QP_MIN) * m_accumPNorm; /* Frame Predictors and Row predictors used in vbv */ -for (int i = 0; i 5; i++) +for (int i = 0; i 4; i++) { m_pred[i].coeff = 1.5; m_pred[i].count = 1.0; @@ -945,6 +945,9 @@ m_curSlice = curEncData.m_slice; m_sliceType = m_curSlice-m_sliceType; rce-sliceType = m_sliceType; +if (!m_2pass) +rce-keptAsRef = IS_REFERENCED(curFrame); +m_predType = m_sliceType == B_SLICE rce-keptAsRef ? 3 : m_sliceType; rce-poc = m_curSlice-m_poc; if (m_param-rc.bStatRead) { @@ -1074,7 +1077,7 @@ m_lastQScaleFor[m_sliceType] = x265_qp2qScale(rce-qpaRc); if (rce-poc == 0) m_lastQScaleFor[P_SLICE] = m_lastQScaleFor[m_sliceType] * fabs(m_param-rc.ipFactor); -rce-frameSizePlanned = predictSize(m_pred[m_sliceType], m_qp, (double)m_currentSatd); +rce-frameSizePlanned = predictSize(m_pred[m_predType], m_qp, (double)m_currentSatd); } } m_framesDone++; @@ -1397,10 +1400,10 @@ qScale = clipQscale(curFrame, rce, qScale); /* clip qp to permissible range after vbv-lookahead estimation to avoid possible * mispredictions by initial frame size predictors */ -if (m_pred[m_sliceType].count == 1) +
Re: [x265] [PATCH] rc: fix bug in ABR 2 pass, calculate aq-offset only for unreferenced frame in 2 pass
For the last pass in multi pass encodes, slice types are taken from the stats file before the frame is added into the lookahead queue. We would not do slice type analysis here and just stick with slice types read from the file. So, at this point, we would already know slice types along with CUTree offsets which we also copy from the previous pass for all referenced slices. Only for the unreferenced frames, we would need to recompute aqoffsets as the data for those won't be written in the log files. Since calcAdaptive() rewrites all the arrays - both AQCUTree offsets, we should not do this and overwrite the values for referenced frames. This flow was broken when the NUMA related commits were pushed in. On Mar 30, 2015 9:14 PM, Steve Borho st...@borho.org wrote: On 03/30, santhosh...@multicorewareinc.com wrote: # HG changeset patch # User Santhoshini Sekarsanthosh...@multicorewareinc.com # Date 1427716771 -19800 # Mon Mar 30 17:29:31 2015 +0530 # Node ID 1bdeb44d775d5be7523925017a1483294da2575d # Parent 22a312799bb033d40a66fc83a1ac7af192ce2420 rc: fix bug in ABR 2 pass, calculate aq-offset only for unreferenced frame in 2 pass diff -r 22a312799bb0 -r 1bdeb44d775d source/encoder/slicetype.cpp --- a/source/encoder/slicetype.cppFri Mar 27 22:59:30 2015 -0500 +++ b/source/encoder/slicetype.cppMon Mar 30 17:29:31 2015 +0530 @@ -699,7 +699,7 @@ ProfileScopeEvent(prelookahead); preFrame-m_lowres.init(preFrame-m_fencPic, preFrame-m_poc); -if (m_bAdaptiveQuant) +if (m_bAdaptiveQuant (!m_param-rc.bStatRead ||(m_param-rc.bStatRead (!m_param-rc.cuTree || ! IS_REFERENCED(preFrame) 1. white-space 2. this is pre-lookahead, the slice type and reference status is not known yet. If the AQ offsets aren't needed, you'll need to clear them after lookahead or just ignore them. If AQ offsets shouldn't be generated regardless of slice type, m_bAdaptiveQuant should be set to false much earlier -- Steve Borho ___ 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
Re: [x265] [PATCH] analysis:add logic for calculate qp for a given cu size
Also, since vbv may be changing the qp for each row, you need to pick up the base qp from curEncData.m_cuStat[cuAddr].baseQp instead of m_frame-m_encData-m_avgQpRc; On Thu, Mar 12, 2015 at 10:25 AM, Sreelakshmy Govindan sreelaks...@multicorewareinc.com wrote: Thanks Steve. I will make the changes and resend the patch. Regards, Sreelakshmy On Thu, Mar 12, 2015 at 9:32 AM, Steve Borho st...@borho.org wrote: On Wed, Mar 11, 2015 at 10:36 PM, sreelaks...@multicorewareinc.com wrote: # HG changeset patch # User Sreelakshmy V G sreelaks...@multicorewareinc.com # Date 1426131126 -19800 # Thu Mar 12 09:02:06 2015 +0530 # Node ID c7182de7496906e81b57cb94278d60cbcc446648 # Parent b931c50d55011a1ddc08f0a230b9632fcb4674d7 analysis:add logic for calculate qp for a given cu size the commit message should mention that the commit is adding the function but that it is not yet used, for the convenience of reviewers diff -r b931c50d5501 -r c7182de74969 source/encoder/analysis.cpp --- a/source/encoder/analysis.cpp Wed Mar 11 21:58:02 2015 -0500 +++ b/source/encoder/analysis.cpp Thu Mar 12 09:02:06 2015 +0530 @@ -1895,3 +1895,41 @@ return false; } + +int Analysis::calculateQpforCuSize(CUData ctu, const CUGeom cuGeom) +{ +x265_emms(); it doesn't appear that this function needs to use floats, so EMMS should eventually be unnecessary +int depth = cuGeom.depth; +uint32_t ctuAddr; +ctuAddr = ctu.m_cuAddr; +double qp = m_frame-m_encData-m_avgQpRc; + +uint32_t width = m_frame-m_fencPic-m_picWidth; +uint32_t height = m_frame-m_fencPic-m_picHeight; +uint32_t block_x = ctu.m_cuPelX + g_zscanToPelX[cuGeom.absPartIdx]; +uint32_t block_y = ctu.m_cuPelY + g_zscanToPelY[cuGeom.absPartIdx]; +uint32_t maxCols = (m_frame-m_fencPic-m_picWidth + (16 - 1)) / 16; +uint32_t blockSize = g_maxCUSize / (uint32_t)pow(2, depth); g_maxCUSize cuGeom.depth +double qp_offset = 0; +uint32_t cnt = 0; +uint32_t idx; + +/* Use cuTree offsets if cuTree enabled and frame is referenced, else use AQ offsets */ +bool isReferenced = IS_REFERENCED(m_frame); +double *qpoffs = (isReferenced m_param-rc.cuTree) ? m_frame-m_lowres.qpCuTreeOffset : m_frame-m_lowres.qpAqOffset; the lookahead is generating FIX8 versions of these values, so integer math can be used in later parts of the encoder. +for (uint32_t block_yy = block_y; block_yy block_y + blockSize block_yy height; block_yy += 16) +{ +for (uint32_t block_xx = block_x; block_xx block_x + blockSize block_xx width; block_xx += 16) +{ +idx = ((block_yy / 16) * (maxCols)) + (block_xx / 16); +qp_offset += qpoffs[idx]; +cnt++; +} +} + +qp_offset /= cnt; +qp += qp_offset; +return x265_clip3(QP_MIN, QP_MAX_MAX, (int)(qp + 0.5)); +} + diff -r b931c50d5501 -r c7182de74969 source/encoder/analysis.h --- a/source/encoder/analysis.h Wed Mar 11 21:58:02 2015 -0500 +++ b/source/encoder/analysis.h Thu Mar 12 09:02:06 2015 +0530 @@ -139,6 +139,8 @@ /* generate residual and recon pixels for an entire CTU recursively (RD0) */ void encodeResidue(const CUData parentCTU, const CUGeom cuGeom); +int calculateQpforCuSize(CUData ctu, const CUGeom cuGeom); + /* check whether current mode is the new best */ inline void checkBestMode(Mode mode, uint32_t depth) { ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel -- Steve Borho ___ 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 ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
Re: [x265] [PATCH] rc: recompute planned frame size when using vbv with --qpfile
I will send the other part as a different patch. It is to prevent drastic qp changes from vbv lookahead estimations due to possible mispredictions by the default vbv frame size predictors. On Mar 12, 2015 6:23 AM, Deepthi Nandakumar deep...@multicorewareinc.com wrote: No, this is not. This is for a customer who wanted to be able to use qpfile with VBV. The first half is - I'm not sure about the second half of the patch. On Thu, Mar 12, 2015 at 1:44 AM, Steve Borho st...@borho.org wrote: On 03/11, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1425994215 -19800 # Tue Mar 10 19:00:15 2015 +0530 # Node ID 9b7b93384e39e90cf2d4c0c0a53213abff362f70 # Parent 8f148ac8dbe4b68e88ceff84f40e33b29e888dc9 rc: recompute planned frame size when using vbv with --qpfile is this at all related to issue 111? diff -r 8f148ac8dbe4 -r 9b7b93384e39 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Tue Mar 10 15:46:36 2015 +0530 +++ b/source/encoder/ratecontrol.cpp Tue Mar 10 19:00:15 2015 +0530 @@ -1067,7 +1067,15 @@ { m_qp = (int32_t)(curFrame-m_forceqp + 0.5) - 1; m_qp = x265_clip3(QP_MIN, QP_MAX_MAX, m_qp); -rce-qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq = m_qp; +rce-qpaRc =curEncData.m_avgQpRc = curEncData.m_avgQpAq = m_qp; +if (m_isAbr) +{ +rce-qpNoVbv = rce-qpaRc; +m_lastQScaleFor[m_sliceType] = x265_qp2qScale(rce-qpaRc); +if (rce-poc == 0) + m_lastQScaleFor[P_SLICE] = m_lastQScaleFor[m_sliceType] * fabs(m_param-rc.ipFactor); +rce-frameSizePlanned = predictSize(m_pred[m_sliceType], rce-qpaRc, (double)m_currentSatd); +} } // Do not increment m_startEndOrder here. Make rateControlEnd of previous thread // to wait until rateControlUpdateStats of this frame is called @@ -1360,13 +1368,14 @@ q += m_pbOffset; double qScale = x265_qp2qScale(q); +double lmin = 0, lmax = 0; if (m_isCbr) { qScale = tuneAbrQScaleFromFeedback(qScale); if (!m_isAbrReset) { -double lmin = m_lastQScaleFor[P_SLICE] / m_lstep; -double lmax = m_lastQScaleFor[P_SLICE] * m_lstep; + lmin = m_lastQScaleFor[P_SLICE] / m_lstep; + lmax = m_lastQScaleFor[P_SLICE] * m_lstep; qScale = x265_clip3(lmin, lmax, qScale); } q = x265_qScale2qp(qScale); @@ -1375,6 +1384,8 @@ if (!m_2pass m_isVbv) { qScale = clipQscale(curFrame, rce, qScale); +if (m_pred[m_sliceType].count == 1) +qScale = x265_clip3(lmin, lmax, qScale); m_lastQScaleFor[m_sliceType] = qScale; rce-frameSizePlanned = predictSize(m_pred[m_sliceType], qScale, (double)m_currentSatd); } @@ -1460,7 +1471,7 @@ * tolerances, the bit distribution approaches that of 2pass. */ double overflow = 1; - +double lqmin = 0, lqmax = 0; m_shortTermCplxSum *= 0.5; m_shortTermCplxCount *= 0.5; m_shortTermCplxSum += m_currentSatd / (CLIP_DURATION(m_frameDuration) / BASE_FRAME_DURATION); @@ -1494,7 +1505,6 @@ { if (m_param-rc.rateControlMode != X265_RC_CRF) { -double lqmin = 0, lqmax = 0; lqmin = m_lastQScaleFor[m_sliceType] / m_lstep; lqmax = m_lastQScaleFor[m_sliceType] * m_lstep; if (!m_partialResidualFrames) @@ -1520,6 +1530,8 @@ q = x265_clip3(MIN_QPSCALE, MAX_MAX_QPSCALE, q); rce-qpNoVbv = x265_qScale2qp(q); q = clipQscale(curFrame, rce, q); +if (m_pred[m_sliceType].count == 1 m_framesDone 0) +q = x265_clip3(lqmin, lqmax, q); } m_lastQScaleFor[m_sliceType] = q; if ((m_curSlice-m_poc == 0 || m_lastQScaleFor[P_SLICE] q) !(m_2pass !m_isVbv)) ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel -- Steve Borho ___ 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 ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
Re: [x265] [PATCH] slicetype: fix crash when rc-lookahead = bframes
crash occurs when lookaheadDepth equals bframes. need to modify it CHECK(param-bframes *=* param-lookaheadDepth On Mon, Mar 9, 2015 at 9:18 PM, Steve Borho st...@borho.org wrote: On 03/09, Deepthi Nandakumar wrote: slicetypeAnalyse::maxSearch also needs to be changed, or you could trigger another crash using --b-adapt 1. It seems to me, under the hood we're just incrementing lookaheadDepth. That may be the right thing to do here, or do a CHECK for lookaheadDepth = bframes? We have: CHECK(param-bframes param-lookaheadDepth !param-rc.bStatRead, Lookahead depth must be greater than the max consecutive bframe count); is this not sufficient? -- Steve Borho ___ 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
Re: [x265] [PATCH 2 of 2] rc: restrict low tolerance for bitrate fluctuations to strict-cbr option
# HG changeset patch # User Aarthi Thirumalai # Date 1419064540 -19800 # Sat Dec 20 14:05:40 2014 +0530 # Node ID 1e7de45ddd54a1af7feab49d807c3fde7d34e1f8 # Parent d55fed4ebcd22823f8ffb878fa898b5d288cbb6a rc: restrict low tolerance for bitrate fluctuations to strict-cbr option diff -r d55fed4ebcd2 -r 1e7de45ddd54 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Tue Dec 23 16:32:30 2014 +0530 +++ b/source/encoder/ratecontrol.cpp Sat Dec 20 14:05:40 2014 +0530 @@ -1759,7 +1759,7 @@ for (int j = 0; bufferFillCur = 0; j++) { int type = curFrame-m_lowres.plannedType[j]; -if (type == X265_TYPE_AUTO) +if (type == X265_TYPE_AUTO || totalDuration = 1.0) break; totalDuration += m_frameDuration; double wantedFrameSize = m_vbvMaxRate * m_frameDuration; @@ -1773,17 +1773,21 @@ bufferFillCur -= curBits; } -/* Try to get the buffer no more than 80% filled, but don't set an impossible goal. */ -double tol = isIFramePresent ? 1 / totalDuration : totalDuration 0.5 ? 2 : 1; -targetFill = X265_MIN(m_bufferFill + totalDuration * m_vbvMaxRate * 0.5 , m_bufferSize * (1 - 0.8 * totalDuration * tol)); +/* Try to get the buffer at least 50% filled, but don't set an impossible goal. */ +double finalDur = 1; +if (m_param-rc.bStrictCbr) +{ +finalDur = x265_clip3(0.4, 1.0, totalDuration); +} +targetFill = X265_MIN(m_bufferFill + totalDuration * m_vbvMaxRate * 0.5 , m_bufferSize * (1 - 0.5 * finalDur)); if (bufferFillCur targetFill) { q *= 1.01; loopTerminate |= 1; continue; } -/* Try to get the buffer atleast 50% filled, but don't set an impossible goal. */ -targetFill = x265_clip3(m_bufferSize - (m_bufferSize * totalDuration * 0.5), m_bufferSize, m_bufferFill - totalDuration * m_vbvMaxRate * 0.5); +/* Try to get the buffer not more than 80% filled, but don't set an impossible goal. */ +targetFill = x265_clip3(m_bufferSize * (1 - 0.2 * finalDur), m_bufferSize, m_bufferFill - totalDuration * m_vbvMaxRate * 0.5); if (m_isCbr bufferFillCur targetFill) { q /= 1.01; @@ -1976,7 +1980,7 @@ if (row sps.numCuInHeight - 1) { /* More threads means we have to be more cautious in letting ratecontrol use up extra bits. */ -double rcTol = (bufferLeftPlanned * 0.2) / m_param-frameNumThreads * m_param-rc.rateTolerance; +double rcTol = bufferLeftPlanned / m_param-frameNumThreads * m_param-rc.rateTolerance; int32_t encodedBitsSoFar = 0; double accFrameBits = predictRowsSizeSum(curFrame, rce, qpVbv, encodedBitsSoFar); @@ -1994,7 +1998,7 @@ while (qpVbv qpMax ((accFrameBits rce-frameSizePlanned + rcTol) || - (rce-bufferFill - accFrameBits bufferLeftPlanned * 0.2) || + (rce-bufferFill - accFrameBits bufferLeftPlanned * 0.5) || (accFrameBits rce-frameSizePlanned qpVbv rce-qpNoVbv))) { qpVbv += stepSize; On Sun, Jan 11, 2015 at 3:57 PM, Aarthi Priya Thirumalai aar...@multicorewareinc.com wrote: no, there were a few conflicts because my local tip wasn't updated. Sending again.. On Thu, Jan 8, 2015 at 8:02 PM, Steve Borho st...@borho.org wrote: On 01/07, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1419064540 -19800 # Sat Dec 20 14:05:40 2014 +0530 # Node ID 5d658640bcf115f2add4da1619eeaec50177973f # Parent 9b30c4b16dfc4c673b57ee4c567fa8956a41e2fc rc: restrict low tolerance for bitrate fluctuations to strict-cbr option this patch isn't applying; perhaps it depends on the RCstart/stop patch diff -r 9b30c4b16dfc -r 5d658640bcf1 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Tue Dec 23 16:32:30 2014 +0530 +++ b/source/encoder/ratecontrol.cpp Sat Dec 20 14:05:40 2014 +0530 @@ -1759,7 +1759,7 @@ for (int j = 0; bufferFillCur = 0; j++) { int type = curFrame-m_lowres.plannedType[j]; -if (type == X265_TYPE_AUTO) +if (type == X265_TYPE_AUTO || totalDuration = 1.0) break; totalDuration += m_frameDuration; double wantedFrameSize = m_vbvMaxRate * m_frameDuration; @@ -1773,17 +1773,21 @@ bufferFillCur -= curBits; } -/* Try to get the buffer no more
Re: [x265] [PATCH 1 of 2] cli: remove tune cbr and introduce strict-cbr as a param option instead
# HG changeset patch # User Aarthi Thirumalai # Date 1419332550 -19800 # Tue Dec 23 16:32:30 2014 +0530 # Node ID d55fed4ebcd22823f8ffb878fa898b5d288cbb6a # Parent 1924c460d1304d9ce775f35864712dd98f758f9f cli: remove tune cbr and introduce strict-cbr as a param option instead strict-cbr can be enabled in CBR mode, enforces stricter checks for bitrate adhearance and lesser tolerance for bitrate deviance from the target. diff -r 1924c460d130 -r d55fed4ebcd2 doc/reST/cli.rst --- a/doc/reST/cli.rst Fri Jan 09 11:35:26 2015 +0530 +++ b/doc/reST/cli.rst Tue Dec 23 16:32:30 2014 +0530 @@ -209,7 +209,7 @@ be applied after :option:`--preset` but before all other parameters. Default none. See :ref:`tunings tunings` for more detail. - **Values:** psnr, ssim, grain, zero-latency, fast-decode, cbr. + **Values:** psnr, ssim, grain, zero-latency, fast-decode. Input/Output File Options = @@ -992,6 +992,12 @@ * :option:`--subme` = MIN(2, :option:`--subme`) * :option:`--rd` = MIN(2, :option:`--rd`) +.. option:: --strict-cbr, --no-strict-cbr + + Enables stricter conditions to control bitrate + deviance from the target in CBR mode. Bitrate adhearance is prioritised + over quality. Rate tolerance is set to 50%. Default disabled + .. option:: --cbqpoffs integer Offset of Cb chroma QP from the luma QP selected by rate control. diff -r 1924c460d130 -r d55fed4ebcd2 doc/reST/presets.rst --- a/doc/reST/presets.rst Fri Jan 09 11:35:26 2015 +0530 +++ b/doc/reST/presets.rst Tue Dec 23 16:32:30 2014 +0530 @@ -105,8 +105,7 @@ +--+-+ | zerolatency | no lookahead, no B frames, no cutree| +--+-+ -| cbr | --pbratio 1.0 --ratetol 0.5 | -+--+-+ + Film Grain Retention diff -r 1924c460d130 -r d55fed4ebcd2 source/CMakeLists.txt --- a/source/CMakeLists.txt Fri Jan 09 11:35:26 2015 +0530 +++ b/source/CMakeLists.txt Tue Dec 23 16:32:30 2014 +0530 @@ -21,7 +21,7 @@ include(CheckCXXCompilerFlag) # X265_BUILD must be incremented each time the public API is changed -set(X265_BUILD 40) +set(X265_BUILD 41) configure_file(${PROJECT_SOURCE_DIR}/x265.def.in ${PROJECT_BINARY_DIR}/x265.def) configure_file(${PROJECT_SOURCE_DIR}/x265_config.h.in diff -r 1924c460d130 -r d55fed4ebcd2 source/common/param.cpp --- a/source/common/param.cpp Fri Jan 09 11:35:26 2015 +0530 +++ b/source/common/param.cpp Tue Dec 23 16:32:30 2014 +0530 @@ -206,6 +206,7 @@ param-rc.complexityBlur = 20; param-rc.qblur = 0.5; param-rc.bEnableSlowFirstPass = 0; +param-rc.bStrictCbr = 0; /* Video Usability Information (VUI) */ param-vui.aspectRatioIdc = 0; @@ -421,11 +422,6 @@ param-rc.aqStrength = 0.3; param-rc.qCompress = 0.8; } -else if (!strcmp(tune, cbr)) -{ -param-rc.pbFactor = 1.0; -param-rc.rateTolerance = 0.5; -} else return -1; } @@ -699,6 +695,12 @@ 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(strict-cbr) +{ +p-rc.bStrictCbr = atobool(value); +p-rc.pbFactor = 1.0; +p-rc.rateTolerance = 0.5; +} OPT(analysis-mode) p-analysisMode = parseName(value, x265_analysis_names, bError); OPT(sar) { @@ -1087,6 +1089,8 @@ Constant rate-factor is incompatible with 2pass); CHECK(param-rc.rateControlMode == X265_RC_CQP param-rc.bStatRead, Constant QP is incompatible with 2pass); +CHECK(param-rc.bStrictCbr (param-rc.bitrate = 0 || param-rc.vbvBufferSize =0), + Strict-cbr cannot be applied without specifying target bitrate or vbv bufsize); return check_failed; } diff -r 1924c460d130 -r d55fed4ebcd2 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Fri Jan 09 11:35:26 2015 +0530 +++ b/source/encoder/ratecontrol.cpp Tue Dec 23 16:32:30 2014 +0530 @@ -324,10 +324,6 @@ m_numEntries = 0; m_amortizeFraction = 0.85; m_amortizeFrames = 75; -if (m_param-totalFrames = 2 * m_fps) -{ -m_amortizeFraction = m_amortizeFrames = 0; -} if (m_param-rc.rateControlMode == X265_RC_CRF) { m_param-rc.qp = (int)m_param-rc.rfConstant; @@ -396,6 +392,11 @@ x265_log(m_param, X265_LOG_WARNING, max bitrate less than average bitrate, assuming CBR\n); m_param-rc.bitrate = m_param-rc.vbvMaxBitrate; } +if (m_param-rc.bStrictCbr m_param-rc.vbvMaxBitrate != m_param-rc.bitrate) +{ +x265_log(m_param, X265_LOG_WARNING, strict CBR set without CBR mode, ignored\n); +m_param-rc.bStrictCbr
Re: [x265] [PATCH 2 of 2] rc: restrict low tolerance for bitrate fluctuations to strict-cbr option
no, there were a few conflicts because my local tip wasn't updated. Sending again.. On Thu, Jan 8, 2015 at 8:02 PM, Steve Borho st...@borho.org wrote: On 01/07, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1419064540 -19800 # Sat Dec 20 14:05:40 2014 +0530 # Node ID 5d658640bcf115f2add4da1619eeaec50177973f # Parent 9b30c4b16dfc4c673b57ee4c567fa8956a41e2fc rc: restrict low tolerance for bitrate fluctuations to strict-cbr option this patch isn't applying; perhaps it depends on the RCstart/stop patch diff -r 9b30c4b16dfc -r 5d658640bcf1 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Tue Dec 23 16:32:30 2014 +0530 +++ b/source/encoder/ratecontrol.cpp Sat Dec 20 14:05:40 2014 +0530 @@ -1759,7 +1759,7 @@ for (int j = 0; bufferFillCur = 0; j++) { int type = curFrame-m_lowres.plannedType[j]; -if (type == X265_TYPE_AUTO) +if (type == X265_TYPE_AUTO || totalDuration = 1.0) break; totalDuration += m_frameDuration; double wantedFrameSize = m_vbvMaxRate * m_frameDuration; @@ -1773,17 +1773,21 @@ bufferFillCur -= curBits; } -/* Try to get the buffer no more than 80% filled, but don't set an impossible goal. */ -double tol = isIFramePresent ? 1 / totalDuration : totalDuration 0.5 ? 2 : 1; -targetFill = X265_MIN(m_bufferFill + totalDuration * m_vbvMaxRate * 0.5 , m_bufferSize * (1 - 0.8 * totalDuration * tol)); +/* Try to get the buffer at least 50% filled, but don't set an impossible goal. */ +double finalDur = 1; +if (m_param-rc.bStrictCbr) +{ +finalDur = Clip3(0.4, 1.0, totalDuration); +} +targetFill = X265_MIN(m_bufferFill + totalDuration * m_vbvMaxRate * 0.5 , m_bufferSize * (1 - 0.5 * finalDur)); if (bufferFillCur targetFill) { q *= 1.01; loopTerminate |= 1; continue; } -/* Try to get the buffer atleast 50% filled, but don't set an impossible goal. */ -targetFill = Clip3(m_bufferSize - (m_bufferSize * totalDuration * 0.5), m_bufferSize, m_bufferFill - totalDuration * m_vbvMaxRate * 0.5); +/* Try to get the buffer not more than 80% filled, but don't set an impossible goal. */ +targetFill = Clip3(m_bufferSize * (1 - 0.2 * finalDur) , m_bufferSize, m_bufferFill - totalDuration * m_vbvMaxRate * 0.5); if (m_isCbr bufferFillCur targetFill) { q /= 1.01; @@ -1976,7 +1980,7 @@ if (row sps.numCuInHeight - 1) { /* More threads means we have to be more cautious in letting ratecontrol use up extra bits. */ -double rcTol = (bufferLeftPlanned * 0.2) / m_param-frameNumThreads * m_param-rc.rateTolerance; +double rcTol = bufferLeftPlanned / m_param-frameNumThreads * m_param-rc.rateTolerance; int32_t encodedBitsSoFar = 0; double accFrameBits = predictRowsSizeSum(curFrame, rce, qpVbv, encodedBitsSoFar); @@ -1994,7 +1998,7 @@ while (qpVbv qpMax ((accFrameBits rce-frameSizePlanned + rcTol) || - (rce-bufferFill - accFrameBits bufferLeftPlanned * 0.2) || + (rce-bufferFill - accFrameBits bufferLeftPlanned * 0.5) || (accFrameBits rce-frameSizePlanned qpVbv rce-qpNoVbv))) { qpVbv += stepSize; ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel -- Steve Borho ___ 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
Re: [x265] [PATCH] rc: fix chroma qp and chroma lambda derivations
We can directly use the array or the wrapper. For high bit depth , there is no difference between the luma qp and chroma qp. that is chroma qp = min(luma qp,51). On Thu, Dec 4, 2014 at 4:53 PM, Deepthi Nandakumar deep...@multicorewareinc.com wrote: Is there an if (csp == I420) wrapper specified though? For some reason, deblock/quant have this. On Thu, Dec 4, 2014 at 4:50 PM, Deepthi Nandakumar deep...@multicorewareinc.com wrote: This looks like a Main bug where rdcost was not looking at g_chromaScale at all. On Thu, Dec 4, 2014 at 4:36 PM, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1417675781 -19800 # Thu Dec 04 12:19:41 2014 +0530 # Node ID 23061220a5fe287cac893320d8ee0a782d6767c0 # Parent 511dde5ac1deee96a0105bb87e14670ef5ed72a6 rc: fix chroma qp and chroma lambda derivations. fix the chroma qp values for Main10 profile, derive chroma qp from luma qp values according to the HEVC spec. improves quality at high qps. diff -r 511dde5ac1de -r 23061220a5fe source/common/constants.cpp --- a/source/common/constants.cpp Thu Dec 04 12:43:06 2014 +0530 +++ b/source/common/constants.cpp Thu Dec 04 12:19:41 2014 +0530 @@ -289,11 +289,21 @@ { 4, -13, 22, -31, 38, -46, 54, -61, 67, -73, 78, -82, 85, -88, 90, -90, 90, -90, 88, -85, 82, -78, 73, -67, 61, -54, 46, -38, 31, -22, 13, -4 } }; + +#if HIGH_BIT_DEPTH +const uint8_t g_chromaScale[ChromaQPMappingTableSize] = +{ +0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, +51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 +}; + +#else const uint8_t g_chromaScale[ChromaQPMappingTableSize] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 29, 30, 31, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 -}; +}; +#endif const uint8_t g_chroma422IntraAngleMappingTable[AngleMapping422TableSize] = { 0, 1, 2, 2, 2, 2, 3, 5, 7, 8, 10, 12, 13, 15, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28, 29, 29, 30, 31, DM_CHROMA_IDX }; diff -r 511dde5ac1de -r 23061220a5fe source/encoder/rdcost.h --- a/source/encoder/rdcost.h Thu Dec 04 12:43:06 2014 +0530 +++ b/source/encoder/rdcost.h Thu Dec 04 12:19:41 2014 +0530 @@ -57,12 +57,12 @@ setLambda(x265_lambda2_tab[qp], x265_lambda_tab[qp]); -int qpCb = Clip3(QP_MIN, QP_MAX_MAX, qp + slice.m_pps-chromaQpOffset[0]); +int qpCb = Clip3(QP_MIN, QP_MAX_MAX, (int)g_chromaScale[qp + slice.m_pps-chromaQpOffset[0]]); int chroma_offset_idx = X265_MIN(qp - qpCb + 12, MAX_CHROMA_LAMBDA_OFFSET); uint16_t lambdaOffset = m_psyRd ? x265_chroma_lambda2_offset_tab[chroma_offset_idx] : 256; setCbDistortionWeight(lambdaOffset); -int qpCr = Clip3(QP_MIN, QP_MAX_MAX, qp + slice.m_pps-chromaQpOffset[1]); +int qpCr = Clip3(QP_MIN, QP_MAX_MAX, (int)g_chromaScale[qp + slice.m_pps-chromaQpOffset[0]]); chroma_offset_idx = X265_MIN(qp - qpCr + 12, MAX_CHROMA_LAMBDA_OFFSET); lambdaOffset = m_psyRd ? x265_chroma_lambda2_offset_tab[chroma_offset_idx] : 256; setCrDistortionWeight(lambdaOffset); diff -r 511dde5ac1de -r 23061220a5fe source/encoder/sao.cpp --- a/source/encoder/sao.cppThu Dec 04 12:43:06 2014 +0530 +++ b/source/encoder/sao.cppThu Dec 04 12:19:41 2014 +0530 @@ -177,7 +177,7 @@ { Slice* slice = frame-m_encData-m_slice; -int qpCb = Clip3(0, QP_MAX_MAX, qp + slice-m_pps-chromaQpOffset[0]); +int qpCb = Clip3(QP_MIN, QP_MAX_MAX, (int)g_chromaScale[qp + slice-m_pps-chromaQpOffset[0]]); m_lumaLambda = x265_lambda2_tab[qp]; m_chromaLambda = x265_lambda2_tab[qpCb]; // Use Cb QP for SAO chroma m_frame = frame; ___ 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 ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
Re: [x265] [PATCH] framefilter: remove heap corruption in tld
sry, Thg client didnt sync the changes properly for the previous commit. here is the right one # HG changeset patch # User Aarthi Thirumalai # Date 1404290172 -19800 # Wed Jul 02 14:06:12 2014 +0530 # Node ID a5a439242bbf367f5d76356b841cfa1ee9e119e4 # Parent a18972fd05b1d6242a881bef979b9e1ff17543d9 framefilter: remove heap corruption in tld diff -r a18972fd05b1 -r a5a439242bbf source/encoder/frameencoder.h --- a/source/encoder/frameencoder.h Tue Jul 01 14:58:35 2014 -0500 +++ b/source/encoder/frameencoder.h Wed Jul 02 14:06:12 2014 +0530 @@ -171,7 +171,7 @@ uint32_t m_checksum[3]; double m_elapsedCompressTime; // elapsed time spent in worker threads double m_frameTime; // wall time from frame start to finish - +ThreadLocalData m_tld; volatile boolm_bAllRowsStop; volatile int m_vbvResetTriggerRow; @@ -191,7 +191,6 @@ Bitstream* m_outStreams; NoiseReduction m_nr; NALList m_nalList; -ThreadLocalData m_tld; Frame* m_frame; diff -r a18972fd05b1 -r a5a439242bbf source/encoder/framefilter.cpp --- a/source/encoder/framefilter.cpp Tue Jul 01 14:58:35 2014 -0500 +++ b/source/encoder/framefilter.cpp Wed Jul 02 14:06:12 2014 +0530 @@ -124,8 +124,7 @@ void FrameFilter::processRow(int row, const int threadId) { PPAScopeEvent(Thread_filterCU); -assert(threadId = 0); -ThreadLocalData tld = Encoder::m_threadLocalData[threadId]; +ThreadLocalData tld = threadId = 0 ? Encoder::m_threadLocalData[threadId] : m_frame-m_tld; if (!m_param-bEnableLoopFilter !m_param-bEnableSAO) { On Wed, Jul 2, 2014 at 2:15 PM, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1404290172 -19800 # Wed Jul 02 14:06:12 2014 +0530 # Node ID 69d9bd3eb5bd015d2e0c90d51eec0d7f8a4747d0 # Parent a18972fd05b1d6242a881bef979b9e1ff17543d9 framefilter: remove heap corruption in tld diff -r a18972fd05b1 -r 69d9bd3eb5bd source/encoder/frameencoder.h --- a/source/encoder/frameencoder.h Tue Jul 01 14:58:35 2014 -0500 +++ b/source/encoder/frameencoder.h Wed Jul 02 14:06:12 2014 +0530 @@ -191,7 +191,6 @@ Bitstream* m_outStreams; NoiseReduction m_nr; NALList m_nalList; -ThreadLocalData m_tld; Frame* m_frame; ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
Re: [x265] [PATCH] framefilter: remove heap corruption in tld
Exactly that! make FrameEncoder::m_tld a public member for framefilter to access, use it in when Wpp is disabled. On Wed, Jul 2, 2014 at 2:25 PM, Deepthi Nandakumar deep...@multicorewareinc.com wrote: The framefilter structure needs ThreadLocalData m_tld, that has to be initialised, and then used if wpp is not enabled. Not sure what you're trying to do here? On Wed, Jul 2, 2014 at 2:20 PM, Aarthi Priya Thirumalai aar...@multicorewareinc.com wrote: sry, Thg client didnt sync the changes properly for the previous commit. here is the right one # HG changeset patch # User Aarthi Thirumalai # Date 1404290172 -19800 # Wed Jul 02 14:06:12 2014 +0530 # Node ID a5a439242bbf367f5d76356b841cfa1ee9e119e4 # Parent a18972fd05b1d6242a881bef979b9e1ff17543d9 framefilter: remove heap corruption in tld diff -r a18972fd05b1 -r a5a439242bbf source/encoder/frameencoder.h --- a/source/encoder/frameencoder.h Tue Jul 01 14:58:35 2014 -0500 +++ b/source/encoder/frameencoder.h Wed Jul 02 14:06:12 2014 +0530 @@ -171,7 +171,7 @@ uint32_t m_checksum[3]; double m_elapsedCompressTime; // elapsed time spent in worker threads double m_frameTime; // wall time from frame start to finish - +ThreadLocalData m_tld; volatile boolm_bAllRowsStop; volatile int m_vbvResetTriggerRow; @@ -191,7 +191,6 @@ Bitstream* m_outStreams; NoiseReduction m_nr; NALList m_nalList; -ThreadLocalData m_tld; Frame* m_frame; diff -r a18972fd05b1 -r a5a439242bbf source/encoder/framefilter.cpp --- a/source/encoder/framefilter.cpp Tue Jul 01 14:58:35 2014 -0500 +++ b/source/encoder/framefilter.cpp Wed Jul 02 14:06:12 2014 +0530 @@ -124,8 +124,7 @@ void FrameFilter::processRow(int row, const int threadId) { PPAScopeEvent(Thread_filterCU); -assert(threadId = 0); -ThreadLocalData tld = Encoder::m_threadLocalData[threadId]; +ThreadLocalData tld = threadId = 0 ? Encoder::m_threadLocalData[threadId] : m_frame-m_tld; if (!m_param-bEnableLoopFilter !m_param-bEnableSAO) { On Wed, Jul 2, 2014 at 2:15 PM, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1404290172 -19800 # Wed Jul 02 14:06:12 2014 +0530 # Node ID 69d9bd3eb5bd015d2e0c90d51eec0d7f8a4747d0 # Parent a18972fd05b1d6242a881bef979b9e1ff17543d9 framefilter: remove heap corruption in tld diff -r a18972fd05b1 -r 69d9bd3eb5bd source/encoder/frameencoder.h --- a/source/encoder/frameencoder.h Tue Jul 01 14:58:35 2014 -0500 +++ b/source/encoder/frameencoder.h Wed Jul 02 14:06:12 2014 +0530 @@ -191,7 +191,6 @@ Bitstream* m_outStreams; NoiseReduction m_nr; NALList m_nalList; -ThreadLocalData m_tld; Frame* m_frame; ___ 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 ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
Re: [x265] [PATCH] framefilter: remove heap corruption in tld
it has to be in scope of each Frame Encoder since frame can be are encoded in parallel with no wpp. On Wed, Jul 2, 2014 at 3:55 PM, Deepthi Nandakumar deep...@multicorewareinc.com wrote: Hmm, I'm wondering doesnt m_tld rightfully belong to Encoder? On Wed, Jul 2, 2014 at 3:39 PM, Aarthi Priya Thirumalai aar...@multicorewareinc.com wrote: Exactly that! make FrameEncoder::m_tld a public member for framefilter to access, use it in when Wpp is disabled. On Wed, Jul 2, 2014 at 2:25 PM, Deepthi Nandakumar deep...@multicorewareinc.com wrote: The framefilter structure needs ThreadLocalData m_tld, that has to be initialised, and then used if wpp is not enabled. Not sure what you're trying to do here? On Wed, Jul 2, 2014 at 2:20 PM, Aarthi Priya Thirumalai aar...@multicorewareinc.com wrote: sry, Thg client didnt sync the changes properly for the previous commit. here is the right one # HG changeset patch # User Aarthi Thirumalai # Date 1404290172 -19800 # Wed Jul 02 14:06:12 2014 +0530 # Node ID a5a439242bbf367f5d76356b841cfa1ee9e119e4 # Parent a18972fd05b1d6242a881bef979b9e1ff17543d9 framefilter: remove heap corruption in tld diff -r a18972fd05b1 -r a5a439242bbf source/encoder/frameencoder.h --- a/source/encoder/frameencoder.h Tue Jul 01 14:58:35 2014 -0500 +++ b/source/encoder/frameencoder.h Wed Jul 02 14:06:12 2014 +0530 @@ -171,7 +171,7 @@ uint32_t m_checksum[3]; double m_elapsedCompressTime; // elapsed time spent in worker threads double m_frameTime; // wall time from frame start to finish - +ThreadLocalData m_tld; volatile boolm_bAllRowsStop; volatile int m_vbvResetTriggerRow; @@ -191,7 +191,6 @@ Bitstream* m_outStreams; NoiseReduction m_nr; NALList m_nalList; -ThreadLocalData m_tld; Frame* m_frame; diff -r a18972fd05b1 -r a5a439242bbf source/encoder/framefilter.cpp --- a/source/encoder/framefilter.cpp Tue Jul 01 14:58:35 2014 -0500 +++ b/source/encoder/framefilter.cpp Wed Jul 02 14:06:12 2014 +0530 @@ -124,8 +124,7 @@ void FrameFilter::processRow(int row, const int threadId) { PPAScopeEvent(Thread_filterCU); -assert(threadId = 0); -ThreadLocalData tld = Encoder::m_threadLocalData[threadId]; +ThreadLocalData tld = threadId = 0 ? Encoder::m_threadLocalData[threadId] : m_frame-m_tld; if (!m_param-bEnableLoopFilter !m_param-bEnableSAO) { On Wed, Jul 2, 2014 at 2:15 PM, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1404290172 -19800 # Wed Jul 02 14:06:12 2014 +0530 # Node ID 69d9bd3eb5bd015d2e0c90d51eec0d7f8a4747d0 # Parent a18972fd05b1d6242a881bef979b9e1ff17543d9 framefilter: remove heap corruption in tld diff -r a18972fd05b1 -r 69d9bd3eb5bd source/encoder/frameencoder.h --- a/source/encoder/frameencoder.h Tue Jul 01 14:58:35 2014 -0500 +++ b/source/encoder/frameencoder.h Wed Jul 02 14:06:12 2014 +0530 @@ -191,7 +191,6 @@ Bitstream* m_outStreams; NoiseReduction m_nr; NALList m_nalList; -ThreadLocalData m_tld; Frame* m_frame; ___ 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 ___ 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 ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
Re: [x265] [PATCH] rc: compute inter, intra and skip cus per frame for the first pass
On Mon, Jun 30, 2014 at 11:45 PM, Steve Borho st...@borho.org wrote: On Mon, Jun 30, 2014 at 11:38 AM, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1403785166 -19800 # Thu Jun 26 17:49:26 2014 +0530 # Node ID 2dd5aded9e192783dfc8f8307a05e3b2a55b7f1d # Parent bab912d0834914e8947a126e6b0ec4dbc75d7843 rc: compute inter, intra and skip cus per frame for the first pass diff -r bab912d08349 -r 2dd5aded9e19 source/Lib/TLibEncoder/TEncCu.cpp --- a/source/Lib/TLibEncoder/TEncCu.cpp Wed Jun 25 22:49:38 2014 +0530 +++ b/source/Lib/TLibEncoder/TEncCu.cpp Thu Jun 26 17:49:26 2014 +0530 @@ -341,6 +341,7 @@ do { m_log-totalCu++; +m_log-rowIntraCuCnt++; part = cu-getDepth(i); int next = numPartition (part * 2); if (part == g_maxCUDepth - 1 cu-getPartitionSize(i) != SIZE_2Nx2N) @@ -383,6 +384,7 @@ if (cu-isSkipped(i)) { m_log-cntSkipCu[part]++; +m_log-rowSkipCuCnt++; I suspect there's an impedance mismatch here between AVC and HEVC. For x264 these inter/intra/skip decisions are for the whole MB, but for us these decisions are made at each CU at every level of the quad-tree. yea, you are right, I missed that. we need to compute the inter,intra and skip cus of the frame in terms of the number of 16x16 blocks to be used for the 2nd pass. We can keep such statistics but they would need to be weighted per depth - perhaps multiplied by the number of pixels in the coding unit so that at the end of the frame you know what percentages of the frame were inter, intra, or merge coded. } else { @@ -390,6 +392,7 @@ if (cu-getPredictionMode(0) == MODE_INTER) { m_log-cntInter[part]++; +m_log-rowInterCuCnt++; if (cu-getPartitionSize(0) AMP_ID) m_log-cuInterDistribution[part][cu-getPartitionSize(0)]++; else @@ -397,6 +400,7 @@ } else if (cu-getPredictionMode(0) == MODE_INTRA) { +m_log-rowIntraCuCnt++; if (part == g_maxCUDepth - 1 cu-getPartitionSize(0) == SIZE_NxN) { m_log-cntIntraNxN++; diff -r bab912d08349 -r 2dd5aded9e19 source/Lib/TLibEncoder/TEncCu.h --- a/source/Lib/TLibEncoder/TEncCu.h Wed Jun 25 22:49:38 2014 +0530 +++ b/source/Lib/TLibEncoder/TEncCu.h Thu Jun 26 17:49:26 2014 +0530 @@ -65,7 +65,9 @@ uint64_t cntSkipCu[4]; uint64_t cntTotalCu[4]; uint64_t totalCu; - +uint32_t rowInterCuCnt; +uint32_t rowIntraCuCnt; +uint32_t rowSkipCuCnt; StatisticLog() { memset(this, 0, sizeof(StatisticLog)); diff -r bab912d08349 -r 2dd5aded9e19 source/encoder/frameencoder.cpp --- a/source/encoder/frameencoder.cpp Wed Jun 25 22:49:38 2014 +0530 +++ b/source/encoder/frameencoder.cpp Thu Jun 26 17:49:26 2014 +0530 @@ -1037,6 +1037,14 @@ enableRowFilter(i); } } + +// copy no. of intra, inter Cu cnt per row into frame stats +m_frame-m_stats.cuCount_i += tld.m_cuCoder.m_log-rowIntraCuCnt; +m_frame-m_stats.cuCount_p += tld.m_cuCoder.m_log-rowInterCuCnt; +m_frame-m_stats.cuCount_skip += tld.m_cuCoder.m_log-rowSkipCuCnt; +//clear the row cu data from thread local object +tld.m_cuCoder.m_log-rowIntraCuCnt = tld.m_cuCoder.m_log-rowInterCuCnt = tld.m_cuCoder.m_log-rowSkipCuCnt = 0; + m_totalTime += x265_mdate() - startTime; curRow.m_busy = false; } ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel -- Steve Borho ___ 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
Re: [x265] [PATCH 2 of 3] rc: accumulate mv bits, coeff bits per frame
# HG changeset patch # User Aarthi Thirumalaiaar...@multicorewareinc.com # Date 1403808050 -19800 # Fri Jun 27 00:10:50 2014 +0530 # Node ID 11ddf73017d44933090a8943f4fc5098b231b56d # Parent 1b669c33ff3a8d8f6c9bd1e18979c009baed2433 rc: accumulate mv bits, coeff bits per frame diff -r 1b669c33ff3a -r 11ddf73017d4 source/Lib/TLibEncoder/TEncCu.cpp --- a/source/Lib/TLibEncoder/TEncCu.cpp Wed Jun 25 22:46:45 2014 +0530 +++ b/source/Lib/TLibEncoder/TEncCu.cpp Fri Jun 27 00:10:50 2014 +0530 @@ -1365,12 +1365,14 @@ m_entropyCoder-encodePredMode(outTempCU, 0); m_entropyCoder-encodePartSize(outTempCU, 0, depth); m_entropyCoder-encodePredInfo(outTempCU, 0); +outTempCU-m_mvBits = m_entropyCoder-getNumberOfWrittenBits(); // Encode Coefficients bool bCodeDQP = getdQPFlag(); m_entropyCoder-encodeCoeff(outTempCU, 0, depth, outTempCU-getCUSize(0), bCodeDQP); m_rdGoOnSbacCoder-store(m_rdSbacCoders[depth][CI_TEMP_BEST]); outTempCU-m_totalBits = m_entropyCoder-getNumberOfWrittenBits(); +outTempCU-m_coeffBits = outTempCU-m_totalBits - outTempCU-m_mvBits; if (m_rdCost-psyRdEnabled()) { @@ -1411,12 +1413,14 @@ m_entropyCoder-encodePredMode(outTempCU, 0); m_entropyCoder-encodePartSize(outTempCU, 0, depth); m_entropyCoder-encodePredInfo(outTempCU, 0); +outTempCU-m_mvBits = m_entropyCoder-getNumberOfWrittenBits(); // Encode Coefficients bool bCodeDQP = getdQPFlag(); m_entropyCoder-encodeCoeff(outTempCU, 0, depth, outTempCU-getCUSize(0), bCodeDQP); m_rdGoOnSbacCoder-store(m_rdSbacCoders[depth][CI_TEMP_BEST]); outTempCU-m_totalBits = m_entropyCoder-getNumberOfWrittenBits(); +outTempCU-m_coeffBits = outTempCU-m_totalBits - outTempCU-m_mvBits; if (m_rdCost-psyRdEnabled()) { diff -r 1b669c33ff3a -r 11ddf73017d4 source/Lib/TLibEncoder/TEncSearch.cpp --- a/source/Lib/TLibEncoder/TEncSearch.cpp Wed Jun 25 22:46:45 2014 +0530 +++ b/source/Lib/TLibEncoder/TEncSearch.cpp Fri Jun 27 00:10:50 2014 +0530 @@ -4059,6 +4059,7 @@ } m_entropyCoder-encodeSkipFlag(cu, 0); m_entropyCoder-encodeMergeIndex(cu, 0); +cu-m_mvBits = m_entropyCoder-getNumberOfWrittenBits(); return m_entropyCoder-getNumberOfWrittenBits(); } else @@ -4073,8 +4074,11 @@ m_entropyCoder-encodePartSize(cu, 0, cu-getDepth(0)); m_entropyCoder-encodePredInfo(cu, 0); bool bDummy = false; +cu-m_mvBits = m_entropyCoder-getNumberOfWrittenBits(); m_entropyCoder-encodeCoeff(cu, 0, cu-getDepth(0), cu-getCUSize(0), bDummy); -return m_entropyCoder-getNumberOfWrittenBits(); +int totalBits = m_entropyCoder-getNumberOfWrittenBits(); +cu-m_coeffBits = totalBits - cu-m_mvBits; +return totalBits; } } diff -r 1b669c33ff3a -r 11ddf73017d4 source/encoder/compress.cpp --- a/source/encoder/compress.cpp Wed Jun 25 22:46:45 2014 +0530 +++ b/source/encoder/compress.cpp Fri Jun 27 00:10:50 2014 +0530 @@ -63,6 +63,7 @@ m_entropyCoder-encodePredMode(cu, 0); m_entropyCoder-encodePartSize(cu, 0, depth); m_entropyCoder-encodePredInfo(cu, 0); +cu-m_mvBits += m_entropyCoder-getNumberOfWrittenBits(); // Encode Coefficients bool bCodeDQP = getdQPFlag(); @@ -71,6 +72,7 @@ m_rdGoOnSbacCoder-store(m_rdSbacCoders[depth][CI_TEMP_BEST]); cu-m_totalBits = m_entropyCoder-getNumberOfWrittenBits(); +cu-m_coeffBits = cu-m_totalBits - cu-m_mvBits; if (m_rdCost-psyRdEnabled()) { int part = g_convertToBit[cu-getCUSize(0)]; diff -r 1b669c33ff3a -r 11ddf73017d4 source/encoder/frameencoder.cpp --- a/source/encoder/frameencoder.cpp Wed Jun 25 22:46:45 2014 +0530 +++ b/source/encoder/frameencoder.cpp Fri Jun 27 00:10:50 2014 +0530 @@ -694,6 +694,11 @@ // Store probabilities of second LCU in line into buffer if (col == 1 m_param-bEnableWavefront) getBufferSBac(lin)-loadContexts(getSbacCoder(subStrm)); + +// Collect Frame Stats for 2 pass +m_frame-m_stats.mvBits += cu-m_mvBits; +m_frame-m_stats.coeffBits += cu-m_coeffBits; +m_frame-m_stats.miscBits += cu-m_totalBits - (cu-m_mvBits + cu-m_coeffBits); } if (slice-getPPS()-getCabacInitPresentFlag()) On Thu, Jun 26, 2014 at 4:25 PM, Deepthi Nandakumar deep...@multicorewareinc.com wrote: Pls fix extra newlines and whitespace nits. On Wed, Jun 25, 2014 at 10:54 PM, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalaiaar...@multicorewareinc.com # Date 1403716735 -19800 # Wed Jun 25 22:48:55 2014 +0530 # Node ID 0995efabd44470c1192994e1aceeb40ae606467f # Parent e71e34d02de228eab43edf1910a71a44417d rc: accumulate mv bits, coeff bits per frame. diff -r e71e34d02d77 -r 0995efabd444 source/Lib/TLibEncoder/TEncCu.cpp --- a/source/Lib/TLibEncoder/TEncCu.cpp Wed Jun 25 22:46:45 2014 +0530 +++ b/source/Lib/TLibEncoder/TEncCu.cpp Wed Jun 25 22:48:55
Re: [x265] [PATCH 2 of 3] lambda: change chroma lambda distortion weighting to resemble x264
On Mon, Jun 16, 2014 at 4:49 PM, deep...@multicorewareinc.com wrote: # HG changeset patch # User Deepthi Nandakumar deep...@multicorewareinc.com # Date 1402916716 -19800 # Mon Jun 16 16:35:16 2014 +0530 # Node ID 4d76a9c8b5abbf143e5869d55cf80a8816d99a68 # Parent ff3a85f715d43e2c21aec295426ae9dbe7c03d75 lambda: change chroma lambda distortion weighting to resemble x264. 1. x264 scales the chroma distortion by a factor derived from a lambda offset table when psyRd is enabled. 2. This patch also removes the separate Cb and Cr distortion weights that were carried over from HM, and replaces it with 256 when psy-rd is disabled, and the above-mentioned lambda offset when it is enabled. diff -r ff3a85f715d4 -r 4d76a9c8b5ab source/Lib/TLibEncoder/TEncSearch.cpp --- a/source/Lib/TLibEncoder/TEncSearch.cpp Mon Jun 16 16:12:00 2014 +0530 +++ b/source/Lib/TLibEncoder/TEncSearch.cpp Mon Jun 16 16:35:16 2014 +0530 @@ -143,16 +143,22 @@ return false; } -void TEncSearch::setQP(int qp, double crWeight, double cbWeight) +void TEncSearch::setQP(int qp) { -double lambda2 = x265_lambda2_tab[qp]; -double chromaLambda = lambda2 / crWeight; +double lambda2 = x265_lambda2_tab[qp]; + +#define SPEC_QP(x) X265_MIN(x, QP_MAX_SPEC) +int effective_chroma_qp = chroma_qp_table[SPEC_QP(qp)] + X265_MAX(qp - QP_MAX_SPEC, 0); +double chromaLambda = x265_lambda2_tab[effective_chroma_qp]; +int chroma_offset_idx = X265_MIN (qp - effective_chroma_qp + 12, MAX_CHROMA_LAMBDA_OFFSET); +uint64_t chromaWeight = m_rdCost-psyRdEnabled() ? x265_chroma_lambda2_offset_tab[chroma_offset_idx] : 256; +#undef SPEC_QP Luma to chroma qp mapping should be done as mentioned in the HEVC standards. the array chroma_qp_table[] is written according to H.264 spec. We cant be using that for HEVC. g_chromaScale[chFmt][qpc]) - gives the correct mapping of chroma qp as per HEVC spec. chroma qp needs to be obtained from luma qp (0-69) before it can be clipped to QP_MAX_SPEC for HEVC. m_me.setQP(qp); m_trQuant-setLambda(lambda2, chromaLambda); m_rdCost-setLambda(lambda2, x265_lambda_tab[qp]); -m_rdCost-setCbDistortionWeight(cbWeight); -m_rdCost-setCrDistortionWeight(crWeight); +m_rdCost-setCbDistortionWeight(chromaWeight); +m_rdCost-setCrDistortionWeight(chromaWeight); } void TEncSearch::xEncSubdivCbfQT(TComDataCU* cu, uint32_t trDepth, uint32_t absPartIdx, uint32_t absPartIdxStep, uint32_t width, uint32_t height, bool bLuma, bool bChroma) diff -r ff3a85f715d4 -r 4d76a9c8b5ab source/Lib/TLibEncoder/TEncSearch.h --- a/source/Lib/TLibEncoder/TEncSearch.h Mon Jun 16 16:12:00 2014 +0530 +++ b/source/Lib/TLibEncoder/TEncSearch.h Mon Jun 16 16:35:16 2014 +0530 @@ -142,7 +142,7 @@ void setRDGoOnSbacCoder(TEncSbac* rdGoOnSbacCoder) { m_rdGoOnSbacCoder = rdGoOnSbacCoder; } -void setQP(int QP, double crWeight, double cbWeight); +void setQP(int QP); TEncSearch(); virtual ~TEncSearch(); diff -r ff3a85f715d4 -r 4d76a9c8b5ab source/encoder/frameencoder.cpp --- a/source/encoder/frameencoder.cpp Mon Jun 16 16:12:00 2014 +0530 +++ b/source/encoder/frameencoder.cpp Mon Jun 16 16:35:16 2014 +0530 @@ -363,22 +363,8 @@ } void FrameEncoder::setLambda(int qp, int row) -{ -TComSlice* slice = m_pic-getSlice(); -int chFmt = slice-getSPS()-getChromaFormatIdc(); - -// for RDO -// in RdCost there is only one lambda because the luma and chroma bits are not separated, -// instead we weight the distortion of chroma. -int chromaQPOffset = slice-getPPS()-getChromaCbQpOffset() + slice-getSliceQpDeltaCb(); -int qpc = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset); -double cbWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset - -chromaQPOffset = slice-getPPS()-getChromaCrQpOffset() + slice-getSliceQpDeltaCr(); -qpc = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset); -double crWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset - -m_rows[row].m_search.setQP(qp, crWeight, cbWeight); +{ +m_rows[row].m_search.setQP(qp); } void FrameEncoder::compressFrame() @@ -387,7 +373,6 @@ int64_t startCompressTime = x265_mdate(); TEncEntropy* entropyCoder = getEntropyCoder(0); TComSlice* slice = m_pic-getSlice(); -int chFmt = slice-getSPS()-getChromaFormatIdc(); int totalCoded= (int)m_top-m_encodedFrameNum - 1; m_nalCount = 0; @@ -515,21 +500,13 @@ } int qp = slice-getSliceQp(); - -// for RDO -// in RdCost there is only one lambda because the luma and chroma bits are not separated, -// instead we weight the distortion of chroma. -int qpc; -int chromaQPOffset =
Re: [x265] [PATCH 2 of 3] lambda: change chroma lambda distortion weighting to resemble x264
pg 155 of HEVC standard: Table 8-9 – Specification of QpC as a function of qPi qPi 30 30 31 32 33 34 35 36 37 38 39 40 41 42 43 43 QpC = qPi 29 30 31 32 33 33 34 34 35 35 36 36 37 37 = qPi − 6 AFAIK, values in g_chromaScale[CHROMA_420] follows the spec exactly. not sure how the values for other chroma formats were derived. On Mon, Jun 16, 2014 at 7:42 PM, Deepthi Nandakumar deep...@multicorewareinc.com wrote: Agreed, thats what I thought too. But the g_chromatable is not in the HEVC spec at all, it's just carried over from HM. On Jun 16, 2014 5:38 PM, Aarthi Priya Thirumalai aar...@multicorewareinc.com wrote: On Mon, Jun 16, 2014 at 4:49 PM, deep...@multicorewareinc.com wrote: # HG changeset patch # User Deepthi Nandakumar deep...@multicorewareinc.com # Date 1402916716 -19800 # Mon Jun 16 16:35:16 2014 +0530 # Node ID 4d76a9c8b5abbf143e5869d55cf80a8816d99a68 # Parent ff3a85f715d43e2c21aec295426ae9dbe7c03d75 lambda: change chroma lambda distortion weighting to resemble x264. 1. x264 scales the chroma distortion by a factor derived from a lambda offset table when psyRd is enabled. 2. This patch also removes the separate Cb and Cr distortion weights that were carried over from HM, and replaces it with 256 when psy-rd is disabled, and the above-mentioned lambda offset when it is enabled. diff -r ff3a85f715d4 -r 4d76a9c8b5ab source/Lib/TLibEncoder/TEncSearch.cpp --- a/source/Lib/TLibEncoder/TEncSearch.cpp Mon Jun 16 16:12:00 2014 +0530 +++ b/source/Lib/TLibEncoder/TEncSearch.cpp Mon Jun 16 16:35:16 2014 +0530 @@ -143,16 +143,22 @@ return false; } -void TEncSearch::setQP(int qp, double crWeight, double cbWeight) +void TEncSearch::setQP(int qp) { -double lambda2 = x265_lambda2_tab[qp]; -double chromaLambda = lambda2 / crWeight; +double lambda2 = x265_lambda2_tab[qp]; + +#define SPEC_QP(x) X265_MIN(x, QP_MAX_SPEC) +int effective_chroma_qp = chroma_qp_table[SPEC_QP(qp)] + X265_MAX(qp - QP_MAX_SPEC, 0); +double chromaLambda = x265_lambda2_tab[effective_chroma_qp]; +int chroma_offset_idx = X265_MIN (qp - effective_chroma_qp + 12, MAX_CHROMA_LAMBDA_OFFSET); +uint64_t chromaWeight = m_rdCost-psyRdEnabled() ? x265_chroma_lambda2_offset_tab[chroma_offset_idx] : 256; +#undef SPEC_QP Luma to chroma qp mapping should be done as mentioned in the HEVC standards. the array chroma_qp_table[] is written according to H.264 spec. We cant be using that for HEVC. g_chromaScale[chFmt][qpc]) - gives the correct mapping of chroma qp as per HEVC spec. chroma qp needs to be obtained from luma qp (0-69) before it can be clipped to QP_MAX_SPEC for HEVC. m_me.setQP(qp); m_trQuant-setLambda(lambda2, chromaLambda); m_rdCost-setLambda(lambda2, x265_lambda_tab[qp]); -m_rdCost-setCbDistortionWeight(cbWeight); -m_rdCost-setCrDistortionWeight(crWeight); +m_rdCost-setCbDistortionWeight(chromaWeight); +m_rdCost-setCrDistortionWeight(chromaWeight); } void TEncSearch::xEncSubdivCbfQT(TComDataCU* cu, uint32_t trDepth, uint32_t absPartIdx, uint32_t absPartIdxStep, uint32_t width, uint32_t height, bool bLuma, bool bChroma) diff -r ff3a85f715d4 -r 4d76a9c8b5ab source/Lib/TLibEncoder/TEncSearch.h --- a/source/Lib/TLibEncoder/TEncSearch.h Mon Jun 16 16:12:00 2014 +0530 +++ b/source/Lib/TLibEncoder/TEncSearch.h Mon Jun 16 16:35:16 2014 +0530 @@ -142,7 +142,7 @@ void setRDGoOnSbacCoder(TEncSbac* rdGoOnSbacCoder) { m_rdGoOnSbacCoder = rdGoOnSbacCoder; } -void setQP(int QP, double crWeight, double cbWeight); +void setQP(int QP); TEncSearch(); virtual ~TEncSearch(); diff -r ff3a85f715d4 -r 4d76a9c8b5ab source/encoder/frameencoder.cpp --- a/source/encoder/frameencoder.cpp Mon Jun 16 16:12:00 2014 +0530 +++ b/source/encoder/frameencoder.cpp Mon Jun 16 16:35:16 2014 +0530 @@ -363,22 +363,8 @@ } void FrameEncoder::setLambda(int qp, int row) -{ -TComSlice* slice = m_pic-getSlice(); -int chFmt = slice-getSPS()-getChromaFormatIdc(); - -// for RDO -// in RdCost there is only one lambda because the luma and chroma bits are not separated, -// instead we weight the distortion of chroma. -int chromaQPOffset = slice-getPPS()-getChromaCbQpOffset() + slice-getSliceQpDeltaCb(); -int qpc = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset); -double cbWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset - -chromaQPOffset = slice-getPPS()-getChromaCrQpOffset() + slice-getSliceQpDeltaCr(); -qpc = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset); -double crWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset - -m_rows[row].m_search.setQP(qp, crWeight
Re: [x265] [PATCH 4 of 6] rc: add 2 pass states in RateControl
On Mon, Jun 16, 2014 at 9:43 AM, Steve Borho st...@borho.org wrote: On Sun, Jun 15, 2014 at 1:50 PM, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalaiaar...@multicorewareinc.com # Date 1402857908 -19800 # Mon Jun 16 00:15:08 2014 +0530 # Node ID 9e0a1f70169df85350507de83c27eeae172e7547 # Parent 5c2aee7700a3e222989fadabcb9ba9b1b3291fbd rc: add 2 pass states in RateControl diff -r 5c2aee7700a3 -r 9e0a1f70169d source/encoder/ratecontrol.h --- a/source/encoder/ratecontrol.h Mon Jun 16 00:04:10 2014 +0530 +++ b/source/encoder/ratecontrol.h Mon Jun 16 00:15:08 2014 +0530 @@ -137,6 +137,30 @@ double m_nominalRemovalTime; double m_prevCpbFinalAT; +/*2 pass */ white-space +bool m_2pass; +FILE *m_statFileOut; +char *m_statFileTmpname; +FILE *m_cutreeStatFileOut; +char *m_cutreeStatFileTmpname; +char *m_cbtreeStatFileName; +FILE *m_cutreeStatFileIn; are filenames required here? atleast these two char *m_statFileTmpname;char *m_cutreeStatFileTmpname; need to be stored, so that they can be used to rename those files back at the end of the encode - during those intermediate passes where both inputStatFile and outputStatFile may share the same name. + +struct +{ +uint16_t *qpBuffer[2]; /* Global buffers for converting MB-tree quantizer data. */ +int qpbufPos; /* In order to handle pyramid reordering, QP buffer acts as a stack. +* This value is the current position (0 or 1). */ +int srcCuCount; +/* For rescaling */ +int rescaleEnabled; +float *scaleBuffer[2]; /* Intermediate buffers */ +int filtersize[2]; /* filter size (H/V) */ +float *coeffs[2]; +int *pos[2]; +int srcdim[2]; /* Source dimensions (W/H) */ +} m_cuTreeStats; + RateControl(x265_param *p); // to be called for each frame to process RateControl and set QP ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel -- Steve Borho ___ 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
Re: [x265] [PATCH] ratecontrol: improve visual quality and bitrate savings in ABR
initially both frameNumThreads and m_totalFrameThreads are set to same value specificed by user. So, we are always creating frameEncoder objects, frameNumThreads holds actual frame thread count. Only when we begin to encode, we change the value n within that second we reset it to orig num of frame threads. So , the destroy func called at very end can use frameNumThreads safely. Logically, There shouldn't be memory leaks here.. On May 29, 2014 11:52 PM, Steve Borho st...@borho.org wrote: On Thu, May 29, 2014 at 1:10 PM, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1401386381 -19800 # Thu May 29 23:29:41 2014 +0530 # Node ID cbefd4760814f85da2f805781177a1fade437709 # Parent e9776dfd1471ec6691276518007b725095ab6d52 ratecontrol: improve visual quality and bitrate savings in ABR. Try to prevent ABR over-compensation after I frames by amortizing the cost over the next few frames; Improve ABR quality with frame parallelism - enable frame parallelism only after first few P frames to prevent excessive qp fluctuations. Fix initial I frame qp. when cu tree is enabled, the qp decided arbitrarily is too low. This causes a huge qp spike in immediate P frames.Tuned cplxrSum for intial I frame so that a more appropriate qp is chosen. diff -r e9776dfd1471 -r cbefd4760814 source/encoder/encoder.cpp --- a/source/encoder/encoder.cppWed May 28 20:39:40 2014 -0500 +++ b/source/encoder/encoder.cppThu May 29 23:29:41 2014 +0530 @@ -186,6 +186,7 @@ } m_lookahead-init(); m_encodeStartTime = x265_mdate(); +m_totalFrameThreads = param-frameNumThreads; } int Encoder::getStreamHeaders(NALUnitEBSP **nalunits) @@ -323,6 +324,20 @@ if (flush) m_lookahead-flush(); +if (param-rc.rateControlMode == X265_RC_ABR) +{ +// delay frame parallelism for non-VBV ABR +if (m_pocLast == 0 !param-rc.vbvBufferSize !param-rc.vbvMaxBitrate) +param-frameNumThreads = 1; +else if (param-frameNumThreads != m_totalFrameThreads) +{ +// re-enable frame parallelism after the first few P frames are encoded +uint32_t frameCnt = (uint32_t)((0.5 * param-fpsNum / param-fpsDenom) / (param-bframes + 1)); +if (m_analyzeP.m_numPics frameCnt) +param-frameNumThreads = m_totalFrameThreads; +} +} There a few places where param-frameNumThreads is used that should be modified to use m_totalFrameThreads instead. In particular, the encoder destroy() function and in the frame encoder and other places which peek at this param to determine if frame parallelism is enabled in order to determine if the ME search range is restricted. This could lead to non-determinism or memory leaks. + FrameEncoder *curEncoder = m_frameEncoder[m_curEncoder]; m_curEncoder = (m_curEncoder + 1) % param-frameNumThreads; int ret = 0; diff -r e9776dfd1471 -r cbefd4760814 source/encoder/encoder.h --- a/source/encoder/encoder.h Wed May 28 20:39:40 2014 -0500 +++ b/source/encoder/encoder.h Thu May 29 23:29:41 2014 +0530 @@ -90,6 +90,7 @@ DPB* m_dpb; /* frame parallelism */ intm_curEncoder; +intm_totalFrameThreads; /* Collect statistics globally */ EncStats m_analyzeAll; diff -r e9776dfd1471 -r cbefd4760814 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cppWed May 28 20:39:40 2014 -0500 +++ b/source/encoder/ratecontrol.cppThu May 29 23:29:41 2014 +0530 @@ -30,6 +30,10 @@ using namespace x265; +/* Amortize the partial cost of I frames over the next N frames */ +const double RateControl::amortizeFraction = 0.85; +const int RateControl::amortizeFrames = 75; + /* Compute variance to derive AC energy of each block */ static inline uint32_t acEnergyVar(TComPic *pic, uint64_t sum_ssd, int shift, int i) { @@ -204,6 +208,8 @@ qCompress = param-rc.qCompress; // validate for param-rc, maybe it is need to add a function like x265_parameters_valiate() +residualFrames = 0; +residualCost = 0; param-rc.rfConstant = Clip3((double)-QP_BD_OFFSET, (double)51, param-rc.rfConstant); param-rc.rfConstantMax = Clip3((double)-QP_BD_OFFSET, (double)51, param-rc.rfConstantMax); rateFactorMaxIncrement = 0; @@ -316,7 +322,7 @@ { /* Adjust the first frame in order to stabilize the quality level compared to the rest */ #define ABR_INIT_QP_MIN (24 + QP_BD_OFFSET) -#define ABR_INIT_QP_MAX (34 + QP_BD_OFFSET) +#define ABR_INIT_QP_MAX (40 + QP_BD_OFFSET) } else if (param-rc.rateControlMode == X265_RC_CRF) { @@ -353,9 +359,12 @@ { totalBits = 0; framesDone = 0; - +double tuneCplxFactor = 1; +/* 720p
Re: [x265] [PATCH] x265: implemented crf-min that specifies a minimum rate factor value for encode
On Thu, May 8, 2014 at 10:39 AM, g...@multicorewareinc.com wrote: # HG changeset patch # User Gopu Govindaswamy # Date 1399524053 -19800 # Thu May 08 10:10:53 2014 +0530 # Node ID 7a3657ff29e24b7832002b76b3f9096736d20a36 # Parent 6494bb2e64253fc0f9413b88933634d1f37c4881 x265: implemented crf-min that specifies a minimum rate factor value for encode diff -r 6494bb2e6425 -r 7a3657ff29e2 source/common/param.cpp --- a/source/common/param.cpp Wed May 07 14:03:25 2014 -0500 +++ b/source/common/param.cpp Thu May 08 10:10:53 2014 +0530 @@ -604,6 +604,7 @@ OPT(vbv-bufsize) p-rc.vbvBufferSize = atoi(value); OPT(vbv-init)p-rc.vbvBufferInit = atof(value); OPT(crf-max) p-rc.rfConstantMax = atof(value); +OPT(crf-min) p-rc.rfConstantMin = atoi(value); OPT(crf) { p-rc.rfConstant = atof(value); diff -r 6494bb2e6425 -r 7a3657ff29e2 source/encoder/encoder.cpp --- a/source/encoder/encoder.cppWed May 07 14:03:25 2014 -0500 +++ b/source/encoder/encoder.cppThu May 08 10:10:53 2014 +0530 @@ -1342,6 +1342,12 @@ x265_log(p, X265_LOG_WARNING, Support for interlaced video is experimental\n); } +if (p-rc.rfConstantMin p-rc.rfConstant) +{ +x265_log(param, X265_LOG_WARNING, CRF min must be less than CRF\n); +p-rc.rfConstantMin = 0; +} + m_bframeDelay = p-bframes ? (p-bBPyramid ? 2 : 1) : 0; //== Coding Tools diff -r 6494bb2e6425 -r 7a3657ff29e2 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cppWed May 07 14:03:25 2014 -0500 +++ b/source/encoder/ratecontrol.cppThu May 08 10:10:53 2014 +0530 @@ -207,6 +207,7 @@ param-rc.rfConstant = Clip3((double)-QP_BD_OFFSET, (double)51, param-rc.rfConstant); param-rc.rfConstantMax = Clip3((double)-QP_BD_OFFSET, (double)51, param-rc.rfConstantMax); rateFactorMaxIncrement = 0; +rateFactorMaxDecrement = 0; if (param-rc.rateControlMode == X265_RC_CRF) { @@ -226,6 +227,8 @@ rateFactorMaxIncrement = 0; } } +if (param-rc.rfConstantMin) +rateFactorMaxDecrement = param-rc.rfConstant - param-rc.rfConstantMin; } isAbr = param-rc.rateControlMode != X265_RC_CQP; // later add 2pass option @@ -851,10 +854,15 @@ /* tweak quality based on difference from predicted size */ double prevRowQp = qpVbv; double qpAbsoluteMax = MAX_MAX_QP; +double qpAbsoluteMin = MIN_QP; if (rateFactorMaxIncrement) qpAbsoluteMax = X265_MIN(qpAbsoluteMax, rce-qpNoVbv + rateFactorMaxIncrement); + +if (rateFactorMaxDecrement) +qpAbsoluteMin = X265_MAX(qpAbsoluteMin, rce-qpNoVbv - rateFactorMaxIncrement); + should not the above line be maximum of qpAbsoluteMin and qpNoVbv - rateFactorMaxDecrement? double qpMax = X265_MIN(prevRowQp + param-rc.qpStep, qpAbsoluteMax); -double qpMin = X265_MAX(prevRowQp - param-rc.qpStep, MIN_QP); +double qpMin = X265_MAX(prevRowQp - param-rc.qpStep, qpAbsoluteMin); double stepSize = 0.5; double bufferLeftPlanned = rce-bufferFill - rce-frameSizePlanned; @@ -922,6 +930,12 @@ qpVbv = Clip3(prevRowQp + 1.0f, qpMax, (prevRowQp + qpVbv) * 0.5); return -1; } + +if (qpVbv qpMin prevRowQp qpMin canReencodeRow) +{ +qpVbv = Clip3(prevRowQp + 1.0f, (prevRowQp + qpVbv) * 0.5, qpMin); +return -1; +} i think the above condition needs to be executed only when param-rc.rfConstantMin is set. else we dont need to reencode if qp falls lesser in normal scenarios. also, the clip should be done as Clip3(qpMin, (prevRowQp - qpVbv) * 0.5, prevRowQp - 1.0f); - find a value between qpMin and prevRowQp. } else { diff -r 6494bb2e6425 -r 7a3657ff29e2 source/encoder/ratecontrol.h --- a/source/encoder/ratecontrol.h Wed May 07 14:03:25 2014 -0500 +++ b/source/encoder/ratecontrol.h Thu May 08 10:10:53 2014 +0530 @@ -96,6 +96,7 @@ double vbvMinRate; /* in kbps */ bool singleFrameVbv; double rateFactorMaxIncrement; /* Don't allow RF above (CRF + this value). */ +double rateFactorMaxDecrement; /* don't allow RF below (this value). */ bool isVbv; Predictor pred[5]; Predictor predBfromP; diff -r 6494bb2e6425 -r 7a3657ff29e2 source/x265.cpp --- a/source/x265.cpp Wed May 07 14:03:25 2014 -0500 +++ b/source/x265.cpp Thu May 08 10:10:53 2014 +0530 @@ -129,6 +129,7 @@ { weightb, no_argument, NULL, 0 }, { crf,required_argument, NULL, 0 }, { crf-max,required_argument, NULL, 0 }, +{ crf-min,required_argument, NULL, 0 }, { vbv-maxrate,required_argument, NULL, 0 }, { vbv-bufsize,required_argument, NULL, 0 }, { vbv-init, required_argument, NULL, 0 }, @@ -360,6 +361,8 @@
Re: [x265] [PATCH 1 of 2] slicetype: update the lowresCosts and intraCosts when cutree is enabled
This is the correct patch. # HG changeset patch # User Aarthi Thirumalai # Date 1399381528 -19800 # Tue May 06 18:35:28 2014 +0530 # Node ID 65cb5558ad4a474114aa95d45a7c155ea16f0008 # Parent a6c7325e6ee60827142c18eaf4141e0eb4d6d98a slicetype: update the lowresCosts and intraCosts when cutree is enabled diff -r a6c7325e6ee6 -r 65cb5558ad4a source/encoder/frameencoder.cpp --- a/source/encoder/frameencoder.cpp Tue May 06 15:31:18 2014 +0530 +++ b/source/encoder/frameencoder.cpp Tue May 06 18:35:28 2014 +0530 @@ -1261,15 +1261,8 @@ qp_offset += qpoffs[idx]; if (bIsVbv) { -uint16_t lowresCuCost = m_pic-m_lowres.lowresCostForRc[idx] LOWRES_COST_MASK; -uint16_t intraCuCost = m_pic-m_lowres.intraCost[idx]; -if (m_cfg-param-rc.cuTree) -{ -lowresCuCost = (lowresCuCost * x265_exp2fix8(qpoffs[idx]) + 128) 8; -intraCuCost = (intraCuCost * x265_exp2fix8(qpoffs[idx]) + 128) 8; -} -m_pic-m_cuCostsForVbv[cuAddr] += lowresCuCost; -m_pic-m_intraCuCostsForVbv[cuAddr] += intraCuCost; +m_pic-m_cuCostsForVbv[cuAddr] += m_pic-m_lowres.lowresCostForRc[idx]; +m_pic-m_intraCuCostsForVbv[cuAddr] += m_pic-m_lowres.intraCost[idx]; } cnt++; } diff -r a6c7325e6ee6 -r 65cb5558ad4a source/encoder/slicetype.cpp --- a/source/encoder/slicetype.cpp Tue May 06 15:31:18 2014 +0530 +++ b/source/encoder/slicetype.cpp Tue May 06 18:35:28 2014 +0530 @@ -255,6 +255,7 @@ uint32_t lowresRow = 0, lowresCol = 0, lowresCuIdx = 0, sum = 0; uint32_t scale = param-maxCUSize / (2 * X265_LOWRES_CU_SIZE); uint32_t widthInLowresCu = (uint32_t)widthInCU, heightInLowresCu = (uint32_t)heightInCU; +double *qp_offset =frames[b]-sliceType == X265_TYPE_B ? frames[b]-qpAqOffset : frames[b]-qpOffset; for (uint32_t row = 0; row pic-getFrameHeightInCU(); row++) { @@ -265,9 +266,16 @@ lowresCuIdx = lowresRow * widthInLowresCu; for (lowresCol = 0; lowresCol widthInLowresCu; lowresCol++, lowresCuIdx++) { -sum += pic-m_lowres.lowresCostForRc[lowresCuIdx] LOWRES_COST_MASK; +uint16_t lowresCuCost = pic-m_lowres.lowresCostForRc[lowresCuIdx] LOWRES_COST_MASK; +if (param-rc.cuTree) +{ +lowresCuCost = (lowresCuCost * x265_exp2fix8(qp_offset[lowresCuIdx]) + 128) 8; +uint16_t intraCuCost = pic-m_lowres.intraCost[lowresCuIdx]; +pic-m_lowres.intraCost[lowresCuIdx] = (intraCuCost * x265_exp2fix8(qp_offset[lowresCuIdx]) + 128) 8; +} +pic-m_lowres.lowresCostForRc[lowresCuIdx] = lowresCuCost; +sum += lowresCuCost; } - pic-m_rowSatdForVbv[row] += sum; } } On Tue, May 6, 2014 at 5:15 PM, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1399375233 -19800 # Tue May 06 16:50:33 2014 +0530 # Node ID a3a234d72841f94f605c6075a5531e93f06eaeb6 # Parent 075705aa41a9144bb1a4d7f12d837169767630e1 slicetype: update the lowresCosts and intraCosts when cutree is enabled. diff -r 075705aa41a9 -r a3a234d72841 source/encoder/frameencoder.cpp --- a/source/encoder/frameencoder.cpp Mon May 05 23:26:59 2014 -0500 +++ b/source/encoder/frameencoder.cpp Tue May 06 16:50:33 2014 +0530 @@ -1261,8 +1261,15 @@ qp_offset += qpoffs[idx]; if (bIsVbv) { -m_pic-m_cuCostsForVbv[cuAddr] += m_pic-m_lowres.lowresCostForRc[idx] LOWRES_COST_MASK; -m_pic-m_intraCuCostsForVbv[cuAddr] += m_pic-m_lowres.intraCost[idx]; +uint16_t lowresCuCost = m_pic-m_lowres.lowresCostForRc[idx] LOWRES_COST_MASK; +uint16_t intraCuCost = m_pic-m_lowres.intraCost[idx]; +if (m_cfg-param-rc.cuTree) +{ +lowresCuCost = (lowresCuCost * x265_exp2fix8(qpoffs[idx]) + 128) 8; +intraCuCost = (intraCuCost * x265_exp2fix8(qpoffs[idx]) + 128) 8; +} +m_pic-m_cuCostsForVbv[cuAddr] += lowresCuCost; +m_pic-m_intraCuCostsForVbv[cuAddr] += intraCuCost; } cnt++; } diff -r 075705aa41a9 -r a3a234d72841 source/encoder/slicetype.cpp --- a/source/encoder/slicetype.cpp Mon May 05 23:26:59 2014 -0500 +++ b/source/encoder/slicetype.cpp Tue May 06 16:50:33 2014 +0530 @@ -1141,7 +1141,7 @@ { int64_t score = 0; int *rowSatd = frames[b]-rowSatds[b - p0][p1 - b]; -double *qp_offset = IS_X265_TYPE_B(frames[b]-sliceType) ? frames[b]-qpAqOffset : frames[b]-qpOffset; +
Re: [x265] [PATCH] vbv: clear row diagonal Satd costs, cu Satd costs when vbv row reset is triggered
On Tue, Apr 15, 2014 at 11:31 PM, Steve Borho st...@borho.org wrote: On Tue, Apr 15, 2014 at 11:34 AM, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1397579661 -19800 # Tue Apr 15 22:04:21 2014 +0530 # Node ID bf48002755a3f5593732ca039ad38a3c799da808 # Parent 0a95a6bb0f8e71d7a7d0f8e3803ec2878ad558fe vbv: clear row diagonal Satd costs, cu Satd costs when vbv row reset is triggered. diff -r 0a95a6bb0f8e -r bf48002755a3 source/encoder/frameencoder.cpp --- a/source/encoder/frameencoder.cpp Tue Apr 15 12:34:36 2014 +0900 +++ b/source/encoder/frameencoder.cpp Tue Apr 15 22:04:21 2014 +0530 @@ -1192,6 +1192,8 @@ m_pic-m_qpaRc[r] = 0; m_pic-m_rowEncodedBits[r] = 0; m_pic-m_numEncodedCusPerRow[r] = 0; +m_pic-m_rowDiagSatd[r] = 0; +m_pic-m_rowDiagIntraSatd[r] = 0; } m_bAllRowsStop = false; @@ -1248,6 +1250,13 @@ x265_emms(); double qp = baseQp; +/*clear cuCostsForVbv when vbv row reset is triggered. */ +if (m_pic-m_cuCostsForVbv[cuAddr] 0 || m_pic-m_intraCuCostsForVbv[cuAddr] 0) +{ +m_pic-m_cuCostsForVbv[cuAddr] = 0; +m_pic-m_intraCuCostsForVbv[cuAddr] = 0; +} + Can we just unconditionally clear these two values? yea, we can remove the if condition and clear them always.. they will be normally be 0 at this point unless the cus are again encoded after vbv row resets in which case, we need to clear them necessarily. -- Steve Borho ___ 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
Re: [x265] [PATCH] vbv: log frame-average QPs for VBV; even when AQ is disabled
hello, reminder : this bug-fix is still pending. can we have this patch pushed in to fix the bug, if there is no problems with it? On Tue, Apr 8, 2014 at 8:33 PM, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1396969086 -19800 # Tue Apr 08 20:28:06 2014 +0530 # Node ID cac0dcd5a5c2470194d58057d9decd38da3e4405 # Parent b5caca9954f36fc8e1cfb9e25f96288bf3aa18e2 vbv: log frame-average QPs for VBV; even when AQ is disabled. diff -r b5caca9954f3 -r cac0dcd5a5c2 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cppTue Apr 08 16:13:11 2014 +0530 +++ b/source/encoder/ratecontrol.cppTue Apr 08 20:28:06 2014 +0530 @@ -1027,6 +1027,8 @@ pic-m_avgQpRc /= (pic-getFrameHeightInCU() * pic-getFrameWidthInCU()); rce-qpaRc = pic-m_avgQpRc; +// copy avg RC qp to m_avgQpAq. To print out the correct qp when aq/cutree is disabled. +pic-m_avgQpAq = pic-m_avgQpRc; } if (pic-m_qpaAq) ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
Re: [x265] [PATCH] vbv: enable row resets during vbv when mid-frame qp adjustemets are too high/low
On Tue, Mar 11, 2014 at 2:51 AM, chen chenm...@163.com wrote: + //block current row if previous row is getting reencoded or prev row reference cus are not completed. + ScopedLock self(curRow.m_lock); +if (row 0 (m_rows[row - 1].m_isReencode || m_rows[row].m_completed numCols - 2 m_rows[row - 1].m_completed m_rows[row].m_completed + 2)) +{ +m_rows[row].m_active = false; +m_rows[row].m_busy = false; +m_totalTime = m_totalTime + (x265_mdate() - startTime); +return; +} Seems you use bottomRows to deactive row thread, but most thread will continue to work. May we reset col to 0 for all rows below re-encode row. other Row threads will not be activated because, we block the scheduler in FindJobs() to early out till the flag m_bAllRowsStop is again set false. so until the current row restart again with col 0, the below rows still wait. If we set col to 0 here, for current active row, the for loop continue with col++ only. for (uint32_t col = curRow.m_completed; col numCols; col++) { +//reset current row data if reencoded is turned on this row +if (m_rows[row].m_isReencode == true ) +{ +col = 0; +m_bAllRowsStop = false; +m_rows[row].m_isReencode = false; +} const uint32_t cuAddr = lineStartCUAddr + col; TComDataCU* cu = m_pic-getCU(cuAddr); cu-initCU(m_pic, cuAddr); @@ -1069,16 +1089,26 @@ codeRow.m_entropyCoder.resetEntropy(); TEncSbac *bufSbac = (m_cfg-param-bEnableWavefront col == 0 row 0) ? m_rows[row - 1].m_bufferSbacCoder : NULL; -if ((uint32_t)row = col (row != 0) isVbv) -qpBase = m_pic-getCU(cuAddr - numCols + 1)-m_baseQp; +if(isVbv) +{ +if ((uint32_t)row == 0) +m_pic-m_rowDiagQp[row] = m_pic-m_avgQpRc; + +if ((uint32_t)row = col (row != 0) m_vbvResetTriggerRow != row) +cu-m_baseQp = m_pic-getCU(cuAddr - numCols + 1)-m_baseQp; +else +cu-m_baseQp = m_pic-m_rowDiagQp[row]; +} +else +cu-m_baseQp = m_pic-m_avgQpRc; if (m_cfg-param-rc.aqMode || isVbv) { -int qp = calcQpForCu(m_pic, cuAddr, qpBase); +int qp = calcQpForCu(m_pic, cuAddr, cu-m_baseQp); setLambda(qp, row); qp = X265_MIN(qp, MAX_QP); cu-setQP(0, char(qp)); -cu-m_baseQp = qpBase; + if (m_cfg-param-rc.aqMode) m_pic-m_qpaAq[row] += qp; } @@ -1087,22 +1117,46 @@ { // Update encoded bits, satdCost, baseQP for each CU m_pic-m_rowDiagSatd[row] += m_pic-m_cuCostsForVbv[cuAddr]; +m_pic-m_rowDiagIntraSatd[row] += m_pic-m_intraCuCostsForVbv[cuAddr]; m_pic-m_rowEncodedBits[row] += cu-m_totalBits; m_pic-m_numEncodedCusPerRow[row] = cuAddr; m_pic-m_qpaRc[row] += cu-m_baseQp; -if ((uint32_t)row == col) -m_pic-m_rowDiagQp[row] = qpBase; - // If current block is at row diagonal checkpoint, call vbv ratecontrol. if ((uint32_t)row == col row != 0) { -m_top-m_rateControl-rowDiagonalVbvRateControl(m_pic, row, m_rce, qpBase); +qpBase = cu-m_baseQp; +int reEncode = m_top-m_rateControl-rowDiagonalVbvRateControl(m_pic, row, m_rce, qpBase); qpBase = Clip3((double)MIN_QP, (double)MAX_MAX_QP, qpBase); +m_pic-m_rowDiagQp[row] = qpBase; +m_pic-m_rowDiagQScale[row] = x265_qp2qScale(qpBase); +if (reEncode 0) +{ + m_bAllRowsStop = true; + m_rows[row].m_completed = 0; + m_rows[row].m_isReencode = true; + m_vbvResetTriggerRow = row; + for (int bottomRows = m_numRows - 1; bottomRows = row ; bottomRows--) + { + if (bottomRows!=row) + { + //wait for each row to be idle +while(m_rows[bottomRows].m_active m_rows[bottomRows].m_busy) +GIVE_UP_TIME(); +} +m_rows[bottomRows].m_isReencode = true; +m_rows[bottomRows].m_completed = 0; +m_pic-m_qpaAq[bottomRows] = 0; +m_pic-m_rowEncodedBits[bottomRows] = 0; +m_pic-m_qpaRc[bottomRows] = 0; +m_pic-m_numEncodedCusPerRow[bottomRows] = 0; +} + } } } // Completed CU processing -m_rows[row].m_completed++; +
Re: [x265] [PATCH] vbv: refactor, implement row wise qp updates only if vbv is enabled
On Wed, Feb 26, 2014 at 6:26 AM, Deepthi Nandakumar deep...@multicorewareinc.com wrote: On Mon, Feb 24, 2014 at 6:26 PM, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1393244455 -19800 # Mon Feb 24 17:50:55 2014 +0530 # Node ID dce74082c20eea1f7ef9eb10f9a9addc5e7c7bb7 # Parent 57ce7f0f4f4cbb9acd401751e8bef7b522774e38 vbv: refactor, implement row wise qp updates only if vbv is enabled. diff -r 57ce7f0f4f4c -r dce74082c20e source/encoder/frameencoder.cpp --- a/source/encoder/frameencoder.cpp Thu Feb 20 16:01:28 2014 -0800 +++ b/source/encoder/frameencoder.cpp Mon Feb 24 17:50:55 2014 +0530 @@ -1058,6 +1058,7 @@ const uint32_t numCols = m_pic-getPicSym()-getFrameWidthInCU(); const uint32_t lineStartCUAddr = row * numCols; double qpBase = m_pic-m_avgQpRc; +bool isVbv = m_cfg-param.rc.vbvBufferSize 0 m_cfg-param.rc.vbvMaxBitrate 0; Shouldnt this be just vbvBufferSize 0? Even if max bitrate is not specified, vbv is still enabled? vbv needs both bufsize and max bitrate to function. if ABR and maxrate is not specified, it copies abr bitrate to maxrate internally. else vbv is disabled. for (uint32_t col = curRow.m_completed; col numCols; col++) { const uint32_t cuAddr = lineStartCUAddr + col; @@ -1068,10 +1069,10 @@ codeRow.m_entropyCoder.resetEntropy(); TEncSbac *bufSbac = (m_cfg-param.bEnableWavefront col == 0 row 0) ? m_rows[row - 1].m_bufferSbacCoder : NULL; -if ((uint32_t)row = col (row != 0)) +if ((uint32_t)row = col (row != 0) isVbv) qpBase = m_pic-getCU(cuAddr - numCols + 1)-m_baseQp; -if (m_cfg-param.rc.aqMode || (m_cfg-param.rc.vbvBufferSize 0 m_cfg-param.rc.vbvMaxBitrate 0)) +if (m_cfg-param.rc.aqMode || isVbv) { int qp = calcQpForCu(m_pic, cuAddr, qpBase); setLambda(qp, row); @@ -1080,7 +1081,7 @@ cu-m_baseQp = qpBase; } As I understand, qp = qpBase + average of qp offsets for that CU. This will be the final QP based on which mode decision happens. So, why are we storing qp and qpBase both in cu? we are triggering row wise vbv at each diagonal point and all cus falling to left of diagonal always get their base qp from their top right cu. so we need to track baseQP at each CU. codeRow.processCU(cu, m_pic-getSlice(), bufSbac, m_cfg-param.bEnableWavefront col == 1); -if (m_cfg-param.rc.vbvBufferSize m_cfg-param.rc.vbvMaxBitrate) +if (isVbv) { // Update encoded bits, satdCost, baseQP for each CU m_pic-m_rowDiagSatd[row] += m_pic-m_cuCostsForVbv[cuAddr]; ___ 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 ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
[x265] [PATCH] rc: bug fix - clip qp before setting into TComPic:m_avgQpRc.
# HG changeset patch # User Aarthi Thirumalai # Date 1393263092 -19800 # Mon Feb 24 23:01:32 2014 +0530 # Node ID 2f813eb983817a48aeb483ba2ac28303d5b4d451 # Parent dce74082c20eea1f7ef9eb10f9a9addc5e7c7bb7 rc: bug fix - clip qp before setting into TComPic:m_avgQpRc. This fix resolves Encoder crash caused due to invalid qp being used in each CU. diff -r dce74082c20e -r 2f813eb98381 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Mon Feb 24 17:50:55 2014 +0530 +++ b/source/encoder/ratecontrol.cpp Mon Feb 24 23:01:32 2014 +0530 @@ -409,7 +409,8 @@ /* Update rce for use in rate control VBV later */ rce-lastSatd = currentSatd; double q = qScale2qp(rateEstimateQscale(pic, rce)); -qp = Clip3(MIN_QP, MAX_MAX_QP, (int)(q + 0.5)); +q = Clip3((double)MIN_QP, (double)MAX_MAX_QP, q); +qp = int(q + 0.5); rce-qpaRc = pic-m_avgQpRc = q; /* copy value of lastRceq into thread local rce struct *to be used in RateControlEnd() */ rce-qRceq = lastRceq; @@ -585,10 +586,10 @@ if (qCompress != 1 framesDone == 0) q = qp2qScale(ABR_INIT_QP) / fabs(cfg-param.rc.ipFactor); } -qpNoVbv = qScale2qp(q); double lmin1 = lmin[sliceType]; double lmax1 = lmax[sliceType]; q = Clip3(lmin1, lmax1, q); +qpNoVbv = qScale2qp(q); q = clipQscale(pic, q); On Mon, Feb 24, 2014 at 10:38 PM, Derek Buitenhuis derek.buitenh...@gmail.com wrote: On 2/24/2014 12:56 PM, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1393244587 -19800 # Mon Feb 24 17:53:07 2014 +0530 # Node ID 3abef12d5b47106005c813bfd60ea49c31048f12 # Parent dce74082c20eea1f7ef9eb10f9a9addc5e7c7bb7 rc: bug fix for encoder crash Please state *what* was fixed. It's not obvious from the commit. - Derek ___ 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
Re: [x265] [PATCH 1 of 2] ratecontrol: clean up confusing if-checks in calcAdaptiveQuantFrame
On Fri, Feb 21, 2014 at 5:23 PM, Aarthi Priya Thirumalai aar...@multicorewareinc.com wrote: On Fri, Feb 21, 2014 at 4:53 PM, deep...@multicorewareinc.com wrote: # HG changeset patch # User Deepthi Nandakumar deep...@multicorewareinc.com # Date 1392976266 -19800 # Node ID 3275142274c8e424c9a9a57dbc2c70b0707ea996 # Parent 5e2043f89aa11363dffe33a0ff06550a7d862326 ratecontrol: clean up confusing if-checks in calcAdaptiveQuantFrame diff -r 5e2043f89aa1 -r 3275142274c8 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cppFri Feb 21 03:05:48 2014 -0600 +++ b/source/encoder/ratecontrol.cppFri Feb 21 15:21:06 2014 +0530 @@ -105,23 +105,20 @@ int block_xy = 0; int block_x = 0, block_y = 0; double strength = 0.f; -if (cfg-param.rc.aqMode == X265_AQ_NONE || cfg-param.rc.aqStrength == 0) + +if (cfg-param.rc.cuTree cfg-param.rc.aqStrength == 0) /* CUTree is enabled with zero strength AQ */ { -/* Need to init it anyways for CU tree */ int cuWidth = ((maxCol / 2) + X265_LOWRES_CU_SIZE - 1) X265_LOWRES_CU_BITS; int cuHeight = ((maxRow / 2) + X265_LOWRES_CU_SIZE - 1) X265_LOWRES_CU_BITS; int cuCount = cuWidth * cuHeight; - -if (cfg-param.rc.aqMode cfg-param.rc.aqStrength == 0) we need the above check . can be re written as if (cfg-param.rc.cuTree) -- sry, pls ignore this comment. since we always malloc inQscaleFactor, dont think this if check is necessary. But since we need to do weighted prediction even if aq and cu tree is disabled, the primary if condition (at the beginning )needs to pass if aqMode is NONE. + +memset(pic-m_lowres.qpOffset, 0, cuCount * sizeof(double)); +memset(pic-m_lowres.qpAqOffset, 0, cuCount * sizeof(double)); +for (int cuxy = 0; cuxy cuCount; cuxy++) { -memset(pic-m_lowres.qpOffset, 0, cuCount * sizeof(double)); -memset(pic-m_lowres.qpAqOffset, 0, cuCount * sizeof(double)); -for (int cuxy = 0; cuxy cuCount; cuxy++) -{ -pic-m_lowres.invQscaleFactor[cuxy] = 256; -} +pic-m_lowres.invQscaleFactor[cuxy] = 256; } - + /* Need variance data for weighted prediction */ if (cfg-param.bEnableWeightedPred) { ___ 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
[x265] [PATCH] abr: reset ABR to prevent high bitrate peaks in single pass ABR
) { -if (rce-sliceType != B_SLICE) -/* The factor 1.5 is to tune up the actual bits, otherwise the cplxrSum is scaled too low - * to improve short term compensation for next frame. */ -cplxrSum += bits * qp2qScale(rce-qpaRc) / rce-qRceq; -else +if (!isVbv) { -/* Depends on the fact that B-frame's QP is an offset from the following P-frame's. - * Not perfectly accurate with B-refs, but good enough. */ -cplxrSum += bits * qp2qScale(rce-qpaRc) / (rce-qRceq * fabs(cfg-param.rc.pbFactor)); +checkAndResetABR(rce); } -wantedBitsWindow += frameDuration * bitrate; + +if (!isAbrReset) +{ +if (rce-sliceType != B_SLICE) +/* The factor 1.5 is to tune up the actual bits, otherwise the cplxrSum is scaled too low + * to improve short term compensation for next frame. */ +cplxrSum += bits * qp2qScale(rce-qpaRc) / rce-qRceq; +else +{ +/* Depends on the fact that B-frame's QP is an offset from the following P-frame's. + * Not perfectly accurate with B-refs, but good enough. */ +cplxrSum += bits * qp2qScale(rce-qpaRc) / (rce-qRceq * fabs(cfg-param.rc.pbFactor)); +} +wantedBitsWindow += frameDuration * bitrate; +totalBits += bits; +} } -totalBits += bits; if (isVbv) { @@ -731,8 +787,7 @@ bframeBits = 0; } } +updateVbv(bits, rce); } - -updateVbv(bits, rce); return 0; } diff -r 2beb0bfb9503 -r ce4d1e450d26 source/encoder/ratecontrol.h --- a/source/encoder/ratecontrol.h Tue Feb 04 12:17:11 2014 -0600 +++ b/source/encoder/ratecontrol.h Wed Feb 05 00:14:12 2014 +0530 @@ -60,6 +60,7 @@ double qRceq; double frameSizePlanned; double bufferRate; +double movingAvgSum; }; struct Predictor @@ -83,7 +84,6 @@ double bitrate; double rateFactorConstant; bool isAbr; - double bufferSize; double bufferFillFinal; /* real buffer as of the last finished frame */ double bufferFill; /* planned buffer, if all in-progress frames hit their bit budget */ @@ -97,7 +97,8 @@ int bframes; int bframeBits; double leadingNoBSatd; - +bool isAbrReset; +int lastAbrResetPoc; int64_t lastSatd; intqpConstant[3]; double cplxrSum; /* sum of bits*qscale/rceq */ @@ -136,6 +137,7 @@ double clipQscale(double q); void updateVbvPlan(Encoder* enc); double predictSize(Predictor *p, double q, double var); +void checkAndResetABR(RateControlEntry* rce); }; } On Sun, Feb 2, 2014 at 6:07 PM, Aarthi Priya Thirumalai aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1391343895 -19800 # Sun Feb 02 17:54:55 2014 +0530 # Node ID bf00f495951eb882e34225740c43540311bf51cb # Parent bb33ab0f4ef933315cedf388d70443bc97fefeea abr: reset ABR to prevent high bitrate peaks in single pass ABR . Long series of blank frames in video followed by detailed content causes heavy ABR underflow and overall bitrates surges high for a long while. patch detects this condition in Single pass ABR mode and resets ABR - to not consider history from blank frames and continue from following scene-cut. diff -r bb33ab0f4ef9 -r bf00f495951e source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Sat Feb 01 16:39:12 2014 -0600 +++ b/source/encoder/ratecontrol.cpp Sun Feb 02 17:54:55 2014 +0530 @@ -240,7 +240,7 @@ shortTermCplxCount = 0; framesDone = 0; lastNonBPictType = I_SLICE; - +isAbrReset = false; // vbv initialization cfg-param.rc.vbvBufferSize = Clip3(0, 200, cfg-param.rc.vbvBufferSize); cfg-param.rc.vbvMaxBitrate = Clip3(0, 200, cfg-param.rc.vbvMaxBitrate); @@ -375,12 +375,12 @@ if (isAbr) //ABR,CRF { lastSatd = l-getEstimatedPictureCost(pic); +rce-lastSatd = lastSatd; double q = qScale2qp(rateEstimateQscale(rce)); qp = Clip3(MIN_QP, MAX_MAX_QP, (int)(q + 0.5)); rce-qpaRc = q; /* copy value of lastRceq into thread local rce struct *to be used in RateControlEnd() */ rce-qRceq = lastRceq; -rce-lastSatd = lastSatd; accumPQpUpdate(); } else //CQP @@ -464,6 +464,7 @@ * tolerances, the bit distribution approaches that of 2pass. */ double wantedBits, overflow = 1; +rce-movingAvgSum = shortTermCplxSum; shortTermCplxSum *= 0.5; shortTermCplxCount *= 0.5; shortTermCplxSum += lastSatd / (CLIP_DURATION(frameDuration) / BASE_FRAME_DURATION); @@ -479,6 +480,8 @@ } else { +if (!isVbv) +checkAndResetABR(rce); q = getQScale
[x265] [PATCH] abr: reset ABR to prevent high bitrate peaks in single pass ABR
# HG changeset patch # User Aarthi Thirumalai # Date 1391343895 -19800 # Sun Feb 02 17:54:55 2014 +0530 # Node ID bf00f495951eb882e34225740c43540311bf51cb # Parent bb33ab0f4ef933315cedf388d70443bc97fefeea abr: reset ABR to prevent high bitrate peaks in single pass ABR . Long series of blank frames in video followed by detailed content causes heavy ABR underflow and overall bitrates surges high for a long while. patch detects this condition in Single pass ABR mode and resets ABR - to not consider history from blank frames and continue from following scene-cut. diff -r bb33ab0f4ef9 -r bf00f495951e source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Sat Feb 01 16:39:12 2014 -0600 +++ b/source/encoder/ratecontrol.cpp Sun Feb 02 17:54:55 2014 +0530 @@ -240,7 +240,7 @@ shortTermCplxCount = 0; framesDone = 0; lastNonBPictType = I_SLICE; - +isAbrReset = false; // vbv initialization cfg-param.rc.vbvBufferSize = Clip3(0, 200, cfg-param.rc.vbvBufferSize); cfg-param.rc.vbvMaxBitrate = Clip3(0, 200, cfg-param.rc.vbvMaxBitrate); @@ -375,12 +375,12 @@ if (isAbr) //ABR,CRF { lastSatd = l-getEstimatedPictureCost(pic); +rce-lastSatd = lastSatd; double q = qScale2qp(rateEstimateQscale(rce)); qp = Clip3(MIN_QP, MAX_MAX_QP, (int)(q + 0.5)); rce-qpaRc = q; /* copy value of lastRceq into thread local rce struct *to be used in RateControlEnd() */ rce-qRceq = lastRceq; -rce-lastSatd = lastSatd; accumPQpUpdate(); } else //CQP @@ -464,6 +464,7 @@ * tolerances, the bit distribution approaches that of 2pass. */ double wantedBits, overflow = 1; +rce-movingAvgSum = shortTermCplxSum; shortTermCplxSum *= 0.5; shortTermCplxCount *= 0.5; shortTermCplxSum += lastSatd / (CLIP_DURATION(frameDuration) / BASE_FRAME_DURATION); @@ -479,6 +480,8 @@ } else { +if (!isVbv) +checkAndResetABR(rce); q = getQScale(rce, wantedBitsWindow / cplxrSum); /* ABR code can potentially be counterproductive in CBR, so just don't bother. @@ -498,7 +501,7 @@ } if (sliceType == I_SLICE cfg-param.keyframeMax 1 - lastNonBPictType != I_SLICE) + lastNonBPictType != I_SLICE !isAbrReset) { q = qp2qScale(accumPQp / accumPNorm); q /= fabs(cfg-param.rc.ipFactor); @@ -539,7 +542,7 @@ lastQScaleFor[sliceType] = q; -if (curSlice-getPOC() == 0) +if (curSlice-getPOC() == 0 || (isAbrReset sliceType == I_SLICE)) lastQScaleFor[P_SLICE] = q * fabs(cfg-param.rc.ipFactor); rce-frameSizePlanned = predictSize(pred[sliceType], q, (double)lastSatd); @@ -548,6 +551,35 @@ } } +void RateControl::checkAndResetABR( RateControlEntry* rce ) +{ +double abrBuffer = 2 * cfg-param.rc.rateTolerance * bitrate; +// Check if current SLice is a scene cut that follow low detailed/blank frames +if (rce-lastSatd 4 * rce-movingAvgSum) +{ +if (!isAbrReset rce-movingAvgSum 0 ) +{ +// Reset ABR if prev frames are blank to prevent further sudden overflows/ high bit rate spikes. +double underflow = 1.0 + (totalBits - wantedBitsWindow) / abrBuffer; +if (underflow 1 curSlice-m_avgQpRc==0) +{ +totalBits = 0; +framesDone = 0; +cplxrSum = .01 * pow(7.0e5, qCompress) * pow(ncu, 0.5); +wantedBitsWindow = bitrate * frameDuration; +accumPNorm = .01; +accumPQp = (ABR_INIT_QP_MIN)*accumPNorm; +isAbrReset = true; +} +} +// Clear flag to reset ABR and continue as usual. + else + { + isAbrReset = false; + } +} +} + void RateControl::updateVbvPlan(Encoder* enc) { bufferFill = bufferFillFinal; @@ -706,19 +738,25 @@ { if (isAbr) { -if (rce-sliceType != B_SLICE) -/* The factor 1.5 is to tune up the actual bits, otherwise the cplxrSum is scaled too low - * to improve short term compensation for next frame. */ -cplxrSum += bits * qp2qScale(rce-qpaRc) / rce-qRceq; -else +if (!isVbv) +checkAndResetABR(rce); + +if(!isAbrReset) { -/* Depends on the fact that B-frame's QP is an offset from the following P-frame's. - * Not perfectly accurate with B-refs, but good enough. */ -cplxrSum += bits * qp2qScale(rce-qpaRc) / (rce-qRceq * fabs(cfg-param.rc.pbFactor)); +if (rce-sliceType != B_SLICE) +/* The factor 1.5 is to tune up the actual bits, otherwise the cplxrSum is scaled too low + * to improve short term compensation for next frame. */ +cplxrSum += bits *
[x265] [PATCH] rc: bug fix in crf mode ; correct qscale set for all the frames.
# HG changeset patch # User Aarthi Thirumalai (aar...@multicorewareinc.com) # Date 1390910023 -19800 # Tue Jan 28 17:23:43 2014 +0530 # Branch stable # Node ID 154f020f6edacd92517b8ced5c0d4dacf808791c # Parent ddd4e4e328d2e626a88b6318781ee160c781be91 rc: bug fix in crf mode ;correct qscale set for all the frames. diff -r ddd4e4e328d2 -r 154f020f6eda source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cpp Tue Jan 28 01:47:11 2014 -0600 +++ b/source/encoder/ratecontrol.cpp Tue Jan 28 17:23:43 2014 +0530 @@ -518,7 +518,7 @@ q = Clip3(lqmin, lqmax, q); } -else if (cfg-param.rc.rateControlMode == X265_RC_CRF qCompress != 1) +else if (cfg-param.rc.rateControlMode == X265_RC_CRF qCompress != 1 framesDone == 0) { q = qp2qScale(ABR_INIT_QP) / fabs(cfg-param.rc.ipFactor); } ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
Re: [x265] [PATCH] cuTree: integrated CuTree into RateControl and Added b-references into RC
On Mon, Dec 2, 2013 at 5:54 PM, Gopu Govindaswamy g...@multicorewareinc.com wrote: # HG changeset patch # User Gopu Govindaswamy g...@multicorewareinc.com # Date 1385986798 -19800 # Node ID 8617e8ab6fafd5dea42e63f135f6df02761d5dd6 # Parent a0f2c87c5f0a27a2f7e6e96af675efc419988d6e cuTree: integrated CuTree into RateControl and Added b-references into RC diff -r a0f2c87c5f0a -r 8617e8ab6faf source/common/common.cpp --- a/source/common/common.cpp Mon Dec 02 12:53:59 2013 +0530 +++ b/source/common/common.cpp Mon Dec 02 17:49:58 2013 +0530 @@ -398,6 +398,7 @@ { //currently the default param-rc.aqMode = X265_AQ_NONE; +param-rc.cuTree = 0; } else if (!strcmp(tune, ssim)) { diff -r a0f2c87c5f0a -r 8617e8ab6faf source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cppMon Dec 02 12:53:59 2013 +0530 +++ b/source/encoder/ratecontrol.cppMon Dec 02 17:49:58 2013 +0530 @@ -118,6 +118,7 @@ if (cfg-param.rc.aqMode) { pic-m_lowres.qpAqOffset[block_xy] = qp_adj; +pic-m_lowres.qpOffset[block_xy] = qp_adj; pic-m_lowres.invQscaleFactor[block_xy] = x265_exp2fix8(qp_adj); block_xy++; } @@ -141,6 +142,14 @@ this-cfg = _cfg; ncu = (int)((cfg-param.sourceHeight * cfg-param.sourceWidth) / pow((int)16, 2.0)); +if (cfg-param.rc.cuTree) +{ +qCompress = 1; +cfg-param.rc.pbFactor = 1; +} +else +qCompress = cfg-param.rc.qCompress; + // validate for cfg-param.rc, maybe it is need to add a function like x265_parameters_valiate() cfg-param.rc.rfConstant = Clip3((double)-QP_BD_OFFSET, (double)51, cfg-param.rc.rfConstant); if (cfg-param.rc.rateControlMode == X265_RC_CRF) @@ -149,8 +158,8 @@ cfg-param.rc.bitrate = 0; double baseCplx = ncu * (cfg-param.bframes ? 120 : 80); -double mbtree_offset = 0; // added later -rateFactorConstant = pow(baseCplx, 1 - cfg-param.rc.qCompress) / +double mbtree_offset = cfg-param.rc.cuTree ? (1.0 - cfg-param.rc.qCompress) * 13.5 : 0; +rateFactorConstant = pow(baseCplx, 1 - qCompress) / qp2qScale(cfg-param.rc.rfConstant + mbtree_offset + QP_BD_OFFSET); } @@ -248,7 +257,7 @@ accumPNorm = .01; accumPQp = (ABR_INIT_QP_MIN)*accumPNorm; /* estimated ratio that produces a reasonable QP for the first I-frame */ -cplxrSum = .01 * pow(7.0e5, cfg-param.rc.qCompress) * pow(ncu, 0.5); +cplxrSum = .01 * pow(7.0e5, qCompress) * pow(ncu, 0.5); wantedBitsWindow = bitrate * frameDuration; } else if (cfg-param.rc.rateControlMode == X265_RC_CRF) @@ -257,7 +266,7 @@ accumPNorm = .01; accumPQp = ABR_INIT_QP * accumPNorm; /* estimated ratio that produces a reasonable QP for the first I-frame */ -cplxrSum = .01 * pow(7.0e5, cfg-param.rc.qCompress) * pow(ncu, 0.5); +cplxrSum = .01 * pow(7.0e5, qCompress) * pow(ncu, 0.5); wantedBitsWindow = bitrate * frameDuration; } @@ -351,9 +360,9 @@ double q0 = prevRefSlice-getSliceQp(); double q1 = nextRefSlice-getSliceQp(); -if (prevRefSlice-getSliceType() == B_SLICE prevRefSlice-isReferenced()) +if (prevRefSlice-getSliceType() == X265_TYPE_BREF prevRefSlice-isReferenced()) q0 -= pbOffset / 2; -if (nextRefSlice-getSliceType() == B_SLICE nextRefSlice-isReferenced()) +if (nextRefSlice-getSliceType() == X265_TYPE_BREF nextRefSlice-isReferenced()) sliceType = X265_TYPE_BREF = its already referenced, no need for the condition check for isReferenced() q1 -= pbOffset / 2; if (i0 i1) q = (q0 + q1) / 2 + ipOffset; @@ -453,7 +462,7 @@ q = Clip3(lqmin, lqmax, q); } } -else if (cfg-param.rc.rateControlMode == X265_RC_CRF cfg-param.rc.qCompress != 1) +else if (cfg-param.rc.rateControlMode == X265_RC_CRF qCompress != 1) { q = qp2qScale(ABR_INIT_QP) / fabs(cfg-param.rc.ipFactor); } @@ -565,7 +574,15 @@ { double q; -q = pow(rce-blurredComplexity, 1 - cfg-param.rc.qCompress); +if (cfg-param.rc.cuTree) +{ +double scale = curSlice-getSPS()-getVuiParameters()-getTimingInfo()-getTimeScale(); +double units = curSlice-getSPS()-getVuiParameters()-getTimingInfo()-getNumUnitsInTick(); +double timescale = units / scale; +q = pow(BASE_FRAME_DURATION / CLIP_DURATION(2 * timescale), 1 - cfg-param.rc.qCompress); +} +else +q = pow(rce-blurredComplexity, 1 - cfg-param.rc.qCompress); // avoid NaN's in the rc_eq if (rce-texBits + rce-mvBits == 0) diff -r a0f2c87c5f0a -r 8617e8ab6faf
Re: [x265] [PATCH] TComPicYuv: fix padding issue
On Mon, Nov 11, 2013 at 8:07 AM, Steve Borho st...@borho.org wrote: On Sat, Nov 9, 2013 at 11:53 PM, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalaiaar...@multicorewareinc.com # Date 1384062755 -19800 # Sun Nov 10 11:22:35 2013 +0530 # Node ID 82c1059d0960d5cbfead3dae61956e8257ff0eb6 # Parent 9d74638c3640679d09264b793afdf3ffc58a9107 TComPicYuv: fix padding issue diff -r 9d74638c3640 -r 82c1059d0960 source/Lib/TLibCommon/TComPicYuv.cpp --- a/source/Lib/TLibCommon/TComPicYuv.cpp Sat Nov 09 20:14:24 2013 -0600 +++ b/source/Lib/TLibCommon/TComPicYuv.cpp Sun Nov 10 11:22:35 2013 +0530 @@ -209,9 +209,9 @@ /* internal pad to multiple of 16x16 blocks */ uint8_t rem = width 15; I changed this line yesterday to use width instead of m_picWidth. I think that is sufficient to fix the padding. Do you agree? Fine :) -padx = rem ? 16 - rem : padx; +padx += rem ? 16 - rem : padx; rem = width 15; -pady = rem ? 16 - rem : pady; +pady += rem ? 16 - rem : pady; #if HIGH_BIT_DEPTH if (pic.bitDepth 8) ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel -- Steve Borho ___ 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
Re: [x265] [PATCH] aq: bug fix.extend border of TComPic::m_origPicYuv to a multiple of 16
On Nov 7, 2013 11:24 PM, Steve Borho st...@borho.org wrote: On Thu, Nov 7, 2013 at 5:17 AM, Aarthi Thirumalai aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1383823017 -19800 # Thu Nov 07 16:46:57 2013 +0530 # Node ID 0823d243b4e2f9eee6323a9750eeb811bccbad77 # Parent 85002898f5b4308547af6ce464bbdff5f360fa13 aq: bug fix.extend border of TComPic::m_origPicYuv to a multiple of 16 diff -r 85002898f5b4 -r 0823d243b4e2 source/Lib/TLibCommon/TComPicYuv.cpp --- a/source/Lib/TLibCommon/TComPicYuv.cpp Thu Nov 07 14:31:05 2013 +0530 +++ b/source/Lib/TLibCommon/TComPicYuv.cpp Thu Nov 07 16:46:57 2013 +0530 @@ -345,6 +345,10 @@ /* width and height - without padsize */ int width = m_picWidth - padx; int height = m_picHeight - pady; +uint8_t rem = m_picWidth % 16; +padx += rem ? 16 - rem : 0; +rem = m_picHeight % 16; +pady += rem ? 16 - rem : 0; if the row width was 17, padx would already be 3 in order to pad out to the nearest multiple of 4. You would be doing: padx += 15, which would result in a pad of 18, which is more than what you bargained for. I believe the += should just be =. Also, Gopu just added a new else {} clause this is missed here, so I've hoisted this operation higher in the file. when row width is 17, padx is already 3 and m_picWidth would be 20 at this stage. So padx += 12 not 15.. // Manually copy pixels to up-size them for (int r = 0; r height; r++) @@ -475,10 +479,12 @@ uint8_t *v = (uint8_t*)pic.planes[2]; /* width and height - without padsize */ -int width = (m_picWidth * (pic.bitDepth 8 ? 2 : 1)) - padx; -int height = m_picHeight - pady; - -// copy pixels by row into encoder's buffer + int width = (m_picWidth * (pic.bitDepth 8 ? 2 : 1)) - padx; + int height = m_picHeight - pady; + uint8_t rem = m_picWidth % 16; + padx += rem ? 16 - rem : 0; + rem = m_picHeight % 16; + pady += rem ? 16 - rem : 0; still white-space alignment problems here, but this code has been removed for (int r = 0; r height; r++) { memcpy(Y, y, width); diff -r 85002898f5b4 -r 0823d243b4e2 source/common/lowres.cpp --- a/source/common/lowres.cpp Thu Nov 07 14:31:05 2013 +0530 +++ b/source/common/lowres.cpp Thu Nov 07 16:46:57 2013 +0530 @@ -150,31 +150,6 @@ intraMbs[i] = 0; } -int y, extWidth = (orig-getWidth() + X265_LOWRES_CU_SIZE - 1); -int srcStride = orig-getStride(); -int srcHeight = orig-getHeight(); -int srcWidth = orig-getWidth(); -Pel *src; -src = orig-getLumaAddr(); - -/* extending right margin */ -if (2 * width srcWidth) -{ -for (y = 0; y srcHeight; y++) -{ -::memset(src + srcWidth, src[srcWidth - 1], sizeof(Pel) * (X265_LOWRES_CU_SIZE - 1)); -src += srcStride; -} -} - -/* extending bottom margin */ -src = orig-getLumaAddr() + (srcHeight - 1) * srcStride; - -for (y = 1; y = 2 * lines - srcHeight; y++) -{ -::memcpy(src + y * srcStride, src, sizeof(Pel) * (extWidth)); -} - /* downscale and generate 4 HPEL planes for lookahead */ primitives.frame_init_lowres_core(orig-getLumaAddr(), lowresPlane[0], lowresPlane[1], lowresPlane[2], lowresPlane[3], diff -r 85002898f5b4 -r 0823d243b4e2 source/encoder/frameencoder.cpp --- a/source/encoder/frameencoder.cpp Thu Nov 07 14:31:05 2013 +0530 +++ b/source/encoder/frameencoder.cpp Thu Nov 07 16:46:57 2013 +0530 @@ -1149,9 +1149,8 @@ { /* Derive qpOffet for each CU by averaging offsets for all 16x16 blocks in the cu. */ double qp_offset = 0; -int blockSize = g_maxCUWidth 2; -int maxBlockCols = (pic-getPicYuvOrg()-getWidth() + (blockSize - 1)) / blockSize; -int maxBlockRows = (pic-getPicYuvOrg()-getHeight() + (blockSize - 1)) / blockSize; +int maxBlockCols = (pic-getPicYuvOrg()-getWidth() + (16 - 1)) / 16; +int maxBlockRows = (pic-getPicYuvOrg()-getHeight() + (16 - 1)) / 16; much better int block_y = (cuAddr / pic-getPicSym()-getFrameWidthInCU()) * 4; int block_x = (cuAddr * 4) - block_y * pic-getPicSym()-getFrameWidthInCU(); int cnt = 0; ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel -- Steve Borho ___ 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
Re: [x265] [PATCH] aq : bug fix . extend border of TComPic::m_origPicYuv to a multiple of 16
On Thu, Nov 7, 2013 at 2:44 AM, Steve Borho st...@borho.org wrote: On Wed, Nov 6, 2013 at 4:33 AM, Aarthi Thirumalai aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1383734012 -19800 # Wed Nov 06 16:03:32 2013 +0530 # Node ID 6b725179b61564df5b4eb497f783b193dcbda1e9 # Parent 21e08cf159c552ff98334c98070b9cd442aaff27 aq : bug fix . extend border of TComPic::m_origPicYuv to a multiple of 16 no space before the : diff -r 21e08cf159c5 -r 6b725179b615 source/Lib/TLibCommon/TComPicYuv.cpp --- a/source/Lib/TLibCommon/TComPicYuv.cpp Wed Nov 06 15:43:19 2013 +0530 +++ b/source/Lib/TLibCommon/TComPicYuv.cpp Wed Nov 06 16:03:32 2013 +0530 @@ -431,10 +431,12 @@ this is only the 8bpp path, the HIGH_BIT_DEPTH path needs the same adjustments uint8_t *v = (uint8_t*)pic.planes[2]; /* width and height - without padsize */ -int width = (m_picWidth * (pic.bitDepth 8 ? 2 : 1)) - padx; -int height = m_picHeight - pady; - -// copy pixels by row into encoder's buffer + int width = (m_picWidth * (pic.bitDepth 8 ? 2 : 1)) - padx; + int height = m_picHeight - pady; + uint8_t rem = m_picWidth % 16; + padx += rem ? 16 - rem : 0; + rem = m_picHeight % 16; + pady += rem ? 16 - rem : 0; white-space alignment for (int r = 0; r height; r++) { memcpy(Y, y, width); diff -r 21e08cf159c5 -r 6b725179b615 source/common/lowres.cpp --- a/source/common/lowres.cpp Wed Nov 06 15:43:19 2013 +0530 +++ b/source/common/lowres.cpp Wed Nov 06 16:03:32 2013 +0530 @@ -150,31 +150,6 @@ intraMbs[i] = 0; } -int y, extWidth = (orig-getWidth() + X265_LOWRES_CU_SIZE - 1); -int srcStride = orig-getStride(); -int srcHeight = orig-getHeight(); -int srcWidth = orig-getWidth(); -Pel *src; -src = orig-getLumaAddr(); - -/* extending right margin */ -if (2 * width srcWidth) -{ -for (y = 0; y srcHeight; y++) -{ -::memset(src + srcWidth, src[srcWidth - 1], sizeof(Pel) * (X265_LOWRES_CU_SIZE - 1)); -src += srcStride; -} -} - -/* extending bottom margin */ -src = orig-getLumaAddr() + (srcHeight - 1) * srcStride; - -for (y = 1; y = 2 * lines - srcHeight; y++) -{ -::memcpy(src + y * srcStride, src, sizeof(Pel) * (extWidth)); -} - /* downscale and generate 4 HPEL planes for lookahead */ primitives.frame_init_lowres_core(orig-getLumaAddr(), lowresPlane[0], lowresPlane[1], lowresPlane[2], lowresPlane[3], The AQ code which iterates over 16x16 blocks also needs to be updated to account for the last padded block in each row, and at the bottom. This has already been taken care of. shall make the other changes and resend -- Steve ___ 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
Re: [x265] [PATCH 2 of 2] rc: implement Adaptive Quantization
This commit causes compile error. missed commenting out a debug stmt. Resending the patch.. On Wed, Oct 16, 2013 at 11:25 PM, aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalaiaar...@multicorewareinc.com # Date 1381946053 -19800 # Wed Oct 16 23:24:13 2013 +0530 # Node ID 3b38eece9db42008f5c8fd582f9236cc7a0dceeb # Parent 46cdbe43d903c23169593f70c28b5d32d8f397e9 rc: implement Adaptive Quantization. added functions to compute AC Energy per CU for all planes, calculate qpAqOffset for each CU diff -r 46cdbe43d903 -r 3b38eece9db4 source/encoder/ratecontrol.cpp --- a/source/encoder/ratecontrol.cppWed Oct 16 23:18:08 2013 +0530 +++ b/source/encoder/ratecontrol.cppWed Oct 16 23:24:13 2013 +0530 @@ -50,6 +50,79 @@ return 0.85 * pow(2.0, (qp - 12.0) / 6.0); } +/* Compute variance to derive AC energy of each block */ +static inline uint32_t acEnergyVar(uint64_t sum_ssd, int shift) +{ +uint32_t sum = (uint32_t)sum_ssd; +uint32_t ssd = (uint32_t)(sum_ssd 32); +return ssd - ((uint64_t)sum * sum shift); +} + +/* Find the energy of each block in Y/Cb/Cr plane */ +static inline uint32_t acEnergyPlane(pixel* src, int srcStride, int b_chroma) +{ +int blockStride = FENC_STRIDE 2; + +if( b_chroma ) +{ +ALIGN_VAR_16( pixel, pix[16 * 16] ); +primitives.blockcpy_pp(8, 8, pix, blockStride, src, srcStride); +return acEnergyVar(primitives.var[PARTITION_8x8](pix, blockStride), 6); +} +else +return acEnergyVar(primitives.var[PARTITION_16x16](src, srcStride), 8); +} + +/* Find the total AC energy of each CU in all planes */ + double RateControl::acEnergyCu(TComPic* pic , uint32_t cuAddr) +{ +uint32_t var = 0; +double avgQp = 0; +pixel* srcLuma = pic-getPicYuvOrg()-getLumaAddr(cuAddr); +pixel* srcCb = pic-getPicYuvOrg()-getCbAddr(cuAddr); +pixel* srcCr = pic-getPicYuvOrg()-getCrAddr(cuAddr); +UInt blockWidth = g_maxCUWidth 2; +UInt blockHeight = g_maxCUHeight 2; +UInt frameStride = pic-getPicYuvOrg()-getStride(); +UInt cStride = pic-getPicYuvOrg()-getCStride(); + +// Calculate Qp offset for each 16x16 block in the CU and average them over entire CU +for (UInt h = 0, cnt = 0; h g_maxCUHeight; h += blockHeight) +for (UInt w = 0 ;w g_maxCUWidth ; w += blockWidth, cnt++) +{ +UInt blockOffsetLuma = w + (h * frameStride); +UInt blockOffsetChroma = (w 1) + ((h 1) * cStride); +var = acEnergyPlane(srcLuma + blockOffsetLuma, frameStride, 0); +var += acEnergyPlane(srcCb + blockOffsetChroma, cStride, 1); +var += acEnergyPlane(srcCr + blockOffsetChroma, cStride, 1); +avgQp += cfg-param.rc.aqStrength * (X265_LOG2(X265_MAX(var, 1)) - (14.427f)); +fprintf(fp2,\n cuAddr : %d , energy : %d ,cuAddr,var); +} +avgQp /= 16; +x265_emms(); +return avgQp; +} + +void RateControl::calcAdaptiveQuantFrame(TComPic *pic) +{ +double strength; +/* Actual adaptive quantization */ +if (cfg-param.rc.aqMode) +{ +strength = cfg-param.rc.aqStrength * 1.0397f; +int maxRows = pic-getPicSym()-getFrameHeightInCU(); +int maxCols = pic-getPicSym()-getFrameWidthInCU(); +for (int cu_y = 0; cu_y maxRows; cu_y++) +for (int cu_x = 0; cu_x maxCols; cu_x++) +{ +double qp_adj; +int cu_xy = maxCols * cu_y + cu_x; +qp_adj = acEnergyCu(pic, cu_xy); +pic-m_qpAqOffset[cu_xy] = qp_adj; +} +} +} + RateControl::RateControl(TEncCfg * _cfg) { this-cfg = _cfg; diff -r 46cdbe43d903 -r 3b38eece9db4 source/encoder/ratecontrol.h --- a/source/encoder/ratecontrol.h Wed Oct 16 23:18:08 2013 +0530 +++ b/source/encoder/ratecontrol.h Wed Oct 16 23:24:13 2013 +0530 @@ -80,7 +80,7 @@ // to be called for each frame to process RateCOntrol and set QP void rateControlStart(TComPic* pic, Lookahead *, RateControlEntry* rce); - +void calcAdaptiveQuantFrame(TComPic *pic); int rateControlEnd(int64_t bits, RateControlEntry* rce); protected: @@ -88,6 +88,7 @@ double getQScale(RateControlEntry *rce, double rateFactor); double rateEstimateQscale(RateControlEntry *rce); // main logic for calculating QP based on ABR void accumPQpUpdate(); +double acEnergyCu(TComPic* pic , uint32_t cuAddr); }; } ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel
Re: [x265] [PATCH] primitves: add c primitives for the following :
On Oct 12, 2013 3:33 AM, Steve Borho st...@borho.org wrote: On Fri, Oct 11, 2013 at 5:40 AM, Aarthi Thirumalai aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1381488011 -19800 # Fri Oct 11 16:10:11 2013 +0530 # Node ID 9b9c6766967dc99cab93c3e09514346606125b3e # Parent c6d89dc62e191f56f63dbcb1781a6494da50a70d primitves: add c primitives for the following : compute AC energy for each block copy pixels of chroma plane diff -r c6d89dc62e19 -r 9b9c6766967d source/common/pixel.cpp --- a/source/common/pixel.cpp Fri Oct 11 01:47:53 2013 -0500 +++ b/source/common/pixel.cpp Fri Oct 11 16:10:11 2013 +0530 @@ -688,6 +688,33 @@ } return ssim; } + +templateint w, int h +uint64_t pixel_var(pixel *pix, intptr_t i_stride) +{ +uint32_t sum = 0, sqr = 0; +for (int y = 0; y h; y++) +{ +for (int x = 0; x w; x++) +{ +sum += pix[x]; +sqr += pix[x] * pix[x]; +} +pix += i_stride; +} +return sum + ((uint64_t)sqr 32); +} + we should to add a _c suffix to the C primitives, I know we haven't been consistent with that but we should try to catch up +void plane_copy_deinterleave_chroma(pixel *dstu, intptr_t dstuStride, pixel *dstv, intptr_t dstvStride, +pixel *src, intptr_t srcStride, int w, int h) +{ +for (int y = 0; y h; y++, dstu += dstuStride, dstv += dstvStride, src += srcStride) +for (int x = 0; x w; x++) +{ +dstu[x] = src[2 * x]; +dstv[x] = src[2 * x + 1]; +} +} } // end anonymous namespace namespace x265 { @@ -905,5 +932,9 @@ p.frame_init_lowres_core = frame_init_lowres_core; p.ssim_4x4x2_core = ssim_4x4x2_core; p.ssim_end_4 = ssim_end_4; + +p.var[PARTITION_16x16] = pixel_var16,16; +p.var[PARTITION_8x8] = pixel_var8,8; +p.plane_copy_deinterleave_c = plane_copy_deinterleave_chroma; } } diff -r c6d89dc62e19 -r 9b9c6766967d source/common/primitives.h --- a/source/common/primitives.hFri Oct 11 01:47:53 2013 -0500 +++ b/source/common/primitives.hFri Oct 11 16:10:11 2013 +0530 @@ -202,6 +202,8 @@ typedef void (*extendCURowBorder_t)(pixel* txt, intptr_t stride, int width, int height, int marginX); typedef void (*ssim_4x4x2_core_t)(const pixel *pix1, intptr_t stride1, const pixel *pix2, intptr_t stride2, ssim_t sums[2][4]); typedef float (*ssim_end4_t)(ssim_t sum0[5][4], ssim_t sum1[5][4], int width); +typedef uint64_t (*var_t)(pixel *pix, intptr_t stride); +typedef void (*plane_copy_deinterleave_t)(pixel *dstu, intptr_t dstuStride, pixel *dstv, intptr_t dstvStride, pixel *src, intptr_t srcStride, int w, int h); /* Define a structure containing function pointers to optimized encoder * primitives. Each pointer can reference either an assembly routine, @@ -261,6 +263,8 @@ downscale_t frame_init_lowres_core; ssim_4x4x2_core_t ssim_4x4x2_core; ssim_end4_t ssim_end_4; +var_t var[NUM_PARTITIONS]; +plane_copy_deinterleave_t plane_copy_deinterleave_c; does the _c at the end here imply chroma? Yes. Implies chroma }; /* This copy of the table is what gets used by the encoder. ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel -- Steve Borho ___ 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
Re: [x265] [PATCH 1 of 2] primitives: added C primitives to compute SSIM
As discussed today, we shall have 64bit int and 32 bit int versions of the primitives for high bit depth and low bit depth cases. On Sun, Oct 6, 2013 at 12:59 AM, Steve Borho st...@borho.org wrote: On Fri, Oct 4, 2013 at 11:07 PM, Aarthi Priya Thirumalai aar...@multicorewareinc.com wrote: I understand. If High_Bit)Depth = 1, you could still choose uint32 version for the primitives but in ssim_end_1(int..) you might get an overflow when bitdepth 9, as mentioned in the comments there. I could use a 64bit int there for all cases to store intermediary calculations , if you want to remove those if conditions. If uint64 is big enough for 12bit pixels, then that would be preferable over floats, I think. But we would still want a 32bit int version for the 8bit pixel case, so you would still need a run-time decision to pick the right version of the function. Am I misunderstanding the need for the float version? Is it just for higher pixel bit depths? -- Steve ___ 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
Re: [x265] [PATCH 2 of 2] calculate SSIM for each Row after deblock, sao
On Sat, Oct 5, 2013 at 12:57 AM, Steve Borho st...@borho.org wrote: On Fri, Oct 4, 2013 at 6:21 AM, Aarthi Thirumalai aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1380885604 -19800 # Fri Oct 04 16:50:04 2013 +0530 # Node ID ed4f57163274364e419dabfa4f864aa5a48cab6b # Parent 92641f3d3195b8da2275cfc44b1921d8f81a54bc calculate SSIM for each Row after deblock, sao. diff -r 92641f3d3195 -r ed4f57163274 source/Lib/TLibEncoder/TEncTop.cpp --- a/source/Lib/TLibEncoder/TEncTop.cppFri Oct 04 16:46:15 2013 +0530 +++ b/source/Lib/TLibEncoder/TEncTop.cppFri Oct 04 16:50:04 2013 +0530 @@ -513,7 +513,7 @@ int width = recon-getWidth() - getPad(0); int height = recon-getHeight() - getPad(1); int size = width * height; - +double ssim = 0; UInt64 ssdY = computeSSD(orig-getLumaAddr(), recon-getLumaAddr(), stride, width, height); height = 1; @@ -604,7 +604,11 @@ { m_analyzeB.addResult(psnrY, psnrU, psnrV, (double)bits); } - +if (param.bEnableSsim) +{ +ssim += pic-getSlice()-m_ssim / pic-getSlice()-m_ssimCnt; is m_ssimCnt always non-zero? needs a check here. +m_globalSsim += ssim; +} if (param.logLevel = X265_LOG_DEBUG) { char c = (slice-isIntra() ? 'I' : slice-isInterP() ? 'P' : 'B'); diff -r 92641f3d3195 -r ed4f57163274 source/encoder/frameencoder.cpp --- a/source/encoder/frameencoder.cpp Fri Oct 04 16:46:15 2013 +0530 +++ b/source/encoder/frameencoder.cpp Fri Oct 04 16:50:04 2013 +0530 @@ -111,6 +111,9 @@ m_rows[i].create(top); } +if (m_cfg-param.bEnableSsim) +CHECKED_MALLOC(tempBuf, int, m_cfg-param.bEnableSsim * 8 * (m_cfg-param.sourceWidth / 4 + 3)); + // NOTE: 2 times of numRows because both Encoder and Filter in same queue if (!WaveFront::init(m_numRows * 2)) { @@ -168,6 +171,10 @@ assert(0); } start(); +return; +fail: +X265_FREE(tempBuf); +tempBuf = 0; this looks quite backwards, you only free tempBuf on malloc failure? the buffer doesn't appear to be used? Its passed as an argument in calculateSSIM(). } int FrameEncoder::getStreamHeaders(NALUnitEBSP **nalunits) @@ -540,6 +547,32 @@ slice-setSaoEnabledFlag((saoParam-bSaoFlag[0] == 1) ? true : false); } +/*Compute SSIM if enabled*/ +if (m_cfg-param.bEnableSsim) +{ +pixel *rec = (pixel*)m_pic-getPicYuvRec()-getLumaAddr(); +pixel *org = (pixel*)m_pic-getPicYuvOrg()-getLumaAddr(); +int stride1 = m_pic-getPicYuvOrg()-getStride(); +int stride2 = m_pic-getPicYuvRec()-getStride(); +for (int row = 0; row m_numRows; row++) +{ +int bEnd = ((row + 1) == (this-m_numRows - 1)); +int bStart = (row == 0); +int minPixY = row * 64 - 4 * !bStart; +int maxPixY = (row + 1) * 64 - 4 * !bEnd; +int ssim_cnt; +x265_emms(); + +/* SSIM is done for each row in blocks of 4x4 . The First blocks are offset by 2 pixels to the right +* to avoid alignment of ssim blocks with DCT blocks. */ +minPixY += bStart ? 2 : -6; +slice-m_ssim += +calculateSSIM(rec + 2 + minPixY * stride1, stride1, org + 2 + minPixY * stride2, stride2, + m_cfg-param.sourceWidth - 2, maxPixY - minPixY, tempBuf, ssim_cnt); +slice-m_ssimCnt += ssim_cnt; +} +} + entropyCoder-setBitstream(NULL); // Reconstruction slice @@ -687,6 +720,39 @@ delete bitstreamRedirect; } +/* Function to calculate SSIM for each row */ +float FrameEncoder::calculateSSIM(pixel *pix1, intptr_t stride1, pixel *pix2, intptr_t stride2, int width, int height, void *buf, int *cnt) +{ +int z = 0; +float ssim = 0.0; + +int(*sum0)[4] = (int(*)[4])buf; +int(*sum1)[4] = sum0 + (width 2) + 3; +width = 2; +height = 2; +for (int y = 1; y height; y++) +{ +for (; z = y; z++) +{ +void* swap = sum0; +sum0 = sum1; +sum1 = (int(*)[4])swap; +for (int x = 0; x width; x += 2) +{ +primitives.ssim_4x4x2_core_int(pix1[4 * (x + (z * stride1))], stride1, pix2[4 * (x + (z * stride2))], stride2, sum0[x]); +} +} + +for (int x = 0; x width - 1; x += 4) +{ +ssim += primitives.ssim_end4_int(sum0 + x, sum1 + x, X265_MIN(4, width - x - 1)); +} +} + +*cnt = (height - 1) * (width - 1); +return ssim; +} + void FrameEncoder::encodeSlice(TComOutputBitstream* substreams) { // choose entropy coder diff -r 92641f3d3195 -r ed4f57163274 source/encoder/frameencoder.h --- a/source/encoder/frameencoder.h Fri Oct 04 16:46:15
Re: [x265] [PATCH 1 of 2] primitives: added C primitives to compute SSIM
I understand. If High_Bit)Depth = 1, you could still choose uint32 version for the primitives but in ssim_end_1(int..) you might get an overflow when bitdepth 9, as mentioned in the comments there. I could use a 64bit int there for all cases to store intermediary calculations , if you want to remove those if conditions. On Sat, Oct 5, 2013 at 12:53 AM, Steve Borho st...@borho.org wrote: On Fri, Oct 4, 2013 at 6:21 AM, Aarthi Thirumalai aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1380885375 -19800 # Fri Oct 04 16:46:15 2013 +0530 # Node ID 92641f3d3195b8da2275cfc44b1921d8f81a54bc # Parent bf14f75b8cf99806c75cdc1a50b28b6cf265e3bd primitives: added C primitives to compute SSIM diff -r bf14f75b8cf9 -r 92641f3d3195 source/common/pixel.cpp --- a/source/common/pixel.cpp Fri Oct 04 01:39:22 2013 -0500 +++ b/source/common/pixel.cpp Fri Oct 04 16:46:15 2013 +0530 @@ -653,6 +653,85 @@ } } +/* structural similarity metric */ +templateclass T1 +void ssim_4x4x2_core(const pixel *pix1, intptr_t stride1, const pixel *pix2, intptr_t stride2, T1 sums[2][4]) +{ +for (int z = 0; z 2; z++) +{ +T1 s1 = 0, s2 = 0, ss = 0, s12 = 0; +for (int y = 0; y 4; y++) +{ +for (int x = 0; x 4; x++) +{ +T1 a = pix1[x + y * stride1]; +T1 b = pix2[x + y * stride2]; +s1 += a; +s2 += b; +ss += a * a; +ss += b * b; +s12 += a * b; +} +} + +sums[z][0] = s1; +sums[z][1] = s2; +sums[z][2] = ss; +sums[z][3] = s12; +pix1 += 4; +pix2 += 4; +} +} + +templateclass T1 +float ssim_end_4(T1 sum0[5][4], T1 sum1[5][4], int width) +{ +float ssim = 0.0; + +for (int i = 0; i width; i++) +{ +ssim += ssim_end_1(sum0[i][0] + sum0[i + 1][0] + sum1[i][0] + sum1[i + 1][0], + sum0[i][1] + sum0[i + 1][1] + sum1[i][1] + sum1[i + 1][1], + sum0[i][2] + sum0[i + 1][2] + sum1[i][2] + sum1[i + 1][2], + sum0[i][3] + sum0[i + 1][3] + sum1[i][3] + sum1[i + 1][3]); +} + +return ssim; +} + +float ssim_end_1(int s1, int s2, int ss, int s12) +{ +static const uint32_t pixelMax = (1 X265_DEPTH) - 1; + +/* Maximum value for 10-bit is: ss*64 = (2^10-1)^2*16*4*64 = 4286582784, which will overflow in some cases. +* s1*s1, s2*s2, and s1*s2 also obtain this value for edge cases: ((2^10-1)*16*4)^2 = 4286582784. +* Maximum value for 9-bit is: ss*64 = (2^9-1)^2*16*4*64 = 1069551616, which will not overflow. */ + +#if X265_DEPTH 9 +#define type int64_t +#else +#define type int32_t +#endif We keep cycling on this issue. With HIGH_BIT_DEPTH=1, X265_DEPTH evaluates to g_bitDepth (a global variable) With HIGH_BIT_DEPTH=0, X265_DEPTH evaluates to 8 So with high bit depth builds the bit depth is a runtime option (it could be 8, 10, or 12). For 8bpp builds the bit depth must be 8. HIGH_BIT_DEPTH=0 builds will probably always use the uint32 version of this function. The HIGH_BIT_DEPTH=1 builds will have to choose between uint32 or float at runtime. + +static const type ssim_c1 = (type)(.01 * .01 * pixelMax * pixelMax * 64 + .5); +static const type ssim_c2 = (type)(.03 * .03 * pixelMax * pixelMax * 64 * 63 + .5); +type vars = ss * 64 - s1 * s1 - s2 * s2; +type covar = s12 * 64 - s1 * s2; +return (float)(2 * s1 * s2 + ssim_c1) * (float)(2 * covar + ssim_c2) + / ((float)(s1 * s1 + s2 * s2 + ssim_c1) * (float)(vars + ssim_c2)); +} + +float ssim_end_1(float s1, float s2, float ss, float s12) +{ +static const float pixelMax = (1 X265_DEPTH) - 1; +static const float ssim_c1 = (float)(.01 * .01 * pixelMax * pixelMax * 64); +static const float ssim_c2 = (float)(.03 * .03 * pixelMax * pixelMax * 64 * 63); +float vars = ss * 64 - s1 * s1 - s2 * s2; +float covar = s12 * 64 - s1 * s2; + +return (2 * s1 * s2 + ssim_c1) * (2 * covar + ssim_c2) + / ((s1 * s1 + s2 * s2 + ssim_c1) * (vars + ssim_c2)); +} } // end anonymous namespace namespace x265 { @@ -870,5 +949,10 @@ p.scale1D_128to64 = scale1D_128to64; p.scale2D_64to32 = scale2D_64to32; p.frame_init_lowres_core = frame_init_lowres_core; + +p.ssim_4x4x2_core_float = ssim_4x4x2_corefloat; +p.ssim_4x4x2_core_int = ssim_4x4x2_coreint; +p.ssim_end4_float = ssim_end_4float; +p.ssim_end4_int = ssim_end_4int; } } diff -r bf14f75b8cf9 -r 92641f3d3195 source/common/primitives.h --- a/source/common/primitives.hFri Oct 04 01:39:22 2013 -0500 +++ b/source/common/primitives.hFri Oct 04 16:46:15 2013 +0530 @@ -235,6 +235,10 @@ typedef void (*scale_t)(pixel *dst, pixel *src,
Re: [x265] [PATCH 2 of 2] Added x265_stats_t structure and x265_encoder_stats API to fetch output stats from encoder
sry, forgot to commit a new change. pls ignore the previous patch. ll send the updated one. On Tue, Oct 1, 2013 at 3:16 PM, Aarthi Thirumalai aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1380620634 -19800 # Tue Oct 01 15:13:54 2013 +0530 # Node ID 2a95812683f8f1b7ab75fcdf9034b6003a166f76 # Parent 36e2f4978ae40b23efa1a5403d59168d551f29a6 Added x265_stats_t structure and x265_encoder_stats API to fetch output stats from encoder. diff -r 36e2f4978ae4 -r 2a95812683f8 source/Lib/TLibEncoder/TEncTop.cpp --- a/source/Lib/TLibEncoder/TEncTop.cppTue Oct 01 15:09:55 2013 +0530 +++ b/source/Lib/TLibEncoder/TEncTop.cppTue Oct 01 15:13:54 2013 +0530 @@ -312,6 +312,19 @@ return 100.0; } +void TEncTop::fetchStats(x265_stats_t *stats) +{ +stats-globalPsnrY = m_analyzeAll.getPsnrY(); +stats-globalPsnrU = m_analyzeAll.getPsnrU(); +stats-globalPsnrV = m_analyzeAll.getPsnrV(); +stats-totalNumPics = m_analyzeAll.getNumPic(); +stats-accBits = m_analyzeAll.getBits(); +if (stats-totalNumPics 0) +stats-globalSsim = m_globalSsim / stats-totalNumPics; +else +stats-globalSsim = 0; +} + #define VERBOSE_RATE 0 #if VERBOSE_RATE static const char* nalUnitTypeToString(NalUnitType type) diff -r 36e2f4978ae4 -r 2a95812683f8 source/Lib/TLibEncoder/TEncTop.h --- a/source/Lib/TLibEncoder/TEncTop.h Tue Oct 01 15:09:55 2013 +0530 +++ b/source/Lib/TLibEncoder/TEncTop.h Tue Oct 01 15:13:54 2013 +0530 @@ -106,6 +106,8 @@ int getStreamHeaders(NALUnitEBSP **nalunits); +void fetchStats(x265_stats_t* stats); + double printSummary(); TComScalingList* getScalingList() { return m_scalingList; } diff -r 36e2f4978ae4 -r 2a95812683f8 source/encoder/encoder.cpp --- a/source/encoder/encoder.cppTue Oct 01 15:09:55 2013 +0530 +++ b/source/encoder/encoder.cppTue Oct 01 15:13:54 2013 +0530 @@ -429,6 +429,15 @@ EXTERN_CYCLE_COUNTER(ME); extern C +void x265_encoder_stats(x265_t *encoder, x265_stats_t *outputStats) +{ +CHECKED_MALLOC(outputStats, x265_stats_t, 1); +encoder-getStats(outputStats); +fail: +return; +} + +extern C void x265_encoder_close(x265_t *encoder, double *outPsnr) { double globalPsnr = encoder-printSummary(); diff -r 36e2f4978ae4 -r 2a95812683f8 source/x265.cpp --- a/source/x265.cpp Tue Oct 01 15:09:55 2013 +0530 +++ b/source/x265.cpp Tue Oct 01 15:13:54 2013 +0530 @@ -511,6 +511,7 @@ x265_picture_t *pic_in = pic_orig; x265_picture_t *pic_recon = cliopt.recon ? pic_out : NULL; x265_nal_t *p_nal; +x265_stats_t *stats = NULL; int nal; if (!x265_encoder_headers(encoder, p_nal, nal)) @@ -571,6 +572,7 @@ fprintf(stderr, \r); double PSNR = 0.0; +x265_encoder_stats(encoder, stats); x265_encoder_close(encoder, PSNR); cliopt.bitstreamFile.close(); @@ -580,8 +582,14 @@ double elapsed = (double)(x265_mdate() - cliopt.i_start) / 100; double vidtime = (double)inFrameCount / param.frameRate; double bitrate = (0.008f * cliopt.totalBytes) / vidtime; -printf(\nencoded %d frames in %.2fs (%.2f fps), %.2f kb/s, Global PSNR: %.3f\n, - outFrameCount, elapsed, outFrameCount / elapsed, bitrate, PSNR); +printf(\nencoded %d frames in %.2fs (%.2f fps), %.2f kb/s, , + outFrameCount, elapsed, outFrameCount / elapsed, bitrate); + +if (param.bEnablePsnr) +printf(Global PSNR: %.3f\n, PSNR); + +if (param.bEnableSsim stats) +printf(Global SSIM: %.3f\n, stats-globalSsim); x265_cleanup(); /* Free library singletons */ diff -r 36e2f4978ae4 -r 2a95812683f8 source/x265.h --- a/source/x265.h Tue Oct 01 15:09:55 2013 +0530 +++ b/source/x265.h Tue Oct 01 15:13:54 2013 +0530 @@ -192,7 +192,20 @@ } X265_RDO_LEVEL; +/* Output Stats from encoder */ +typedef struct x265_stats_t +{ +doubleglobalPsnrY; +doubleglobalPsnrU; +doubleglobalPsnrV; +doubleglobalSsim; +doubleaccBits; +doubletotalNumPics; +} +x265_stats_t; + +/* Input parameters to the encoder */ typedef struct x265_param_t { int logLevel; @@ -344,6 +357,10 @@ * the payloads of all output NALs are guaranteed to be sequential in memory. */ int x265_encoder_encode(x265_t *encoder, x265_nal_t **pp_nal, int *pi_nal, x265_picture_t *pic_in, x265_picture_t *pic_out); +/* x265_encoder_stats: +* returns output stats from the encoder */ +voidx265_encoder_stats(x265_t *encoder, x265_stats_t *); + /* x265_encoder_close: * close an encoder handler. Optionally return the global PSNR value (6 * psnrY + psnrU + psnrV) / 8 */ voidx265_encoder_close(x265_t *, double *globalPsnr); ___ x265-devel mailing list
Re: [x265] [PATCH 5 of 5] integrated ssim computation for each CTURow
On Oct 1, 2013 1:44 AM, Steve Borho st...@borho.org wrote: On Fri, Sep 27, 2013 at 11:52 PM, Aarthi Thirumalai aar...@multicorewareinc.com wrote: # HG changeset patch # User Aarthi Thirumalai # Date 1380343885 -19800 # Sat Sep 28 10:21:25 2013 +0530 # Node ID b1539ccab7bab1708433a9b8b18f5f8c090b1810 # Parent a8b00de495520f00a4648dac5d111e40b5570ca3 integrated ssim computation for each CTURow diff -r a8b00de49552 -r b1539ccab7ba source/encoder/frameencoder.cpp --- a/source/encoder/frameencoder.cpp Sat Sep 28 10:18:23 2013 +0530 +++ b/source/encoder/frameencoder.cpp Sat Sep 28 10:21:25 2013 +0530 @@ -91,6 +91,9 @@ delete[] m_rows; } +if (tempBuf) X265_FREE does the NULL check for you +X265_FREE(tempBuf); + m_frameFilter.destroy(); // wait for worker thread to exit @@ -106,6 +109,8 @@ 2 : (m_cfg-param.bEnableSAO || m_cfg-param.bEnableLoopFilter ? 1 : 0); m_rows = new CTURow[m_numRows]; +if(m_cfg-param.bEnableSsim) white-space +CHECKED_MALLOC(tempBuf, int, m_cfg-param.bEnableSsim * 8 * (m_cfg-param.sourceWidth/4 + 3)); for (int i = 0; i m_numRows; ++i) { m_rows[i].create(top); @@ -168,6 +173,8 @@ assert(0); } start(); +fail: +return; } int FrameEncoder::getStreamHeaders(NALUnitEBSP **nalunits) @@ -540,6 +547,31 @@ slice-setSaoEnabledFlag((saoParam-bSaoFlag[0] == 1) ? true : false); } +/*Compute SSIM if enabled*/ + if(m_cfg-param.bEnableSsim) white-space + { +pixel *rec = (pixel*)m_pic-getPicYuvRec()-getLumaAddr(); +pixel *org = (pixel*)m_pic-getPicYuvOrg()-getLumaAddr(); +int stride = m_pic-getPicYuvOrg()-getStride(); + for(int row = 0; row m_numRows; row++) + { + int bEnd = ((row + 1) == (this-m_numRows - 1)); + int bStart = (row == 0); + int minPixY = row * 64 - 4 * !bStart; + int maxPixY = (row + 1)* 64 - 4 * !bEnd; + int ssim_cnt; + x265_emms(); + /* offset by 2 pixels to avoid alignment of ssim blocks with dct blocks, + * and overlap by 4 */ do you understand what this comment implies? I don't and we probably should The function to calculate ssim for each row in this manner. Starting point : offset block by 2 in x axis. Do ssim for 2 4x4 blocks till row end. Offset by 4 in y axis from starting point n repeat above step for entire height(maxpicy - minpic) this offset is done so block positions don't match with dct sizes. +minPixY += bStart ? 2 : -6; +slice-m_ssim += +calculateSSIM( +rec + 2 + minPixY * stride, stride, +org + 2 + minPixY * stride, stride, +m_cfg-param.sourceWidth-2, maxPixY - minPixY, tempBuf, ssim_cnt ); formatting +slice-m_ssimCnt += ssim_cnt; +} + } entropyCoder-setBitstream(NULL); // Reconstruction slice @@ -687,6 +719,38 @@ delete bitstreamRedirect; } +/* Function to calculate SSIM for each row */ +float FrameEncoder::calculateSSIM( pixel *pix1, intptr_t stride1, + pixel *pix2, intptr_t stride2, + int width, int height, void *buf, int *cnt ) coding-style +{ +int z = 0; +float ssim = 0.0; +int (*sum0)[4] = (int (*)[4]) buf; +int (*sum1)[4] = sum0 + (width 2) + 3; +width = 2; +height = 2; +for( int y = 1; y height; y++ ) +{ +for( ; z = y; z++ ) +{ +void* swap = sum0; +sum0 = sum1; +sum1 = (int (*)[4])swap; +for( int x = 0; x width; x+=2 ) +{ +if(m_pic-getPicYuvRec() == 0 || x== 98){ +int nullaalret = 1; nullaalret++; +} +primitives.ssim4x4x2Core( pix1[4*(x+z*stride1)], stride1, pix2[4*(x+z*stride2)], stride2, sum0[x] ); +} +} +for( int x = 0; x width-1; x += 4 ) +ssim += primitives.ssimEnd4( sum0+x, sum1+x, X265_MIN(4,width-x-1) ); +} +*cnt = (height-1) * (width-1); +return ssim; +} void FrameEncoder::encodeSlice(TComOutputBitstream* substreams) { // choose entropy coder diff -r a8b00de49552 -r b1539ccab7ba source/encoder/frameencoder.h --- a/source/encoder/frameencoder.h Sat Sep 28 10:18:23 2013 +0530 +++ b/source/encoder/frameencoder.h Sat Sep 28 10:21:25 2013 +0530 @@ -153,6 +153,10 @@ // worker thread void threadMain(); +/* called by compressFrame to calculate SSIM for each row after applying deblock filter and SAO. */ +float calculateSSIM(pixel *pix1, intptr_t stride1,pixel *pix2, intptr_t stride2, +int width,
Re: [x265] [PATCH] Encoder: do not use std::list for the class AccessUnit
On Tue, Sep 24, 2013 at 5:26 PM, Gopu Govindaswamy g...@multicorewareinc.com wrote: # HG changeset patch # User Gopu Govindaswamy g...@multicorewareinc.com # Date 1380019510 -19800 # Node ID 70ba2b3b7bc972ed04f5fd135d940e4759315fa8 # Parent a8f6f62217d5e519f99a004c420e5906ac900f2f Encoder: do not use std::list for the class AccessUnit diff -r a8f6f62217d5 -r 70ba2b3b7bc9 source/Lib/TLibEncoder/TEncTop.cpp --- a/source/Lib/TLibEncoder/TEncTop.cppTue Sep 24 14:22:02 2013 +0530 +++ b/source/Lib/TLibEncoder/TEncTop.cppTue Sep 24 16:15:10 2013 +0530 @@ -114,14 +114,16 @@ for (int i = 0; i param.frameNumThreads; i++) { // Ensure frame encoder is idle before destroying it -AccessUnit tmp; -m_frameEncoder[i].getEncodedPicture(tmp); -for (AccessUnit::const_iterator it = tmp.begin(); it != tmp.end(); it++) +NALUnitEBSP **nalunits = NULL; +m_frameEncoder[i].getEncodedPicture(nalunits); +if (nalunits) { -const NALUnitEBSP nalu = **it; -free(nalu.m_nalUnitData); +for (int nalcount = 0; nalunits[nalcount] != NULL; nalcount++) +{ +const NALUnitEBSP nalu = *nalunits[nalcount]; +free(nalu.m_nalUnitData); +} } - m_frameEncoder[i].destroy(); } @@ -161,9 +163,9 @@ } } -int TEncTop::getStreamHeaders(AccessUnit accessUnit) +int TEncTop::getStreamHeaders(NALUnitEBSP **nalunits) { -return m_frameEncoder-getStreamHeaders(accessUnit); +return m_frameEncoder-getStreamHeaders(nalunits); } /** @@ -173,7 +175,7 @@ \param accessUnitsOut output bitstream \retval number of encoded pictures */ -int TEncTop::encode(bool flush, const x265_picture_t* pic_in, x265_picture_t *pic_out, AccessUnit accessUnitOut) +int TEncTop::encode(bool flush, const x265_picture_t* pic_in, x265_picture_t *pic_out, NALUnitEBSP **nalunits) { if (pic_in) { @@ -213,7 +215,7 @@ // getEncodedPicture() should block until the FrameEncoder has completed // encoding the frame. This is how back-pressure through the API is // accomplished when the encoder is full. -TComPic *out = curEncoder-getEncodedPicture(accessUnitOut); +TComPic *out = curEncoder-getEncodedPicture(nalunits); if (!out flush) { @@ -227,7 +229,7 @@ { curEncoder = m_frameEncoder[m_curEncoder]; m_curEncoder = (m_curEncoder + 1) % param.frameNumThreads; -out = curEncoder-getEncodedPicture(accessUnitOut); +out = curEncoder-getEncodedPicture(nalunits); } while (!out flushed != m_curEncoder); } @@ -259,7 +261,7 @@ pic_out-stride[2] = recpic-getCStride(); } -double bits = calculateHashAndPSNR(out, accessUnitOut); +double bits = calculateHashAndPSNR(out, nalunits); // Allow this frame to be recycled if no frame encoders are using it for reference ATOMIC_DEC(out-m_countRefEncoders); @@ -487,7 +489,7 @@ /* Returns Number of bits in current encoded pic */ -double TEncTop::calculateHashAndPSNR(TComPic* pic, AccessUnit accessUnit) +double TEncTop::calculateHashAndPSNR(TComPic* pic, NALUnitEBSP **nalunits) { TComPicYuv* recon = pic-getPicYuvRec(); TComPicYuv* orig = pic-getPicYuvOrg(); @@ -544,7 +546,10 @@ m_frameEncoder-m_seiWriter.writeSEImessage(onalu.m_Bitstream, sei_recon_picture_digest, pic-getSlice()-getSPS()); writeRBSPTrailingBits(onalu.m_Bitstream); -accessUnit.insert(accessUnit.end(), new NALUnitEBSP(onalu)); +int count = 0; +while(nalunits[count] != NULL) +count++; +nalunits[count]-init(onalu); } Isn't nalunits[count] supposed to be initalized , if its null - before calling its init() ? /* calculate the size of the access unit, excluding: @@ -552,13 +557,14 @@ * - SEI NAL units */ UInt numRBSPBytes = 0; -for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++) +int count = 0; +for (;nalunits[count] != NULL; count++) { -UInt numRBSPBytes_nal = (*it)-m_packetSize; +UInt numRBSPBytes_nal = nalunits[count]-m_packetSize; #if VERBOSE_RATE printf(*** %6s numBytesInNALunit: %u\n, nalUnitTypeToString((*it)-m_nalUnitType), numRBSPBytes_nal); #endif -if ((*it)-m_nalUnitType != NAL_UNIT_PREFIX_SEI (*it)-m_nalUnitType != NAL_UNIT_SUFFIX_SEI) +if (nalunits[count]-m_nalUnitType != NAL_UNIT_PREFIX_SEI nalunits[count]-m_nalUnitType != NAL_UNIT_SUFFIX_SEI) { numRBSPBytes += numRBSPBytes_nal; } diff -r a8f6f62217d5 -r 70ba2b3b7bc9