On Wed, Oct 17, 2007 at 12:03:53PM +0200, Tom St wrote:
> I am looking for testers of the uvc-streamer successor, called
> "mjpg-streamer" [1].

Hi! First of all, congratulations on the nice, clean code! It works well 
with my QuickCam 9000 Pro. :-)

There is a problem when I view the stream using VLC 0.8.6c: The video is 
displayed, but with wrong colours. For each JPEG, the luma part is 
displayed correctly, but the chroma parts are stretched vertically to twice 
their proper size, which results in a colour "ghost image" behind the 
actual picture. I suspect the camera uses an unusual chroma subsampling 
variant which VLC doesn't understand.

In firefox, the MJPEG stream sometimes seems to hang, IIRC you also noticed 
this.

I have written an AJAX-based web page to view the stream - IMHO, it's 
better than the Java applet. It requests snapshot images from the server as 
fast as it can. A patch is attached - the web server must return the images 
as non-cacheable, otherwise you will get a recording of the image stream 
when you visit the page a second time. This code works fine with Firefox, 
Konqueror, Opera and MSIE 6!

This is a first try, some more work is probably required to get this to 
work well. One problem: The web server sometimes seems to get into an 
infinite loop, consuming 100% CPU even though the browser no longer 
requests images. This happens more with some browsers than with others. - 
Could it be that the server will have trouble serving multiple clients at 
the same time? E.g., what happens if there is one fast client and one slow 
client who can only fetch every n-th frame?

Furthermore, it may be possible to increase performance a *lot* by 
implementing HTTP/1.1 persistent connections. However, I don't know whether 
this would work with the current JavaScript code, as the the browser might 
close the connection once one JPEG has been fetched, and open another one 
when the JavaScript requests the next one. If this is the case, some extra 
logic would be required at the server side to "force" HTTP pipelining to 
take place: The JavaScript would always need to keep _two_ image requests 
active at any time, and the server would have to delay responses and only 
deliver each webcam frame to each IP at most once. With HTTP pipelining, 
performance should be comparable to that of an MJPEG stream!

Nitpick mode: HTTP requires that the name in the "Server:" header is 
followed by a version number. Also, isn't "MJPEG" more correct than "MJPG"?

Oh, and one wishlist item: It would be cool to have an "input_http" plugin. 
That way, I could run one instance of mjpg-streamer at home, stream from 
there to another instance on a server with more bandwidth, and finally use 
that server to feed multiple clients.

Thanks for starting this nice project! :)
Cheers,

  Richard

-- 
  __   _
  |_) /|  Richard Atterer     |  GnuPG key: 888354F7
  | \/¯|  http://atterer.net  |  08A9 7B7D 3D13 3EF2 3D25  D157 79E6 F6DC 8883 
54F7
  ¯ '` ¯
diff --minimal --unified -urN mjpg-streamer.orig/Makefile mjpg-streamer/Makefile
--- mjpg-streamer.orig/Makefile 2007-10-18 13:36:22.000000000 +0200
+++ mjpg-streamer/Makefile      2007-10-20 21:24:37.181712079 +0200
@@ -21,7 +21,7 @@
 clean:
        @echo "Cleaning up directory."
        rm -f *.a *.o $(APP_BINARY) core *~ *.so *.lo
-       rm -f plugins/*/*.a plugins/*/*.o plugins/*/core plugins/*/*~ 
plugins/*/*.so
+       rm -f plugins/*/*.a plugins/*/*.o plugins/*/core plugins/*/*~ 
plugins/*/*.so plugins/*/*.lo
 
 # Applications:
 uga_buga: $(OBJECTS) input_uvc.so output_http.so output_file.so
diff --minimal --unified -urN mjpg-streamer.orig/plugins/output_http/httpd.c 
mjpg-streamer/plugins/output_http/httpd.c
--- mjpg-streamer.orig/plugins/output_http/httpd.c      2007-10-13 
10:42:31.000000000 +0200
+++ mjpg-streamer/plugins/output_http/httpd.c   2007-10-21 01:18:02.479828534 
+0200
@@ -242,8 +242,11 @@
   /* write the response */
   sprintf(buffer, "HTTP/1.0 200 OK\r\n" \
                   "Connection: close\r\n" \
-                  "Server: MJPG-Streamer\r\n" \
+                  "Server: MJPG-Streamer/0.1\r\n" \
                   "Content-type: image/jpeg\r\n" \
+                  "Cache-Control: no-store, no-cache, must-revalidate\r\n" \
+                  "Pragma: no-cache\r\n" \
+                  "Expires: Mon, 31 Jan 2000 05:00:00 GMT\r\n" \
                   "\r\n");
 
   /* send header and image now */
Binary files mjpg-streamer.orig/plugins/output_http/httpd.lo and 
mjpg-streamer/plugins/output_http/httpd.lo differ
diff --minimal --unified -urN mjpg-streamer.orig/www/javascript.html 
mjpg-streamer/www/javascript.html
--- mjpg-streamer.orig/www/javascript.html      1970-01-01 01:00:00.000000000 
+0100
+++ mjpg-streamer/www/javascript.html   2007-10-21 12:40:48.528501962 +0200
@@ -0,0 +1,51 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";>
+<html xmlns="http://www.w3.org/1999/xhtml";>
+<head>
+<title>MJPEG-Streamer</title>
+</head>
+<script type="text/javascript">
+
+/* Copyright (C) 2007 Richard Atterer, richard©atterer.net
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License, version 2. See the file
+   COPYING for details. */
+
+var imageNr = 0; // Serial number of current image
+var finished = new Array(); // References to img objects which have finished 
downloading
+var paused = false;
+
+function createImageLayer() {
+  var img = new Image();
+  img.style.position = "absolute";
+  img.style.zIndex = -1;
+  img.onload = imageOnload;
+  img.onclick = imageOnclick;
+  img.src = "/?action=snapshot&n=" + (++imageNr);
+  var webcam = document.getElementById("webcam");
+  webcam.insertBefore(img, webcam.firstChild);
+}
+
+// Two layers are always present (except at the very beginning), to avoid 
flicker
+function imageOnload() {
+  this.style.zIndex = imageNr; // Image finished, bring to front!
+  while (1 < finished.length) {
+    var del = finished.shift(); // Delete old image(s) from document
+    del.parentNode.removeChild(del);
+  }
+  finished.push(this);
+  if (!paused) createImageLayer();
+}
+
+function imageOnclick() { // Clicking on the image will pause the stream
+  paused = !paused;
+  if (!paused) createImageLayer();
+}
+
+</script>
+<body onload="createImageLayer();">
+
+<div id="webcam"><noscript><img src="/?action=snapshot" /></noscript></div>
+
+</body>
+</html>

Attachment: signature.asc
Description: Digital signature

_______________________________________________
Linux-uvc-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel

Reply via email to