Last Comment Bug 502894 - HTTP byte range requests for Ogg/Theora video streams make no sense
: HTTP byte range requests for Ogg/Theora video streams make no sense
Status: RESOLVED WORKSFORME
:
Product: Core
Classification: Components
Component: Audio/Video (show other bugs)
: unspecified
: x86 Mac OS X
: -- normal (vote)
: ---
Assigned To: Nobody; OK to take it and work on it
:
: Maire Reavy [:mreavy]
Mentors:
: 530421 (view as bug list)
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2009-07-07 12:39 PDT by Joseph Huckaby
Modified: 2016-02-23 22:55 PST (History)
5 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments

Description Joseph Huckaby 2009-07-07 12:39:25 PDT
User-Agent:       Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5
Build Identifier: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5

When an Ogg/Theora video stream is placed into a <video> tag, Firefox 3.5 makes several requests to the server for chunks of the file using HTTP "Range" requests.  These requests make no sense, as the entire file is downloaded first, followed by chunks of the file in separate requests.



Reproducible: Always

Steps to Reproduce:
1. Navigate to a page containing an Ogg/Theora video file in a <video> tag.  Make sure you have access to the web server hosting the video file, to watch the access logs.  I downloaded the "meet.ogv" sample video from the Firefox 3.5 Video page at http://www.mozilla.com/en-US/firefox/video/

Load the page in Firefox 3.5 while watching your web server access log.


Actual Results:  
The web server receives the following requests for the video.  This is while the page is loading, before hitting the "Play" button.

1. First, a HTTP GET request for "Range: bytes=0-" is received by the server for the ogv file.  According to the HTTP 1.1 Specification (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html), this means "give me the entire file".  This results in the entire file (7.75 MB) sent over the wire, which negates the use of HTTP Range entirely.

2. Immediately following that, a separate HTTP GET request for "Range: bytes=8122368-" is received by the server for the ogv file.  According to the HTTP 1.1 Spec, and the size of the file, this is requesting the last 4481 bytes of the file.

3. Immediately following that, a third HTTP GET request for "Range: bytes=8192-" is received for the ogv file, which according to the HTTP 1.1 Spec means "everything from byte offset 8192 onward".  This results in another 8126849 bytes (nearly 7.75 MB) sent to the client again.

This all happens before the play button is pressed by the user.

When the Play button is pressed, another requests is received by the server for the same ogv file.

4. A request for "Range: bytes=16538-" is received by the server for the ogv file, which according to the HTTP 1.1 Spec means "everything from byte offset 165378 onward".  This results in another 8110311 bytes (nearly 7.75 MB) sent to the client again.



Expected Results:  
I expected an HTTP HEAD request to be sent first, to determine the byte size of the file, followed by one HTTP GET Range request for the first N bytes (determined by the client -- enough to read the header, maybe show the first frame, and maybe pre-buffer a few seconds of video).

When the play button is finally pressed, I expect the video to be fetched in N-byte range chunks, with the byte ranges to be neighboring each other (example: 0-32768, 32768-65536, etc. etc.).


This behavior doesn't seem to make sense.  Why fetch the entire file, then the last 4481 bytes of the file you already have, then the entire file again sans the first 8192 bytes?
Comment 1 Chris Pearce (:cpearce) 2009-07-07 16:32:21 PDT
This behaviour makes sense to us. ;)

(In reply to comment #0)
> Actual Results:  
> 1. First, a HTTP GET request for "Range: bytes=0-"

This reads the first chunk of the ogg file. From this we can ensure it's a valid ogg etc. The data downloaded should be cached by Firefox.

> 2. Immediately following that, a separate HTTP GET request for "Range:
> bytes=8122368-"

Unfortunately Ogg files don't contain their duration, so we terminate the initial download, and we seek to the end of the Ogg file and read a bit of data to extract the time duration of the media. 

> 3. Immediately following that, a third HTTP GET request for "Range:
> bytes=8192-"

After we've ascertained the duration of the media, we'll resume download of the media. We don't need to redownload data which is already cached, so we resume from wherever the previous download stopped (8K into the stream in your example). We'll download enough data to display the first frame of video, then stop the download (unless the <video> has the autobuffer attribute set). This means that if you have multiple <video> on the page, they won't all download and cause a slow loading page, or a big bandwidth drain.

> 4. [After pressing play] A request for "Range: bytes=16538-" 

I'm assuming you didn't have the autobuffer set? When the user presses play we resume downloading the remaining resource so it can begin playback.

> This results in another 8110311 bytes (nearly 7.75 MB) sent to
> the client again.

Are you sure that the connections aren't being terminated? Can you tell when only a fraction of the requested resource is being downloaded?

> This behavior doesn't seem to make sense.  Why fetch the entire file, then the
> last 4481 bytes of the file you already have, then the entire file again sans
> the first 8192 bytes?

It shouldn't fetch the entire file. We should only have 1 connection open per video at any one time at the moment. 

If you have your server serve an X-Content-Duration header, you shouldn't see the seek to the end to get the duration. The headers are specified here: https://trac.annodex.net/wiki/HttpHeaders

If you also set the autobuffer attribute, you should see only one connection throughout the video load.
Comment 2 Joseph Huckaby 2009-07-07 16:48:52 PDT
Understood.  Correct, I did not have autobuffer set, and my logs do not show terminated connections.  So that makes sense.  Thank you for the explanation, and sorry for the non-bug bug :)

- Joe
Comment 3 Chris Pearce (:cpearce) 2009-11-22 11:10:29 PST
*** Bug 530421 has been marked as a duplicate of this bug. ***
Comment 4 Ramcena 2016-02-23 22:48:58 PST
Hi... I access a audio element with 135KB audio data in HTML file.

HTML CODE

 <audio id="ring" src="Ring.wav" loop></audio> 

 When I have access the HTML, 1 Http Get request with status 206 fired.(Request range: bytes=0-)

 My problem is when I tried to play that audio from Js file ,at the time again Get request with status 206 fired.(Request range: bytes=16044-)

 JS CODE 

 var ring = Drizzle("[id=ring]")[0];
 ring.play();

 Please answer my following questions:

 1.Why second time Get request fired.

 2.How to change  this multiple Get request  to single multiple.

 Thanks in advance.

Note You need to log in before you can comment on or make changes to this bug.