Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

IP cameras and vb6 1

Status
Not open for further replies.

tedsmith

Programmer
Nov 23, 2000
1,762
AU
Yes I'm still alive, my 78th birthday is next week!
Has anybody and suggestions as to how to capture frames from an IP camera connected to the computer?
I would want these to be in a format that can be sent say one per second on a local network to other workstations for display on standard image boxes like my previous applications using USB web cameras that I have listed on this forum. They could be bitmaps of jpgs.

There are a number of progs about that use special ocx's to show IP video in a special video box but I was hoping to use ordinary vb6 controls and some APIs if this is possible.

It appears that most IP cameras send a mp4 stream.
 
I suspect that without the special OCXs you'll find this difficult in VB6; there's no real consensus on a standard API for talking to IP cameras, and even DirectShow (which VB6 doesn't really talk with very well without additional wrapper libraries) generally needs custom filters (often provided by the camera manufacturer) before it can talk to IP cameras video streams.

I can't say much more, as I've never tried getting an IP camera to work with VB6.
 
@tedsmith,

Better watch it, sonny. I'm not far behind you at 72 (gonna retire formally in 112 days) but I do not intend to stop working.

Skip,
[sub]
[glasses]Just traded in my OLD subtlety...
for a NUance![tongue][/sub]
 
Thanks.
1.
Is there a way of capturing frames to an image box of an ordinary mp4 movie using vb6?
I have noticed that the Windows media player control will play some mp4s but not others that remain blank with no error message for some reason.

2. The problem with using other ocxs is in trying to extract a frame from them.
Although it sounds a bit cludgy, is there perhaps an API that will capture the a "screen" of an invisible form containing the ocx's picture?
 
>is there perhaps an API that will capture the a "screen" of an invisible form containing the ocx's picture?
Depends on the OCX, frankly. we have previously illustrated fro you how to grab a bitmap from a device context, for example; so if your OCX maintained a dc that reflected the current image this could be pretty easy.

>Is there a way of capturing frames to an image box of an ordinary mp4 movie using vb6?
Sure. It involves writing an MPEG-4 decoder, though ...

DirectShow will allow you to do some of this stuff. But frankly not from VB6, and in general not without wrappers ...
 
Thanks
Looks like I had better get an IP camera and experiment.
The reason I want to get away from USB cameras is that they don't come with much flexibility like different lenses or zooms or quality for that matter.
 
Ted, one of the big players in IP cameras is a company called Axis.
They supply a free OCX for talking to their cameras via VB6 which enables you to do everything listed here and more:

Download and install the AxisCamControl.

Set the AxisCamControl’s URL property and get live images.

Use the SaveImage and LoadImage methods.

Use the OnNewEvent to be notified every time a new image has been captured.

Read a Jpeg image from disk and display it in the control window using the SetImage method.

Good Luck

Alan



[gray]Experience is something you don't get until just after you need it.[/gray]
 
While there is talk of "standards" there are at least two different industry groups and the odds of convergence seem small.

I suspect you'll probably have to pick a vendor and then live with the decision. If you dig deep enough you might find several vendors with products supported through a common SDK but I have doubts about that.
 
You might find this link useful:


Note: The AXIS Media Control is currently the only Windows SDK publicly available from Axis. However, additional Windows SDKs for recording and playback, camera management and camera simulation, along with technical documentation, tools and dedicated development support are available to participants of the Axis Application Development Partner (ADP) Program. If you are developing solutions to support Axis network video products, take advantage of the many commercial and technical benefits available to Axis ADPs.
 
Thanks everyone for that wealth of info.
I shall investigate.
 
Did some digging around. It looks like quite a few of these support MJPEG over HTTP. This probably means writing a client based on a Winsock control since "normal" HTTP client controls don't handle it but it doesn't sound difficult.

Beware though: it sounds as if some of the older low-end products (even the 640x480 ones) don't have the processing power to keep up or something. They "fall over" (lock up?) after a period of time. A newer "HD" unit will probably have a newer and more powerful CPU (ARM microcontroller) instead of something as cruddy as the one in a Raspberry Pi. This also gets you higher resolution of course, and maybe even better lenses.

H.264 is probably going to force you to deal with DirectShow, Windows Media Encoder, or something of the kind in a VB6 program. So MJPEG is probably a better option for the average programmer.
 
Tried a test program based on the WinHttpRequest object to download and display the Motion JPEG (MJPEG, M-JPEG) stream over HTTP from a vendor's demo camera they have online.

It works as a proof of concept, and I can get 640x480 video at about 5fps (though they are in China and I am in the US).

It isn't fit for production use as is however, since it has a serious memory leak. All of the frames of video end up buffering in RAM, accumulating forever.

This is exactly what I expected. That's why I previously suggested that there aren't any Microsoft HTTP ActiveX client controls or classes usable from VB6 that can cope with these "long poll" COMET-like streams. You'd have to work from dirt at the TCP level (ugly, since you have no SSL support without buying 3rd party libraries and you'd have to deal with some tricky HTTP operations to handle things like authentication challenges).. or sort of "in the middle" at the UrlMon.dll level or something.

I may give UrlMon a shot, since I found an old VB6 wrapper class that might be reworked for such a purpose. Depends on availability of free time and whether I stay interested. I'm not sure such a thing is worth refining into a marketable product, the VB6 library market is tiny (most people still writing VB6 won't pay for anything), and I don't work for free anymore.
 
Well that vendor seems to have taken the server (camera) down so I might not do anything further with this. I don't have any IP cameras handy to test against.
 
Thanks
Would it perhaps be possible (relatively easily) to write a sort of active-x control in a language like visual c or vbnet and use this encapsulated control in a vb6 app?
Or would I have the same sort of problem you describe?
Reason is I didn't want to rewrite my whole existing app that uses USB cameras in another language, just replace the USB camera part of it with an IP camera.

 
You might find somebody selling an ActiveX control designed to handle generic M-JPEG over HTTP streams that raises an event every frame that presents the host program with the bytes of a JPEG frame, those bytes converted to a GDI DIB, or even an IPicture object you can treat as a StdPicture for display easily in VB. Or you might roll your own.

But as far as I can tell all of the easy to use HTTP mechanisms, even those offering interim results chunk by chunk for async requests, buffer the entire response. So when receiving an M-JPEG stream more and more memory gets consumed until finally the server closes the connection or your program aborts it. This seems to be the case for the WinInet control, MSXML.XMLHTTP, WinHttpRequest, and even calls to UrlMon's URLOpenStream. With 40KB average frames times 15 f/s that's 600KB more memory used every second you stream video!

This is an issue because MJPEG over HTTP works in a "long poll" or COMET-like fashion rather than "normal" HTTP request/response operation.


So this means rolling your own async/chunking HTTP Request object first, based on raw TCP. Not trivial because you need to handle authentication. Cameras I see range from no-auth, to simple URL query string auth, to Basic Authentication and even Digest Authentication.

These cameras also appear to be quirky. Some fail to correctly implement [tt]Content-Type: multipart/x-mixed-replace[/tt] headers (which MJPEG uses) so your code would need to handle that. Based on on articles and samples I found, a few used to even have spaces instead of hyphens in response header names (sending you [tt]Content Type:[/tt] instead of [tt]Content-Type:[/tt]).

So far so good, and it just means a lot of programming and testing. Then if you have to support SSL/TLS you will need a 3rd party Winsock control replacement.


Once you have that done you need to decode the streamed content body data as you receive it chunk by chunk. Each time you have a frame of JPEG parsed out you can present that and discard those bytes of the stream. Rinse, repeat... until you abort the connection or the server closes it on you.


The last issue I can think of is that if your network is too slow or your program can't process frames fast enough eventually the server is going to close the connection on you. So you either need to set your cameras for low frame rates and small image size or else have a fast network, very optimal code, and nothing that ever steals much CPU from your M-JPEG stream processing logic.

These MJPEG cameras do not seem to drop frames on TCP congestion push-back, they drop the connection. As far as I can tell from how this content type works they have no choice.

Another solution is to use something like H.264 instead of M-JPEG over HTTP. This is less well documented and a lot harder to handle in VB6, but it doesn't require as much network bandwidth. It probably also provides for frame dropping on congestion.


I could see using C++ to create such an ActiveX control but I'd have serious doubts about doing it in a .Net language. VB6 will be superior in terms of performance because it doesn't have the potentially fatal handicap of .Net Garbage Collection. And as far as I can tell all of the .Net Framework's HTTP client libraries have the same "leak memory until end of response" issue.
 
While doing some casual browsing I came across this:

MJPEG vs. H.264

There "John" is commenting on an article by "Jason" (for which the original seems no longer available?).

Then "Jason" responds in a comment at the bottom of the page.

In between there are other people piping up with a few comments.

You might find all of it of interest for your application, especially the comments by "Polarismd" regarding court admissability, insurance company acceptance, etc.


All of these comments are 4 or more years old and the technology has advanced since then but many of the issues are probably still relevant. A big issue is that even though MJPEG eats network bandwidth and if recorded to disk eats disk like crazy but more complex alternatives eat a ton of CPU power both at the IP camera (leading to the threat of overheating) and at real-time monitor PCs and "DVR" machines.
 
Thanks,
As I only want still frames once a second and not motion, I guess I need a camera that will send a frame only on request.
Ideally if it was in a format the VB6 webbrowser control would understand, I would have the solution.
I will investigate further.
 
Most of them appear to offer the ability to just request a current single frame as a JPEG via HTTP. If that's all you need there isn't any challenge at all. The AsyncRead method can be used to retrieve those as StdPicture objects ready for display.

I have no clue how a WebBrowser control comes into the picture though. That just seems like one of the bulkiest and least flexible ways to display an image I can think of. If you had to display an animated GIF in the most quick and dirty way possible maybe, but for anything else just use an Image, PictureBox, UserControl, or Form.
 
Thanks
When you say "via HTTP" what do you mean?
Also can you give me an example of what would go in the Winsock_Dataarrival sub to feed the data into the image box?
Is is simply something like accumulating the data into a buffer then -
Set Image1.picture=Buffer or is there something else needed to separate or convert the received data into a picture?

Alternatively
The IP camera may be sending a continuous picture to another device and monitor on a ip address and fixed port. I think it will be Mp4.
Is it possible to view this stream on a different computer on the same LAN without interrupting this and intercept say one frame per second. If so, what method would be needed?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top