From: Antoine Cellerier Date: Fri, 7 Dec 2007 21:27:03 +0000 (+0000) Subject: Add MJPEG support to the v4l2 access (and simplify the buffer size handling code... X-Git-Tag: 0.9.0-test0~4246 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=23a8765c1a4ead053d509b385dbf0673751eb89f;hp=fcde47951ad8224954a73d423d59da046d69497e;p=vlc Add MJPEG support to the v4l2 access (and simplify the buffer size handling code). I now need people with v4l2 compatible devices with JPEG, DV and MPEG support to try to enable those features. --- diff --git a/modules/access/v4l2.c b/modules/access/v4l2.c index 27594f18bf..eacf8b3f5c 100644 --- a/modules/access/v4l2.c +++ b/modules/access/v4l2.c @@ -4,8 +4,9 @@ * Copyright (C) 2002-2007 the VideoLAN team * $Id$ * - * Author: Benjamin Pracht - * Richard Hosking + * Authors: Benjamin Pracht + * Richard Hosking + * Antoine Cellerier * * 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 @@ -220,7 +221,7 @@ static int Control( demux_t *, int, va_list ); static int Demux( demux_t * ); static block_t* GrabVideo( demux_t *p_demux ); -static block_t* ProcessVideoFrame( demux_t *p_demux, uint8_t *p_frame ); +static block_t* ProcessVideoFrame( demux_t *p_demux, uint8_t *p_frame, size_t ); static block_t* GrabAudio( demux_t *p_demux ); vlc_bool_t IsPixelFormatSupported( demux_t *p_demux, unsigned int i_pixelformat ); @@ -244,20 +245,28 @@ static struct int i_fourcc; } v4l2chroma_to_fourcc[] = { - { V4L2_PIX_FMT_GREY, VLC_FOURCC( 'G', 'R', 'E', 'Y' ) }, - { V4L2_PIX_FMT_HI240, VLC_FOURCC( 'I', '2', '4', '0' ) }, - { V4L2_PIX_FMT_RGB565, VLC_FOURCC( 'R', 'V', '1', '6' ) }, - { V4L2_PIX_FMT_RGB555, VLC_FOURCC( 'R', 'V', '1', '5' ) }, - { V4L2_PIX_FMT_BGR24, VLC_FOURCC( 'R', 'V', '2', '4' ) }, - { V4L2_PIX_FMT_BGR32, VLC_FOURCC( 'R', 'V', '3', '2' ) }, - { V4L2_PIX_FMT_YUYV, VLC_FOURCC( 'Y', 'U', 'Y', '2' ) }, - { V4L2_PIX_FMT_YUYV, VLC_FOURCC( 'Y', 'U', 'Y', 'V' ) }, - { V4L2_PIX_FMT_UYVY, VLC_FOURCC( 'U', 'Y', 'V', 'Y' ) }, - { V4L2_PIX_FMT_Y41P, VLC_FOURCC( 'I', '4', '1', 'N' ) }, - { V4L2_PIX_FMT_YUV422P, VLC_FOURCC( 'I', '4', '2', '2' ) }, - { V4L2_PIX_FMT_YVU420, VLC_FOURCC( 'I', '4', '2', '0' ) }, - { V4L2_PIX_FMT_YUV411P, VLC_FOURCC( 'I', '4', '1', '1' ) }, - { V4L2_PIX_FMT_YUV410, VLC_FOURCC( 'I', '4', '1', '0' ) }, + /* Raw data types */ + { V4L2_PIX_FMT_GREY, VLC_FOURCC('G','R','E','Y') }, + { V4L2_PIX_FMT_HI240, VLC_FOURCC('I','2','4','0') }, + { V4L2_PIX_FMT_RGB565, VLC_FOURCC('R','V','1','6') }, + { V4L2_PIX_FMT_RGB555, VLC_FOURCC('R','V','1','5') }, + { V4L2_PIX_FMT_BGR24, VLC_FOURCC('R','V','2','4') }, + { V4L2_PIX_FMT_BGR32, VLC_FOURCC('R','V','3','2') }, + { V4L2_PIX_FMT_YUYV, VLC_FOURCC('Y','U','Y','2') }, + { V4L2_PIX_FMT_YUYV, VLC_FOURCC('Y','U','Y','V') }, + { V4L2_PIX_FMT_UYVY, VLC_FOURCC('U','Y','V','Y') }, + { V4L2_PIX_FMT_Y41P, VLC_FOURCC('I','4','1','N') }, + { V4L2_PIX_FMT_YUV422P, VLC_FOURCC('I','4','2','2') }, + { V4L2_PIX_FMT_YVU420, VLC_FOURCC('I','4','2','0') }, + { V4L2_PIX_FMT_YUV411P, VLC_FOURCC('I','4','1','1') }, + { V4L2_PIX_FMT_YUV410, VLC_FOURCC('I','4','1','0') }, + /* Compressed data types */ + { V4L2_PIX_FMT_MJPEG, VLC_FOURCC('M','J','P','G') }, +#if 0 + { V4L2_PIX_FMT_JPEG, VLC_FOURCC('J','P','E','G') }, + { V4L2_PIX_FMT_DV, VLC_FOURCC('?','?','?','?') }, + { V4L2_PIX_FMT_MPEG, VLC_FOURCC('?','?','?','?') }, +#endif { 0, 0 } }; @@ -321,9 +330,6 @@ struct demux_sys_t int i_hue; int i_gamma; - picture_t pic; - int i_video_frame_size; - es_out_id_t *p_es_video; /* Audio */ @@ -933,6 +939,7 @@ static block_t* GrabVideo( demux_t *p_demux ) block_t *p_block = NULL; struct v4l2_buffer buf; + ssize_t i_ret; if( p_sys->f_fps >= 0.1 && p_sys->i_video_pts > 0 ) { @@ -946,7 +953,8 @@ static block_t* GrabVideo( demux_t *p_demux ) switch( p_sys->io ) { case IO_METHOD_READ: - if( read( p_sys->i_fd_video, p_sys->p_buffers[0].start, p_sys->p_buffers[0].length ) ) + i_ret = read( p_sys->i_fd_video, p_sys->p_buffers[0].start, p_sys->p_buffers[0].length ); + if( i_ret == -1 ) { switch( errno ) { @@ -961,7 +969,7 @@ static block_t* GrabVideo( demux_t *p_demux ) } } - p_block = ProcessVideoFrame( p_demux, (uint8_t*)p_sys->p_buffers[0].start ); + p_block = ProcessVideoFrame( p_demux, (uint8_t*)p_sys->p_buffers[0].start, i_ret ); if( !p_block ) return 0; break; @@ -992,7 +1000,7 @@ static block_t* GrabVideo( demux_t *p_demux ) return 0; } - p_block = ProcessVideoFrame( p_demux, p_sys->p_buffers[buf.index].start ); + p_block = ProcessVideoFrame( p_demux, p_sys->p_buffers[buf.index].start, buf.bytesused ); if( !p_block ) return 0; /* Unlock */ @@ -1039,7 +1047,7 @@ static block_t* GrabVideo( demux_t *p_demux ) return 0; } - p_block = ProcessVideoFrame( p_demux, (uint8_t*)buf.m.userptr ); + p_block = ProcessVideoFrame( p_demux, (uint8_t*)buf.m.userptr, buf.bytesused ); if( !p_block ) return 0; /* Unlock */ @@ -1063,22 +1071,21 @@ static block_t* GrabVideo( demux_t *p_demux ) * ProcessVideoFrame: Helper function to take a buffer and copy it into * a new block *****************************************************************************/ -static block_t* ProcessVideoFrame( demux_t *p_demux, uint8_t *p_frame ) +static block_t* ProcessVideoFrame( demux_t *p_demux, uint8_t *p_frame, size_t i_size ) { - demux_sys_t *p_sys = p_demux->p_sys; block_t *p_block; if( !p_frame ) return 0; /* New block */ - if( !( p_block = block_New( p_demux, p_sys->i_video_frame_size ) ) ) + if( !( p_block = block_New( p_demux, i_size ) ) ) { msg_Warn( p_demux, "Cannot get new block" ); return 0; } /* Copy frame */ - memcpy( p_block->p_buffer, p_frame, p_sys->i_video_frame_size ); + memcpy( p_block->p_buffer, p_frame, i_size ); return p_block; } @@ -1383,26 +1390,26 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device ) /* Verify device support for the various IO methods */ switch( p_sys->io ) { - case IO_METHOD_READ: - if( !(p_sys->dev_cap.capabilities & V4L2_CAP_READWRITE) ) - { - msg_Err( p_demux, "device does not support read i/o" ); - goto open_failed; - } - break; + case IO_METHOD_READ: + if( !(p_sys->dev_cap.capabilities & V4L2_CAP_READWRITE) ) + { + msg_Err( p_demux, "device does not support read i/o" ); + goto open_failed; + } + break; - case IO_METHOD_MMAP: - case IO_METHOD_USERPTR: - if( !(p_sys->dev_cap.capabilities & V4L2_CAP_STREAMING) ) - { - msg_Err( p_demux, "device does not support streaming i/o" ); - goto open_failed; - } - break; + case IO_METHOD_MMAP: + case IO_METHOD_USERPTR: + if( !(p_sys->dev_cap.capabilities & V4L2_CAP_STREAMING) ) + { + msg_Err( p_demux, "device does not support streaming i/o" ); + goto open_failed; + } + break; - default: - msg_Err( p_demux, "io method not supported" ); - goto open_failed; + default: + msg_Err( p_demux, "io method not supported" ); + goto open_failed; } /* Reset Cropping */ @@ -1416,12 +1423,12 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device ) { switch( errno ) { - case EINVAL: - /* Cropping not supported. */ - break; - default: - /* Errors ignored. */ - break; + case EINVAL: + /* Cropping not supported. */ + break; + default: + /* Errors ignored. */ + break; } } } @@ -1582,21 +1589,6 @@ int OpenVideoDev( demux_t *p_demux, char *psz_device ) VideoControl( p_demux, i_fd, "hue", V4L2_CID_HUE, p_sys->i_hue ); VideoControl( p_demux, i_fd, "gamma", V4L2_CID_GAMMA, p_sys->i_gamma ); - /* Init vout Picture */ - vout_InitPicture( VLC_OBJECT(p_demux), &p_sys->pic, p_sys->i_fourcc, - p_sys->i_width, p_sys->i_height, p_sys->i_width * - VOUT_ASPECT_FACTOR / p_sys->i_height ); - if( !p_sys->pic.i_planes ) - { - msg_Err( p_demux, "unsupported chroma" ); - goto open_failed; - } - p_sys->i_video_frame_size = 0; - for( int i = 0; i < p_sys->pic.i_planes; i++ ) - { - p_sys->i_video_frame_size += p_sys->pic.p[i].i_visible_lines * p_sys->pic.p[i].i_visible_pitch; - } - /* Init IO method */ switch( p_sys->io ) {