From 57364ff88e840e7cd3126f4537378bc6660fc98b Mon Sep 17 00:00:00 2001
From: Lawrence Rust <lvr@softsystem.co.uk>
Date: Sun, 1 Jan 2012 14:03:09 +0100
Subject: [PATCH] modules/stream: Reduce video playback startup latency
These fixes considerably reduce video startup latency for common viewers
like totem and gstreamer.
1. RFC 3875 4.3.3. says that a CGI "script MUST NOT provide a response
message-body for a HEAD request". At the moment the whole video file
(which can be several GB) is unnecessarily copied. This can add
several seconds of delay and overhead.
2. If the CGI output pipe is closed then the script should stop outputting
data. Some clients can GET a URL to parse the headers/length and then
abort it. This change can save outputting several GB of data.
Signed-off-by: Lawrence Rust <lvr@softsystem.co.uk>
---
modules/stream/stream_flv.pl | 10 +++++++++-
modules/stream/stream_mp4.pl | 10 +++++++++-
modules/stream/stream_raw.pl | 10 +++++++++-
3 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/modules/stream/stream_flv.pl b/modules/stream/stream_flv.pl
index e8d69b7..f118e8d 100755
a
|
b
|
|
148 | 148 | print header(-type => 'video/x-flv'); |
149 | 149 | } |
150 | 150 | |
| 151 | # RFC 3875 4.3.3. script MUST NOT provide a response message-body for a HEAD request |
| 152 | if ($ENV{'REQUEST_METHOD'} eq 'HEAD') { |
| 153 | exit; |
| 154 | } |
| 155 | |
151 | 156 | my $buffer; |
152 | 157 | if (read DATA, $buffer, 53) { |
153 | 158 | print $buffer; |
… |
… |
|
155 | 160 | $durPrint = reverse pack("d",$lengthSec); |
156 | 161 | print $durPrint; |
157 | 162 | while (read DATA, $buffer, 262144) { |
158 | | print $buffer; |
| 163 | # Exit if the output pipe is broken i.e. client disconnect |
| 164 | unless (print $buffer ) { |
| 165 | last; |
| 166 | } |
159 | 167 | } |
160 | 168 | } |
161 | 169 | close DATA; |
diff --git a/modules/stream/stream_mp4.pl b/modules/stream/stream_mp4.pl
index 242fca8..9cedc73 100755
a
|
b
|
|
80 | 80 | ); |
81 | 81 | } |
82 | 82 | |
| 83 | # RFC 3875 4.3.3. script MUST NOT provide a response message-body for a HEAD request |
| 84 | if ($ENV{'REQUEST_METHOD'} eq 'HEAD') { |
| 85 | exit; |
| 86 | } |
| 87 | |
83 | 88 | # Seek to the requested position |
84 | 89 | sysseek DATA, $start, 0; |
85 | 90 | |
86 | 91 | # Print the content to the browser |
87 | 92 | my $buffer; |
88 | 93 | while (sysread DATA, $buffer, $read_size ) { |
89 | | print $buffer; |
| 94 | # Exit if the output pipe is broken i.e. client disconnect |
| 95 | unless (print $buffer ) { |
| 96 | last; |
| 97 | } |
90 | 98 | $size -= $read_size; |
91 | 99 | if ($size == 0) { |
92 | 100 | last; |
diff --git a/modules/stream/stream_raw.pl b/modules/stream/stream_raw.pl
index 31f6854..dbdf79e 100755
a
|
b
|
|
104 | 104 | ); |
105 | 105 | } |
106 | 106 | |
| 107 | # RFC 3875 4.3.3. script MUST NOT provide a response message-body for a HEAD request |
| 108 | if ($ENV{'REQUEST_METHOD'} eq 'HEAD') { |
| 109 | exit; |
| 110 | } |
| 111 | |
107 | 112 | # Seek to the requested position |
108 | 113 | sysseek DATA, $start, 0; |
109 | 114 | |
110 | 115 | # Print the content to the browser |
111 | 116 | my $buffer; |
112 | 117 | while (sysread DATA, $buffer, $read_size ) { |
113 | | print $buffer; |
| 118 | # Exit if the output pipe is broken i.e. client disconnect |
| 119 | unless (print $buffer ) { |
| 120 | last; |
| 121 | } |
114 | 122 | $size -= $read_size; |
115 | 123 | if ($size <= 0) { |
116 | 124 | my $fileSize = -s $filename; |