set_callbacks( DemuxOpen, DemuxClose )
add_submodule ()
+ add_shortcut( "v4l2" )
add_shortcut( "v4l2c" )
set_description( N_("Video4Linux2 Compressed A/V") )
set_capability( "access", 0 )
} v4l2chroma_to_fourcc[] =
{
/* Raw data types */
- { V4L2_PIX_FMT_GREY, VLC_FOURCC('G','R','E','Y'), 0, 0, 0 },
+ { V4L2_PIX_FMT_GREY, VLC_CODEC_GREY, 0, 0, 0 },
{ V4L2_PIX_FMT_HI240, VLC_FOURCC('I','2','4','0'), 0, 0, 0 },
- { V4L2_PIX_FMT_RGB555, VLC_FOURCC('R','V','1','5'), 0x001f,0x03e0,0x7c00 },
- { V4L2_PIX_FMT_RGB565, VLC_FOURCC('R','V','1','6'), 0x001f,0x07e0,0xf800 },
+ { V4L2_PIX_FMT_RGB555, VLC_CODEC_RGB15, 0x001f,0x03e0,0x7c00 },
+ { V4L2_PIX_FMT_RGB565, VLC_CODEC_RGB16, 0x001f,0x07e0,0xf800 },
/* Won't work since we don't know how to handle such gmask values
* correctly
- { V4L2_PIX_FMT_RGB555X, VLC_FOURCC('R','V','1','5'), 0x007c,0xe003,0x1f00 },
- { V4L2_PIX_FMT_RGB565X, VLC_FOURCC('R','V','1','6'), 0x00f8,0xe007,0x1f00 },
+ { V4L2_PIX_FMT_RGB555X, VLC_CODEC_RGB15, 0x007c,0xe003,0x1f00 },
+ { V4L2_PIX_FMT_RGB565X, VLC_CODEC_RGB16, 0x00f8,0xe007,0x1f00 },
*/
- { V4L2_PIX_FMT_BGR24, VLC_FOURCC('R','V','2','4'), 0xff0000,0xff00,0xff },
- { V4L2_PIX_FMT_RGB24, VLC_FOURCC('R','V','2','4'), 0xff,0xff00,0xff0000 },
- { V4L2_PIX_FMT_BGR32, VLC_FOURCC('R','V','3','2'), 0xff0000,0xff00,0xff },
- { V4L2_PIX_FMT_RGB32, VLC_FOURCC('R','V','3','2'), 0xff,0xff00,0xff0000 },
- { V4L2_PIX_FMT_YUYV, VLC_FOURCC('Y','U','Y','2'), 0, 0, 0 },
- { V4L2_PIX_FMT_YUYV, VLC_FOURCC('Y','U','Y','V'), 0, 0, 0 },
- { V4L2_PIX_FMT_UYVY, VLC_FOURCC('U','Y','V','Y'), 0, 0, 0 },
+ { V4L2_PIX_FMT_BGR24, VLC_CODEC_RGB24, 0xff0000,0xff00,0xff },
+ { V4L2_PIX_FMT_RGB24, VLC_CODEC_RGB24, 0xff,0xff00,0xff0000 },
+ { V4L2_PIX_FMT_BGR32, VLC_CODEC_RGB32, 0xff0000,0xff00,0xff },
+ { V4L2_PIX_FMT_RGB32, VLC_CODEC_RGB32, 0xff,0xff00,0xff0000 },
+ { V4L2_PIX_FMT_YUYV, VLC_CODEC_YUYV, 0, 0, 0 },
+ { V4L2_PIX_FMT_UYVY, VLC_CODEC_UYVY, 0, 0, 0 },
{ V4L2_PIX_FMT_Y41P, VLC_FOURCC('I','4','1','N'), 0, 0, 0 },
- { V4L2_PIX_FMT_YUV422P, VLC_FOURCC('I','4','2','2'), 0, 0, 0 },
- { V4L2_PIX_FMT_YVU420, VLC_FOURCC('Y','V','1','2'), 0, 0, 0 },
- { V4L2_PIX_FMT_YUV411P, VLC_FOURCC('I','4','1','1'), 0, 0, 0 },
- { V4L2_PIX_FMT_YUV410, VLC_FOURCC('I','4','1','0'), 0, 0, 0 },
+ { V4L2_PIX_FMT_YUV422P, VLC_CODEC_I422, 0, 0, 0 },
+ { V4L2_PIX_FMT_YVU420, VLC_CODEC_YV12, 0, 0, 0 },
+ { V4L2_PIX_FMT_YUV411P, VLC_CODEC_I411, 0, 0, 0 },
+ { V4L2_PIX_FMT_YUV410, VLC_CODEC_I410, 0, 0, 0 },
/* Raw data types, not in V4L2 spec but still in videodev2.h and supported
* by VLC */
- { V4L2_PIX_FMT_YUV420, VLC_FOURCC('I','4','2','0'), 0, 0, 0 },
- /* FIXME { V4L2_PIX_FMT_RGB444, VLC_FOURCC('R','V','3','2') }, */
+ { V4L2_PIX_FMT_YUV420, VLC_CODEC_I420, 0, 0, 0 },
+ /* FIXME { V4L2_PIX_FMT_RGB444, VLC_CODEC_RGB32 }, */
/* Compressed data types */
- { V4L2_PIX_FMT_MJPEG, VLC_FOURCC('M','J','P','G'), 0, 0, 0 },
+ { V4L2_PIX_FMT_MJPEG, VLC_CODEC_MJPG, 0, 0, 0 },
#if 0
{ V4L2_PIX_FMT_JPEG, VLC_FOURCC('J','P','E','G') },
{ V4L2_PIX_FMT_DV, VLC_FOURCC('?','?','?','?') },
ssize_t (*pf_read)( int, void *, size_t );
void *(*pf_mmap)( void *, size_t, int, int, int, off_t );
int (*pf_munmap)( void *, size_t );
+ bool b_libv4l2;
#endif
};
p_sys->pf_read = read;
p_sys->pf_mmap = mmap;
p_sys->pf_munmap = munmap;
+ p_sys->b_libv4l2 = false;
}
static void use_libv4l2( demux_sys_t *p_sys )
p_sys->pf_read = v4l2_read;
p_sys->pf_mmap = v4l2_mmap;
p_sys->pf_munmap = v4l2_munmap;
+ p_sys->b_libv4l2 = true;
}
# define v4l2_close (p_sys->pf_close)
{
msg_Dbg( p_this, "Trying direct kernel v4l2" );
use_kernel_v4l2( p_sys );
- if( FindMainDevice( p_this, p_sys, true ) == VLC_SUCCESS)
+ if( FindMainDevice( p_this, p_sys, false ) == VLC_SUCCESS)
return VLC_SUCCESS;
}
#endif
/* This is new in Linux 2.6.19 */
struct v4l2_frmivalenum frmival;
- frmival.index = 0;
+ memset( &frmival, 0, sizeof(frmival) );
frmival.pixel_format = i_pixel_format;
frmival.width = i_width;
frmival.height = i_height;
#endif
/* This is new in Linux 2.6.19 */
struct v4l2_frmsizeenum frmsize;
- frmsize.index = 0;
+ memset( &frmsize, 0, sizeof(frmsize) );
frmsize.pixel_format = i_pixel_format;
if( v4l2_ioctl( i_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize ) >= 0 )
{
#endif
/* This is new in Linux 2.6.19 */
struct v4l2_frmsizeenum frmsize;
- frmsize.index = 0;
+ memset( &frmsize, 0, sizeof(frmsize) );
frmsize.pixel_format = i_pixel_format;
if( v4l2_ioctl( i_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize ) >= 0 )
{
enum v4l2_buf_type buf_type;
const char *psz_device = p_sys->psz_device;
es_format_t es_fmt;
- int libv4l2_fd;
if( ( i_fd = open( psz_device, O_RDWR ) ) < 0 )
{
custom cam format to normal formats conversion). Chances are big we will
still fail then though, as normally v4l2_fd_open only fails if the
device is not a v4l2 device. */
- libv4l2_fd = v4l2_fd_open( i_fd, V4L2_ENABLE_ENUM_FMT_EMULATION );
- if( libv4l2_fd != -1 )
- i_fd = libv4l2_fd;
-#else
- libv4l2_fd = i_fd;
+ if( p_sys->b_libv4l2 )
+ {
+ int libv4l2_fd;
+ libv4l2_fd = v4l2_fd_open( i_fd, V4L2_ENABLE_ENUM_FMT_EMULATION );
+ if( libv4l2_fd != -1 )
+ i_fd = libv4l2_fd;
+ }
#endif
/* Tune the tuner */
ControlList( p_obj, p_sys, i_fd,
var_GetBool( p_obj, "v4l2-controls-reset" ), b_demux );
SetAvailControlsByString( p_obj, p_sys, i_fd );
+
if( false == b_demux)
{
return i_fd;
case IO_METHOD_READ:
if( !(p_sys->dev_cap.capabilities & V4L2_CAP_READWRITE) )
{
- msg_Err( p_demux, "device does not support read i/o" );
+ msg_Err( p_obj, "device does not support read i/o" );
goto open_failed;
}
break;
case IO_METHOD_USERPTR:
if( !(p_sys->dev_cap.capabilities & V4L2_CAP_STREAMING) )
{
- msg_Err( p_demux, "device does not support streaming i/o" );
+ msg_Err( p_obj, "device does not support streaming i/o" );
goto open_failed;
}
break;
default:
- msg_Err( p_demux, "io method not supported" );
+ msg_Err( p_obj, "io method not supported" );
goto open_failed;
}
fmt.fmt.pix.width = p_sys->i_width;
fmt.fmt.pix.height = p_sys->i_height;
- fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
+ fmt.fmt.pix.field = V4L2_FIELD_NONE;
/* Test and set Chroma */
fmt.fmt.pix.pixelformat = 0;
/* User specified chroma */
if( strlen( p_sys->psz_requested_chroma ) >= 4 )
{
- int i_requested_fourcc = VLC_FOURCC(
+ int i_requested_fourcc = vlc_fourcc_GetCodec( VIDEO_ES,
+ VLC_FOURCC(
p_sys->psz_requested_chroma[0], p_sys->psz_requested_chroma[1],
- p_sys->psz_requested_chroma[2], p_sys->psz_requested_chroma[3] );
+ p_sys->psz_requested_chroma[2], p_sys->psz_requested_chroma[3] ) );
for( int i = 0; v4l2chroma_to_fourcc[i].i_v4l2 != 0; i++ )
{
if( v4l2chroma_to_fourcc[i].i_fourcc == i_requested_fourcc )
p_sys->i_width = fmt.fmt.pix.width;
p_sys->i_height = fmt.fmt.pix.height;
+ /* Check interlacing */
+ if( v4l2_ioctl( i_fd, VIDIOC_G_FMT, &fmt ) < 0 ) {;}
+ switch( fmt.fmt.pix.field )
+ {
+ case V4L2_FIELD_NONE:
+ msg_Dbg( p_demux, "Interlacing setting: progressive" );
+ break;
+ case V4L2_FIELD_TOP:
+ msg_Dbg( p_demux, "Interlacing setting: top field only" );
+ break;
+ case V4L2_FIELD_BOTTOM:
+ msg_Dbg( p_demux, "Interlacing setting: bottom field only" );
+ break;
+ case V4L2_FIELD_INTERLACED:
+ msg_Dbg( p_demux, "Interlacing setting: interleaved (bottom top if M/NTSC, top bottom otherwise)" );
+ break;
+ case V4L2_FIELD_SEQ_TB:
+ msg_Dbg( p_demux, "Interlacing setting: sequential top bottom" );
+ break;
+ case V4L2_FIELD_SEQ_BT:
+ msg_Dbg( p_demux, "Interlacing setting: sequential bottom top" );
+ break;
+ case V4L2_FIELD_ALTERNATE:
+ msg_Dbg( p_demux, "Interlacing setting: alternate fields" );
+ break;
+ case V4L2_FIELD_INTERLACED_TB:
+ msg_Dbg( p_demux, "Interlacing setting: interleaved top bottom" );
+ break;
+ case V4L2_FIELD_INTERLACED_BT:
+ msg_Dbg( p_demux, "Interlacing setting: interleaved bottom top" );
+ break;
+ default:
+ msg_Warn( p_demux, "Interlacing setting: unknown type (%d)",
+ fmt.fmt.pix.field );
+ break;
+ }
+ if( fmt.fmt.pix.field != V4L2_FIELD_NONE )
+ msg_Warn( p_demux, "Interlaced inputs haven't been tested. Please report any issue." );
+
/* Look up final fourcc */
p_sys->i_fourcc = 0;
for( int i = 0; v4l2chroma_to_fourcc[i].i_fourcc != 0; i++ )
/* This is new in Linux 2.6.19 */
/* List supported frame rates */
struct v4l2_frmivalenum frmival;
- frmival.index = 0;
+ memset( &frmival, 0, sizeof(frmival) );
frmival.pixel_format = fmt.fmt.pix.pixelformat;
frmival.width = p_sys->i_width;
frmival.height = p_sys->i_height;
int i_standard;
int i_fd;
- int libv4l2_fd;
if( ( i_fd = open( psz_device, O_RDWR ) ) < 0 )
{
custom cam format to normal formats conversion). Chances are big we will
still fail then though, as normally v4l2_fd_open only fails if the
device is not a v4l2 device. */
- libv4l2_fd = v4l2_fd_open( i_fd, V4L2_ENABLE_ENUM_FMT_EMULATION );
- if( libv4l2_fd != -1 )
- i_fd = libv4l2_fd;
-#else
- libv4l2_fd = i_fd;
+ if( p_sys->b_libv4l2 )
+ {
+ int libv4l2_fd;
+ libv4l2_fd = v4l2_fd_open( i_fd, V4L2_ENABLE_ENUM_FMT_EMULATION );
+ if( libv4l2_fd != -1 )
+ i_fd = libv4l2_fd;
+ }
#endif
/* Get device capabilites */
if( p_sys->dev_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE )
{
struct v4l2_input t_input;
- t_input.index = 0;
+ memset( &t_input, 0, sizeof(t_input) );
while( v4l2_ioctl( i_fd, VIDIOC_ENUMINPUT, &t_input ) >= 0 )
{
p_sys->i_input++;
/* This is new in Linux 2.6.19 */
/* List valid frame sizes for this format */
struct v4l2_frmsizeenum frmsize;
- frmsize.index = 0;
+ memset( &frmsize, 0, sizeof(frmsize) );
frmsize.pixel_format = p_sys->p_codecs[i_index].pixelformat;
if( v4l2_ioctl( i_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize ) < 0 )
{