1 /*
2     Copyright (C) 2005 by Jasem Mutlaq <mutlaqja@ikarustech.com>
3     Copyright (C) 2013 Geehalel (geehalel@gmail.com)
4 
5     Based on V4L 2 Example
6     http://v4l2spec.bytesex.org/spec-single/v4l2.html#CAPTURE-EXAMPLE
7 
8     This library is free software; you can redistribute it and/or
9     modify it under the terms of the GNU Lesser General Public
10     License as published by the Free Software Foundation; either
11     version 2.1 of the License, or (at your option) any later version.
12 
13     This library is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16     Lesser General Public License for more details.
17 
18     You should have received a copy of the GNU Lesser General Public
19     License along with this library; if not, write to the Free Software
20     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21 
22 */
23 
24 #pragma once
25 
26 //#include "videodev2.h"
27 #include "eventloop.h"
28 #include "indidevapi.h"
29 // this adds add dependency to indidriver for v4l_legacy, meade_lpi
30 
31 // Can't use logger as legacy drivers don't use defaultdevice
32 //#include "indilogger.h"
33 #include "v4l2_decode/v4l2_decode.h"
34 // for direct recording
35 #include "stream/streammanager.h"
36 
37 #include <stdio.h>
38 #include <cstdlib>
39 
40 #include <linux/videodev2.h>
41 
42 #define VIDEO_COMPRESSION_LEVEL 4
43 
44 class V4L2_Driver;
45 
46 enum
47 {
48     LX_ACTIVE = 0,
49     LX_TRIGGERED,
50     LX_ACCUMULATING
51 };
52 
53 namespace INDI
54 {
55 
56 class V4L2_Base
57 {
58   public:
59     V4L2_Base();
60     virtual ~V4L2_Base();
61 
62     typedef enum { IO_METHOD_READ, IO_METHOD_MMAP, IO_METHOD_USERPTR } io_method;
63 
64     struct buffer
65     {
66         void *start;
67         size_t length;
68     };
69 
70     /* Connection */
71     virtual int connectCam(const char *devpath, char *errmsg, int pixelFormat = -1, int width = -1, int height = -1);
72     virtual void disconnectCam(bool stopcapture);
73     char *getDeviceName();
74     void setDeviceName(const char *name);
75     bool isLXmodCapable();
76 
77     /* Updates */
78     void callFrame(void *p);
79 
80     /* Image Format/Size */
81     int getFormat();
82     int getWidth();
83     int getHeight();
84     int getBpp();
85     virtual int setSize(int x, int y);
86     virtual void getMaxMinSize(int &x_max, int &y_max, int &x_min, int &y_min);
87 
88     /* Frame rate */
89     int (V4L2_Base::*setframerate)(struct v4l2_fract frate, char *errmsg);
90     struct v4l2_fract (V4L2_Base::*getframerate)();
91 
92     unsigned char *getY();
93     unsigned char *getU();
94     unsigned char *getV();
95     // 2017-01-24 JM: Deprecated RGBA (32bit) buffer. Should use RGB24 buffer to save space
96     //unsigned char * getColorBuffer();
97     unsigned char *getRGBBuffer();
98     float *getLinearY();
99 
100     void registerCallback(WPF *fp, void *ud);
101 
102     int start_capturing(char *errmsg);
103     int stop_capturing(char *errmsg);
104     static void newFrame(int fd, void *p);
105 
106     //void setDropFrameCount(unsigned int count) { dropFrameCount = count;}
107     void enumerate_ctrl();
108     void enumerate_menu();
109     bool enumerate_ext_ctrl();
110     int queryINTControls(INumberVectorProperty *nvp);
111     bool queryExtControls(INumberVectorProperty *nvp, unsigned int *nnumber, ISwitchVectorProperty **options,
112                           unsigned int *noptions, const char *dev, const char *group);
113     void queryControls(INumberVectorProperty *nvp, unsigned int *nnumber, ISwitchVectorProperty **options,
114                        unsigned int *noptions, const char *dev, const char *group);
115 
116     int getControl(unsigned int ctrl_id, double *value, char *errmsg);
117     int setINTControl(unsigned int ctrl_id, double new_value, char *errmsg);
118     int setOPTControl(unsigned int ctrl_id, unsigned int new_value, char *errmsg);
119 
120     int query_ctrl(unsigned int ctrl_id, double &ctrl_min, double &ctrl_max, double &ctrl_step, double &ctrl_value,
121                    char *errmsg);
122     void getinputs(ISwitchVectorProperty *inputssp);
123     int setinput(unsigned int inputindex, char *errmsg);
124     void getcaptureformats(ISwitchVectorProperty *captureformatssp);
125     int setcaptureformat(unsigned int captureformatindex, char *errmsg);
126     void getcapturesizes(ISwitchVectorProperty *capturesizessp, INumberVectorProperty *capturesizenp);
127     int setcapturesize(unsigned int w, unsigned int h, char *errmsg);
128     void getframerates(ISwitchVectorProperty *frameratessp, INumberVectorProperty *frameratenp);
129     int setcroprect(int x, int y, int w, int h, char *errmsg);
130     struct v4l2_rect getcroprect();
131 
132     void setColorProcessing(bool quantization, bool colorconvert, bool linearization);
133 
setlxstate(short s)134     void setlxstate(short s)
135     {
136         IDLog("setlexstate to %d\n", s);
137         lxstate = s;
138     }
getlxstate()139     short getlxstate() { return lxstate; }
isstreamactive()140     bool isstreamactive() { return streamactive; }
141 
142     void doDecode(bool);
143 
144   protected:
145     int xioctl(int fd, int request, void *arg, char const *const request_str);
146     int ioctl_set_format(struct v4l2_format new_fmt, char *errmsg);
147 
148     int read_frame(char *errsg);
149     int uninit_device(char *errmsg);
150     int open_device(const char *devpath, char *errmsg);
151     int check_device(char *errmsg);
152     int init_device(char *errmsg);
153     int init_mmap(char *errmsg);
154     int errno_exit(const char *s, char *errmsg);
155 
156     void close_device();
157     void init_userp(unsigned int buffer_size);
158     void init_read(unsigned int buffer_size);
159 
160     void findMinMax();
161 
162     int enumeratedInputs;
163     int enumeratedCaptureFormats;
164 
165     /* Frame rate */
166     int stdsetframerate(struct v4l2_fract frate, char *errmsg);
167     int pwcsetframerate(struct v4l2_fract frate, char *errmsg);
168     struct v4l2_fract stdgetframerate();
169 
170     struct v4l2_capability cap;
171     struct v4l2_cropcap cropcap;
172     struct v4l2_crop crop;
173     struct v4l2_format fmt;
174     struct v4l2_input input;
175     struct v4l2_buffer buf;
176 
177     bool cancrop;
178     bool cropset;
179     bool cansetrate;
180     bool streamedonce;
181     bool streamactive;
182 
183     short lxstate;
184 
185     struct v4l2_queryctrl queryctrl;
186     struct v4l2_querymenu querymenu;
187     bool has_ext_pix_format;
188 
189     bool is_compressed() const;
190 
191     WPF *callback;
192     void *uptr;
193     char dev_name[64];
194     const char *path;
195     io_method io;
196     int fd;
197     struct buffer *buffers;
198     unsigned int n_buffers;
199     bool reallocate_buffers;
200     //int		dropFrame;
201     //bool      dropFrameEnabled;
202     //unsigned int      dropFrameCount;
203 
204     struct v4l2_fract frameRate;
205     int xmax, xmin, ymax, ymin;
206     int selectCallBackID;
207     //unsigned char * YBuf,*UBuf,*VBuf, *yuvBuffer, *colorBuffer, *rgb24_buffer, *cropbuf;
208 
209     V4L2_Decode *v4l2_decode;
210     V4L2_Decoder *decoder;
211     bool dodecode;
212 
213     int bpp;
214 
215     friend class ::V4L2_Driver;
216 
217     char deviceName[MAXINDIDEVICE];
218 };
219 }
220