Skip to content

Commit

Permalink
Merge pull request #93 from bitmovin/develop
Browse files Browse the repository at this point in the history
  • Loading branch information
rohrlaf authored Jul 14, 2022
2 parents 2670ff6 + a94f942 commit 0bc6f00
Show file tree
Hide file tree
Showing 23 changed files with 3,310 additions and 4 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ navigate to a demo inside one of our products, for example [player/4k](./player/

## Creating a demo
In order to create a new demo, you need to create a new folder (with new demo name) in either the
[demos/encoding](./demos/analytics), [demos/encoding](./demos/encoding) or [demos/player](./demos/player) folder,
[demos/analytics](./demos/analytics), [demos/encoding](./demos/encoding) or [demos/player](./demos/player) folder,
depending on the category of the demo, with the following contents:

- `info.yaml` (required) - Demo configuration
Expand Down
11 changes: 11 additions & 0 deletions encoding/av1-break-even-calculator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# AV1 break-even point calculation

Calculate the break-even point of AV1 versus H.264 and H.265 encoding for our customers.

### Tags

- av1
- break-even point
- encoding
- h264
- h265
1 change: 1 addition & 0 deletions encoding/av1-break-even-calculator/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
180 changes: 180 additions & 0 deletions encoding/av1-break-even-calculator/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
<p class="text-justify">
The purpose of this calculator is to estimate the AV1 break-even point:
How many views does it take to make up for the cost of using AV1 in addition to H.264 or H.265?
</p>

<h2 class="my-3">Inputs</h2>
<p class="text-justify">
Note: These are price point values that may be different for different customers.
</p>
<form class="container" id="av1-form">
<div class="row">

<div class="col-md-6">
<div class="form-group">
<label for="encodingCostPerMinute">Encoding cost per billing minute</label>
<div class="input-group">
<input class="form-control"
id="encodingCostPerMinute"
min="0"
step="0.01"
type="number"
value="0.02" />
<div class="input-group-append"><span class="input-group-text">$</span></div>
</div>
<div>
<small>Based on <a href="https://bitmovin.com/pricing/" rel="noreferrer" target="_blank" style="font-size: inherit;">Bitmovin flexible pricing</a></small>
</div>
</div>
<div class="form-group">
<label for="ingressCostPerGb">Ingress cost per GB</label>
<div class="input-group">
<input class="form-control"
id="ingressCostPerGb"
min="0"
step="0.01"
type="number"
value="0" />
<div class="input-group-append"><span class="input-group-text">$</span></div>
</div>
<div>
<small>&nbsp;</small>
</div>
</div>
<div class="form-group">
<label for="egressCostPerGb">CDN delivery cost per GB</label>
<div class="input-group">
<input class="form-control"
id="egressCostPerGb"
min="0"
step="0.01"
type="number"
value="0.04" />
<div class="input-group-append"><span class="input-group-text">$</span></div>
</div>
</div>
</div>

<div class="col-md-6">

<div class="form-group">
<label for="numberOfStreamsUhd">Number of 4K UHD streams (H.264 bitrate: 12 Mbps; billing multiplier: 4)</label>
<input class="form-control"
id="numberOfStreamsUhd"
min="1"
step="1"
type="number"
value="2" />
<div>
<small>&nbsp;</small>
</div>
</div>
<div class="form-group">
<label for="numberOfStreamsHd">Number of HD streams (H.264 bitrate: 5 Mbps; billing multiplier: 2)</label>
<input class="form-control"
id="numberOfStreamsHd"
min="1"
step="1"
type="number"
value="3" />
<div>
<small>&nbsp;</small>
</div>
</div>
<div class="form-group">
<label for="numberOfStreamsSd">Number of SD streams (H.264 bitrate: 1 Mbps; billing multiplier: 1)</label>
<input class="form-control"
id="numberOfStreamsSd"
min="1"
step="1"
type="number"
value="4" />
</div>
</div>

</div>
</form>

<div class="container">
<div class="row">

<div class="col-md-6 my-2">
<div>Break-even point - H.264+AV1 vs H.264 only</div>
<div id="av1-h264" class="font-weight-bold" style="font-size: 24px">--</div>
</div>

<div class="col-md-6 my-2">
<div>Break-even point - H.265+AV1 vs H.265 only</div>
<div id="av1-h265" class="font-weight-bold" style="font-size: 24px">--</div>
</div>

</div>
</div>
<p class="text-justify">
Starting from these numbers of views, supplementing encodings with AV1 becomes more
profitable than the respective codec alone.
</p>

<h3 class="my-3">Calculation multipliers</h3>
<p class="text-justify">
These are the multipliers and factors used in our calculation<a href="#formulaFootnote" target="_self" class="btm-footnote"></a>.
They are based on the
<a href="https://bitmovin.com/_emcm/" rel="noreferrer" target="_blank" style="font-size: inherit;">Bitmovin Encoding Minute Calculation Methodology</a>.
</p>
<div class="container">
<div class="row">
<table class="table">
<thead>
<th colspan="3">Multipliers</th>
</thead>
<tbody>
<tr class="table-secondary">
<th class="col-3">SD</th>
<th class="col-3">HD</th>
<th class="col-3">UHD</th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>4</td>
</tr>
<tr class="table-secondary">
<th>PerTitle</th>
<th colspan="2">3-Pass</th>
</tr>
<tr>
<td>1.1</td>
<td colspan="2">2</td>
</tr>
<tr class="table-secondary">
<th>H264</th>
<th>H265</th>
<th>AV1</th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>10</td>
</tr>
<tr class="table-secondary">
<th>AV1 efficiency improvement over H.264</th>
<th colspan="2">AV1 efficiency improvement over H.265</th>
</tr>
<tr>
<td>50%</td>
<td colspan="2">30%</td>
</tr>
</tbody>
</table>
</div>
</div>

<div class="mt-5">
<ol>
<li class="mb-2" style="font-size: 12px;">
<span id="formulaFootnote">
Simplified formula break-even point: ( [AV1 encoding cost] + [AV1 ingress cost] ) / ( [H.26X CDN delivery cost] - [AV1 CDN delivery cost] )
</span>
</li>
</ol>
</div>
21 changes: 21 additions & 0 deletions encoding/av1-break-even-calculator/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"title": "AV1 break-even calculator",
"description": "Calculate the break-even point for AV1 encoding",
"long_description": "Calculate the break-even point for AV1 encoding, supplementing the existing encoding.",
"executable": {
"executable": true,
"indexfile": "index.html"
},
"tags": [
"AV1",
"break-even",
"calculator",
"encoding",
"return on investment"
],
"metadata":{
"title":"AV1 break-even point calculator » Demo | Bitmovin",
"description": "Calculate the break-even point for AV1 encoding"
},
"hide_github_link": true
}
157 changes: 157 additions & 0 deletions encoding/av1-break-even-calculator/js/av1-break-even-calculator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
$(function() {

/**
* https://stackoverflow.com/questions/17369098/simplest-way-of-getting-the-number-of-decimals-in-a-number-in-javascript
* @param n {number}
* @returns {number}
*/
function countDecimals(n) {
if (Math.floor(n.valueOf()) === n.valueOf()) {
return 0;
}
return n.toString().split('.')[1].length || 0;
}

/**
* https://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-only-if-necessary
* @param n {number}
* @param decimalPlaces {number}
* @returns {number}
*/
function roundDecimals(n, decimalPlaces) {
var diff = Math.pow(10, decimalPlaces);
return Math.round((n.valueOf() + Number.EPSILON) * diff) / diff;
}

/**
* Generic handler that sets 'is-invalid' class to input, if value is NaN or <0
* @param onInputValue
* @returns {function(value : Number | NaN): (undefined)}
*/
function inputEventHandler(onInputValue) {
return function(e) {
var inputEl = $(this);
inputEl.removeClass('is-invalid');

var numberValue = Number(e.target.value);
if (isNaN(numberValue) || numberValue < 0
|| countDecimals(numberValue) > 2) {
inputEl.addClass('is-invalid');
onInputValue(NaN);
return;
}

onInputValue(numberValue);
};
}

(function initAv1Form() {
// form values for calculation
let encodingCostPerMinute = 0.02;
let ingressCostPerGb = 0.00;
let egressCostPerGb = 0.04;

let numberOfStreamsUhd = 2;
let numberOfStreamsHd = 3;
let numberOfStreamsSd = 4;

const multiplierStreamUhd = 4;
const multiplierStreamHd = 2;
const multiplierStreamSd = 1;
const multiplierTechPerTitle = 1.1;
const multiplierTech3Pass = 2; // Multipass
const multiplierCodecAv1 = 10;

// streams/renditions
const improvementsAv1H264 = 0.5; // 50%
const improvementsAv1H265 = 0.7; // 30%
const mbpsH264Uhd = 12;
const mbpsH264Hd = 5;
const mbpsH264Sd = 1;
const uhdRenditionGbPerMinH264 = (mbpsH264Uhd * 60) / (8 * 1000); // GB (8 * 1000) per min (60 seconds)
const uhdRenditionGbPerMinH265 = uhdRenditionGbPerMinH264 * improvementsAv1H264 / improvementsAv1H265;
const uhdRenditionGbPerMinAv1 = uhdRenditionGbPerMinH264 * improvementsAv1H264;

// result elements
const av1H264Element = $('#av1-h264');
const av1H265Element = $('#av1-h265');

const calculateBreakEvenPoints = () => {
// stream composition
const multiplierStreamComposition = numberOfStreamsUhd * multiplierStreamUhd
+ numberOfStreamsHd * multiplierStreamHd
+ numberOfStreamsSd * multiplierStreamSd;
const encodingCostPerMinuteAv1 = encodingCostPerMinute * multiplierStreamComposition
* multiplierTech3Pass * multiplierTechPerTitle * multiplierCodecAv1;

// all stream bandwidth
const multiplierStreamCompositionMbps = numberOfStreamsUhd * mbpsH264Uhd
+ numberOfStreamsHd * mbpsH264Hd
+ numberOfStreamsSd * mbpsH264Sd;
const allRenditionsGbPerMinH264 = (multiplierStreamCompositionMbps * 60) / (8 * 1000); // GB (8 * 1000) per min (60 seconds)
const allRenditionsGbPerMinAv1 = allRenditionsGbPerMinH264 * improvementsAv1H264;

const oneTimeCosts = encodingCostPerMinuteAv1 + allRenditionsGbPerMinAv1 * ingressCostPerGb;
const savingsPerViewH264 = egressCostPerGb * (uhdRenditionGbPerMinH264 - uhdRenditionGbPerMinAv1);
const savingsPerViewH265 = egressCostPerGb * (uhdRenditionGbPerMinH265 - uhdRenditionGbPerMinAv1);

const av1H264BreakEven = oneTimeCosts / savingsPerViewH264;
const av1H265BreakEven = oneTimeCosts / savingsPerViewH265;

if (isNaN(av1H264BreakEven) || isNaN(av1H265BreakEven)) {
av1H264Element.text('--');
av1H265Element.text('--');
} else {
av1H264Element.text(`${roundDecimals(av1H264BreakEven, 0)} views`);
av1H265Element.text(`${roundDecimals(av1H265BreakEven, 0)} views`);
}
}

// disable submit event
const formElement = $('#av1-form');
formElement.on('submit', function(e) {
e.preventDefault();
e.stopPropagation();
});

// handle input fields
$('input#encodingCostPerMinute', formElement).val(encodingCostPerMinute)
.on('input', inputEventHandler((value) => {
encodingCostPerMinute = value;
calculateBreakEvenPoints();
}));

$('input#ingressCostPerGb', formElement).val(ingressCostPerGb)
.on('input', inputEventHandler((value) => {
ingressCostPerGb = value;
calculateBreakEvenPoints();
}));

$('input#egressCostPerGb', formElement).val(egressCostPerGb)
.on('input', inputEventHandler((value) => {
egressCostPerGb = value;
calculateBreakEvenPoints();
}));

$('input#numberOfStreamsUhd', formElement).val(numberOfStreamsUhd)
.on('input', inputEventHandler((value) => {
numberOfStreamsUhd = value;
calculateBreakEvenPoints();
}));

$('input#numberOfStreamsHd', formElement).val(numberOfStreamsHd)
.on('input', inputEventHandler((value) => {
numberOfStreamsHd = value;
calculateBreakEvenPoints();
}));

$('input#numberOfStreamsSd', formElement).val(numberOfStreamsSd)
.on('input', inputEventHandler((value) => {
numberOfStreamsSd = value;
calculateBreakEvenPoints();
}));

calculateBreakEvenPoints();
})();

});
2 changes: 1 addition & 1 deletion player/drm/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var source = {
smooth: 'https://test.playready.microsoft.com/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism/manifest',
drm: {
widevine: {
LA_URL: 'https://widevine-proxy.appspot.com/proxy'
LA_URL: 'https://cwip-shaka-proxy.appspot.com/no_auth'
},
playready: {
LA_URL: 'https://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&ContentKey=EAtsIJQPd5pFiRUrV9Layw=='
Expand Down
Loading

0 comments on commit 0bc6f00

Please sign in to comment.