File: Programming-FAQ

package info (click to toggle)
xawtv 3.72
  • links: PTS
  • area: main
  • in suites: woody
  • size: 2,732 kB
  • ctags: 4,362
  • sloc: ansic: 40,774; sh: 449; makefile: 446; perl: 280
file content (109 lines) | stat: -rw-r--r-- 3,460 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

mostly for bttv currently, also a bit outdated and incomplete...


Initialisation
==============

Grabbing does'nt work if the bt848 chip can't sync, you'll get errno
== EAGAIN then (Overlay does work and gives snow).  You have to make
sure:

  * The driver uses the correct Video Input (VIDIOCSCHAN)
  * The driver uses the correct TV norm (VIDIOCSCHAN,VIDIOCSTUNER)
  * For TV input: There is some station tuned in.

With VIDIOCGCHAN you can ask for available input channels and
informations about these.


Simple grabbing with mmap()
===========================

With bttv you can mmap() the bttv memory.  There is room for two
frames, therefore you can get 2*BTTV_MAX_FBUF bytes mapped.

	fd = open("/dev/video", ...);
	/* ... initialisation ... */
	map = mmap(0,BTTV_MAX_FBUF*2,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

Frame 0 starts at map, frame 1 at map+BTTV_MAX_FBUF.

Ok, that's the preparation, now let's start grabbing.  You have to
fill the parameters (size, format, frame) into a struct video_mmap,
and then do

	ioctl(fd,VIDIOCMCAPTURE,&video_mmap);

This instructs the driver to capture a frame.  The ioctl will return
immedantly, the driver will process your request asyncron (interrupt
driven).  If you want to get the result, you have to wait for it using

	ioctl(fd,VIDIOCSYNC,&video_mmap.frame);

If your request is still in progress, the ioctl will block until it is
done.  Otherwise it will return.  That's all, now you have the result
in the mmap()ed area.


Advanced grabbing
=================

The scheme outlined above works fine for single frames.  If you want
do continuous grabbing and keep up with the full frame rate (25 fps
for PAL), it is'nt that simple.  As mentioned above, the driver has
room for two frames.  There is room for two grabbing requests too.

The basic idea for handling full speed is to let work the bttv driver
and the application in parallel.  The application processes the
picture in one of the frames, while the driver captures the next
picture to the other one.  Works this way:

	/* ... initialisation ... */

	ioctl(capture frame 0)

loop:
	ioctl(capture frame 1)
	ioctl(sync    frame 0)
	/*
         * this sync returns if the first request (for frame 0) is done
         * the driver will continue with the next one (for frame 1),
         * while the application can proccess frame 0.  If the
         * application is done, we reuse frame 0 for the next request ...
         */
	ioctl(capture frame 0)
	ioctl(sync    frame 1)
	/*
	 * same procedure, but the other way around: driver captures
         * to frame 0, application proccesses frame 1
	 */
	goto loop;


Pitfalls / driver changes
=========================

video4linux is work-in-progress, and there still some interface
changes from time to time due to design bugs.

One problem is that the TV norm (PAL/NTSC/...) is in struct
video_tuner, not struct video_channel.  That's bad if you have a board
without tuner at all and a PAL video recorder connected to Composite1
and a NTSC Camera to Composite2...
Fixing this required changes in both structs and the VIDIOCSCHAN
ioctl.

Another one is that the VIDIOCSYNC ioctl had no argument at all, newer
versions take the frame number as argument.  The new scheme is more
stable.

The hard-coded frame size (BTTV_MAX_FBUF) is gone in newer versions,
you should use the VIDIOCGMBUF ioctl to figure out the size at runtime.

Happy hacking,

   Gerd

--
Gerd Knorr <kraxel@goldbach.in-berlin.de>