Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.1 / 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 #include "channel.inc"
26 #include "condition.h"
27 #include "vframe.inc"
28 #include "devicev4l2base.inc"
29 #include "mutex.inc"
30 #include "thread.h"
31 #include "vframe.h"
32 #include "videodevice.inc"
33
34 class DeviceV4L2BufferQ
35 {
36         volatile int in, out;
37         int limit, *buffers;
38         Mutex *bfr_lock;
39 public:
40         DeviceV4L2BufferQ(int qsize);
41         ~DeviceV4L2BufferQ();
42         int q(int bfr);
43         int dq();
44         int dq(Condition *time_lock, int time_out);
45         int sz();
46         void reset() { in = out = 0; }
47 };
48
49 // Another thread which puts back buffers asynchronously of the buffer
50 // grabber.  Because 2.6.7 drivers block the buffer enqueuer.
51 class DeviceV4L2Put : public Thread
52 {
53         DeviceV4L2Base *v4l2;
54 public:
55         DeviceV4L2Put(DeviceV4L2Base *v4l2);
56         ~DeviceV4L2Put();
57
58         void run();
59         DeviceV4L2BufferQ *putq;
60         Condition *buffer_lock;
61         int done;
62         void put_buffer(int bfr) {
63                 if( !putq->q(bfr) ) buffer_lock->unlock();
64         }
65 };
66
67 class DeviceV4L2VFrame : public VFrame {
68         unsigned char *dev_data;
69         unsigned long dev_size;
70 public:
71         unsigned char *get_dev_data() { return dev_data; }
72         unsigned long get_dev_size() { return dev_size; }
73
74         DeviceV4L2VFrame(int dev_fd, unsigned long ofs, unsigned long sz);
75         ~DeviceV4L2VFrame();
76 };
77
78 class DeviceV4L2Base : public Thread
79 {
80         friend class DeviceV4L2Put;
81         DeviceV4L2Put *put_thread;
82         Mutex *v4l2_lock;
83 // Some of the drivers in 2.6.7 can't handle simultaneous QBUF and DQBUF calls.
84         Mutex *qbfrs_lock;
85         Condition *video_lock;
86         DeviceV4L2VFrame **device_buffers;
87         Channel *device_channel;
88         DeviceV4L2BufferQ *getq;
89
90         int done;
91         int opened;
92         int streamon;
93         int dev_status;
94         int total_buffers;
95         volatile int q_bfrs;
96 // COMPRESSED or another color model the device should use.
97         int color_model;
98         int dev_fd;
99
100         int dev_open();
101         void dev_close();
102         int v4l2_open(int color_model);
103         int v4l2_status();
104
105         int vioctl (unsigned long int req, void *arg);
106         static unsigned int cmodel_to_device(int color_model);
107         void run();
108 public:
109         DeviceV4L2Base();
110         ~DeviceV4L2Base();
111
112         virtual VideoDevice *v4l2_device() = 0;
113
114         int v4l2_fd() { return dev_fd; }
115         int open_dev(int color_model);
116         void close_dev();
117         int status_dev();
118         virtual int start_dev();
119         virtual int stop_dev();
120         int get_sources();
121         int is_opened() { return opened; }
122         int dev_signal() { return dev_status; }
123         VFrame *device_buffer(int bfr) { return device_buffers[bfr]; }
124         int get_color_model() { return color_model; }
125         int get_buffer() { return getq->dq(video_lock,V4L2_BUFFER_TIMEOUT); }
126         void put_buffer(int bfr) { put_thread->put_buffer(bfr); }
127         int putq_sz() { return put_thread->putq->sz(); }
128 };
129
130 #endif