Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 #include "config.h"
  2 
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 #include <unistd.h>
  6 #include <signal.h>
  7 #include <time.h>
  8 #include <pthread.h>
  9 #include <aalib.h>
 10 
 11 #include "grab-ng.h"
 12 #include "capture.h"
 13 #include "channel.h"
 14 #include "commands.h"
 15 #include "frequencies.h"
 16 #include "parseconfig.h"
 17 #include "sound.h"
 18 
 19 /* ---------------------------------------------------------------------- */
 20 /* capture stuff                                                          */
 21 
 22 static struct aa_hardware_params params;
 23 static aa_renderparams render;
 24 static aa_context *context;
 25 char *framebuffer;
 26 static int signaled;
 27 
 28 static char title[256];
 29 static char message[256];
 30 static time_t mtime;
 31 static struct ng_video_fmt   fmt,gfmt;
 32 static struct ng_video_conv  *conv;
 33 static struct ng_convert_handle *ch;
 34 static int fast;
 35 
 36 static void
 37 grabber_init(void)
 38 {
 39     drv = ng_vid_open(ng_dev.video,NULL,NULL,0,&h_drv);
 40     if (NULL == drv) {
 41         fprintf(stderr,"no grabber device available\n");
 42         exit(1);
 43     }
 44     f_drv = drv->capabilities(h_drv);
 45     add_attrs(drv->list_attrs(h_drv));
 46 }
 47 
 48 static void
 49 new_title(char *txt)
 50 {
 51     strcpy(title,txt);
 52 }
 53 
 54 static void
 55 new_message(char *txt)
 56 {
 57     mtime = time(NULL);
 58     strcpy(message,txt);
 59 }
 60 
 61 static void do_capture(int from, int to, int tmp_switch)
 62 {
 63     /* off */
 64     switch (from) {
 65     case CAPTURE_GRABDISPLAY:
 66         if (f_drv & CAN_CAPTURE)
 67             drv->stopvideo(h_drv);
 68         break;
 69     }
 70 
 71     /* on */
 72     switch (to) {
 73     case CAPTURE_GRABDISPLAY:
 74         /* try native */
 75         fmt.fmtid  = VIDEO_GRAY;
 76         fmt.width  = aa_imgwidth(context);
 77         fmt.height = aa_imgheight(context);
 78         if (0 != ng_grabber_setformat(&fmt,1)) {
 79             gfmt = fmt;
 80             if (NULL == (conv = ng_grabber_findconv(&gfmt,0))) {
 81                 fprintf(stderr,"can't capture gray data\n");
 82                 exit(1);
 83             }
 84             ch = ng_convert_alloc(conv,&gfmt,&fmt);
 85             ng_convert_init(ch);
 86         }
 87         if (f_drv & CAN_CAPTURE)
 88             drv->startvideo(h_drv,-1,2);
 89         break;
 90     }
 91 }
 92 
 93 static void blitframe(struct ng_video_buf *buf)
 94 {
 95     int w,h,y;
 96     char *s,*d;
 97 
 98 #if 0
 99     /* debug */
100     fprintf(stdout,"P5\n%d %d\n255\n",buf->fmt.width,buf->fmt.height);
101     fwrite(buf->data,buf->fmt.width,buf->fmt.height,stdout);
102     exit(1);
103 #endif
104     if (buf->fmt.width  == aa_imgwidth(context) &&
105         buf->fmt.height == aa_imgheight(context)) {
106         memcpy(framebuffer,buf->data,buf->fmt.width*buf->fmt.height);
107     } else {
108         s = buf->data;
109         d = framebuffer;
110         if (buf->fmt.height < aa_imgheight(context)) {
111             h  = buf->fmt.height;
112             d += (aa_imgheight(context)-buf->fmt.height)/2 *
113                 aa_imgwidth(context);
114         } else {
115             h = aa_imgheight(context);
116             s += (buf->fmt.height-aa_imgheight(context))/2 *
117                 buf->fmt.width;
118         }
119         if (buf->fmt.width < aa_imgwidth(context)) {
120             w  = buf->fmt.width;
121             d += (aa_imgwidth(context)-buf->fmt.width)/2;
122         } else {
123             w  = aa_imgwidth(context);
124             s += (buf->fmt.width-aa_imgwidth(context))/2;
125         }
126         for (y = 0; y < h; y++) {
127             memcpy(d,s,w);
128             s += buf->fmt.width;
129             d += aa_imgwidth(context);
130         }
131     }
132 }
133 
134 /* ----------------------------------------------------------------------- */
135 
136 static void aa_cleanup(void)
137 {
138     aa_uninitkbd(context);
139     aa_close(context);
140 }
141 
142 static void
143 ctrlc(int signal)
144 {
145     signaled++;
146 }
147 
148 static void
149 usage(void)
150 {
151     printf("ttv -- watch tv on a ascii terminal using aalib\n"
152            "\n"
153            "ttv options:\n"
154            "  -h             print this text\n"
155            "  -f             use fast aalib render function\n"
156            "  -c <device>    video device [%s]\n"
157            "\n"
158            "aalib options:\n"
159            "%s",
160            ng_dev.video,aa_help);
161     exit(1);
162 }
163 
164 int
165 main(int argc, char **argv)
166 {
167     struct ng_video_buf *buf;
168     unsigned long freq;
169     int c,i,key,frames,fps;
170     time_t now,last;
171     struct tm *t;
172 
173     ng_init();
174     params = aa_defparams;
175     render = aa_defrenderparams;
176     if (!aa_parseoptions (&params, &render, &argc, argv))
177         usage();
178     for (;;) {
179         c = getopt(argc, argv, "vfhc:");
180         if (c == -1)
181             break;
182         switch (c) {
183         case 'v':
184             debug++;
185             ng_debug++;
186             break;
187         case 'f':
188             fast++;
189             break;
190         case 'c':
191             ng_dev.video = optarg;
192             break;
193         case 'h':
194         default:
195             usage();
196             break;
197         }
198     }
199 
200     /* init aalib */
201     context = aa_autoinit(&params);
202     if (context == NULL) {
203         printf("Failed to initialize aalib\n");
204         exit (1);
205     }
206     aa_autoinitkbd(context,0);
207     atexit(aa_cleanup);
208     framebuffer = aa_image(context);
209 
210     /* init v4l */
211     grabber_init();
212     freq_init();
213     read_config(NULL,NULL,NULL);
214     ng_ratio_x = 0;
215     ng_ratio_y = 0;
216 
217     /* init mixer */
218     if (0 != strlen(mixerdev)) {
219         struct ng_attribute *attr;
220         if (NULL != (attr = ng_mix_init(mixerdev,mixerctl)))
221             add_attrs(attr);
222     }
223 
224     /* set hooks (command.c) */
225     update_title      = new_title;
226     display_message   = new_message;
227     set_capture_hook  = do_capture;
228 
229     /* init hardware */
230     attr_init();
231     audio_on();
232     audio_init();
233 
234     /* build channel list */
235     parse_config();
236     do_va_cmd(2,"setfreqtab",(-1 != chantab)
237               ? chanlist_names[chantab].str : "europe-west");
238     cur_capture = 0;
239     do_va_cmd(2,"capture","grabdisplay");
240     if (optind+1 == argc) {
241         do_va_cmd(2,"setstation",argv[optind]);
242     } else {
243         if ((f_drv & CAN_TUNE) && 0 != (freq = drv->getfreq(h_drv))) {
244             for (i = 0; i < chancount; i++)
245                 if (chanlist[i].freq == freq*1000/16) {
246                     do_va_cmd(2,"setchannel",chanlist[i].name);
247                     break;
248                 }
249         }
250         if (-1 == cur_channel) {
251             if (count > 0)
252                 do_va_cmd(2,"setstation","");
253             else
254                 set_defaults();
255         }
256     }
257     
258     /* catch ^C */
259     signal(SIGINT,ctrlc);
260     signal(SIGTERM,ctrlc);
261     signal(SIGQUIT,ctrlc);
262 
263     /* main loop */
264     last = now = time(NULL);
265     frames = fps = 0;
266     for (;!signaled;) {
267         /* time + performance */
268         now = time(NULL);
269         t = localtime(&now);
270         frames++;
271         if (now - last >= 5) {
272             fps = frames * 10 / (now-last);
273             last = now;
274             frames = 0;
275         }
276         
277         /* grab + convert frame */
278         if (NULL == (buf = ng_grabber_grab_image(0))) {
279             fprintf(stderr,"capturing image failed\n");
280             exit(1);
281         }
282         if (ch)
283             buf = ng_convert_frame(ch,NULL,buf);
284 
285         /* blit frame */
286         blitframe(buf);
287         ng_release_video_buf(buf);
288         if (fast)
289             aa_fastrender(context, 0, 0,
290                           aa_scrwidth (context), aa_scrheight (context));
291         else
292             aa_render(context, &render, 0, 0,
293                       aa_scrwidth (context), aa_scrheight (context));
294         if (now - mtime < 6) {
295             aa_printf(context,0,0,AA_NORMAL,"[ %s ] ",
296                       message);
297         } else {
298             aa_printf(context,0,0,AA_NORMAL,"[ %s - %d.%d fps - %02d:%02d ] ",
299                       title,fps/10,fps%10,t->tm_hour,t->tm_min);
300         }
301         aa_flush(context);
302 
303         /* check for keys */
304         key = aa_getkey(context,0);
305         switch (key) {
306         case 'q':
307         case 'Q':
308         case 'e':
309         case 'E':
310         case 'x':
311         case 'X':
312             audio_off();
313             signaled++;
314             break;
315         case 'd':
316         case 'D':
317             mtime = time(NULL);
318             sprintf(message,"debug: scr=%dx%d / img=%dx%d / cap=%dx%d",
319                     aa_scrwidth(context),aa_scrheight(context),
320                     aa_imgwidth(context),aa_imgheight(context),
321                     fmt.width,fmt.height);
322             break;
323         case '+':
324             do_va_cmd(2,"volume","inc");
325             break;
326         case '-':
327             do_va_cmd(2,"volume","dec");
328             break;
329         case 10:
330         case 13:
331             do_va_cmd(2,"volume","mute");
332             break;
333         case AA_UP:
334             do_va_cmd(2,"setchannel","next");
335             break;
336         case AA_DOWN:
337             do_va_cmd(2,"setchannel","prev");
338             break;
339         case AA_RIGHT:
340             do_va_cmd(2,"setchannel","fine_up");
341             break;
342         case AA_LEFT:
343             do_va_cmd(2,"setchannel","fine_down");
344             break;
345         case ' ':
346             do_va_cmd(2,"setstation","next");
347             break;
348         default:
349             /* nothing */
350             break;
351         }
352     }
353     exit(0);
354 }
355 
  This page was automatically generated by the LXR engine.