
#ifndef _H_VIDEODEV_V4L2_H_
#define _H_VIDEODEV_V4L2_H_

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <getopt.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <linux/videodev2.h>

#include <list>
#include <string>


#include "convert.h"
#include "gui.h"
#include "videodev.h"


enum {
	IOMODE_READ,
	IOMODE_MMAP
};



#define VDEV_INBUFFERS 3
class VideoDev_V4L2: public VideoDev {
private:
	int io;		// IO Mode
	int fd;

	int inbuffer_idx;
	VideoInBuffer inbuffer[VDEV_INBUFFERS];
	struct v4l2_cropcap cropcap;
	struct v4l2_crop crop;
	struct v4l2_format fmt;

	int Grab(VideoFrameRaw *vf);
	int Open();
	int Close();
	int CaptureStart();
	int CaptureStop();
	int SetDevCtrl(unsigned int id, int value);
	int GetDevCtrl(unsigned int id, int *value);

	int InitMMap();
	int UnInit();

	void PrintCaps(uint32_t caps);
	void PrintFmt (struct v4l2_format *f);
	int xioctl(int fd, int request, void *arg);
public:
	VideoDev_V4L2();
	~VideoDev_V4L2();
	int GetDeviceList(std::list<std::string> *list);
	int GetDeviceFormats(string device, std::list<string> *formats);
	int GetDeviceResolutions(string device, std::list<string> *formats) { return VDEV_STATUS_OK; };
};

#endif
