summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xine_frontend.c84
1 files changed, 81 insertions, 3 deletions
diff --git a/xine_frontend.c b/xine_frontend.c
index 353f6f9d..06dd08e3 100644
--- a/xine_frontend.c
+++ b/xine_frontend.c
@@ -4,7 +4,7 @@
* See the main source file 'xineliboutput.c' for copyright information and
* how to reach the author.
*
- * $Id: xine_frontend.c,v 1.102 2009-10-08 19:51:08 phintuka Exp $
+ * $Id: xine_frontend.c,v 1.103 2009-10-08 19:52:20 phintuka Exp $
*
*/
@@ -1798,6 +1798,75 @@ static char *frame_compress_pnm(fe_t *this, int *size, vo_frame_t *frame)
return (char*)pnm;
}
+#ifdef XINE_GUI_SEND_GRAB_FRAME
+static char *fe_grab_raw_frame(fe_t *this, int *size, int jpeg, int quality, int width, int height, xine_grab_frame_t *frame)
+{
+ frame->width = width;
+ frame->height = height;
+ if (xine_port_send_gui_data(this->stream->video_out, XINE_GUI_SEND_GRAB_FRAME, frame))
+ return NULL;
+
+#ifdef HAVE_LIBJPEG
+ if (jpeg) {
+ /* Compress JPEG */
+ struct jpeg_destination_mgr jdm;
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ tJpegCompressData jcd;
+
+ jdm.init_destination = JpegCompressInitDestination;
+ jdm.empty_output_buffer = JpegCompressEmptyOutputBuffer;
+ jdm.term_destination = JpegCompressTermDestination;
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+ cinfo.dest = &jdm;
+ cinfo.client_data = &jcd;
+ cinfo.image_width = width;
+ cinfo.image_height = height;
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality(&cinfo, quality, TRUE);
+ jpeg_start_compress(&cinfo, TRUE);
+
+ JSAMPROW rp[height];
+ int rs = width * 3;
+ int k;
+ for (k = 0; k < height; k++)
+ rp[k] = frame->img + k * rs;
+ jpeg_write_scanlines(&cinfo, rp, height);
+
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+
+ *size = jcd.size;
+ return (char*) jcd.mem;
+ }
+#endif
+
+ /* convert to PNM */
+
+ /* allocate memory for result */
+ size_t bytes = width * height * 3;
+ uint8_t *pnm = malloc(bytes + 64);
+ if (!pnm) {
+ LOGMSG("fe_grab: malloc failed");
+ return NULL;
+ }
+
+ /* PNM header */
+ sprintf((char*)pnm, "P6\n%d\n%d\n255\n", width, height);
+ int hdrlen = strlen((char*)pnm);
+
+ /* copy image */
+ xine_fast_memcpy(pnm + hdrlen, frame->img, bytes);
+
+ *size = bytes + hdrlen;
+ return (char*)pnm;
+}
+#endif
+
static char *fe_grab(frontend_t *this_gen, int *size, int jpeg,
int quality, int width, int height)
{
@@ -1820,11 +1889,20 @@ static char *fe_grab(frontend_t *this_gen, int *size, int jpeg,
/* validate parameters */
if ((quality < 0) || (quality > 100))
quality = 100;
- width = (MIN(16, MAX(width, 1920)) + 1) & ~1; /* 16...1920, even */
- height = (MIN(16, MAX(width, 1200)) + 1) & ~1; /* 16...1200, even */
+ width = (MAX(16, MIN(width, 1920)) + 1) & ~1; /* 16...1920, even */
+ height = (MAX(16, MIN(width, 1200)) + 1) & ~1; /* 16...1200, even */
/* get last frame */
this->stream->xine->port_ticket->acquire(this->stream->xine->port_ticket, 0);
+#ifdef XINE_GUI_SEND_GRAB_FRAME
+ xine_grab_frame_t *grab_frame;
+ if (!xine_port_send_gui_data(this->stream->video_out, XINE_GUI_SEND_ALLOC_GRAB_FRAME, &grab_frame)) {
+ char *img = fe_grab_raw_frame(this, size, jpeg, quality, width, height, grab_frame);
+ xine_port_send_gui_data(this->stream->video_out, XINE_GUI_SEND_FREE_GRAB_FRAME, grab_frame);
+ this->stream->xine->port_ticket->release(this->stream->xine->port_ticket, 0);
+ return img;
+ }
+#endif
frame = this->stream->video_out->get_last_frame (this->stream->video_out);
if(frame)
frame->lock(frame);