Video from mjpgStream

Hey. I just got my hands on a wireless axis cameras (207W), which serves up both MPEG-4 and AVI mjpg streams … with a really sharp image. Unfortunately, the MPEG-4 stream has a considerable delay and the mjpg stream isn’t supported by QuickTime.

However, the camera’s server has a .cgi script that returns JPEG images and I thought it would be possible to just read the raw data and then return it into a FreeImage bitmap and then transfer the bitmap into a texture (or maybe there is a faster way to do it).

I can copy the data from the image using curl, which returns a string. FreeImage wants a byte buffer and it’s not clear to me how to transform the string to make FreeImage happy. I guess this is more of a C question than anything else.

  
  
  
// this would be the jpeg data from the .cgi script  
string buffer = "this is just a test";  
  
// copy the string to a byte array  
char * barray = new char[buffer.size()];  
std::copy(buffer.begin(), buffer.end(), barray);  
  
// allocate a memory buffer and load temporary data   
BYTE * mem_buffer = (BYTE*)malloc(buffer.size());   
  
// copy the byte array   
memcpy(mem_buffer, barray, buffer.size());  
  
FIMEMORY *hmem = FreeImage_OpenMemory(mem_buffer, buffer.size());   
  
  

I’ll ask on the FreeImage list as well.

Thanks!

Jeremy

hey - this post which deals with loading a image to freeimage from a url might be useful!

If you already have the bytes as a c-string you can ignore all the poco stuff and just use the freeimage code.

(2nd to last post)
http://forum.openframeworks.cc/t/loading-ofimage-from-url-using-poco/562/0

Hope that helps!

hey again … just returning to an old thread.

i’ve been working an addon that uses FFMPEG to decode the motion jpeg stream coming from the axis cam. the camera is serving up 30 fps at 640 x 480 (in a browser), but the addon only runs at 15 fps in oF. i’m wondering if it’s the library or my implementation of the code, which is based on this example: http://www.dranger.com/ffmpeg/tutorial04.html

it crossed my mind that it could be an issue with my threading approach. i spawn the thread right after the connection with the camera is made. the thread reads a frame, converts the pixels to RGB, and then stores them in a buffer. i call lock, then copy the pixels to the public buffer, and then call unlock and the set the flag to indicate that there is a new frame. this thread performs as fast as possible … no delays, pauses, etc. is this the right way to be handling this?

anybody here familar with FFMPEG? just in case … i’ll post some code.

jeremy

  
  
  
int ofxMjpegStreamViewer::grabFrameThreaded(){  
  
	while(true){  
  
		// reading the data  
		int frameFinished=0;  
		AVPacket packet;  
  
		int i=0;  
		while(av_read_frame(pFormatCtx, &packet)>=0 && frameFinished==0) {  
		  // Is this a packet from the video stream?  
		  if(packet.stream_index==videoStream) {  
			// Decode video frame  
			avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, packet.data, packet.size);  
			  
			//printf("frameFinished %i\n", frameFinished);  
			  
			// Did we get a video frame?  
			if(frameFinished) {  
			// Convert the image from its native format to RGB  
				img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24,   
					(AVPicture*)pFrame, pCodecCtx->pix_fmt,   
					pCodecCtx->width, pCodecCtx->height);  
			  
			}  
		  }  
		    
		  //printf("frame read!\n");  
			  
		  // Free the packet that was allocated by av_read_frame  
		    
		}  
		  
		av_free_packet(&packet);  
		  
		frameThread.lock();  
		  
		copyPixels();  
		  
		frameThread.unlock();  
		  
		bIsFrameNew = true;  
  
		bFrameLoaded = 1;  
		  
		frameCount++;  
	  
	}  
}  
  

Hi Mantissa

I’m looking for the same thing. I want to load videos on the fly without having the app freeze for a couple of seconds. Did you get this to work with ffmpeg in the end? If you did, would you mind sharing som source?

I’m compleately new to ffmpeg and don’t really know how to even compile it for windows (VS or CodeBlocks). So if anyone has a compiled ffmpeg lib, that would be great too!

Or could i do this with the quicktime lib?

/cj

Hey CJ,

What kind of video files are you trying to play back? The motion jpeg streams were coming from IP cameras. Unfortunately I wasn’t able to work with multiple using this code.

I do believe that Zach came up with a better solution for doing this.

But I’ll gladly post my code if you’re interested.

Jeremy

Hey,

Ok, I’m looking for a way to load “any” video on the fly. But i think i found a solution through Zach’s Liners code.

However I have another project where i would very much like to look into faster IP camera communication. I have a Vivotek camera which i so far have only been able to communicate with through analogue video and/or http requests for still images.

Is the code you came up with specific to an Axis camera or is it more general. Sorry, but I’m not very familiar with the mjpg protocols yet. Would love to have a look at how you did it anyway!

cheers
/cj

You not find a general solution for “any” type of video. if you want to use a collection of QuickTime movies, then definitely use QuickTime. Zach’s liners code demonstrates how to load files on the fly using threading. it works like a charm.

Re: FFMPEG – it’ll work with any IP camera that uses MJPEG compression. I have to check with a client about the code. i hope to get back to you about in the next day or two. I was able to get it running at 640 x 480 at 15 frames per second … you might find that analog video importing will have faster performance.

Jeremy

this is my mjpeg / axis camera reading code. it still needs some love (right now there is a BGR / RGB issue) , but it’s fast :slight_smile:

mac only, project compiles for 0.05. it’s a port of some quartz composer code:

http://visiblevisible.org/deliver/marco-…-WithOF.zip

and a movie describing how it works and an outstanding issues (byte
order) and an important point (need to compile with openmp):

http://visiblevisible.org/deliver/marco-…-WithOF.mov

I don’t think it will work with multiple cameras (but maybe it’s possible to
make it work)…

take care!
zach

(also – requires compilation against OS 10.5 since it uses some new qtkit decompression, which might require a small amount of hacking in OF – I can’t remember, but I think I had to comment out vertical sync code)

Hi Zach!
This code was a perfect help for Charli and me in Berlin to get the signal from a Axis camera!

I just add couple things: RGB conversion and fix a memory leak that was, adding a: CGImageRelease( m_cgImageRef);

cheers,

Mar

AxisCameraPatch.zip