Motion - Feature Request 2005x 05x 30x 143842

Feature Request: adding pixel_dif in the mjpeg stream

Description

OK Here is my last angle on this request

Embed in the Jpeg image Motion information as comments using the jpeg_write_marker function.

I have not had enough time to dissect the motion structures as they are not well commented so I threw in a bunch of attributes from the motion context structure just for testing.

1.

I made a copy of the put_jpeg_yuv420p function and gave it the signature as below where picInfo is a new parameter and is the data to embed in the jpeg

void put_jpeg_yuv420p_with_info (FILE *fp, unsigned char *image, int width, int height, int quality, char *picInfo)

2.

I added the jpeg_write_marker to the new function put_jpeg_yuv420p_with_info at the point as shown below


   jpeg_stdio_dest (&cinfo, fp);   
   jpeg_start_compress (&cinfo, TRUE);
   jpeg_write_marker(&cinfo, JPEG_COM, picInfo, strlen(picInfo));

3.

In function put_picture_fd I added the following (only test so not robust but to show the concept);

char msgBuffer[250];
sprintf(msgBuffer, "Diffs=%i\nNoise=%i\nThreshold=%i\nSnapShot=%i\nPevent=%i\nType=%i\n", cnt->diffs,cnt->noise,cnt->threshold,cnt->snapshot, cnt->prev_event, cnt->imgs.type);

and changed put_picture_fd to call

put_jpeg_yuv420p_with_info(picture, image, cnt->imgs.width, cnt->imgs.height, quality, msgBuffer);

Now

  • The mjpeg stream remains intact as per protocol
  • This is a valid Jpeg
  • Nothing is broken or convoluted.

The strings above were for testing to see what values change. Really the most important attribute is Diffs.

What do you think ?

Modified Code from picture.c

void put_picture_fd (struct context *cnt, FILE *picture, char *image, int quality)
{
   
       char msgBuffer[250];
   sprintf(msgBuffer, "Diffs=%i\nNoise=%i\nThreshold=%i\nSnapShot=%i\nPevent=%i\nType=%i\n", cnt->diffs,cnt->noise,cnt->threshold,cnt->snapshot, cnt->prev_event, cnt->imgs.type);

   
   if (cnt->conf.ppm) {
      put_ppm_bgr24(picture, image, cnt->imgs.width, cnt->imgs.height);
   } else {
      switch (cnt->imgs.type) {
         case VIDEO_PALETTE_YUV420P:
            //put_jpeg_yuv420p(picture, image, cnt->imgs.width, cnt->imgs.height, quality);
            put_jpeg_yuv420p_with_info(picture, image, cnt->imgs.width, cnt->imgs.height, quality, msgBuffer);
            break;
         case VIDEO_PALETTE_GREY:
            put_jpeg_grey(picture, image, cnt->imgs.width, cnt->imgs.height, quality);
            break;
      }
   }
}





void put_jpeg_yuv420p_with_info (FILE *fp, unsigned char *image, int width, int height, int quality, char *picInfo)
{
   int i,j;

   JSAMPROW y[16],cb[16],cr[16]; // y[2][5] = color sample of row 2 and pixel column 5; (one plane)
   JSAMPARRAY data[3]; // t[0][2][5] = color sample 0 of row 2 and column 5

   struct jpeg_compress_struct cinfo;
   struct jpeg_error_mgr jerr;
   
   data[0] = y;
   data[1] = cb;
   data[2] = cr;
   
   
   cinfo.err = jpeg_std_error(&jerr);  // errors get written to stderr 
   
   jpeg_create_compress (&cinfo);
   cinfo.image_width = width;
   cinfo.image_height = height;
   cinfo.input_components = 3;
   jpeg_set_defaults (&cinfo);

   jpeg_set_colorspace(&cinfo, JCS_YCbCr);

   cinfo.raw_data_in = TRUE; // supply downsampled data
   cinfo.comp_info[0].h_samp_factor = 2;
   cinfo.comp_info[0].v_samp_factor = 2;
   cinfo.comp_info[1].h_samp_factor = 1;
   cinfo.comp_info[1].v_samp_factor = 1;
   cinfo.comp_info[2].h_samp_factor = 1;
   cinfo.comp_info[2].v_samp_factor = 1;

   jpeg_set_quality (&cinfo, quality, TRUE);
   cinfo.dct_method = JDCT_FASTEST;

   jpeg_stdio_dest (&cinfo, fp);       // data written to file
   jpeg_start_compress (&cinfo, TRUE);
   jpeg_write_marker(&cinfo, JPEG_COM, picInfo, strlen(picInfo));


   for (j=0;j<height;j+=16) {
      for (i=0;i<16;i++) {
         y[i] = image + width*(i+j);
         if (i%2 == 0) {
            cb[i/2] = image + width*height + width/2*((i+j)/2);
            cr[i/2] = image + width*height + width*height/4 + width/2*((i+j)/2);
         }
      }
      jpeg_write_raw_data (&cinfo, data, 16);
   }

   jpeg_finish_compress (&cinfo);
   jpeg_destroy_compress (&cinfo);
}



-- RobertH - 30 May 2005

Follow up

Hmm. Interesting idea.

Maybe a good implementation would be a config option "jpeg_marker_text" which allows all the same rules as on_xxxx like time stamp, diffs, noise, coordinates etc. And let this be a general option for both normal jpegs and the mjpeg stream. If the string is empty - no marker is written.

It may open up for all sorts of usage. The code overhead is small and the user can select to use it or not.

The main problem is that this is a feature at level 4 on Kenneths NerdoMeter. But since I am proposing it myself ...

Implementation is simple since the function for writing the string based on conversion specifiers is already there and the info is in the global "cnt" structure.

I am interested in reactions from both Robert and the regular developers.

Robert, you have another feedback which I agree with. The global cnt variable is not very well documented. I have made a topic MotionCntStructureOverview which should list all the variables or members in a table. It will probably take a while before this table is complete but it is a start.

-- KennethLavrsen - 30 May 2005

Comments

Kenneth, I really like the idea of a config option such as you propose as it stays in line with the current rules and offers a lot of flexibility. The only point since this information will always be read by software and not a person we would also be required to embed the format string used to construct the data.

So we might end up with [formatString] [some delimiter] [actualData] as our payload.

-- RobertH - 30 May 2005

The method used with the conversion specifiers allow any combination of text and %-something codes. So it would be fully flexible.

E.g. jpeg_marker_text "diffs = %D, x = %K, y = %L"

or jpeg_marker_text "<D,K,L><%D><%K><%L>"

I'd rather keep things flexible. And anyone who develops viewer software can then specify the string to be used for the jpeg_marker_text option.

-- KennethLavrsen - 31 May 2005
Topic revision: r6 - 06 Jun 2005, KennethLavrsen
Copyright © 1999-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Please do not email Kenneth for support questions (read why). Use the Support Requests page or join the Mailing List.
This website only use harmless session cookies. See Cookie Policy for details. By using this website you accept the use of these cookies.