From e4e577063a7d0cf8c093cd7cc3c6ca01fff8e6dc Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Fri, 5 Apr 2013 09:44:20 +0200 Subject: [PATCH] OpenGL: added keys for screenshot and pause --- src/video_codec.c | 23 +++++++++++++++++++ src/video_codec.h | 1 + src/video_display/gl.c | 52 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/src/video_codec.c b/src/video_codec.c index d453b0caa..c9ac29c04 100644 --- a/src/video_codec.c +++ b/src/video_codec.c @@ -909,6 +909,29 @@ static void vc_copylineToUYVY(unsigned char *dst, const unsigned char *src, int } } +/** + * Converts UYVY to RGB + * Uses Rec. 709 with standard SDI ceiling and floor + * @todo make it faster if needed + */ +void vc_copylineUYVYtoRGB(unsigned char *dst, const unsigned char *src, int dst_len) { + while(dst_len > 0) { + register int y1, y2, u ,v; + u = *src++; + y1 = *src++; + v = *src++; + y2 = *src++; + *dst++ = min(max(1.164*(y1 - 16) + 1.793*(v - 128), 0), 255); + *dst++ = min(max(1.164*(y1 - 16) - 0.534*(v - 128) - 0.213*(u - 128), 0), 255); + *dst++ = min(max(1.164*(y1 - 16) + 2.115*(u - 128), 0), 255); + *dst++ = min(max(1.164*(y2 - 16) + 1.793*(v - 128), 0), 255); + *dst++ = min(max(1.164*(y2 - 16) - 0.534*(v - 128) - 0.213*(u - 128), 0), 255); + *dst++ = min(max(1.164*(y2 - 16) + 2.115*(u - 128), 0), 255); + + dst_len -= 6; + } +} + /** * Converts RGB to UYVY. * Uses full scale Rec. 601 YUV (aka JPEG) diff --git a/src/video_codec.h b/src/video_codec.h index 3bda0733a..1eac9d8b7 100644 --- a/src/video_codec.h +++ b/src/video_codec.h @@ -114,6 +114,7 @@ void vc_copylineABGRtoRGB(unsigned char *dst, const unsigned char *src, int len) void vc_copylineRGBAtoRGBwithShift(unsigned char *dst, const unsigned char *src, int len, int rshift, int gshift, int bshift); void vc_copylineRGBtoRGBA(unsigned char *dst, const unsigned char *src, int len, int rshift, int gshift, int bshift); void vc_copylineRGBtoUYVY(unsigned char *dst, const unsigned char *src, int len); +void vc_copylineUYVYtoRGB(unsigned char *dst, const unsigned char *src, int len); void vc_copylineBGRtoUYVY(unsigned char *dst, const unsigned char *src, int len); void vc_copylineRGBAtoUYVY(unsigned char *dst, const unsigned char *src, int len); void vc_copylineBGRtoRGB(unsigned char *dst, const unsigned char *src, int len); diff --git a/src/video_display/gl.c b/src/video_display/gl.c index a2bb6704f..5b04b926f 100644 --- a/src/video_display/gl.c +++ b/src/video_display/gl.c @@ -209,6 +209,7 @@ struct state_gl { struct timeval tv; bool sync_on_vblank; + bool paused; }; static struct state_gl *gl; @@ -230,6 +231,7 @@ static void glut_key_callback(unsigned char key, int x, int y); static void glut_close_callback(void); static void glut_resize_window(struct state_gl *s); static void display_gl_enable_sync_on_vblank(void); +static void screenshot(struct state_gl *s); #ifdef HAVE_MACOSX void NSApplicationLoad(void); @@ -304,6 +306,7 @@ void * display_gl_init(char *fmt, unsigned int flags) { pthread_mutex_init(&s->lock, NULL); pthread_cond_init(&s->reconf_cv, NULL); + s->paused = false; s->fs = FALSE; s->deinterlace = FALSE; s->video_aspect = 0.0; @@ -640,6 +643,45 @@ static void display_gl_enable_sync_on_vblank() { #endif } +static void screenshot(struct state_gl *s) +{ + unsigned char *data = NULL, *tmp = NULL; + int len = s->tile->width * s->tile->height * 3; + if (s->frame->color_spec == RGB) { + data = (unsigned char *) s->buffers[s->image_display]; + } else { + data = tmp = (unsigned char *) malloc(len); + if (s->frame->color_spec == UYVY) { + vc_copylineUYVYtoRGB(data, (const unsigned char *) + s->buffers[s->image_display], len); + } else if (s->frame->color_spec == RGBA) { + vc_copylineRGBAtoRGB(data, (const unsigned char *) + s->buffers[s->image_display], len); + } + } + + if(!data) { + return; + } + + char name[128]; + time_t t; + struct tm time_tmp; + + t = time(NULL); + localtime_r(&t, &time_tmp); + + strftime(name, sizeof(name), "screenshot-%a, %d %b %Y %T %z.pnm", + &time_tmp); + FILE *out = fopen(name, "w"); + if(out) { + fprintf(out, "P6\n%d %d\n255\n", s->tile->width, s->tile->height); + fwrite(data, 1, len, out); + fclose(out); + } + free(tmp); +} + /** * This function must be called only from GL thread * (display_thread_gl) !!! @@ -775,6 +817,9 @@ static void glut_idle_callback(void) gl_check_error(); + if(s->paused) + goto processed; + switch(s->frame->color_spec) { case DXT1: glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, @@ -832,6 +877,7 @@ static void glut_idle_callback(void) gl_draw(s->aspect); glutPostRedisplay(); +processed: pthread_mutex_lock(&s->lock); pthread_cond_signal(&s->processed_cv); s->processed = TRUE; @@ -864,6 +910,12 @@ static void glut_key_callback(unsigned char key, int x, int y) gl->deinterlace = gl->deinterlace ? FALSE : TRUE; printf("Deinterlacing: %s\n", gl->deinterlace ? "ON" : "OFF"); break; + case ' ': + gl->paused = !gl->paused; + break; + case 's': + screenshot(gl); + break; } }