ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mintv/mintv.cpp
(Generate patch)

Comparing mintv/mintv.cpp (file contents):
Revision 1.1 by cebix, 2003-02-08T17:51:47Z vs.
Revision 1.8 by cebix, 2005-10-02T11:57:30Z

# Line 1 | Line 1
1   /*
2 < *  mintv.cpp - 50/60Hz video display using v4l and XVideo
2 > *  mintv.cpp - 50/60Hz noninterlaced video display using v4l and XVideo
3   *
4 < *  Written in 2003 by Christian Bauer
4 > *  Written in 2003-2004 by Christian Bauer
5   */
6  
7   #include <stdio.h>
# Line 22 | Line 22
22   #include <X11/StringDefs.h>
23   #include <X11/Intrinsic.h>
24   #include <X11/Shell.h>
25 + #include <X11/cursorfont.h>
26   #include <X11/Xaw/Simple.h>
27   #include <X11/extensions/XShm.h>
28   #include <X11/extensions/Xv.h>
29   #include <X11/extensions/Xvlib.h>
30  
31 + static bool ntsc = false;
32 +
33   const int PAL_WIDTH = 384;
34   const int PAL_HEIGHT = 288;
35 < const int NTSC_WIDTH = 320;
35 > const int NTSC_WIDTH = 360;
36   const int NTSC_HEIGHT = 240;
37  
38 < static int grab_width, grab_height;
38 > static int grab_width = -1, grab_height;
39   static int image_width, image_height;
40   static int win_width, win_height;
41  
42 < const int PAL_FPS = 50;
43 < const int NTSC_FPS = 60;
42 > const double PAL_FPS = 50.0;
43 > const double NTSC_FPS = 59.94;
44 >
45 > static double fps;
46  
47 < static int fps;
47 > static int brightness = 50, contrast = 50, color = 50;
48 >
49 > static int channel = 1;
50  
51   #define XV_FORMAT 0x32595559
52   #define BYTES_PER_PIXEL 2
# Line 77 | Line 84 | static void quit(Widget widget, XEvent *
84          exit(0);
85   }
86  
87 + static void set_bcc(void)
88 + {
89 +        video_picture pict;
90 +        if (ioctl(fd, VIDIOCGPICT, &pict) < 0) {
91 +                fprintf(stderr, "ioctl VIDIOCGPICT: %s\n", strerror(errno));
92 +                exit(1);
93 +        }
94 +        pict.brightness = brightness * 65536 / 100;
95 +        pict.contrast = contrast * 65536 / 100;
96 +        pict.colour = color * 65536 / 100;
97 +        if (ioctl(fd, VIDIOCSPICT, &pict) < 0) {
98 +                fprintf(stderr, "ioctl VIDIOCSPICT: %s\n", strerror(errno));
99 +                exit(1);
100 +        }
101 + }
102 +
103 + static void inc_brightness(Widget widget, XEvent *event, String *params, Cardinal *num_params)
104 + {
105 +        if (brightness < 100)
106 +                brightness++;
107 +        set_bcc();
108 + }
109 +
110 + static void dec_brightness(Widget widget, XEvent *event, String *params, Cardinal *num_params)
111 + {
112 +        if (brightness > 0)
113 +                brightness--;
114 +        set_bcc();
115 + }
116 +
117 + static void reset_brightness(Widget widget, XEvent *event, String *params, Cardinal *num_params)
118 + {
119 +        brightness = 50;
120 +        set_bcc();
121 + }
122 +
123 + static void inc_contrast(Widget widget, XEvent *event, String *params, Cardinal *num_params)
124 + {
125 +        if (contrast < 100)
126 +                contrast++;
127 +        set_bcc();
128 + }
129 +
130 + static void dec_contrast(Widget widget, XEvent *event, String *params, Cardinal *num_params)
131 + {
132 +        if (contrast > 0)
133 +                contrast--;
134 +        set_bcc();
135 + }
136 +
137 + static void reset_contrast(Widget widget, XEvent *event, String *params, Cardinal *num_params)
138 + {
139 +        contrast = 50;
140 +        set_bcc();
141 + }
142 +
143 + static void inc_color(Widget widget, XEvent *event, String *params, Cardinal *num_params)
144 + {
145 +        if (color < 100)
146 +                color++;
147 +        set_bcc();
148 + }
149 +
150 + static void dec_color(Widget widget, XEvent *event, String *params, Cardinal *num_params)
151 + {
152 +        if (color > 0)
153 +                color--;
154 +        set_bcc();
155 + }
156 +
157 + static void reset_color(Widget widget, XEvent *event, String *params, Cardinal *num_params)
158 + {
159 +        color = 50;
160 +        set_bcc();
161 + }
162 +
163 + static void set_channel(void)
164 + {
165 +        video_channel chan;
166 +        chan.channel = channel;
167 +        if (ioctl(fd, VIDIOCGCHAN, &chan) < 0) {
168 +                fprintf(stderr, "ioctl VIDIOCGCHAN: %s\n", strerror(errno));
169 +                exit(1);
170 +        }
171 +        if (ntsc)
172 +                chan.norm = VIDEO_MODE_NTSC;
173 +        else
174 +                chan.norm = VIDEO_MODE_PAL;
175 +        if (ioctl(fd, VIDIOCSCHAN, &chan) < 0) {
176 +                fprintf(stderr, "ioctl VIDIOCSCHAN: %s\n", strerror(errno));
177 +                exit(1);
178 +        }
179 + }
180 +
181 + static void select_channel_1(Widget widget, XEvent *event, String *params, Cardinal *num_params)
182 + {
183 +        channel = 1;
184 +        set_channel();
185 + }
186 +
187 + static void select_channel_2(Widget widget, XEvent *event, String *params, Cardinal *num_params)
188 + {
189 +        channel = 2;
190 +        set_channel();
191 + }
192 +
193   static XtActionsRec actionTable[] = {
194 <        {"quit", quit}
194 >        {"quit", quit},
195 >        {"inc_brightness", inc_brightness},
196 >        {"dec_brightness", dec_brightness},
197 >        {"reset_brightness", reset_brightness},
198 >        {"inc_contrast", inc_contrast},
199 >        {"dec_contrast", dec_contrast},
200 >        {"reset_contrast", reset_contrast},
201 >        {"inc_color", inc_color},
202 >        {"dec_color", dec_color},
203 >        {"reset_color", reset_color},
204 >        {"select_channel_1", select_channel_1},
205 >        {"select_channel_2", select_channel_2}
206   };
207  
208   static void resize_event(Widget widget, XtPointer client_data, XEvent *event, Boolean *d)
# Line 161 | Line 285 | static Boolean work_proc(XtPointer clien
285  
286          now = GetTicks_usec();
287          uint64 elapsed = now - prev;
288 <        int64 delay = 1000000 / fps - (now - prev);
288 >        int64 delay = int64(1000000.0 / fps) - (now - prev);
289   #if LOGGING
290          fprintf(log, "elapsed %Ld usec, delay %Ld usec\n", elapsed, delay);
291   #endif
# Line 198 | Line 322 | int main(int argc, char **argv)
322                  {"help", 0, 0, 'h'},
323                  {"ntsc", 0, 0, 'n'},
324                  {"port", 1, 0, 'p'},
325 +                {"width", 1, 0, 'w'},
326                  {NULL, 0, 0, 0}
327          };
328  
# Line 205 | Line 330 | int main(int argc, char **argv)
330          log = fopen("log", "w");
331   #endif
332  
208        // Init X11
209        XtAppContext app_context;
210        app_shell = XtAppInitialize(&app_context, "mintv", NULL, 0, &argc, argv, NULL,  NULL, 0);
211        dpy = XtDisplay(app_shell);
212        XtAppAddActions(app_context,actionTable, sizeof(actionTable) / sizeof(XtActionsRec));
213        XtOverrideTranslations(app_shell, XtParseTranslationTable(
214                "<Message>WM_PROTOCOLS: quit()\n"
215                "<Key>q: quit()"
216        ));
217        XtAddEventHandler(app_shell, StructureNotifyMask, True, resize_event, NULL);
218        wm = XInternAtom(XtDisplay(app_shell), "WM_DELETE_WINDOW", False);
219
333          // Parse options
221        bool ntsc = false;
334          for (;;) {
335                  int c;
336 <                if ((c = getopt_long(argc, argv, "hnp:", long_opts,NULL)) == -1)
336 >                if ((c = getopt_long(argc, argv, "hnp:w:", long_opts, NULL)) == -1)
337                          break;
338  
339                  switch (c) {
# Line 233 | Line 345 | int main(int argc, char **argv)
345                          case 'p':
346                                  port = atoi(optarg);
347                                  break;
348 +                        case 'w':
349 +                                grab_width = atoi(optarg);
350 +                                break;
351                          case 'h':
352                          default:
353                                  fprintf(stderr,
354 <                                        "This is an xvideo test application.\n"
354 >                                        "50/60Hz video display application\n\n"
355                                          "Options:\n"
356 <                                        "  -h | --help    this text\n"
357 <                                        "  -n | --ntsc    NTSC mode\n"
358 <                                        "  -p | --port n  Xv output port\n"
356 >                                        "  -h | --help     this text\n"
357 >                                        "  -n | --ntsc     NTSC mode\n"
358 >                                        "  -p | --port n   Xv output port\n"
359 >                                        "  -w | --width n  image width\n\n"
360 >                                        "Keyboard commands:\n"
361 >                                        "  q         quit\n"
362 >                                        "  1/2       select channel\n"
363 >                                        "  KP 7/4/1  adjust brightness\n"
364 >                                        "  KP 8/5/2  adjust contrast\n"
365 >                                        "  KP 9/6/3  adjust color\n"
366                                  );
367                                  exit(1);
368                                  break;
369                  }
370          }
371  
372 +        // Init X11
373 +        XtAppContext app_context;
374 +        app_shell = XtAppInitialize(&app_context, "mintv", NULL, 0, &argc, argv, NULL,  NULL, 0);
375 +        dpy = XtDisplay(app_shell);
376 +        XtAppAddActions(app_context,actionTable, sizeof(actionTable) / sizeof(XtActionsRec));
377 +        XtOverrideTranslations(app_shell, XtParseTranslationTable(
378 +                "<Message>WM_PROTOCOLS: quit()\n"
379 +                "<Key>q: quit()\n"
380 +                "<Key>Escape: quit()\n"
381 +                "<Key>1: select_channel_1()\n"
382 +                "<Key>2: select_channel_2()\n"
383 +                "<Key>KP_7: inc_brightness()\n"
384 +                "<Key>KP_4: reset_brightness()\n"
385 +                "<Key>KP_1: dec_brightness()\n"
386 +                "<Key>KP_8: inc_contrast()\n"
387 +                "<Key>KP_5: reset_contrast()\n"
388 +                "<Key>KP_2: dec_contrast()\n"
389 +                "<Key>KP_9: inc_color()\n"
390 +                "<Key>KP_6: reset_color()\n"
391 +                "<Key>KP_3: dec_color()"
392 +        ));
393 +        XtAddEventHandler(app_shell, StructureNotifyMask, True, resize_event, NULL);
394 +        wm = XInternAtom(XtDisplay(app_shell), "WM_DELETE_WINDOW", False);
395 +
396          // Xvideo available?
397          unsigned ver, rel, req, ev, err, val;
398          if (XvQueryExtension(dpy, &ver, &rel, &req, &ev, &err) != Success) {
# Line 292 | Line 438 | port_found:
438  
439          // Set grab and window dimensions
440          if (ntsc) {
441 <                grab_width = NTSC_WIDTH;
441 >                if (grab_width == -1)
442 >                        grab_width = NTSC_WIDTH;
443                  grab_height = NTSC_HEIGHT;
444                  fps = NTSC_FPS;
445          } else {
446 <                grab_width = PAL_WIDTH;
446 >                if (grab_width == -1)
447 >                        grab_width = PAL_WIDTH;
448                  grab_height = PAL_HEIGHT;
449                  fps = PAL_FPS;
450          }
# Line 317 | Line 465 | port_found:
465          XtRealizeWidget(app_shell);
466          XtVaSetValues(app_shell,
467                  XtNtitle, "mintv",
468 +                XtNinput, True,
469                  NULL
470          );
471 <        XSetWMProtocols(XtDisplay(app_shell), XtWindow(app_shell), &wm, 1);
471 >        XSetWMProtocols(dpy, XtWindow(app_shell), &wm, 1);
472          gc = XCreateGC(dpy, XtWindow(video), 0, NULL);
473  
474 +        // Hide cursor
475 +        Colormap cmap = DefaultColormap(dpy, DefaultScreen(dpy));
476 +        XColor black;
477 +        XParseColor(dpy, cmap, "#000000", &black);
478 +        XAllocColor(dpy, cmap, &black);
479 +        static char null_data[] = {0, 0, 0, 0, 0, 0, 0, 0};
480 +        Pixmap null_pixmap = XCreateBitmapFromData(dpy, XtWindow(video), null_data, 8, 8);
481 +        Cursor null_cursor = XCreatePixmapCursor(dpy, null_pixmap, null_pixmap, &black, &black, 0, 0);
482 +        XDefineCursor(dpy, XtWindow(video), null_cursor);
483 +
484          // Set image format
485          unsigned format = XV_FORMAT;
486  
# Line 346 | Line 505 | port_found:
505          }
506  
507          // Set channel
508 <        video_channel chan;
509 <        chan.channel = 1;
351 <        if (ioctl(fd, VIDIOCGCHAN, &chan) < 0) {
352 <                fprintf(stderr, "ioctl VIDIOCGCHAN: %s\n", strerror(errno));
353 <                exit(1);
354 <        }
355 <        if (ntsc)
356 <                chan.norm = VIDEO_MODE_NTSC;
357 <        else
358 <                chan.norm = VIDEO_MODE_PAL;
359 <        if (ioctl(fd, VIDIOCSCHAN, &chan) < 0) {
360 <                fprintf(stderr, "ioctl VIDIOCSCHAN: %s\n", strerror(errno));
361 <                exit(1);
362 <        }
508 >        set_channel();
509 >
510          video_audio au;
511          au.audio = 1;
512          if (ioctl(fd, VIDIOCGAUDIO, &au) < 0) {
# Line 373 | Line 520 | port_found:
520          }
521  
522          // Configure frame grabber
523 <        video_picture pict;
377 <        if (ioctl(fd, VIDIOCGPICT, &pict) < 0) {
378 <                fprintf(stderr, "ioctl VIDIOCGPICT: %s\n", strerror(errno));
379 <                exit(1);
380 <        }
381 <        pict.brightness = 45 * 65536 / 100;
382 <        pict.contrast = 55 * 65536 / 100;
383 <        pict.colour = 60 * 65536 / 100;
384 <        if (ioctl(fd, VIDIOCSPICT, &pict) < 0) {
385 <                fprintf(stderr, "ioctl VIDIOCSPICT: %s\n", strerror(errno));
386 <                exit(1);
387 <        }
523 >        set_bcc();
524  
525          if (ioctl(fd, VIDIOCGMBUF, &mbuf) < 0) {
526                  fprintf(stderr, "ioctl VIDIOCGMBUF: %s\n", strerror(errno));

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines