| 27 |
#include <X11/extensions/Xv.h> |
#include <X11/extensions/Xv.h> |
| 28 |
#include <X11/extensions/Xvlib.h> |
#include <X11/extensions/Xvlib.h> |
| 29 |
|
|
| 30 |
|
static bool ntsc = false; |
| 31 |
|
|
| 32 |
const int PAL_WIDTH = 384; |
const int PAL_WIDTH = 384; |
| 33 |
const int PAL_HEIGHT = 288; |
const int PAL_HEIGHT = 288; |
| 34 |
const int NTSC_WIDTH = 320; |
const int NTSC_WIDTH = 320; |
| 43 |
|
|
| 44 |
static int fps; |
static int fps; |
| 45 |
|
|
| 46 |
|
static int brightness = 50, contrast = 50, color = 50; |
| 47 |
|
|
| 48 |
|
static int channel = 1; |
| 49 |
|
|
| 50 |
#define XV_FORMAT 0x32595559 |
#define XV_FORMAT 0x32595559 |
| 51 |
#define BYTES_PER_PIXEL 2 |
#define BYTES_PER_PIXEL 2 |
| 52 |
|
|
| 83 |
exit(0); |
exit(0); |
| 84 |
} |
} |
| 85 |
|
|
| 86 |
|
static void set_bcc(void) |
| 87 |
|
{ |
| 88 |
|
video_picture pict; |
| 89 |
|
if (ioctl(fd, VIDIOCGPICT, &pict) < 0) { |
| 90 |
|
fprintf(stderr, "ioctl VIDIOCGPICT: %s\n", strerror(errno)); |
| 91 |
|
exit(1); |
| 92 |
|
} |
| 93 |
|
pict.brightness = brightness * 65536 / 100; |
| 94 |
|
pict.contrast = contrast * 65536 / 100; |
| 95 |
|
pict.colour = color * 65536 / 100; |
| 96 |
|
if (ioctl(fd, VIDIOCSPICT, &pict) < 0) { |
| 97 |
|
fprintf(stderr, "ioctl VIDIOCSPICT: %s\n", strerror(errno)); |
| 98 |
|
exit(1); |
| 99 |
|
} |
| 100 |
|
} |
| 101 |
|
|
| 102 |
|
static void inc_brightness(Widget widget, XEvent *event, String *params, Cardinal *num_params) |
| 103 |
|
{ |
| 104 |
|
if (brightness < 100) |
| 105 |
|
brightness++; |
| 106 |
|
set_bcc(); |
| 107 |
|
} |
| 108 |
|
|
| 109 |
|
static void dec_brightness(Widget widget, XEvent *event, String *params, Cardinal *num_params) |
| 110 |
|
{ |
| 111 |
|
if (brightness > 0) |
| 112 |
|
brightness--; |
| 113 |
|
set_bcc(); |
| 114 |
|
} |
| 115 |
|
|
| 116 |
|
static void reset_brightness(Widget widget, XEvent *event, String *params, Cardinal *num_params) |
| 117 |
|
{ |
| 118 |
|
brightness = 50; |
| 119 |
|
set_bcc(); |
| 120 |
|
} |
| 121 |
|
|
| 122 |
|
static void inc_contrast(Widget widget, XEvent *event, String *params, Cardinal *num_params) |
| 123 |
|
{ |
| 124 |
|
if (contrast < 100) |
| 125 |
|
contrast++; |
| 126 |
|
set_bcc(); |
| 127 |
|
} |
| 128 |
|
|
| 129 |
|
static void dec_contrast(Widget widget, XEvent *event, String *params, Cardinal *num_params) |
| 130 |
|
{ |
| 131 |
|
if (contrast > 0) |
| 132 |
|
contrast--; |
| 133 |
|
set_bcc(); |
| 134 |
|
} |
| 135 |
|
|
| 136 |
|
static void reset_contrast(Widget widget, XEvent *event, String *params, Cardinal *num_params) |
| 137 |
|
{ |
| 138 |
|
contrast = 50; |
| 139 |
|
set_bcc(); |
| 140 |
|
} |
| 141 |
|
|
| 142 |
|
static void inc_color(Widget widget, XEvent *event, String *params, Cardinal *num_params) |
| 143 |
|
{ |
| 144 |
|
if (color < 100) |
| 145 |
|
color++; |
| 146 |
|
set_bcc(); |
| 147 |
|
} |
| 148 |
|
|
| 149 |
|
static void dec_color(Widget widget, XEvent *event, String *params, Cardinal *num_params) |
| 150 |
|
{ |
| 151 |
|
if (color > 0) |
| 152 |
|
color--; |
| 153 |
|
set_bcc(); |
| 154 |
|
} |
| 155 |
|
|
| 156 |
|
static void reset_color(Widget widget, XEvent *event, String *params, Cardinal *num_params) |
| 157 |
|
{ |
| 158 |
|
color = 50; |
| 159 |
|
set_bcc(); |
| 160 |
|
} |
| 161 |
|
|
| 162 |
|
static void set_channel(void) |
| 163 |
|
{ |
| 164 |
|
video_channel chan; |
| 165 |
|
chan.channel = channel; |
| 166 |
|
if (ioctl(fd, VIDIOCGCHAN, &chan) < 0) { |
| 167 |
|
fprintf(stderr, "ioctl VIDIOCGCHAN: %s\n", strerror(errno)); |
| 168 |
|
exit(1); |
| 169 |
|
} |
| 170 |
|
if (ntsc) |
| 171 |
|
chan.norm = VIDEO_MODE_NTSC; |
| 172 |
|
else |
| 173 |
|
chan.norm = VIDEO_MODE_PAL; |
| 174 |
|
if (ioctl(fd, VIDIOCSCHAN, &chan) < 0) { |
| 175 |
|
fprintf(stderr, "ioctl VIDIOCSCHAN: %s\n", strerror(errno)); |
| 176 |
|
exit(1); |
| 177 |
|
} |
| 178 |
|
} |
| 179 |
|
|
| 180 |
|
static void select_channel_1(Widget widget, XEvent *event, String *params, Cardinal *num_params) |
| 181 |
|
{ |
| 182 |
|
channel = 1; |
| 183 |
|
set_channel(); |
| 184 |
|
} |
| 185 |
|
|
| 186 |
|
static void select_channel_2(Widget widget, XEvent *event, String *params, Cardinal *num_params) |
| 187 |
|
{ |
| 188 |
|
channel = 2; |
| 189 |
|
set_channel(); |
| 190 |
|
} |
| 191 |
|
|
| 192 |
static XtActionsRec actionTable[] = { |
static XtActionsRec actionTable[] = { |
| 193 |
{"quit", quit} |
{"quit", quit}, |
| 194 |
|
{"inc_brightness", inc_brightness}, |
| 195 |
|
{"dec_brightness", dec_brightness}, |
| 196 |
|
{"reset_brightness", reset_brightness}, |
| 197 |
|
{"inc_contrast", inc_contrast}, |
| 198 |
|
{"dec_contrast", dec_contrast}, |
| 199 |
|
{"reset_contrast", reset_contrast}, |
| 200 |
|
{"inc_color", inc_color}, |
| 201 |
|
{"dec_color", dec_color}, |
| 202 |
|
{"reset_color", reset_color}, |
| 203 |
|
{"select_channel_1", select_channel_1}, |
| 204 |
|
{"select_channel_2", select_channel_2} |
| 205 |
}; |
}; |
| 206 |
|
|
| 207 |
static void resize_event(Widget widget, XtPointer client_data, XEvent *event, Boolean *d) |
static void resize_event(Widget widget, XtPointer client_data, XEvent *event, Boolean *d) |
| 335 |
XtAppAddActions(app_context,actionTable, sizeof(actionTable) / sizeof(XtActionsRec)); |
XtAppAddActions(app_context,actionTable, sizeof(actionTable) / sizeof(XtActionsRec)); |
| 336 |
XtOverrideTranslations(app_shell, XtParseTranslationTable( |
XtOverrideTranslations(app_shell, XtParseTranslationTable( |
| 337 |
"<Message>WM_PROTOCOLS: quit()\n" |
"<Message>WM_PROTOCOLS: quit()\n" |
| 338 |
"<Key>q: quit()" |
"<Key>q: quit()\n" |
| 339 |
|
"<Key>1: select_channel_1()\n" |
| 340 |
|
"<Key>2: select_channel_2()\n" |
| 341 |
|
"<Key>KP_7: inc_brightness()\n" |
| 342 |
|
"<Key>KP_4: reset_brightness()\n" |
| 343 |
|
"<Key>KP_1: dec_brightness()\n" |
| 344 |
|
"<Key>KP_8: inc_contrast()\n" |
| 345 |
|
"<Key>KP_5: reset_contrast()\n" |
| 346 |
|
"<Key>KP_2: dec_contrast()\n" |
| 347 |
|
"<Key>KP_9: inc_color()\n" |
| 348 |
|
"<Key>KP_6: reset_color()\n" |
| 349 |
|
"<Key>KP_3: dec_color()" |
| 350 |
)); |
)); |
| 351 |
XtAddEventHandler(app_shell, StructureNotifyMask, True, resize_event, NULL); |
XtAddEventHandler(app_shell, StructureNotifyMask, True, resize_event, NULL); |
| 352 |
wm = XInternAtom(XtDisplay(app_shell), "WM_DELETE_WINDOW", False); |
wm = XInternAtom(XtDisplay(app_shell), "WM_DELETE_WINDOW", False); |
| 353 |
|
|
| 354 |
// Parse options |
// Parse options |
|
bool ntsc = false; |
|
| 355 |
for (;;) { |
for (;;) { |
| 356 |
int c; |
int c; |
| 357 |
if ((c = getopt_long(argc, argv, "hnp:", long_opts,NULL)) == -1) |
if ((c = getopt_long(argc, argv, "hnp:", long_opts,NULL)) == -1) |
| 369 |
case 'h': |
case 'h': |
| 370 |
default: |
default: |
| 371 |
fprintf(stderr, |
fprintf(stderr, |
| 372 |
"This is an xvideo test application.\n" |
"50/60Hz video display application\n" |
| 373 |
"Options:\n" |
"Options:\n" |
| 374 |
" -h | --help this text\n" |
" -h | --help this text\n" |
| 375 |
" -n | --ntsc NTSC mode\n" |
" -n | --ntsc NTSC mode\n" |
| 376 |
" -p | --port n Xv output port\n" |
" -p | --port n Xv output port\n\n" |
| 377 |
|
"Keyboard commands:\n" |
| 378 |
|
" q quit\n" |
| 379 |
|
" 1/2 select channel\n" |
| 380 |
|
" KP 7/4/1 adjust brightness\n" |
| 381 |
|
" KP 8/5/2 adjust contrast\n" |
| 382 |
|
" KP 9/6/3 adjust color\n" |
| 383 |
); |
); |
| 384 |
exit(1); |
exit(1); |
| 385 |
break; |
break; |
| 485 |
} |
} |
| 486 |
|
|
| 487 |
// Set channel |
// Set channel |
| 488 |
video_channel chan; |
set_channel(); |
| 489 |
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); |
|
|
} |
|
| 490 |
video_audio au; |
video_audio au; |
| 491 |
au.audio = 1; |
au.audio = 1; |
| 492 |
if (ioctl(fd, VIDIOCGAUDIO, &au) < 0) { |
if (ioctl(fd, VIDIOCGAUDIO, &au) < 0) { |
| 500 |
} |
} |
| 501 |
|
|
| 502 |
// Configure frame grabber |
// Configure frame grabber |
| 503 |
video_picture pict; |
set_bcc(); |
|
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); |
|
|
} |
|
| 504 |
|
|
| 505 |
if (ioctl(fd, VIDIOCGMBUF, &mbuf) < 0) { |
if (ioctl(fd, VIDIOCGMBUF, &mbuf) < 0) { |
| 506 |
fprintf(stderr, "ioctl VIDIOCGMBUF: %s\n", strerror(errno)); |
fprintf(stderr, "ioctl VIDIOCGMBUF: %s\n", strerror(errno)); |