Page 1 of 1

Using another ZoneMinder box as the remote IP camera source

Posted: Tue Jan 17, 2006 12:01 pm
by conor
Hi,

What parameters or other special things are there to look out for when setting a ZoneMinder system to use the stream output from another ZoneMinder box as a remote camera source?

Which should I use, the zms or nph-zms streamer?

I'm going to test version 1.22.0 in this configuration.

Conor Downey

Posted: Tue Jan 17, 2006 12:08 pm
by jameswilson
i have personally used bioth but most people seem to recommend the nph line. All you need to do is insert the mjpeg path as the source and your in

James

Posted: Tue Jan 17, 2006 10:10 pm
by zoneminder
The nph variant is pretty much guaranteed not to have it's output munged by apache whereas the non-nph one might (or might not). The former is probably the safest bet.

Posted: Thu Jan 19, 2006 9:40 am
by candlerb
Interesting - this is something I also need to be able to do, i.e. add a remote PC with a USB webcam on it. The README mentions in passing that this is possible:
o Motion JPEG Capture. Previously image capture from
network devices has been limited to single stills capture
only. This has now changed and if you entered a remote camera
path that returns the multipart/x-mixed-replace MIME type then
this will be parsed and images extracted from the stream. This
is much faster than before and frame rates can be as fast now
with network cameras as with capture cards and video. This
feature also has the side-effect that one ZoneMinder
installation can use another as a remote video source.
Is there more detail on this? In particular, what parameters should be given in the (nph-)zms URL?

Presumably I have to configure the remote zm installation with its local camera. Can I leave its mode set to 'none', or does it have to be set at 'monitor'? (I am intending that motion detection and recording will be done on the central server only)

Also, I imagine the remote server needs its own mysql database just for configuration information, even if it's not storing events. I also expect that this has to be a different database instance to the main one (although I can point it to a second database instance on the same mysql server). Is that all correct?

Thanks, Brian.

Posted: Fri Jan 20, 2006 6:06 pm
by jameswilson
Yes you will need to run it in monitor mode as in none it wont capture any images. You will need a sql server. I have thought about experimementing with a central server running mysql and sharing a folder fot the images to be captured. As its the processing of images, motion detection etc, that takes all the power this could be distributed. I havnt done this as i dont know enough to do it, but in thery it should work. The hard bit would be tellingf zm to store its images elsewhere. Plus playabck would be strange as you would need to playback from the remote machine not the central server.

Posted: Sat Jan 21, 2006 12:05 pm
by zoneminder
Remote mounting disks is actually pretty easy. I think the problems might lie in performance of writing images to networked filesystems but until someone tries it I can't say for sure.

I've just added support in 1.22.1 for ZM to read the raw image stream I added for the viewer so that would reduce the load on cpu on both ends, though rather substantially increase the network throughput. I've also put in a zipped raw format to make a bit of a compromise.

Posted: Sat Jan 21, 2006 2:08 pm
by conor
Hi all,

Thanks for the advice all. I did try it out. I got it to work in the end but only at 360x288 image size. I could not get it to work at 512x384 (at the local and remote) which was my desired size of capture.

The other thing I noticed is that the frame rate I set for the camera at the main ZM caused it to fetch the picture that number of times per second. I read this from the Apache logs of the remote. Therefore shouldn't the setting passed be single and not jpeg. I then wanted it to view the camera in the view window from the remote instance of ZM and not stream it from the main instance. This is of an advantage because it means that there is less strain placed on the local ZM. Of course if it uses the remote string set in the local database and you then go to view it you only see a snapshot because that is what is in the Path string. In any case I modified the getStreamRemoteSrc function in zm_funcs.php to use the jpeg parameter to give me a stream from the remote within zm_html_view_watchfeed.php and this then worked. Crude but it proved the concept. This is useful for non-ZM remotes as well because it is recieving the picture directly from the remote, reducing the strain on the main ZM instance. However it should be optional which is viewed I guess - from main ZM or directly from the remote - useful for debugging.

As James has suggested an ideal is to have ZM remotes using the MySQL instance of a main ZM box. This allows them to boot from flash disk for instance. The most mature method for mounting directories and copying files across is NFS. Each remote instance must mount the events directory and copy it's files there. However I'm unsure about the implications for table locking on a busy main ZM system but it could be made workable I feel.

To enable a remote ZM instance to use a main ZM box I suggest that there is another Type added to the Monitors table which is ZM. The Host field could then be an identifier that is set up on the remote so that it only looks for Monitors which are of ZM type and have the identifier it has been configured with in the host field. This gets round an awkwardness with remote ZM instances where the Monitor Id is different between the remote and main - they will be the same. The device and channel are all set up on the main ZM so that is what the remote uses. When it comes to writing events.

I've not got my two ZM boxes anymore but I'll try and build a second one using this concept and see how it goes.

Conor Downey

Posted: Sat Jan 21, 2006 11:51 pm
by jameswilson
good luck sound intersting for scaling, but would clustering be easier to administer?

Posted: Tue Jan 24, 2006 1:46 pm
by candlerb
I have this working now. For reference, this is how it looks:

Code: Select all

  QuickCam 4000                 old QuickCam
   pwc driver                   qc-usb driver
       |           HTTP             |
Central ZM ------------------> Remote ZM
       |                            |
       v                            |
database "zm"                       |
database "zm2" <--------------------'
    mysql
Web users connect to the Central ZM instance only, which lists two cameras.

I modified db/schema.sql to create a database called "zm2", and then created a user for the remote ZM machine with privileges to update it. Once this was done, running zmconfig.pl on the remote ZM was able to post its updated settings to database zm2 on the central server. This saved me having to install mysql on the remote server.

The remote ZM machine didn't have php installed, so for simplicity to configure it I copied a row from zm.Monitors to zm2.Monitors and edited it by hand. (For this purpose it might be nice if the PHP pages could access multiple database instances). I had to start Apache in order to get /cgi-bin/zms to be served - a standalone zms might be nice too.

I used /cgi-bin/nph-zms?mode=jpeg&monitor=1&scale=100&maxfps=5 as the URL on the central server to retrieve images from the remote camera. The remote server is set to 'Monitor' mode only and doesn't use up any disk space; the central server is in 'Mocord' mode for both the local and remote cameras.

This all works well, although it was a lot more hassle to set up than a real IP camera :-)

Perhaps one day it would be nice if the remote ZM could be standalone, analysing and storing its own images and events. Then clicks on the central ZM would cause events to be replayed from either the local or remote ZM directly (a sort of "unified view" across multiple ZM installations). That would scale really well, for CPU usage, disk usage, and network bandwidth. But I suspect there would be a fair amount of work involved.

Actually... given zm's split frontend/backend architecture, it might not be so bad. You'd need to break the linkage that all cameras and events are in the local mysql database (i.e. be able to point to a different mysql database for each camera). For image playback you'd need to specify an absolute URL http://remote.hostname/cgi-bin/zms?... instead of relative /cgi-bin/zms?... And that might be all.

Suppose you had a table of sites:

Code: Select all

siteid  mysql_hostname  mysql_db  mysql_user  mysql_pass  zms_url
------  --------------  --------  ----------  ----------  -------
   1    localhost       zm        zm          foobar      /cgi-bin/zms
   2    rem.example.com zm        zm          foobar2     http://rem.example.com/cgi-bin/zms
...
This is more or less the same as the existing /usr/local/etc/zm.conf but with multiple entries.

Then the PHP could iterate over all the sites, list all the cameras (displaying siteid:id instead of just id), access all the events from the appropriate database, replay images directly from the remote site, and so on. The remote sites could also be configured to access other remote sites; or they could display just their local cameras; or they could be completely without a local frontend (running zmc, the perl scripts and zms, but needing no PHP)

Anyway, this is all blue sky, so I'll stop speculating now :-)

Regards, Brian.

Posted: Tue Jan 24, 2006 2:19 pm
by candlerb
conor wrote:The other thing I noticed is that the frame rate I set for the camera at the main ZM caused it to fetch the picture that number of times per second. I read this from the Apache logs of the remote.
I see this too (zm-1.21.4). The code in zm_remote_camera.cpp looks like it ought to loop over the stream. I get a bunch of these messages logged though:

Code: Select all

Jan 24 14:04:05 webcam zmc_m3[21731]: ERR [Found unsupported content type 'Y ü· ü·í!ü·¥$ü·+%ü·²%ü·&ü·&ü·Á&ü·(ü·])ü·²)ü·"*ü·¼*ü·ð*ü·,ü·´,ü·Ý,ü·ö,ü·û.ü·/ü·Ë/ü·ü/ü·(0ü·ö0ü·<1ü·K1ü·S1ü·¾1ü·)2ü·F3ü·k4ü·û4ü·¹6ü·f8ü·×8ü·9ü·«9ü·×9ü·-:ü·:=ü·>ü·¾>ü·E?ü·+@ü·JAü·Aü·Bü·±Bü·vCü·Cü·+Dü·rDü·°Eü·PGü·úGü·Hü·<Hü·[Jü·©Jü·íJü·Kü·mLü·­Lü·iMü·Nü·Nü·
        Oü·ÚOü·Qü·>Qü·$¯û·°û·°û·Î°û·B±û·D±û·X²û·Z²û·½²û·³û·X³û·f³û·òþû·']
Jan 24 14:04:05 webcam zmc_m3[21731]: WAR [Unable to use netcam regexps as not compiled with libpcre]
Jan 24 14:04:06 webcam zmc_m3[21731]: WAR [Unable to use netcam regexps as not compiled with libpcre]
Jan 24 14:04:06 webcam zmc_m3[21731]: ERR [Found unsupported content type 'ë°ü·ñ°ü·     ²ü·z²ü·²ü·1³ü·³ü·']
Jan 24 14:04:06 webcam zmc_m3[21731]: WAR [Unable to use netcam regexps as not compiled with libpcre]
Jan 24 14:04:06 webcam zmc_m3[21731]: WAR [Unable to use netcam regexps as not compiled with libpcre]
Jan 24 14:04:06 webcam zmc_m3[21731]: ERR [Found unsupported content type 'ûUý·jVý·Vý·úVý·ÎWý·Xý·£Xý·/Zý· Zý·ÐZý·[ý·Y[ý·\ý·\ý·\ý·Ç\ý·-]ý·ð^ý·=_ý·V_ý··_ý·ð_ý·1`ý·òaý·cý·dý·ëeý·Úfý·4ký·Tlý·ßlý·çlý·ný·oý·éoý·ôoý·Òpý·¤qý·rý·^rý·©rý·Þrý·Usý·fsý·sý·ìsý·3uý·Ëuý·¿vý·qyý·ø{ý·|ý·|ý·Y|ý·|ý·¶}ý·-~ý·<~ý·']
Jan 24 14:04:06 webcam zmc_m3[21731]: WAR [Unable to use netcam regexps as not compiled with libpcre]
and if I enable Tools -> ZM_EXTRA_DEBUG with level 4 it looks like the client and server are getting out of sync somehow:

Code: Select all

01/24/06 14:09:11.211234 zmc_m3[24277].DB3-zm_remote_camera.cpp/154 [Connected to host, socket = 7]
01/24/06 14:09:11.211755 zmc_m3[24277].DB3-zm_remote_camera.cpp/174 [Request sent]
01/24/06 14:09:11.211964 zmc_m3[24277].WAR-zm_remote_camera.cpp/514 [Unable to use netcam regexps as not compiled with libpcre]
01/24/06 14:09:11.230820 zmc_m3[24277].DB3-zm_remote_camera.cpp/219 [Expecting 255 bytes]
01/24/06 14:09:11.231102 zmc_m3[24277].DB3-zm_remote_camera.cpp/244 [Read 255 bytes]
01/24/06 14:09:11.231280 zmc_m3[24277].DB3-zm_remote_camera.cpp/770 [Unable to extract entire header from stream, continuing]
01/24/06 14:09:11.235127 zmc_m3[24277].DB3-zm_remote_camera.cpp/219 [Expecting 68 bytes]
01/24/06 14:09:11.235427 zmc_m3[24277].DB3-zm_remote_camera.cpp/244 [Read 68 bytes]
01/24/06 14:09:11.235603 zmc_m3[24277].DB3-zm_remote_camera.cpp/696 [Got status '200' (OK), http version 1.0]
01/24/06 14:09:11.235754 zmc_m3[24277].DB3-zm_remote_camera.cpp/718 [Got content type 'multipart/x-mixed-replace']
01/24/06 14:09:11.235907 zmc_m3[24277].DB3-zm_remote_camera.cpp/727 [Got content boundary '--ZoneMinderFrame']
01/24/06 14:09:11.236058 zmc_m3[24277].DB3-zm_remote_camera.cpp/880 [Unable to extract subheader from stream, retrying]
01/24/06 14:09:11.242661 zmc_m3[24277].DB3-zm_remote_camera.cpp/219 [Expecting 70 bytes]
01/24/06 14:09:11.243034 zmc_m3[24277].DB3-zm_remote_camera.cpp/244 [Read 70 bytes]
01/24/06 14:09:11.243266 zmc_m3[24277].DB4-zm_remote_camera.cpp/829 [Got boundary subheader '--ZoneMinderFrame
Content-Length: 20012
Content-Type: image/jpeg

']
01/24/06 14:09:11.243535 zmc_m3[24277].DB4-zm_remote_camera.cpp/835 [Got content length subheader ' 20012']
01/24/06 14:09:11.243903 zmc_m3[24277].DB4-zm_remote_camera.cpp/841 [Got content type subheader ' image/jpeg']
01/24/06 14:09:11.244200 zmc_m3[24277].DB3-zm_remote_camera.cpp/861 [Got boundary '--ZoneMinderFrame']
01/24/06 14:09:11.244615 zmc_m3[24277].DB3-zm_remote_camera.cpp/867 [Got subcontent length '20012']
01/24/06 14:09:11.245183 zmc_m3[24277].DB3-zm_remote_camera.cpp/874 [Got subcontent type 'image/jpeg']
01/24/06 14:09:11.245665 zmc_m3[24277].DB3-zm_remote_camera.cpp/219 [Expecting 20016 bytes]
01/24/06 14:09:11.246039 zmc_m3[24277].DB3-zm_remote_camera.cpp/244 [Read 20016 bytes]
01/24/06 14:09:11.246255 zmc_m3[24277].DB3-zm_remote_camera.cpp/918 [Got end of image by length, content-length = 20012]
01/24/06 14:09:11.246440 zmc_m3[24277].DB3-zm_remote_camera.cpp/983 [Returning 20012 (20016) bytes of captured content]
01/24/06 14:09:11.411469 zmc_m3[24277].WAR-zm_remote_camera.cpp/514 [Unable to use netcam regexps as not compiled with libpcre]
01/24/06 14:09:11.411736 zmc_m3[24277].DB3-zm_remote_camera.cpp/880 [Unable to extract subheader from stream, retrying]
01/24/06 14:09:11.446597 zmc_m3[24277].DB3-zm_remote_camera.cpp/219 [Expecting 70 bytes]
01/24/06 14:09:11.447157 zmc_m3[24277].DB3-zm_remote_camera.cpp/244 [Read 70 bytes]
01/24/06 14:09:11.447568 zmc_m3[24277].DB4-zm_remote_camera.cpp/835 [Got content length subheader ' 19886']
01/24/06 14:09:11.447805 zmc_m3[24277].DB4-zm_remote_camera.cpp/841 [Got content type subheader ' image/jpeg']
01/24/06 14:09:11.448034 zmc_m3[24277].DB3-zm_remote_camera.cpp/880 [Unable to extract subheader from stream, retrying]
01/24/06 14:09:11.448302 zmc_m3[24277].DB3-zm_remote_camera.cpp/219 [Expecting 15432 bytes]
01/24/06 14:09:11.448724 zmc_m3[24277].DB3-zm_remote_camera.cpp/244 [Read 15432 bytes]
01/24/06 14:09:11.448964 zmc_m3[24277].DB3-zm_remote_camera.cpp/880 [Unable to extract subheader from stream, retrying]
01/24/06 14:09:11.449144 zmc_m3[24277].DB3-zm_remote_camera.cpp/219 [Expecting 4458 bytes]
01/24/06 14:09:11.449366 zmc_m3[24277].DB3-zm_remote_camera.cpp/244 [Read 4458 bytes]
01/24/06 14:09:11.450229 zmc_m3[24277].DB3-zm_remote_camera.cpp/861 [Got boundary '8üÙcÆ|Ñlì;×a©éóè·÷BÄHÐÜ«$w#¶vR1õïéU>Ù´2ßß;ìI"êïú×Mã-FÊÚ2HVfµrTÀãh-ØpÝó®▒²ªâ»▒]Es#?ÃrOàíÖGÌáBëÓ2=qí^^c£jSøÅ º¤7']
01/24/06 14:09:11.450413 zmc_m3[24277].DB3-zm_remote_camera.cpp/867 [Got subcontent length '0']
01/24/06 14:09:11.450749 zmc_m3[24277].DB3-zm_remote_camera.cpp/874 [Got subcontent type '½ý·ý·ý·ý·Fý·Cý·ý·-ý·ý·Êý·▒ý·»▒ý·Û▒ý·p·x·¨·0ý·ý·þý·Lý·cý·Qý·rý· ý·
                                                                           !ý·T!ý"ý·3$ý·©$ý·±$ý·i%ý·|%ý·%ý·å%ý·A&ý·!(ý·D(ý·(ý·á*ý·r,ý·¬.ý/ý·P/ý·s/ý·L0ý·j0ý·Þ0ý·Æ2ý·4ý·84ý·4ý·  5ý·L5ý·.6ý·S8ý·Y8ý·;:ý·C:ý·H<ý·L<ý·=ý·¢=ý·Î=ý·×=ý·>ý·>ý·>ý·>ý·Æ?ý·▒Aý·bCý·Cý·;ü·Fü·Xü·ßü·ü·Qü·Xü·ü·½ü·ü·Éü·Ñü·~ü·ü·ý·Dý·w¥ü·¥ü·ú¥ü·A']
01/24/06 14:09:11.451315 zmc_m3[24277].ERR-zm_remote_camera.cpp/894 [Found unsupported content type '½ý·ý·ý·ý·Fý·Cý·ý·-ý·ý·Êý·▒ý·»▒ý·Û▒ý·p·x·¨·0ý·ý·þý·Lý·cý·Qý·rý· ý·
      !ý·T!ý"ý·3$ý·©$ý·±$ý·i%ý·|%ý·%ý·å%ý·A&ý·!(ý·D(ý·(ý·á*ý·r,ý·¬.ý/ý·P/ý·s/ý·L0ý·j0ý·Þ0ý·Æ2ý·4ý·84ý·4ý·       5ý·L5ý·.6ý·S8ý·Y8ý·;:ý·C:ý·H<ý·L<ý·=ý·¢=ý·Î=ý·×=ý·>ý·>ý·>ý·>ý·Æ?ý·▒Aý·bCý·Cý·;ü·Fü·Xü·ßü·ü·Qü·Xü·ü·½ü·ü·Éü·Ñü·~ü·ü·ý·Dý·w¥ü·¥ü·ú¥ü·A']
01/24/06 14:09:11.613785 zmc_m3[24277].DB3-zm_remote_camera.cpp/154 [Connected to host, socket = 7]
01/24/06 14:09:11.614109 zmc_m3[24277].DB3-zm_remote_camera.cpp/174 [Request sent]
Syslogs at the remote side aren't very informative, although I've not turned on debugging there:

Code: Select all

Jan 24 14:58:53 emi kernel: quickcam: frame lost
Jan 24 14:59:24 emi last message repeated 29 times
Jan 24 15:00:25 emi last message repeated 58 times
Jan 24 15:01:26 emi last message repeated 57 times
Jan 24 15:02:21 emi last message repeated 52 times
Jan 24 15:02:22 emi zmc_dvideo0[16599]: INF [ground-floor: 67000 - Capturing at 4.76 fps]
Jan 24 15:02:22 emi kernel: quickcam: frame lost
Jan 24 15:02:53 emi last message repeated 29 times
Jan 24 15:03:54 emi last message repeated 57 times
Jan 24 15:04:55 emi last message repeated 58 times
I guess I can install pcre-devel and rebuild zm, but it looks like things aren't working when pcre is not available.

Cheers, Brian.

Posted: Tue Jan 24, 2006 2:56 pm
by zoneminder
I would try using libpcre.a. The basic analysis works for some sources but sometimes seems to fail when it otherwise looks valid.

Posted: Tue Jan 24, 2006 3:00 pm
by zoneminder
candlerb wrote:Perhaps one day it would be nice if the remote ZM could be standalone, analysing and storing its own images and events. Then clicks on the central ZM would cause events to be replayed from either the local or remote ZM directly (a sort of "unified view" across multiple ZM installations). That would scale really well, for CPU usage, disk usage, and network bandwidth. But I suspect there would be a fair amount of work involved.

[snip]

Anyway, this is all blue sky, so I'll stop speculating now :-)
You make some good suggestions and I'll add them to the todo list. This is one of those areas that wasn't really considered when ZM started but has evolved and is now starting to outgroup the slightl Heath Robinson hacks used to support it. I agree that a top-down rework of the remote ZM concept would make it the systems a lot more expandable and flexible.

Posted: Wed Jan 25, 2006 12:00 pm
by candlerb
zoneminder wrote:I would try using libpcre.a. The basic analysis works for some sources but sometimes seems to fail when it otherwise looks valid.
Like you, when I see something which needs doing, I find it hard to put down :-)

I think I've found the problems:
(a) content_boundary_len was not declared as static, so after each frame a random value was used. This meant that the frame boundary was not being matched.
(b) there was some dubious updating of buffer pointers when Consume()ing data. At least, I think it's right now.

I haven't given this an enormous amount of testing but it seems to be streaming properly now. Regards, Brian.

Code: Select all

--- src/zm_remote_camera.cpp.orig       2006-01-24 14:41:33.000000000 +0000
+++ src/zm_remote_camera.cpp 2006-01-25 11:46:31.000000000 +0000
@@ -557,7 +557,7 @@
             static int content_length;
             static char content_type[32];
             static char content_boundary[64];
-            int content_boundary_len;
+            static int content_boundary_len;

             while ( true )
             {
@@ -602,7 +602,7 @@
                                {
                                        *header_ptr = '\0';
                                        header_ptr += crlf_len;
-                                       header_len -= buffer.Consume( header_ptr-(char *)buffer );
+                                       header_len -= buffer.Consume( crlf_len );
                                        all_headers = true;
                                        break;
                                }
@@ -617,7 +617,7 @@
                                {
                                        *header_ptr = '\0';
                                        header_ptr += crlf_len;
-                                       header_len -= buffer.Consume( header_ptr-(char *)buffer );
+                                       header_len -= buffer.Consume( crlf_len );
                                }
                             }

@@ -650,8 +650,8 @@
                                {
                                        Debug( 6, ( "Got ignored header '%s'", header_ptr ));
                                }
+                               header_len -= buffer.Consume( crlf - header_ptr );
                                header_ptr = crlf;
-                               header_len -= buffer.Consume( header_ptr-(char *)buffer );
                             }
                             else
                             {
@@ -747,7 +747,7 @@
                             else if ( !strcasecmp( content_type, "multipart/x-mixed-replace" ) )
                             {
                                // Image stream, so start processing
-                               if ( !content_boundary )
+                               if ( !content_boundary[0] )
                                {
                                        Error(( "No content boundary found in header '%s'", content_type_header ));
                                        exit( -1 );
@@ -798,7 +798,7 @@
                                {
                                        *subheader_ptr = '\0';
                                        subheader_ptr += crlf_len;
-                                       subheader_len -= buffer.Consume( subheader_ptr-(char *)buffer );
+                                       subheader_len -= buffer.Consume( crlf_len );
                                        all_headers = true;
                                        break;
                                }
@@ -813,7 +813,7 @@
                                {
                                        *subheader_ptr = '\0';
                                        subheader_ptr += crlf_len;
-                                       subheader_len -= buffer.Consume( subheader_ptr-(char *)buffer );
+                                       subheader_len -= buffer.Consume( crlf_len );
                                }
                             }

@@ -844,8 +844,8 @@
                                {
                                        Debug( 6, ( "Got ignored subheader '%s' found", subheader_ptr ));
                                }
+                               subheader_len -= buffer.Consume( crlf - subheader_ptr );
                                subheader_ptr = crlf;
-                               subheader_len -= buffer.Consume( subheader_ptr-(char *)buffer );
                             }
                             else
                             {

Posted: Wed Jan 25, 2006 2:15 pm
by candlerb
Actually, those buffer manipulations were OK after all - I see the overloading of the (char *) operator in zm_buffer.h which means it's really the 'head' pointer which is returned.

So here's a reduced patch, which I've tested and also works.

Code: Select all

--- src/zm_remote_camera.cpp.orig       2006-01-24 14:41:33.000000000 +0000
+++ src/zm_remote_camera.cpp    2006-01-25 14:08:09.000000000 +0000
@@ -557,7 +557,7 @@
                static int content_length;
                static char content_type[32];
                static char content_boundary[64];
-               int content_boundary_len;
+               static int content_boundary_len;

                while ( true )
                {
@@ -747,7 +747,7 @@
                                                else if ( !strcasecmp( content_type, "multipart/x-mixed-replace" ) )
                                                {
                                                        // Image stream, so start processing
-                                                       if ( !content_boundary )
+                                                       if ( !content_boundary[0] )
                                                        {
                                                                Error(( "No content boundary found in header '%s'", content_type_header ));
                                                                exit( -1 );

Posted: Thu Jan 26, 2006 12:24 am
by zoneminder
Thanks for having a rummage around! That's pretty gash code in there, just trying to speed up the processing without using regexps. The first of your mods I think someone else spotted a couple of weeks ago and should in 1.22.0 already but your second change looks kosher so I'll put that in.

Cheers