Question

I have VideoSec IP camera, and daemon running on embedded linux NPE controler. Daemon needs to gram images from IP camera, that part is implemented with libcurl in standard way, and with axis camera is working just fine:

static size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
     size_t written = fwrite(ptr, size, nmemb, stream);
     return written;
}

void refreshCameraImage(char *target, char *url)
{
     CURL *image;
     CURLcode imgresult;
     FILE *fp;

     image = curl_easy_init();

     if (image)
     {
          fp = fopen(target, "wb");
          if(fp == NULL)
          printf("\nFile cannot be opened");


          curl_easy_setopt(image, CURLOPT_URL, url);
          curl_easy_setopt(image, CURLOPT_WRITEFUNCTION, NULL);
          curl_easy_setopt(image, CURLOPT_WRITEDATA, fp);

          imgresult = curl_easy_perform(image);
          if( imgresult )
          {
               printf("\nCannot grab the image!");
          }
     }
     curl_easy_cleanup(image);
     fclose(fp);
}

Problem with VideoSec camera is that i cannot define any jpeg stream, only MJPEG. So, i need a way to grab only one frame from mjpeg stream with libcurl. OpenCV is not an option.

Was it helpful?

Solution

In M-JPEG, JPEG images are embedded intact and separated by textual separators with subheaders. So extracting a JPEG is an easy thing:

  • you locate first/next subheader/separator in the response body
  • you locate Content-Length value, if available
  • you skip up to \r\n\r\n to locate beginning of the JPEG data
  • you receive JPEG data to get either Content-Length number of bytes, or if length is unavailalble, you read until you get next separator

The resulting data is exactly JPEG file/image/stream.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top