2014-08-10 08:33:03 -07:00
|
|
|
/*
|
|
|
|
Copyright (C) 2014 by Leonhard Oelke <leonhard@in-verted.de>
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <linux/videodev2.h>
|
|
|
|
#include <libv4l2.h>
|
|
|
|
|
|
|
|
#include <obs-module.h>
|
|
|
|
#include <media-io/video-io.h>
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Data structure for mapped buffers
|
|
|
|
*/
|
|
|
|
struct v4l2_mmap_info {
|
|
|
|
/** length of the mapped buffer */
|
|
|
|
size_t length;
|
|
|
|
/** start address of the mapped buffer */
|
|
|
|
void *start;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Data structure for buffer info
|
|
|
|
*/
|
|
|
|
struct v4l2_buffer_data {
|
|
|
|
/** number of mapped buffers */
|
|
|
|
uint_fast32_t count;
|
|
|
|
/** memory info for mapped buffers */
|
|
|
|
struct v4l2_mmap_info *info;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert v4l2 pixel format to obs video format
|
|
|
|
*
|
|
|
|
* @param format v4l2 format id
|
|
|
|
*
|
|
|
|
* @return obs video_format id
|
|
|
|
*/
|
|
|
|
static inline enum video_format v4l2_to_obs_video_format(uint_fast32_t format)
|
|
|
|
{
|
|
|
|
switch (format) {
|
2019-06-22 22:13:45 -07:00
|
|
|
case V4L2_PIX_FMT_YVYU:
|
|
|
|
return VIDEO_FORMAT_YVYU;
|
|
|
|
case V4L2_PIX_FMT_YUYV:
|
|
|
|
return VIDEO_FORMAT_YUY2;
|
|
|
|
case V4L2_PIX_FMT_UYVY:
|
|
|
|
return VIDEO_FORMAT_UYVY;
|
|
|
|
case V4L2_PIX_FMT_NV12:
|
|
|
|
return VIDEO_FORMAT_NV12;
|
|
|
|
case V4L2_PIX_FMT_YUV420:
|
|
|
|
return VIDEO_FORMAT_I420;
|
|
|
|
case V4L2_PIX_FMT_YVU420:
|
|
|
|
return VIDEO_FORMAT_I420;
|
2015-04-20 11:52:40 -07:00
|
|
|
#ifdef V4L2_PIX_FMT_XBGR32
|
2019-06-22 22:13:45 -07:00
|
|
|
case V4L2_PIX_FMT_XBGR32:
|
|
|
|
return VIDEO_FORMAT_BGRX;
|
2015-04-20 11:52:40 -07:00
|
|
|
#endif
|
|
|
|
#ifdef V4L2_PIX_FMT_ABGR32
|
2019-06-22 22:13:45 -07:00
|
|
|
case V4L2_PIX_FMT_ABGR32:
|
|
|
|
return VIDEO_FORMAT_BGRA;
|
2015-04-20 11:52:40 -07:00
|
|
|
#endif
|
2019-06-22 22:13:45 -07:00
|
|
|
case V4L2_PIX_FMT_BGR24:
|
|
|
|
return VIDEO_FORMAT_BGR3;
|
|
|
|
default:
|
|
|
|
return VIDEO_FORMAT_NONE;
|
2014-08-10 08:33:03 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fixed framesizes for devices that don't support enumerating discrete values.
|
|
|
|
*
|
|
|
|
* The framesizes in this array are packed, the width encoded in the high word
|
|
|
|
* and the height in the low word.
|
|
|
|
* The array is terminated with a zero.
|
|
|
|
*/
|
2019-06-22 22:13:45 -07:00
|
|
|
static const int v4l2_framesizes[] = {
|
2014-08-10 08:33:03 -07:00
|
|
|
/* 4:3 */
|
2019-06-22 22:13:45 -07:00
|
|
|
160 << 16 | 120, 320 << 16 | 240, 480 << 16 | 320, 640 << 16 | 480,
|
|
|
|
800 << 16 | 600, 1024 << 16 | 768, 1280 << 16 | 960, 1440 << 16 | 1050,
|
|
|
|
1440 << 16 | 1080, 1600 << 16 | 1200,
|
2014-08-10 08:33:03 -07:00
|
|
|
|
|
|
|
/* 16:9 */
|
2019-06-22 22:13:45 -07:00
|
|
|
640 << 16 | 360, 960 << 16 | 540, 1280 << 16 | 720, 1600 << 16 | 900,
|
|
|
|
1920 << 16 | 1080, 1920 << 16 | 1200, 2560 << 16 | 1440,
|
|
|
|
3840 << 16 | 2160,
|
2017-12-16 00:19:02 -08:00
|
|
|
|
|
|
|
/* 21:9 */
|
2019-06-22 22:13:45 -07:00
|
|
|
2560 << 16 | 1080, 3440 << 16 | 1440, 5120 << 16 | 2160,
|
2014-08-10 08:33:03 -07:00
|
|
|
|
|
|
|
/* tv */
|
2019-06-22 22:13:45 -07:00
|
|
|
432 << 16 | 520, 480 << 16 | 320, 480 << 16 | 530, 486 << 16 | 440,
|
|
|
|
576 << 16 | 310, 576 << 16 | 520, 576 << 16 | 570, 720 << 16 | 576,
|
|
|
|
1024 << 16 | 576,
|
2014-08-10 08:33:03 -07:00
|
|
|
|
2019-06-22 22:13:45 -07:00
|
|
|
0};
|
2014-08-10 08:33:03 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Fixed framerates for devices that don't support enumerating discrete values.
|
|
|
|
*
|
|
|
|
* The framerates in this array are packed, the numerator encoded in the high
|
|
|
|
* word and the denominator in the low word.
|
|
|
|
* The array is terminated with a zero.
|
|
|
|
*/
|
2019-06-22 22:13:45 -07:00
|
|
|
static const int v4l2_framerates[] = {1 << 16 | 60,
|
|
|
|
1 << 16 | 50,
|
|
|
|
1 << 16 | 30,
|
|
|
|
1 << 16 | 25,
|
|
|
|
1 << 16 | 20,
|
|
|
|
1 << 16 | 15,
|
|
|
|
1 << 16 | 10,
|
|
|
|
1 << 16 | 5,
|
2014-08-10 08:33:03 -07:00
|
|
|
|
2019-06-22 22:13:45 -07:00
|
|
|
0};
|
2014-08-10 08:33:03 -07:00
|
|
|
|
2014-09-15 15:05:11 -07:00
|
|
|
/**
|
|
|
|
* Pack two integer values into one
|
|
|
|
*
|
|
|
|
* Obviously the input integers have to be truncated in order to fit into
|
|
|
|
* one. The effective 16bits left are still enough to handle resolutions and
|
|
|
|
* framerates just fine.
|
|
|
|
*
|
|
|
|
* @param a integer one
|
|
|
|
* @param b integer two
|
|
|
|
*
|
|
|
|
* @return the packed integer
|
|
|
|
*/
|
|
|
|
static inline int v4l2_pack_tuple(int a, int b)
|
|
|
|
{
|
|
|
|
return (a << 16) | (b & 0xffff);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unpack two integer values from one
|
|
|
|
*
|
|
|
|
* @see v4l2_pack_tuple
|
|
|
|
*
|
|
|
|
* @param a pointer to integer a
|
|
|
|
* @param b pointer to integer b
|
|
|
|
* @param packed the packed integer
|
|
|
|
*/
|
|
|
|
static void v4l2_unpack_tuple(int *a, int *b, int packed)
|
|
|
|
{
|
|
|
|
*a = packed >> 16;
|
|
|
|
*b = packed & 0xffff;
|
|
|
|
}
|
|
|
|
|
2014-08-10 08:33:03 -07:00
|
|
|
/**
|
|
|
|
* Start the video capture on the device.
|
|
|
|
*
|
|
|
|
* This enqueues the memory mapped buffers and instructs the device to start
|
|
|
|
* the video stream.
|
|
|
|
*
|
|
|
|
* @param dev handle for the v4l2 device
|
|
|
|
* @param buf buffer data
|
|
|
|
*
|
|
|
|
* @return negative on failure
|
|
|
|
*/
|
|
|
|
int_fast32_t v4l2_start_capture(int_fast32_t dev, struct v4l2_buffer_data *buf);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stop the video capture on the device.
|
|
|
|
*
|
|
|
|
* @param dev handle for the v4l2 device
|
|
|
|
*
|
|
|
|
* @return negative on failure
|
|
|
|
*/
|
|
|
|
int_fast32_t v4l2_stop_capture(int_fast32_t dev);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create memory mapping for buffers
|
|
|
|
*
|
|
|
|
* This tries to map at least 2, preferably 4, buffers to application memory.
|
|
|
|
*
|
|
|
|
* @param dev handle for the v4l2 device
|
|
|
|
* @param buf buffer data
|
|
|
|
*
|
|
|
|
* @return negative on failure
|
|
|
|
*/
|
|
|
|
int_fast32_t v4l2_create_mmap(int_fast32_t dev, struct v4l2_buffer_data *buf);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy the memory mapping for buffers
|
|
|
|
*
|
|
|
|
* @param buf buffer data
|
|
|
|
*
|
|
|
|
* @return negative on failure
|
|
|
|
*/
|
|
|
|
int_fast32_t v4l2_destroy_mmap(struct v4l2_buffer_data *buf);
|
|
|
|
|
2014-09-15 14:59:41 -07:00
|
|
|
/**
|
|
|
|
* Set the video input on the device.
|
|
|
|
*
|
|
|
|
* If the action succeeds input is set to the currently selected input.
|
|
|
|
*
|
|
|
|
* @param dev handle for the v4l2 device
|
|
|
|
* @param input index of the input or -1 to leave it as is
|
|
|
|
*
|
|
|
|
* @return negative on failure
|
|
|
|
*/
|
|
|
|
int_fast32_t v4l2_set_input(int_fast32_t dev, int *input);
|
|
|
|
|
2015-02-16 13:29:39 -08:00
|
|
|
/**
|
|
|
|
* Get capabilities for an input.
|
|
|
|
*
|
|
|
|
* @param dev handle for the v4l2 device
|
|
|
|
* @param input index of the input or -1 to use the currently selected
|
|
|
|
* @param caps capabilities for the input
|
|
|
|
*
|
|
|
|
* @return negative on failure
|
|
|
|
*/
|
|
|
|
int_fast32_t v4l2_get_input_caps(int_fast32_t dev, int input, uint32_t *caps);
|
|
|
|
|
2014-09-15 15:05:11 -07:00
|
|
|
/**
|
|
|
|
* Set the video format on the device.
|
|
|
|
*
|
|
|
|
* If the action succeeds resolution, pixelformat and bytesperline are set
|
|
|
|
* to the used values.
|
|
|
|
*
|
|
|
|
* @param dev handle for the v4l2 device
|
|
|
|
* @param resolution packed value of the resolution or -1 to leave as is
|
|
|
|
* @param pixelformat index of the pixelformat or -1 to leave as is
|
|
|
|
* @param bytesperline this will be set accordingly on success
|
|
|
|
*
|
|
|
|
* @return negative on failure
|
|
|
|
*/
|
|
|
|
int_fast32_t v4l2_set_format(int_fast32_t dev, int *resolution,
|
2019-06-22 22:13:45 -07:00
|
|
|
int *pixelformat, int *bytesperline);
|
2014-09-15 15:05:11 -07:00
|
|
|
|
2014-09-15 15:06:42 -07:00
|
|
|
/**
|
|
|
|
* Set the framerate on the device.
|
|
|
|
*
|
|
|
|
* If the action succeeds framerate is set to the used value.
|
|
|
|
*
|
|
|
|
* @param dev handle to the v4l2 device
|
|
|
|
* @param framerate packed value of the framerate or -1 to leave as is
|
|
|
|
*
|
|
|
|
* @return negative on failure
|
|
|
|
*/
|
|
|
|
int_fast32_t v4l2_set_framerate(int_fast32_t dev, int *framerate);
|
|
|
|
|
2015-02-23 12:08:57 -08:00
|
|
|
/**
|
|
|
|
* Set a video standard on the device.
|
|
|
|
*
|
|
|
|
* If the action succeeds standard is set to the used video standard id.
|
|
|
|
*
|
|
|
|
* @param dev handle to the v4l2 device
|
|
|
|
* @param standard id of the standard to use or -1 to leave as is
|
|
|
|
*
|
|
|
|
* @return negative on failure
|
|
|
|
*/
|
|
|
|
int_fast32_t v4l2_set_standard(int_fast32_t dev, int *standard);
|
|
|
|
|
2015-02-24 13:27:00 -08:00
|
|
|
/**
|
|
|
|
* Get the dv timing for an input with a specified index
|
|
|
|
*
|
|
|
|
* @param dev handle to the v4l2 device
|
2015-04-06 11:11:11 -07:00
|
|
|
* @param dvt pointer to the timing structure to fill
|
2015-02-24 13:27:00 -08:00
|
|
|
* @param index index of the dv timing to fetch
|
|
|
|
*
|
|
|
|
* @return negative on failure
|
|
|
|
*/
|
|
|
|
int_fast32_t v4l2_enum_dv_timing(int_fast32_t dev, struct v4l2_dv_timings *dvt,
|
2019-06-22 22:13:45 -07:00
|
|
|
int index);
|
2015-02-24 13:18:24 -08:00
|
|
|
/**
|
|
|
|
* Set a dv timing on the device
|
|
|
|
*
|
|
|
|
* Currently standard will not be changed on success or error.
|
|
|
|
*
|
|
|
|
* @param dev handle to the v4l2 device
|
|
|
|
* @param timing index of the timing to use or -1 to leave as is
|
|
|
|
*
|
|
|
|
* @return negative on failure
|
|
|
|
*/
|
|
|
|
int_fast32_t v4l2_set_dv_timing(int_fast32_t dev, int *timing);
|
2015-02-24 13:27:00 -08:00
|
|
|
|
2014-08-10 08:33:03 -07:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|