CRF diffs relatively bit rate diffs formula
CRF1 - CRF setting which was in first/prev encode, bitrate1 - bitrate setting in kbps which has result encoded file in first/prev encode, CRF2 and bitrate2 - choose what to calculate and set it to null value and to which relative parameter to make a calculation and set it to numeric value.
(function () {
// ********************************
// x265 bitrate or CRF predictor based on first encode.
// version 0.0.0
// RuTracker.org, LiveM
// ********************************
let obj = {
// first/previos encode. this is calcutation basis
CRF1: 23.2,
bitrate1: 3500, //kbps
// set one property to null and another one the a numeric value you want
CRF2: null,
bitrate2: 3000, //kbps
};
function calcNewCRForBitrate(obj) {
if ((obj.CRF2 && obj.bitrate2) || (!obj.CRF2 && !obj.bitrate2)) {
return 'Error: Please, set one unknown parameter to null value and another one to a number which the estimation will be based on';
} else if (!obj.CRF1 || !obj.bitrate1) {
return 'Error: Please set CRF1 and bitrate1 values like they was in first/prev encode result';
}
let result;
if (obj.CRF2) {
result = obj.bitrate1 * Math.pow(Math.pow(10, (obj.CRF1 - obj.CRF2)), 0.1);
result = Math.ceil(result);
result = 'bitrate2 estimation is ' + result + ' kbps';
} else {
result = 10 * Math.log10(obj.bitrate1 / obj.bitrate2) + obj.CRF1;
result = Math.ceil(result*10) / 10;
result = 'CRF2 estimation is ' + result + ' points';
}
return result;
}
return calcNewCRForBitrate(obj);
}());
Comments (2)
-
-
extended to variable bit depths functionality:
(function () { // ******************************** // x265 10bit bitrate or CRF predictor based on first encode. // Looks like it works for x264 10 bit encode (tested on single instance only). // Delivers approximate estimate. // // Version 0.1.1.20170511 // RuTracker.org, LiveM // // This script powered by maths below: // For 10 bit encode: to change bit rate in 2 times we must change CRF by 3 points. Verified by own experience. // !Perhaps! for 8 bit encode (!untested!): to change bit rate in 2 times we must change CRF by 6 points. // !Perhaps! for 12 bit encode (!untested!): to change bit rate in 2 times we must change CRF by 1.5 points. // !Perhaps! the CRF point where bit rates are the same for 8,10,12 bit encodes is about CRF=28 (!untested!). // ******************************** let obj = { // first/previos encode. This is calcutation basis CRF1: 23.2, bitrate1: 3550, //in kbps // set one property to null to be estimated and another one the a numeric value you want CRF2: null, bitrate2: 3000, //in kbps }, // set encoder's bit depth. Experimental untested feature. colorBitDepthOfEncoder = 10; //in bits. 10 bits value verified as making good predictions. 8 and 12 bits are experimental untested values. // ============================================================================================ // script core function calcNewCRForBitrate(obj) { if ((obj.CRF2 && obj.bitrate2) || (!obj.CRF2 && !obj.bitrate2)) { return 'Error: Please set one unknown parameter to null value and another one to a number which the estimation will be based on'; } else if (!obj.CRF1 || !obj.bitrate1) { return 'Error: Please set CRF1 and bitrate1 values like they was in first/prev encode result'; } if (colorBitDepthOfEncoder !== 8 && colorBitDepthOfEncoder !== 10 && colorBitDepthOfEncoder !== 12) { return 'Error: Please set colorBitDepthOfEncoder to values either 8, 10 or 12'; } let result, // script's core variables based on encoder bit depths CRFBitsBasedCoef = 5 * Math.pow(2, (6 - (colorBitDepthOfEncoder / 2))), // 8b -> 20, 10b -> 10, 12b -> 5 BitRateBitsBasedCoef = 0.05 * Math.pow(2, ((colorBitDepthOfEncoder / 2) - 4)) ; // 8b -> 0.05, 10b -> 0.1, 12b -> 0.2 if (obj.CRF2) { result = obj.bitrate1 * Math.pow(Math.pow(10, (obj.CRF1 - obj.CRF2)), BitRateBitsBasedCoef); result = Math.round(result); result = 'bitrate2 estimation is ' + result + ' kbps'; } else { result = CRFBitsBasedCoef * Math.log10(obj.bitrate1 / obj.bitrate2) + obj.CRF1; result = Math.round(result*10) / 10; result = 'CRF2 estimation is ' + result + ' points'; } return 'x265 ' + colorBitDepthOfEncoder + ' bits encoder: ' + result; } return calcNewCRForBitrate(obj); }());
Copyright notes about site, author, version and other meta-content or script itself. I want to cut it out then it will be published your docs. It's your x265 encoder and my 'pull request' is extremely weak, so I want to leave it with no matter. Just review and publish the core content/main concept/script core itself in your docs section as you want. It's just to share an ability of wide use. Thanks for pay attention to this topic.
- Log in to comment
Hi! That's me who sent this script. Sorry for Anonymous account usage.
Please combine this topic with it's description in https://bitbucket.org/multicoreware/x265/issues/338/crf-diffs-relatively-bit-rate-diffs
I want to correct the script in aspect of working area.
KG7x assemblies author shares 8,10,12bit builds on x265.ru/en/builds/. I do not know exactly that is it (--output-depth defaults only or whole encoder's pipeline is has the same color-channel depth or pipeline always has high bit depth) but the predictor script works great for x265 10bit builds. I use Visual C++ compiled builds (it gives about 1% performance increase for me among other compilers running on Intel G1610 CPU and Win10 v1607).
Usual settings I used it with different CRF (22.5...27 for 1080p@25 and 720p@30 content): & 'c:\Program Files (x86)\AviSynth\additional\avs4x265.exe' c:\desktop\pph.avs --x265-binary 'c:\Program Files (x86)\AviSynth\additional\x265_64-10bit[vc12].exe' -o "c:\desktop\pph_138.hevc" --preset veryslow --crf 24 --crf-max 51 --crf-min 0 --vbv-maxrate 100000 --vbv-bufsize 2000000 --vbv-init 0.9 --qcomp 0.5 --qpstep 100 --rd 4 --ref 6 --bframes 16 --weightb --b-intra --max-merge 5 --subme 7 --tu-intra-depth 4 --tu-inter-depth 4 --limit-tu 0 --limit-refs 0 --no-limit-modes --rskip --no-amp --rc-lookahead 250 --pools '2' --wpp --no-pme --no-pmode --frame-threads 1 --lookahead-slices 0 --ssim --psnr --log-level 4
I want to share this info with all, so please add it into your docs if you decide if it is correct in first approximation. I used it in 8-10 cases and approximation was always very close to results.