Credit Andrew - improve in-tree documentation
[goodguy/cinelerra.git] / cinelerra / devicev4l2base.h
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #ifndef DEVICEV4L2BASE_H
23 #define DEVICEV4L2BASE_H
24
25 #ifdef HAVE_VIDEO4LINUX2
26
27 #include "channel.inc"
28 #include "condition.h"
29 #include "vframe.inc"
30 #include "devicev4l2base.inc"
31 #include "mutex.inc"
32 #include "thread.h"
33 #include "vframe.h"
34 #include "videodevice.inc"
35
36 class DeviceV4L2BufferQ
37 {
38         volatile int in, out;
39         int limit, *buffers;
40         Mutex *bfr_lock;
41 public:
42         DeviceV4L2BufferQ(int qsize);
43         ~DeviceV4L2BufferQ();
44         int q(int bfr);
45         int dq();
46         int dq(Condition *time_lock, int time_out);
47         int sz();
48         void reset() { in = out = 0; }
49 };
50
51 // Another thread which puts back buffers asynchronously of the buffer
52 // grabber.  Because 2.6.7 drivers block the buffer enqueuer.
53 class DeviceV4L2Put : public Thread
54 {
55         DeviceV4L2Base *v4l2;
56 public:
57         DeviceV4L2Put(DeviceV4L2Base *v4l2);
58         ~DeviceV4L2Put();
59
60         void run();
61         DeviceV4L2BufferQ *putq;
62         Condition *buffer_lock;
63         int done;
64         void put_buffer(int bfr) {
65                 if( !putq->q(bfr) ) buffer_lock->unlock();
66         }
67 };
68
69 class DeviceV4L2VFrame : public VFrame {
70         unsigned char *dev_data;
71         unsigned long dev_size;
72 public:
73         unsigned char *get_dev_data() { return dev_data; }
74         unsigned long get_dev_size() { return dev_size; }
75
76         DeviceV4L2VFrame(int dev_fd, unsigned long ofs, unsigned long sz);
77         ~DeviceV4L2VFrame();
78 };
79
80 class DeviceV4L2Base : public Thread
81 {
82         friend class DeviceV4L2Put;
83         DeviceV4L2Put *put_thread;
84         Mutex *v4l2_lock;
85 // Some of the drivers in 2.6.7 can't handle simultaneous QBUF and DQBUF calls.
86         Mutex *qbfrs_lock;
87         Condition *video_lock;
88         DeviceV4L2VFrame **device_buffers;
89         Channel *device_channel;
90         DeviceV4L2BufferQ *getq;
91
92         int done;
93         int opened;
94         int streamon;
95         int dev_status;
96         int total_buffers;
97         volatile int q_bfrs;
98 // COMPRESSED or another color model the device should use.
99         int color_model;
100         int dev_fd;
101         int iwidth;
102         int iheight;
103
104         int dev_open();
105         void dev_close();
106         int v4l2_open(int color_model);
107         int v4l2_status();
108
109         int vioctl (unsigned long int req, void *arg);
110         static unsigned int cmodel_to_device(int color_model);
111         void run();
112 public:
113         DeviceV4L2Base();
114         ~DeviceV4L2Base();
115
116         virtual VideoDevice *v4l2_device() = 0;
117
118         int v4l2_fd() { return dev_fd; }
119         int open_dev(int color_model);
120         void close_dev();
121         int status_dev();
122         virtual int start_dev();
123         virtual int stop_dev();
124         int get_sources();
125         int is_opened() { return opened; }
126         int dev_signal() { return dev_status; }
127         VFrame *device_buffer(int bfr) { return device_buffers[bfr]; }
128         int get_color_model() { return color_model; }
129         int get_buffer() { return getq->dq(video_lock,V4L2_BUFFER_TIMEOUT); }
130         void put_buffer(int bfr) { put_thread->put_buffer(bfr); }
131         int putq_sz() { return put_thread->putq->sz(); }
132 };
133
134 #endif
135 #endif