--- mintv/mintv.cpp 2003/02/08 17:51:47 1.1 +++ mintv/mintv.cpp 2003/09/24 16:35:16 1.7 @@ -22,24 +22,31 @@ #include #include #include +#include #include #include #include #include +static bool ntsc = false; + const int PAL_WIDTH = 384; const int PAL_HEIGHT = 288; -const int NTSC_WIDTH = 320; +const int NTSC_WIDTH = 360; const int NTSC_HEIGHT = 240; -static int grab_width, grab_height; +static int grab_width = -1, grab_height; static int image_width, image_height; static int win_width, win_height; -const int PAL_FPS = 50; -const int NTSC_FPS = 60; +const double PAL_FPS = 50.0; +const double NTSC_FPS = 59.94; + +static double fps; -static int fps; +static int brightness = 50, contrast = 50, color = 50; + +static int channel = 1; #define XV_FORMAT 0x32595559 #define BYTES_PER_PIXEL 2 @@ -77,8 +84,125 @@ static void quit(Widget widget, XEvent * exit(0); } +static void set_bcc(void) +{ + video_picture pict; + if (ioctl(fd, VIDIOCGPICT, &pict) < 0) { + fprintf(stderr, "ioctl VIDIOCGPICT: %s\n", strerror(errno)); + exit(1); + } + pict.brightness = brightness * 65536 / 100; + pict.contrast = contrast * 65536 / 100; + pict.colour = color * 65536 / 100; + if (ioctl(fd, VIDIOCSPICT, &pict) < 0) { + fprintf(stderr, "ioctl VIDIOCSPICT: %s\n", strerror(errno)); + exit(1); + } +} + +static void inc_brightness(Widget widget, XEvent *event, String *params, Cardinal *num_params) +{ + if (brightness < 100) + brightness++; + set_bcc(); +} + +static void dec_brightness(Widget widget, XEvent *event, String *params, Cardinal *num_params) +{ + if (brightness > 0) + brightness--; + set_bcc(); +} + +static void reset_brightness(Widget widget, XEvent *event, String *params, Cardinal *num_params) +{ + brightness = 50; + set_bcc(); +} + +static void inc_contrast(Widget widget, XEvent *event, String *params, Cardinal *num_params) +{ + if (contrast < 100) + contrast++; + set_bcc(); +} + +static void dec_contrast(Widget widget, XEvent *event, String *params, Cardinal *num_params) +{ + if (contrast > 0) + contrast--; + set_bcc(); +} + +static void reset_contrast(Widget widget, XEvent *event, String *params, Cardinal *num_params) +{ + contrast = 50; + set_bcc(); +} + +static void inc_color(Widget widget, XEvent *event, String *params, Cardinal *num_params) +{ + if (color < 100) + color++; + set_bcc(); +} + +static void dec_color(Widget widget, XEvent *event, String *params, Cardinal *num_params) +{ + if (color > 0) + color--; + set_bcc(); +} + +static void reset_color(Widget widget, XEvent *event, String *params, Cardinal *num_params) +{ + color = 50; + set_bcc(); +} + +static void set_channel(void) +{ + video_channel chan; + chan.channel = channel; + if (ioctl(fd, VIDIOCGCHAN, &chan) < 0) { + fprintf(stderr, "ioctl VIDIOCGCHAN: %s\n", strerror(errno)); + exit(1); + } + if (ntsc) + chan.norm = VIDEO_MODE_NTSC; + else + chan.norm = VIDEO_MODE_PAL; + if (ioctl(fd, VIDIOCSCHAN, &chan) < 0) { + fprintf(stderr, "ioctl VIDIOCSCHAN: %s\n", strerror(errno)); + exit(1); + } +} + +static void select_channel_1(Widget widget, XEvent *event, String *params, Cardinal *num_params) +{ + channel = 1; + set_channel(); +} + +static void select_channel_2(Widget widget, XEvent *event, String *params, Cardinal *num_params) +{ + channel = 2; + set_channel(); +} + static XtActionsRec actionTable[] = { - {"quit", quit} + {"quit", quit}, + {"inc_brightness", inc_brightness}, + {"dec_brightness", dec_brightness}, + {"reset_brightness", reset_brightness}, + {"inc_contrast", inc_contrast}, + {"dec_contrast", dec_contrast}, + {"reset_contrast", reset_contrast}, + {"inc_color", inc_color}, + {"dec_color", dec_color}, + {"reset_color", reset_color}, + {"select_channel_1", select_channel_1}, + {"select_channel_2", select_channel_2} }; static void resize_event(Widget widget, XtPointer client_data, XEvent *event, Boolean *d) @@ -161,7 +285,7 @@ static Boolean work_proc(XtPointer clien now = GetTicks_usec(); uint64 elapsed = now - prev; - int64 delay = 1000000 / fps - (now - prev); + int64 delay = int64(1000000.0 / fps) - (now - prev); #if LOGGING fprintf(log, "elapsed %Ld usec, delay %Ld usec\n", elapsed, delay); #endif @@ -198,6 +322,7 @@ int main(int argc, char **argv) {"help", 0, 0, 'h'}, {"ntsc", 0, 0, 'n'}, {"port", 1, 0, 'p'}, + {"width", 1, 0, 'w'}, {NULL, 0, 0, 0} }; @@ -205,23 +330,10 @@ int main(int argc, char **argv) log = fopen("log", "w"); #endif - // Init X11 - XtAppContext app_context; - app_shell = XtAppInitialize(&app_context, "mintv", NULL, 0, &argc, argv, NULL, NULL, 0); - dpy = XtDisplay(app_shell); - XtAppAddActions(app_context,actionTable, sizeof(actionTable) / sizeof(XtActionsRec)); - XtOverrideTranslations(app_shell, XtParseTranslationTable( - "WM_PROTOCOLS: quit()\n" - "q: quit()" - )); - XtAddEventHandler(app_shell, StructureNotifyMask, True, resize_event, NULL); - wm = XInternAtom(XtDisplay(app_shell), "WM_DELETE_WINDOW", False); - // Parse options - bool ntsc = false; for (;;) { int c; - if ((c = getopt_long(argc, argv, "hnp:", long_opts,NULL)) == -1) + if ((c = getopt_long(argc, argv, "hnp:w:", long_opts,NULL)) == -1) break; switch (c) { @@ -233,20 +345,54 @@ int main(int argc, char **argv) case 'p': port = atoi(optarg); break; + case 'w': + grab_width = atoi(optarg); + break; case 'h': default: fprintf(stderr, - "This is an xvideo test application.\n" + "50/60Hz video display application\n\n" "Options:\n" - " -h | --help this text\n" - " -n | --ntsc NTSC mode\n" - " -p | --port n Xv output port\n" + " -h | --help this text\n" + " -n | --ntsc NTSC mode\n" + " -p | --port n Xv output port\n" + " -w | --width n image width\n\n" + "Keyboard commands:\n" + " q quit\n" + " 1/2 select channel\n" + " KP 7/4/1 adjust brightness\n" + " KP 8/5/2 adjust contrast\n" + " KP 9/6/3 adjust color\n" ); exit(1); break; } } + // Init X11 + XtAppContext app_context; + app_shell = XtAppInitialize(&app_context, "mintv", NULL, 0, &argc, argv, NULL, NULL, 0); + dpy = XtDisplay(app_shell); + XtAppAddActions(app_context,actionTable, sizeof(actionTable) / sizeof(XtActionsRec)); + XtOverrideTranslations(app_shell, XtParseTranslationTable( + "WM_PROTOCOLS: quit()\n" + "q: quit()\n" + "Escape: quit()\n" + "1: select_channel_1()\n" + "2: select_channel_2()\n" + "KP_7: inc_brightness()\n" + "KP_4: reset_brightness()\n" + "KP_1: dec_brightness()\n" + "KP_8: inc_contrast()\n" + "KP_5: reset_contrast()\n" + "KP_2: dec_contrast()\n" + "KP_9: inc_color()\n" + "KP_6: reset_color()\n" + "KP_3: dec_color()" + )); + XtAddEventHandler(app_shell, StructureNotifyMask, True, resize_event, NULL); + wm = XInternAtom(XtDisplay(app_shell), "WM_DELETE_WINDOW", False); + // Xvideo available? unsigned ver, rel, req, ev, err, val; if (XvQueryExtension(dpy, &ver, &rel, &req, &ev, &err) != Success) { @@ -292,11 +438,13 @@ port_found: // Set grab and window dimensions if (ntsc) { - grab_width = NTSC_WIDTH; + if (grab_width == -1) + grab_width = NTSC_WIDTH; grab_height = NTSC_HEIGHT; fps = NTSC_FPS; } else { - grab_width = PAL_WIDTH; + if (grab_width == -1) + grab_width = PAL_WIDTH; grab_height = PAL_HEIGHT; fps = PAL_FPS; } @@ -317,11 +465,22 @@ port_found: XtRealizeWidget(app_shell); XtVaSetValues(app_shell, XtNtitle, "mintv", + XtNinput, True, NULL ); - XSetWMProtocols(XtDisplay(app_shell), XtWindow(app_shell), &wm, 1); + XSetWMProtocols(dpy, XtWindow(app_shell), &wm, 1); gc = XCreateGC(dpy, XtWindow(video), 0, NULL); + // Hide cursor + Colormap cmap = DefaultColormap(dpy, DefaultScreen(dpy)); + XColor black; + XParseColor(dpy, cmap, "#000000", &black); + XAllocColor(dpy, cmap, &black); + static char null_data[] = {0, 0, 0, 0, 0, 0, 0, 0}; + Pixmap null_pixmap = XCreateBitmapFromData(dpy, XtWindow(video), null_data, 8, 8); + Cursor null_cursor = XCreatePixmapCursor(dpy, null_pixmap, null_pixmap, &black, &black, 0, 0); + XDefineCursor(dpy, XtWindow(video), null_cursor); + // Set image format unsigned format = XV_FORMAT; @@ -346,20 +505,8 @@ port_found: } // Set channel - video_channel chan; - chan.channel = 1; - if (ioctl(fd, VIDIOCGCHAN, &chan) < 0) { - fprintf(stderr, "ioctl VIDIOCGCHAN: %s\n", strerror(errno)); - exit(1); - } - if (ntsc) - chan.norm = VIDEO_MODE_NTSC; - else - chan.norm = VIDEO_MODE_PAL; - if (ioctl(fd, VIDIOCSCHAN, &chan) < 0) { - fprintf(stderr, "ioctl VIDIOCSCHAN: %s\n", strerror(errno)); - exit(1); - } + set_channel(); + video_audio au; au.audio = 1; if (ioctl(fd, VIDIOCGAUDIO, &au) < 0) { @@ -373,18 +520,7 @@ port_found: } // Configure frame grabber - video_picture pict; - if (ioctl(fd, VIDIOCGPICT, &pict) < 0) { - fprintf(stderr, "ioctl VIDIOCGPICT: %s\n", strerror(errno)); - exit(1); - } - pict.brightness = 45 * 65536 / 100; - pict.contrast = 55 * 65536 / 100; - pict.colour = 60 * 65536 / 100; - if (ioctl(fd, VIDIOCSPICT, &pict) < 0) { - fprintf(stderr, "ioctl VIDIOCSPICT: %s\n", strerror(errno)); - exit(1); - } + set_bcc(); if (ioctl(fd, VIDIOCGMBUF, &mbuf) < 0) { fprintf(stderr, "ioctl VIDIOCGMBUF: %s\n", strerror(errno));