HRD Emulator in HTML5

Source: Internet
Author: User

Posted on March, from Moto

Just like MPEG-2 video uses VBV (video Buffer Verifier), H. Uses HRD (hypothetical Reference Decoder) to Defin e Correctness of streams.

One of the verification provided by HRD is CPB buffer fullness. The idea was simple; Feed H. Stream to HRD and monitor the CPB fullness. Make sure the fullness never goes negative nor above the CPB buffer size. The importance of this buffer fullness requirement is explained here.

HRD defines the CPB fullness in somewhat counter intuitive. To make it easy, I wrote a interactive HRD emulator in HTML5.

HRD Emulator (CBR)

The Blue Line is the number of bits entered to HRD over time. The input rate was constant in CBR mode, i.e. the Blue line is straight. The red line was the number of bits removed (= decoded) from CPB. Thus, the CPB fullness is the blue line minus the red line for a given time.

Let's select the VBR in rate Control Mode.

HRD Emulator (VBR)

The Blue Line now have some periods where the input rate is zero. H. uses Init_cpb_removal_delay to control the period; Bits for a picture N can enter HRD only after the picture decode time minus Init_cpb_removal_delay.

To see this rule more clearly, check "Show init_cpb_removal_delay" option. When the last bit of picture N–1 arrives before the picture N decoding time minus init_cpb_removal_delay, the input rate Goes down to zero.

HRD (VBR) with Init_cpb_removal_delay

The value of Init_cpb_removal_delay also determines the initial decoding delay. It's currently set to a. It means the first picture was decoded Ms after the first bit of the "the picture enters HRD."

The initial decoding delay determines the channel switching delay as discussed here. Can we reduce it to make channel switching faster?

HRD underflow due to the short initial delay

Not really. As shown above, reducing the value of init_cpb_removal_delay resulted in the underflow error (the Red line crosses the blu E line).

H. Introduced another parameter to allow the reduction of initial decoding delay at the expense of Increas Ed average bit rate. Here we have init_cpb_removal_delay_offset parameter. It ' s added to Init_cpb_removal_delay for every picture except the first one.

HRD with Non-zero Init_cpb_removal_delay_offset

H. HRD provides these parameters to encoders so, they can choose optimal bit stream configuration for each target D Evices.

Here is the HTML and Java Script of the HRD emulator above.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21st

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

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

<TITLE>HRD emulator</title>

<script src= "./script.js" type= "Text/javascript" ></script>

<style type= "Text/css" >

#plot {

Float:left

}

#control-container {

Float:left

}

#widget {

Float:right;

Width:10em

}

#heading {

Float:left

}

</style>

<body onload= "init ()" >

<div id= "Plot" >

<canvas id= "Canvas" width= "height=" 480 "></canvas>

</div>

<div id= "Control-container" >

<div class= "Control" >

<div class= "heading" >hrd bit_rate [<span id= "Showbitrate" > </span> kbps]</div>

<div class= "Widgets" >

<input id= "bitrate" onchange= "update ()" type= "range" min= "0" max= "$" value= "/>"

</div>

</div>

<div class= "Control" >

<div class= "Heading" >initial_cpb_removal_delay [<span id= "SHOWICRD" > </span> ms]</div>

<div>

<input id= "Initial_cpb_removal_delay" onchange= "Update ()" type= "range" min= "0" max= "+" value= "/>"

</div>

</div>

<div class= "Control" >

<div class= "Heading" >initial_cpb_removal_delay_offset [<span id= "Showicrdo" > </span> ms]</div >

<div>

<input id= "Initial_cpb_removal_delay_offset" onchange= "Update ()" type= "range" min= "0" max= "+" value= "0"/>

</div>

</div>

<div class= "Control" >

<div>rate Control mode</div>

<div>

<input type= "Radio" name= "mode" value= "CBR" onclick= "SetMode (' cbr '); Update () "checked=" Checked "/>cbr

</div>

<div>

<input type= "Radio" name= "mode" value= "VBR" onclick= "setmode (' VBR '); Update () "/>VBR

</div>

</div>

<div class= "Control" >

<div>

<input type= "checkbox" id= "isicrdvisible" onclick= "Update ()"/>show Init_cpb_removal_delay

</div>

</div>

<div class= "Control" >

<div>

<input type= "checkbox" id= "isicrdovisible" onclick= "Update ()"/>show Init_cpb_removal_delay_offset

</div>

</div>

<div class= "Control" >

<input id= "Reset" type= "button" value= "Redraw Graph" onclick= "Resetstream (); Update (); " />

</div>

</div>

</body>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21st

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

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

Save this as "script.js"

var canvas;

var picture = new Array ();

var pictureduration = 900900;

var initial_cpb_removal_delay = 900900;

var initial_cpb_removal_delay_offset = 90090;

var cbr_flag = true;

function init ()

{

Canvas = document.getElementById (' canvas ');

Resetstream ();

Update ();

}

function Resetstream ()

{

var bit_rate = document.getElementById (' bitrate '). Value * 1000;

var averagepicsize = pictureduration/27000000 * BIT_RATE/8;

for (var i = 0; i < i++) {

Picture[i] = averagepicsize + (math.random ()-0.5) * averagepicsize;

}

}

function Ticktox (tick)

{

return tick/900900 * 64;

}

function Leveltoy (level)

{

return canvas.height-level/50;

}

function Drawdecodepictures (CTX)

{

Ctx.strokestyle = ' Rgba (255, 0, 0, 255) ';

Ctx.beginpath ();

Ctx.moveto (0, Leveltoy (0));

Ctx.lineto (Ticktox (Initial_cpb_removal_delay), Leveltoy (0));

var PrevX = Ticktox (Initial_cpb_removal_delay)

var prevlevel = 0;

for (var i = 0; i < i++) {

var level = Prevlevel + picture[i];

var x1 = PrevX;

var x2 = PrevX + Ticktox (pictureduration)

var y = Leveltoy (level);

Ctx.lineto (x1, y);

Ctx.lineto (x2, y);

Prevlevel = level;

PrevX = x2

}

Ctx.stroke ();

}

function Levelfromperiod (period, bitrate)

{

return period/27000000.0 * BITRATE/8;

}

function Drawinputdata (CTX)

{

var t_af = new Array ();

var t_ai = new Array ();

var t_ai_earliest = new Array ();

var t_rn = new Array ();

var bit_rate = document.getElementById (' bitrate '). Value * 1000;

T_ai[0] = 0;

T_af[0] = picture[0] * 8 * 27000000/bit_rate;

T_rn[0] = Initial_cpb_removal_delay;

for (var n = 1; n < picture.length; n++)

{

T_rn[n] = t_rn[n-1] + pictureduration;

if (Cbr_flag = = True)

{

T_ai[n] = t_af[n-1];

}

Else

{

T_ai_earliest = T_rn[n]-(Initial_cpb_removal_delay + initial_cpb_removal_delay_offset);

T_ai[n] = Math.max (t_af[n-1], t_ai_earliest);

}

T_af[n] = T_ai[n] + picture[n] * 8 * 27000000/bit_rate;

}

Ctx.strokestyle = ' Rgba (0, 0, 255, 255) ';

Ctx.beginpath ();

Ctx.moveto (Ticktox (0), Leveltoy (0));

var level = 0;

for (var n = 0; n < picture.length; n++)

{

Ctx.lineto (Ticktox (T_ai[n]), Leveltoy (level));

Level + = Picture[n];

Ctx.lineto (Ticktox (T_af[n]), Leveltoy (level));

}

Ctx.stroke ();

level = 0;

for (var n = 0; n < picture.length; n++)

{

var isicrdvisible = document.getElementById ("isicrdvisible"). Checked;

if (isicrdvisible) {

Draw Initial_cpb_removal_delay Period

var icrd_x1 = Ticktox (T_rn[n]-Initial_cpb_removal_delay)

var icrd_x2 = Ticktox (T_rn[n])

var icrd_y = Leveltoy (level)-4

Ctx.strokestyle = ' Rgba (0, 0, 0, 255) ';

Ctx.beginpath ();

Ctx.moveto (icrd_x1, icrd_y);

Ctx.lineto (icrd_x2, icrd_y);

Ctx.stroke ();

Ctx.beginpath ();

Ctx.moveto (icrd_x1 + 2, icrd_y-2);

Ctx.lineto (icrd_x1, icrd_y);

Ctx.lineto (icrd_x1 + 2, icrd_y + 2);

Ctx.stroke ();

Ctx.beginpath ();

Ctx.moveto (icrd_x2-2, icrd_y-2);

Ctx.lineto (icrd_x2, icrd_y);

Ctx.lineto (icrd_x2-2, icrd_y + 2);

Ctx.stroke ();

}

var isicrdovisible = document.getElementById ("isicrdovisible"). Checked;

if (isicrdovisible) {

Draw Initial_cpb_removal_delay Period

var icrdo_x1 = Ticktox (T_rn[n]-Initial_cpb_removal_delay-initial_cpb_removal_delay_offset)

var icrdo_x2 = icrd_x1

var icrdo_y = Leveltoy (level)-4

Ctx.strokestyle = ' Rgba (0, 0, 0, 255) ';

Ctx.beginpath ();

Ctx.moveto (icrdo_x1, icrdo_y);

Ctx.lineto (icrdo_x2, icrdo_y);

Ctx.stroke ();

Ctx.beginpath ();

Ctx.moveto (icrdo_x1 + 2, icrdo_y-2);

Ctx.lineto (icrdo_x1, icrdo_y);

Ctx.lineto (icrdo_x1 + 2, icrdo_y + 2);

Ctx.stroke ();

Ctx.beginpath ();

Ctx.moveto (icrdo_x2-2, icrdo_y-2);

Ctx.lineto (icrdo_x2, icrdo_y);

Ctx.lineto (icrdo_x2-2, icrdo_y + 2);

Ctx.stroke ();

}

Level + = Picture[n];

}

}

function SetMode (mode)

{

Cbr_flag = mode = = "CBR";

}

function UpdateUI (uiname, ValueName)

{

document.getElementById (uiname). InnerHTML = document.getElementById (valueName). Value

}

function Update ()

{

var ctx = Canvas.getcontext (' 2d ');

Ctx.fillstyle = ' Rgba (255, 255, 255, 255) ';

Ctx.fillrect (0, 0, canvas.width, canvas.height);

UpdateUI ("Showbitrate", "bitrate");

UpdateUI ("Showicrd", "Initial_cpb_removal_delay");

UpdateUI ("Showicrdo", "Initial_cpb_removal_delay_offset");

Initial_cpb_removal_delay = document.getElementById (' Initial_cpb_removal_delay '). Value * 27000;

Initial_cpb_removal_delay_offset = document.getElementById (' Initial_cpb_removal_delay_offset '). Value * 27000;

Drawdecodepictures (CTX);

Drawinputdata (CTX);

};

HRD Emulator in HTML5

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.