axiomatic-systems / Bento4

Full-featured MP4 format, MPEG DASH, HLS, CMAF SDK and tools
http://www.bento4.com
1.96k stars 478 forks source link

HLS fmp4 "BANDWIDTH" calculation #232

Open awakenedguy opened 6 years ago

awakenedguy commented 6 years ago

Hi,

A question, how exactly mp4dash calculates the BANDWIDTH value for HLS master playlist? Could you show in which file exactly this calculation (or estimation) is being done? Is there a way to automate this exact estimation with mp4info or some other utility?

The mystery of how exactly Apple's native variantplaylistcreator calculates this value always intrigued me. I have impression that nobody calculate the exact peak, everybody just estimate it in its own way, probably because no standard way exist to measure bitrate peak correctly, if I am not wrong. Or because it is just an incredibly difficult task to do it right.

E.g. when I test it with a sample, mp4dash estimates its 1080p BANDWIDTH to be 4.5 mbps. While if I open it with Telestream Switch Pro, it visualizes all videostream's bitrate fluctuations and indicates a clearly different peak - 5.8 mbps. So I sort of don't know how should I measure it, and moreover, how to automate this measure in my scripts.

If I underreport BANDWIDTH, it leads to player stalls. If I overreport it, then such stream is being "punished" by the automatic quality selector - it rarely selects 1080p, even when it can and should. So the task of putting a real correct BANDWIDTH value becomes imperative, the question is just how to correctly measure it. BTW Telestream Switch Pro takes time to visualize bitrate fluctuations... it really seems to calculate rather than estimate.

P.S.: Though when one calculate the peak of that same sample, now accordingly to HLS spec:

The segment bit rate of a Media Segment is the size of the Media Segment divided by its EXTINF duration (Section 4.3.2.1). Note that this includes container overhead but does not include overhead imposed by the delivery system, such as HTTP, TCP or IP headers.

The peak segment bit rate of a Media Playlist is the largest bit rate of any contiguous set of segments whose total duration is between 0.5 and 1.5 times the target duration. The bit rate of a set is calculated by dividing the sum of the segment sizes by the sum of the segment durations.

...then, surprisingly, it gives even higher value - around 6.8 mbps (video only).

So, mp4dash says 4.5 mbps, Telestream Switch Pro says 5.8 mbps, manual calculation says 6.8 mbps. All about one same sample. I also tried Shaka packager, it says the same as Bento4 - 4.5 mbps.

I take another, different sample, 576p resolution. mp4dash says 1.7 mbps. Shaka Packager says 1.3 mbps. Telestream reports its peak as being 2.2 mbps. Manual calculation according to HLS spec shows it to be around 1.5 mbps.

Enough to be confused...

barbibulle commented 6 years ago

The bandwidth calculation for DASH streams is actually not that straightforward. The current version of the packager uses method that should be fairly close to what's expected: it is based on the minBufferTime value for the MPD, and the size of the frames found in the media. The rule is that the bandwidth value should be such that if a player had exactly that constant bandwidth, and respected the minBufferTime value, it would never underflow. So the peak media bandwidth isn't really a good indicator, nor is the average bandwidth. Bento4 looks at a variable buffer over time, and tries to compute what value of the bandwidth would be able to guarantee never to underflow. If you change the minBufferTime value, the bandwidth calculation will change.

awakenedguy commented 6 years ago

As far as I see it, no such variable as minBufferTime even exist in hls.js API. The recommended value for packager's minBufferTime is always a segment size, right?