Changeset f913159da06612d0278f87bd8160dafaa8a30b53

Show
Ignore:
Timestamp:
10/06/07 13:26:34 (10 months ago)
Author:
Jean-Paul Saman <jpsaman@videolan.org>
git-committer:
Jean-Paul Saman <jpsaman@videolan.org> 1191669994 +0000
git-parent:

[c7d5b899f524df1c54599b42b6d4cb115644f1ec]

git-author:
Jean-Paul Saman <jpsaman@videolan.org> 1191669994 +0000
Message:

Patch for v4l2 support by Richard Hosking <richard AT hovis DOT net>

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • THANKS

    r2f9a9c5 rf913159  
    173173Remco Poortinga <poortinga at telin.nl> - IPv6 multicast patch 
    174174Rene Gollent <rgollent at u.arizona.edu> - BeOS interface fix 
     175Richard Hosking <richard at hovis.net> - v4l2 support 
    175176Rob Casey (rob dot casey AT swishgroup dot com dot au) - Amino RTSP fix 
    176177Rudolf Cornelissen <rag.cornelissen at inter.nl.net> - BeOS fixes 
  • modules/access/v4l2.c

    r552e595 rf913159  
    33 ***************************************************************************** 
    44 * Copyright (C) 2002-2004 the VideoLAN team 
    5  * $Id: v4l.c 16084 2006-07-19 09:45:02Z zorglub $ 
     5 * $Id: v4l2.c 16084 2006-07-19 09:45:02Z zorglub $ 
    66 * 
    77 * Author: Benjamin Pracht <bigben at videolan dot org> 
     8 *         Richard Hosking <richard at hovis dot net> 
    89 * 
    910 * This program is free software; you can redistribute it and/or modify 
     
    1920 * You should have received a copy of the GNU General Public License 
    2021 * along with this program; if not, write to the Free Software 
    21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ 
     22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 
     23 *****************************************************************************/ 
     24 
     25/*  
     26 * Sections based on the reference V4L2 capture example at 
     27 * http://v4l2spec.bytesex.org/spec/capture-example.html 
     28 */ 
     29  
     30/* 
     31 * TODO: No mjpeg support yet.  
     32 * TODO: mmap untested.  
     33 * TODO: Tuner partial implementation. 
     34 * TODO: Alsa input support? 
     35 */ 
    2236 
    2337/***************************************************************************** 
     
    3751#include <sys/ioctl.h> 
    3852#include <sys/errno.h> 
     53#include <sys/mman.h> 
    3954 
    4055#include <asm/types.h>          /* for videodev2.h */ 
     
    4257#include <linux/videodev2.h> 
    4358 
     59#include <sys/soundcard.h> 
     60 
    4461/***************************************************************************** 
    4562 * Module descriptior 
    46   *****************************************************************************/ 
     63 *****************************************************************************/ 
    4764 
    4865static int  Open ( vlc_object_t * ); 
     
    5370    "Name of the device to use. " \ 
    5471    "If you don't specify anything, /dev/video0 will be used.") 
     72#define ADEV_TEXT N_("Audio device name") 
     73#define ADEV_LONGTEXT N_( \ 
     74    "Name of the audio device to use. " \ 
     75    "If you don't specify anything, no audio device will be used.") 
     76#define STANDARD_TEXT N_( "Standard" ) 
     77#define STANDARD_LONGTEXT N_( \ 
     78    "Video standard (Default, SECAM, PAL, or NTSC)." ) 
     79#define CHROMA_TEXT N_("Video input chroma format") 
     80#define CHROMA_LONGTEXT N_( \ 
     81    "Force the Video4Linux2 video device to use a specific chroma format " \ 
     82    "(eg. I420, RV24, etc.)") 
    5583#define INPUT_TEXT N_( "Input" ) 
    5684#define INPUT_LONGTEXT N_( \ 
    5785    "Input of the card to use (Usually, 0 = tuner, " \ 
    5886    "1 = composite, 2 = svideo)." ) 
    59  
     87#define IOMETHOD_TEXT N_( "IO Method" ) 
     88#define IOMETHOD_LONGTEXT N_( \ 
     89    "IO Method (READ, MMAP, USERPTR)." ) 
     90#define FPS_TEXT N_( "Framerate" ) 
     91#define FPS_LONGTEXT N_( "Framerate to capture, if applicable " \ 
     92    "(-1 for autodetect)." ) 
     93#define STEREO_TEXT N_( "Stereo" ) 
     94#define STEREO_LONGTEXT N_( \ 
     95    "Capture the audio stream in stereo." ) 
     96#define SAMPLERATE_TEXT N_( "Samplerate" ) 
     97#define SAMPLERATE_LONGTEXT N_( \ 
     98    "Samplerate of the captured audio stream, in Hz (eg: 11025, 22050, 44100, 48000)" )     
     99#define CACHING_TEXT N_("Caching value in ms") 
     100#define CACHING_LONGTEXT N_( \ 
     101    "Caching value for V4L2 captures. This " \ 
     102    "value should be set in milliseconds." ) 
     103     
     104typedef enum { 
     105    IO_METHOD_READ, 
     106    IO_METHOD_MMAP, 
     107    IO_METHOD_USERPTR, 
     108} io_method; 
     109 
     110static int i_standards_list[] = 
     111    { V4L2_STD_UNKNOWN, V4L2_STD_SECAM, V4L2_STD_PAL, V4L2_STD_NTSC }; 
     112static const char *psz_standards_list_text[] = 
     113    { N_("Default"), N_("SECAM"), N_("PAL"),  N_("NTSC") }; 
     114     
     115static int i_iomethod_list[] = 
     116    { IO_METHOD_READ, IO_METHOD_MMAP, IO_METHOD_USERPTR }; 
     117static const char *psz_iomethod_list_text[] = 
     118    { N_("READ"), N_("MMAP"),  N_("USERPTR") }; 
    60119 
    61120vlc_module_begin(); 
     
    67126    add_string( "v4l2-dev", "/dev/video0", 0, DEV_TEXT, DEV_LONGTEXT, 
    68127                VLC_FALSE ); 
     128    add_string( "v4l2-adev", "/dev/dsp", 0, DEV_TEXT, DEV_LONGTEXT, 
     129                VLC_FALSE ); 
     130    add_integer( "v4l2-standard", 0, NULL, STANDARD_TEXT, STANDARD_LONGTEXT, 
     131                VLC_FALSE ); 
     132    change_integer_list( i_standards_list, psz_standards_list_text, 0 ); 
     133    add_string( "v4l2-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT, 
     134                VLC_TRUE ); 
    69135    add_integer( "v4l2-input", 0, NULL, INPUT_TEXT, INPUT_LONGTEXT, 
    70136                VLC_TRUE ); 
     137    add_integer( "v4l2-io", IO_METHOD_MMAP, NULL, IOMETHOD_TEXT, IOMETHOD_LONGTEXT, 
     138                VLC_FALSE ); 
     139    change_integer_list( i_iomethod_list, psz_iomethod_list_text, 0 ); 
     140    add_float( "v4l2-fps", 0, NULL, FPS_TEXT, FPS_LONGTEXT, VLC_TRUE ); 
     141    add_bool( "v4l2-stereo", VLC_TRUE, NULL, STEREO_TEXT, STEREO_LONGTEXT, 
     142                VLC_TRUE ); 
     143    add_integer( "v4l2-samplerate", 48000, NULL, SAMPLERATE_TEXT, 
     144                SAMPLERATE_LONGTEXT, VLC_TRUE ); 
     145    add_integer( "v4l2-caching", DEFAULT_PTS_DELAY / 1000, NULL, 
     146                CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE ); 
    71147 
    72148    add_shortcut( "v4l2" ); 
     
    79155 *****************************************************************************/ 
    80156 
    81 static int DemuxMMAP( demux_t * ); 
     157static void ParseMRL( demux_t * ); 
     158 
    82159static int Control( demux_t *, int, va_list ); 
    83160 
    84 static int ProbeDev( demux_t * ); 
    85 static int OpenVideoDev( demux_t * ); 
     161static int Demux( demux_t * ); 
     162static block_t* GrabVideo( demux_t *p_demux ); 
     163static block_t* ProcessVideoFrame( demux_t *p_demux, uint8_t *p_frame ); 
     164static block_t* GrabAudio( demux_t *p_demux ); 
     165 
     166vlc_bool_t IsChromaSupported( demux_t *p_demux, unsigned int i_v4l2 ); 
     167unsigned int GetChromaFromFourcc( char *psz_fourcc ); 
     168 
     169static int OpenVideoDev( demux_t *, char *psz_device ); 
     170static int OpenAudioDev( demux_t *, char *psz_device ); 
     171static vlc_bool_t ProbeVideoDev( demux_t *, char *psz_device ); 
     172static vlc_bool_t ProbeAudioDev( demux_t *, char *psz_device ); 
     173 
     174static struct 
     175
     176    unsigned int i_v4l2; 
     177    int i_fourcc; 
     178} v4l2chroma_to_fourcc[] = 
     179
     180    { V4L2_PIX_FMT_GREY, VLC_FOURCC( 'G', 'R', 'E', 'Y' ) }, 
     181    { V4L2_PIX_FMT_HI240, VLC_FOURCC( 'I', '2', '4', '0' ) }, 
     182    { V4L2_PIX_FMT_RGB565, VLC_FOURCC( 'R', 'V', '1', '6' ) }, 
     183    { V4L2_PIX_FMT_RGB555, VLC_FOURCC( 'R', 'V', '1', '5' ) }, 
     184    { V4L2_PIX_FMT_BGR24, VLC_FOURCC( 'R', 'V', '2', '4' ) }, 
     185    { V4L2_PIX_FMT_BGR32, VLC_FOURCC( 'R', 'V', '3', '2' ) }, 
     186    { V4L2_PIX_FMT_YUYV, VLC_FOURCC( 'Y', 'U', 'Y', '2' ) }, 
     187    { V4L2_PIX_FMT_YUYV, VLC_FOURCC( 'Y', 'U', 'Y', 'V' ) }, 
     188    { V4L2_PIX_FMT_UYVY, VLC_FOURCC( 'U', 'Y', 'V', 'Y' ) }, 
     189    { V4L2_PIX_FMT_Y41P, VLC_FOURCC( 'I', '4', '1', 'N' ) }, 
     190    { V4L2_PIX_FMT_YUV422P, VLC_FOURCC( 'I', '4', '2', '2' ) }, 
     191    { V4L2_PIX_FMT_YVU420, VLC_FOURCC( 'I', '4', '2', '0' ) }, 
     192    { V4L2_PIX_FMT_YUV411P, VLC_FOURCC( 'I', '4', '1', '1' ) }, 
     193    { V4L2_PIX_FMT_YUV410, VLC_FOURCC( 'I', '4', '1', '0' ) }, 
     194    { 0, 0 } 
     195}; 
     196 
     197struct buffer_t  
     198
     199    void *  start; 
     200    size_t  length; 
     201}; 
    86202 
    87203struct demux_sys_t 
    88204{ 
    89     char *psz_device; 
    90  
    91     int i_fd_video; 
     205    char *psz_device;  /* Main device from MRL, can be video or audio */ 
     206     
     207    char *psz_vdev; 
     208    int  i_fd_video; 
     209 
     210    char *psz_adev; 
     211    int  i_fd_audio; 
     212     
     213    /* Video */ 
     214    io_method io; 
     215     
     216    int i_pts; 
    92217 
    93218    struct v4l2_capability dev_cap; 
     
    96221    struct v4l2_input *p_inputs; 
    97222    int i_selected_input; 
     223     
     224    int i_standard; 
     225    struct v4l2_standard *p_standards; 
     226    v4l2_std_id i_selected_standard_id; 
    98227 
    99228    int i_audio; 
     
    106235    int i_codec; 
    107236    struct v4l2_fmtdesc *p_codecs; 
     237     
     238    struct buffer_t *p_buffers; 
     239    unsigned int i_nbuffers; 
     240     
     241    int i_width; 
     242    int i_height; 
     243    float f_fps;            /* <= 0.0 mean to grab at full rate */ 
     244    mtime_t i_video_pts;    /* only used when f_fps > 0 */ 
     245    int i_fourcc; 
     246     
     247    picture_t pic; 
     248    int i_video_frame_size; 
     249     
     250    es_out_id_t *p_es_video; 
     251     
     252    /* Audio */ 
     253    int i_sample_rate; 
     254    vlc_bool_t b_stereo; 
     255    int i_audio_max_frame_size; 
     256    block_t *p_block_audio; 
     257    es_out_id_t *p_es_audio; 
    108258}; 
    109259 
    110260/***************************************************************************** 
    111  * Open: opens v4l device 
     261 * Open: opens v4l2 device 
    112262 ***************************************************************************** 
    113263 * 
     
    119269    demux_t     *p_demux = (demux_t*)p_this; 
    120270    demux_sys_t *p_sys; 
    121  
     271    vlc_value_t val; 
     272    char *psz; 
     273     
    122274    /* Only when selected */ 
    123     if( *p_demux->psz_access == '\0' ) 
    124         return VLC_EGENERIC; 
     275    if( *p_demux->psz_access == '\0' ) return VLC_EGENERIC; 
    125276 
    126277    /* Set up p_demux */ 
    127278    p_demux->pf_control = Control; 
     279    p_demux->pf_demux = Demux; 
    128280    p_demux->info.i_update = 0; 
    129281    p_demux->info.i_title = 0; 
     
    133285    if( p_sys == NULL ) return VLC_ENOMEM; 
    134286    memset( p_sys, 0, sizeof( demux_sys_t ) ); 
    135  
    136     p_sys->psz_device = var_CreateGetString( p_demux, "v4l2-dev" ); 
    137  
    138     if( ProbeDev( p_demux ) < 0 ) return VLC_EGENERIC; 
    139  
    140     if( OpenVideoDev( p_demux ) < 0 ) return VLC_EGENERIC; 
     287     
     288    p_sys->i_video_pts = -1; 
     289     
     290    var_Create( p_demux, "v4l2-standard", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); 
     291    var_Get( p_demux, "v4l2-standard", &val ); 
     292    p_sys->i_selected_standard_id = i_standards_list[val.i_int]; 
     293     
     294    p_sys->i_selected_input = var_CreateGetInteger( p_demux, "v4l2-input" ); 
     295     
     296    p_sys->io = var_CreateGetInteger( p_demux, "v4l2-io" ); 
     297     
     298    var_Create( p_demux, "v4l2-fps", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); 
     299    var_Get( p_demux, "v4l2-fps", &val ); 
     300    p_sys->f_fps = val.f_float; 
     301               
     302    var_Create( p_demux, "v4l2-samplerate", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); 
     303    var_Get( p_demux, "v4l2-samplerate", &val ); 
     304    p_sys->i_sample_rate = val.i_int; 
     305     
     306    psz = var_CreateGetString( p_demux, "v4l2-chroma" ); 
     307    p_sys->i_fourcc = GetChromaFromFourcc( psz ); 
     308    free( psz );     
     309     
     310    var_Create( p_demux, "v4l2-stereo", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); 
     311    var_Get( p_demux, "v4l2-stereo", &val ); 
     312    p_sys->b_stereo = val.b_bool; 
     313 
     314    p_sys->i_pts = var_CreateGetInteger( p_demux, "v4l2-caching" ); 
     315 
     316    p_sys->psz_device = p_sys->psz_vdev = p_sys->psz_adev = NULL; 
     317    p_sys->i_fd_video = -1; 
     318    p_sys->i_fd_audio = -1; 
     319     
     320    p_sys->p_es_video = p_sys->p_es_audio = 0; 
     321    p_sys->p_block_audio = 0; 
     322 
     323    ParseMRL( p_demux ); 
     324     
     325    /* Find main device (video or audio) */ 
     326    if( p_sys->psz_device && *p_sys->psz_device ) 
     327    { 
     328        msg_Dbg( p_demux, "main device='%s'", p_sys->psz_device ); 
     329 
     330        /* Try to open as video device */ 
     331        msg_Dbg( p_demux, "trying device '%s' as video", p_sys->psz_device ); 
     332        if( ProbeVideoDev( p_demux, p_sys->psz_device ) ) 
     333        { 
     334            msg_Dbg( p_demux, "'%s' is a video device", p_sys->psz_device ); 
     335            /* Device was a video device */             
     336            if( p_sys->psz_vdev ) free( p_sys->psz_vdev ); 
     337            p_sys->psz_vdev = p_sys->psz_device; 
     338            p_sys->psz_device = NULL; 
     339            p_sys->i_fd_video = OpenVideoDev( p_demux, p_sys->psz_vdev ); 
     340            if( p_sys->i_fd_video < 0 ) 
     341            { 
     342                Close( p_this ); 
     343                return VLC_EGENERIC;             
     344            } 
     345        } 
     346        else 
     347        { 
     348            /* Try to open as audio device */      
     349            msg_Dbg( p_demux, "trying device '%s' as audio", p_sys->psz_device ); 
     350            if( ProbeAudioDev( p_demux, p_sys->psz_device ) ) 
     351            { 
     352                msg_Dbg( p_demux, "'%s' is an audio device", p_sys->psz_device ); 
     353                /* Device was an audio device */ 
     354                if( p_sys->psz_adev ) free( p_sys->psz_adev ); 
     355                p_sys->psz_adev = p_sys->psz_device; 
     356                p_sys->psz_device = NULL; 
     357                p_sys->i_fd_audio = OpenAudioDev( p_demux, p_sys->psz_adev ); 
     358                if( p_sys->i_fd_audio < 0 ) 
     359                { 
     360                    Close( p_this ); 
     361                    return VLC_EGENERIC;             
     362                } 
     363            } 
     364        } 
     365    } 
     366 
     367    /* If no device opened, only continue if the access was forced */ 
     368    if( p_sys->i_fd_video < 0 && p_sys->i_fd_audio < 0 ) 
     369    { 
     370        if( strcmp( p_demux->psz_access, "v4l2" ) ) 
     371        { 
     372            Close( p_this ); 
     373            return VLC_EGENERIC; 
     374        } 
     375    } 
     376 
     377    /* Find video device */ 
     378    if( p_sys->i_fd_video < 0 ) 
     379    { 
     380        if( !p_sys->psz_vdev || !*p_sys->psz_vdev ) 
     381        { 
     382            if( p_sys->psz_vdev ) free( p_sys->psz_vdev ); 
     383            p_sys->psz_vdev = var_CreateGetString( p_demux, "v4l2-dev" );; 
     384        } 
     385 
     386        if( p_sys->psz_vdev && *p_sys->psz_vdev && ProbeVideoDev( p_demux, p_sys->psz_vdev ) ) 
     387        { 
     388            p_sys->i_fd_video = OpenVideoDev( p_demux, p_sys->psz_vdev ); 
     389        } 
     390    } 
     391 
     392    /* Find audio device */ 
     393    if( p_sys->i_fd_audio < 0 ) 
     394    { 
     395        if( !p_sys->psz_adev || !*p_sys->psz_adev ) 
     396        { 
     397            if( p_sys->psz_adev ) free( p_sys->psz_adev ); 
     398            p_sys->psz_adev = var_CreateGetString( p_demux, "v4l2-adev" );; 
     399        } 
     400 
     401        if( p_sys->psz_adev && *p_sys->psz_adev && ProbeAudioDev( p_demux, p_sys->psz_adev ) ) 
     402        { 
     403            p_sys->i_fd_audio = OpenAudioDev( p_demux, p_sys->psz_adev ); 
     404        } 
     405    } 
     406 
     407    if( p_sys->i_fd_video < 0 && p_sys->i_fd_audio < 0 ) 
     408    { 
     409        Close( p_this ); 
     410        return VLC_EGENERIC; 
     411    } 
    141412 
    142413    return VLC_SUCCESS; 
     
    144415 
    145416/***************************************************************************** 
     417 * ParseMRL: parse the options contained in the MRL 
     418 *****************************************************************************/ 
     419static void ParseMRL( demux_t *p_demux ) 
     420{ 
     421    demux_sys_t *p_sys = p_demux->p_sys; 
     422 
     423    char *psz_dup = strdup( p_demux->psz_path ); 
     424    char *psz_parser = psz_dup; 
     425 
     426    while( *psz_parser && *psz_parser != ':' ) 
     427    { 
     428        psz_parser++; 
     429    } 
     430 
     431    if( *psz_parser == ':' ) 
     432    { 
     433        /* read options */ 
     434        for( ;; ) 
     435        { 
     436            *psz_parser++ = '\0'; 
     437             
     438            if( !strncmp( psz_parser, "adev=", strlen( "adev=" ) ) ) 
     439            { 
     440                int  i_len; 
     441 
     442                psz_parser += strlen( "adev=" ); 
     443                if( strchr( psz_parser, ':' ) ) 
     444                { 
     445                    i_len = strchr( psz_parser, ':' ) - psz_parser; 
     446                } 
     447                else 
     448                { 
     449                    i_len = strlen( psz_parser ); 
     450                } 
     451 
     452                p_sys->psz_adev = strndup( psz_parser, i_len ); 
     453 
     454                psz_parser += i_len;  
     455            } 
     456            else if( !strncmp( psz_parser, "standard=", strlen( "standard=" ) ) ) 
     457            { 
     458                psz_parser += strlen( "standard=" ); 
     459                if( !strncmp( psz_parser, "pal", strlen( "pal" ) ) ) 
     460                { 
     461                    p_sys->i_selected_standard_id = V4L2_STD_PAL; 
     462                    psz_parser += strlen( "pal" ); 
     463                } 
     464                else if( !strncmp( psz_parser, "ntsc", strlen( "ntsc" ) ) ) 
     465                { 
     466                    p_sys->i_selected_standard_id = V4L2_STD_NTSC; 
     467                    psz_parser += strlen( "ntsc" ); 
     468                } 
     469                else if( !strncmp( psz_parser, "secam", strlen( "secam" ) ) ) 
     470                { 
     471                    p_sys->i_selected_standard_id = V4L2_STD_SECAM; 
     472                    psz_parser += strlen( "secam" ); 
     473                } 
     474                else if( !strncmp( psz_parser, "default", strlen( "default" ) ) ) 
     475                { 
     476                    p_sys->i_selected_standard_id = V4L2_STD_UNKNOWN; 
     477                    psz_parser += strlen( "default" ); 
     478                } 
     479                else 
     480                { 
     481                    p_sys->i_selected_standard_id = i_standards_list[strtol( psz_parser, &psz_parser, 0 )]; 
     482                } 
     483            } 
     484            else if( !strncmp( psz_parser, "chroma=", strlen( "chroma=" ) ) ) 
     485            { 
     486                int  i_len; 
     487 
     488                psz_parser += strlen( "chroma=" ); 
     489                if( strchr( psz_parser, ':' ) ) 
     490                { 
     491                    i_len = strchr( psz_parser, ':' ) - psz_parser; 
     492                } 
     493                else 
     494                { 
     495                    i_len = strlen( psz_parser ); 
     496                } 
     497 
     498                char* chroma = strndup( psz_parser, i_len ); 
     499                p_sys->i_fourcc = GetChromaFromFourcc( chroma ); 
     500                free( chroma );                 
     501 
     502                psz_parser += i_len;  
     503            } 
     504            else if( !strncmp( psz_parser, "input=", strlen( "input=" ) ) ) 
     505            { 
     506                p_sys->i_selected_input = strtol( psz_parser + strlen( "input=" ), 
     507                                       &psz_parser, 0 ); 
     508            }             
     509            else if( !strncmp( psz_parser, "fps=", strlen( "fps=" ) ) ) 
     510            { 
     511                p_sys->f_fps = strtof( psz_parser + strlen( "fps=" ), 
     512                                       &psz_parser ); 
     513            } 
     514            else if( !strncmp( psz_parser, "io=", strlen( "io=" ) ) ) 
     515            { 
     516                psz_parser += strlen( "io=" ); 
     517                if( !strncmp( psz_parser, "read", strlen( "read" ) ) ) 
     518                { 
     519                    p_sys->io = IO_METHOD_READ; 
     520                    psz_parser += strlen( "read" ); 
     521                } 
     522                else if( !strncmp( psz_parser, "mmap", strlen( "mmap" ) ) ) 
     523                { 
     524                    p_sys->io = IO_METHOD_MMAP; 
     525                    psz_parser += strlen( "mmap" ); 
     526                } 
     527                else if( !strncmp( psz_parser, "userptr", strlen( "userptr" ) ) ) 
     528                { 
     529                    p_sys->io = IO_METHOD_USERPTR; 
     530                    psz_parser += strlen( "userptr" ); 
     531                } 
     532                else 
     533                { 
     534                    p_sys->io = strtol( psz_parser, &psz_parser, 0 ); 
     535                } 
     536            } 
     537            else if( !strncmp( psz_parser, "samplerate=", 
     538                               strlen( "samplerate=" ) ) ) 
     539            { 
     540                p_sys->i_sample_rate = 
     541                    strtol( psz_parser + strlen( "samplerate=" ), 
     542                            &psz_parser, 0 ); 
     543            } 
     544            else if( !strncmp( psz_parser, "stereo", strlen( "stereo" ) ) ) 
     545            { 
     546                psz_parser += strlen( "stereo" ); 
     547                p_sys->b_stereo = VLC_TRUE; 
     548            } 
     549            else if( !strncmp( psz_parser, "mono", strlen( "mono" ) ) ) 
     550            { 
     551                psz_parser += strlen( "mono" ); 
     552                p_sys->b_stereo = VLC_FALSE; 
     553            } 
     554            else if( !strncmp( psz_parser, "caching=", strlen( "caching=" ) ) ) 
     555            { 
     556                p_sys->i_pts = strtol( psz_parser + strlen( "caching=" ), 
     557                                       &psz_parser, DEFAULT_PTS_DELAY / 1000 ); 
     558            } 
     559            else 
     560            { 
     561                msg_Warn( p_demux, "unknown option" ); 
     562            } 
     563 
     564            while( *psz_parser && *psz_parser != ':' ) 
     565            { 
     566                psz_parser++; 
     567            } 
     568 
     569            if( *psz_parser == '\0' ) 
     570            { 
     571                break; 
     572            } 
     573        } 
     574    } 
     575 
     576    /* Main device */ 
     577    if( *psz_dup ) 
     578    { 
     579        p_sys->psz_device = strdup( psz_dup ); 
     580    } 
     581    if( psz_dup ) free( psz_dup ); 
     582} 
     583 
     584/***************************************************************************** 
    146585 * Close: close device, free resources 
    147586 *****************************************************************************/ 
     
    149588{ 
    150589    demux_t     *p_demux = (demux_t *)p_this; 
    151     demux_sys_t *p_sys   = p_demux->p_sys; 
    152  
     590    demux_sys_t *p_sys   = p_demux->p_sys;     
     591    struct v4l2_buffer buf; 
     592    enum v4l2_buf_type buf_type; 
     593    unsigned int i; 
     594     
     595    /* Stop video capture */ 
     596    if( p_sys->i_fd_video >= 0 )  
     597    { 
     598        switch( p_sys->io ) 
     599        { 
     600        case IO_METHOD_READ: 
     601            /* Nothing to do */ 
     602            break; 
     603             
     604        case IO_METHOD_MMAP: 
     605        case IO_METHOD_USERPTR:     
     606            /* Some drivers 'hang' internally if this is not done before streamoff */                
     607            for( unsigned int i = 0; i < p_sys->i_nbuffers; i++ ) 
     608            { 
     609                memset( &buf, 0, sizeof(buf) ); 
     610                buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
     611                buf.memory = V4L2_MEMORY_USERPTR; 
     612                ioctl( p_sys->i_fd_video, VIDIOC_DQBUF, &buf ); /* ignore result */ 
     613            } 
     614                 
     615            buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;                         
     616            if( ioctl( p_sys->i_fd_video, VIDIOC_STREAMOFF, &buf_type ) < 0 ) { 
     617                msg_Err( p_demux, "VIDIOC_STREAMOFF failed" ); 
     618            }     
     619             
     620            break;         
     621        } 
     622    } 
     623 
     624    /* Close */     
    153625    if( p_sys->i_fd_video >= 0 ) close( p_sys->i_fd_video ); 
    154  
     626    if( p_sys->i_fd_audio >= 0 ) close( p_sys->i_fd_audio ); 
     627 
     628    /* Free Video Buffers */ 
     629    if( p_sys->p_buffers ) { 
     630        switch( p_sys->io ) 
     631        { 
     632        case IO_METHOD_READ: 
     633            free( p_sys->p_buffers[0].start ); 
     634            break; 
     635             
     636        case IO_METHOD_MMAP: 
     637            for( i = 0; i < p_sys->i_nbuffers; ++i )  
     638            { 
     639                if( munmap( p_sys->p_buffers[i].start, p_sys->p_buffers[i].length ) ) 
     640                { 
     641                    msg_Err( p_demux, "munmap failed" ); 
     642                } 
     643            }     
     644            break; 
     645             
     646        case IO_METHOD_USERPTR:         
     647            for( i = 0; i < p_sys->i_nbuffers; ++i )  
     648            { 
     649               free( p_sys->p_buffers[i].start ); 
     650            }         
     651            break;         
     652        } 
     653        free( p_sys->p_buffers ); 
     654    } 
     655 
     656    if( p_sys->p_block_audio ) block_Release( p_sys->p_block_audio ); 
    155657    if( p_sys->psz_device ) free( p_sys->psz_device ); 
     658    if( p_sys->psz_vdev ) free( p_sys->psz_vdev ); 
     659    if( p_sys->psz_adev ) free( p_sys->psz_adev ); 
     660    if( p_sys->p_standards ) free( p_sys->p_standards ); 
    156661    if( p_sys->p_inputs ) free( p_sys->p_inputs ); 
    157662    if( p_sys->p_tuners ) free( p_sys->p_tuners ); 
     
    166671static int Control( demux_t *p_demux, int i_query, va_list args ) 
    167672{ 
     673    demux_sys_t *p_sys = p_demux->p_sys; 
     674    vlc_bool_t *pb; 
     675    int64_t    *pi64; 
     676 
     677    switch( i_query ) 
     678    { 
     679        /* Special for access_demux */ 
     680        case DEMUX_CAN_PAUSE: 
     681        case DEMUX_SET_PAUSE_STATE: 
     682        case DEMUX_CAN_CONTROL_PACE: 
     683            pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * ); 
     684            *pb = VLC_FALSE; 
     685            return VLC_SUCCESS; 
     686 
     687        case DEMUX_GET_PTS_DELAY: 
     688            pi64 = (int64_t*)va_arg( args, int64_t * ); 
     689            *pi64 = (int64_t)p_sys->i_pts * 1000; 
     690            return VLC_SUCCESS; 
     691 
     692        case DEMUX_GET_TIME: 
     693            pi64 = (int64_t*)va_arg( args, int64_t * ); 
     694            *pi64 = mdate(); 
     695            return VLC_SUCCESS; 
     696 
     697        /* TODO implement others */ 
     698        default: 
     699            return VLC_EGENERIC; 
     700    } 
     701 
    168702    return VLC_EGENERIC; 
    169703} 
    170704 
    171705/***************************************************************************** 
    172  * Demux: 
    173  *****************************************************************************/ 
    174 static int DemuxMMAP( demux_t *p_demux ) 
    175 
    176     msleep( 40000 ); 
     706 * Demux: Processes the audio or video frame 
     707 *****************************************************************************/ 
     708static int Demux( demux_t *p_demux ) 
     709
     710    demux_sys_t *p_sys = p_demux->p_sys; 
     711    es_out_id_t *p_es = p_sys->p_es_audio; 
     712    block_t *p_block = NULL; 
     713       
     714    /* Try grabbing audio frames first */ 
     715    if( p_sys->i_fd_audio < 0 || !( p_block = GrabAudio( p_demux ) ) ) 
     716    { 
     717        /* Try grabbing video frame */ 
     718        p_es = p_sys->p_es_video; 
     719        if( p_sys->i_fd_video > 0 ) p_block = GrabVideo( p_demux ); 
     720    } 
     721   
     722    if( !p_block ) 
     723    { 
     724        /* Sleep so we do not consume all the cpu, 10ms seems 
     725         * like a good value (100fps) */ 
     726        msleep( 10 ); 
     727        return 1; 
     728    } 
     729 
     730    es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts ); 
     731    es_out_Send( p_demux->out, p_es, p_block ); 
     732 
    177733    return 1; 
    178734} 
    179735 
     736/***************************************************************************** 
     737 * GrabVideo: Grab a video frame 
     738 *****************************************************************************/ 
     739static block_t* GrabVideo( demux_t *p_demux ) 
     740{ 
     741    demux_sys_t *p_sys = p_demux->p_sys; 
     742 
     743    block_t *p_block = NULL; 
     744    struct v4l2_buffer buf; 
     745 
     746    if( p_sys->f_fps >= 0.1 && p_sys->i_video_pts > 0 ) 
     747    { 
     748        mtime_t i_dur = (mtime_t)((double)1000000 / (double)p_sys->f_fps); 
     749 
     750        /* Did we wait long enough ? (frame rate reduction) */ 
     751        if( p_sys->i_video_pts + i_dur > mdate() ) return 0; 
     752    } 
     753     
     754    /* Grab Video Frame */ 
     755    switch( p_sys->io ) 
     756    { 
     757    case IO_METHOD_READ: 
     758        if( read( p_sys->i_fd_video, p_sys->p_buffers[0].start, p_sys->p_buffers[0].length ) ) 
     759        { 
     760            switch( errno )  
     761            { 
     762            case EAGAIN: 
     763                return 0; 
     764            case EIO: 
     765                /* Could ignore EIO, see spec. */ 
     766                /* fall through */ 
     767            default: 
     768                msg_Err( p_demux, "Failed to read frame" ); 
     769                return 0; 
     770            }         
     771        } 
     772         
     773        p_block = ProcessVideoFrame( p_demux, (uint8_t*)p_sys->p_buffers[0].start ); 
     774        if( !p_block ) return 0; 
     775         
     776        break; 
     777         
     778    case IO_METHOD_MMAP: 
     779        memset( &buf, 0, sizeof(buf) ); 
     780        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
     781        buf.memory = V4L2_MEMORY_MMAP; 
     782         
     783        /* Wait for next frame */ 
     784        if (ioctl( p_sys->i_fd_video, VIDIOC_DQBUF, &buf ) < 0 ) 
     785        { 
     786            switch( errno )  
     787            { 
     788            case EAGAIN: 
     789                return 0; 
     790            case EIO: 
     791                /* Could ignore EIO, see spec. */ 
     792                /* fall through */ 
     793            default: 
     794                msg_Err( p_demux, "Failed to wait (VIDIOC_DQBUF)" ); 
     795                return 0; 
     796            } 
     797        } 
     798 
     799        if( buf.index >= p_sys->i_nbuffers ) { 
     800            msg_Err( p_demux, "Failed capturing new frame as i>=nbuffers" ); 
     801            return 0; 
     802        } 
     803         
     804        p_block = ProcessVideoFrame( p_demux, p_sys->p_buffers[buf.index].start ); 
     805        if( !p_block ) return 0; 
     806 
     807        /* Unlock */     
     808        if( ioctl( p_sys->i_fd_video, VIDIOC_QBUF, &buf ) < 0 ) 
     809        { 
     810            msg_Err (p_demux, "Failed to unlock (VIDIOC_QBUF)"); 
     811            return 0; 
     812        } 
     813     
     814        break; 
     815         
     816    case IO_METHOD_USERPTR:         
     817        memset( &buf, 0, sizeof(buf) ); 
     818        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
     819        buf.memory = V4L2_MEMORY_USERPTR; 
     820         
     821        /* Wait for next frame */ 
     822        if (ioctl( p_sys->i_fd_video, VIDIOC_DQBUF, &buf ) < 0 ) 
     823        { 
     824            switch( errno )  
     825            { 
     826            case EAGAIN: 
     827                return 0; 
     828            case EIO: 
     829                /* Could ignore EIO, see spec. */ 
     830                /* fall through */ 
     831            default: 
     832                msg_Err( p_demux, "Failed to wait (VIDIOC_DQBUF)" ); 
     833                return 0; 
     834            } 
     835        } 
     836 
     837        /* Find frame? */ 
     838        unsigned int i; 
     839        for( i = 0; i < p_sys->i_nbuffers; i++ ) 
     840        { 
     841            if( buf.m.userptr == (unsigned long)p_sys->p_buffers[i].start &&  
     842                buf.length == p_sys->p_buffers[i].length ) break; 
     843        } 
     844 
     845        if( i >= p_sys->i_nbuffers ) { 
     846            msg_Err( p_demux, "Failed capturing new frame as i>=nbuffers" ); 
     847            return 0; 
     848        } 
     849         
     850        p_block = ProcessVideoFrame( p_demux, (uint8_t*)buf.m.userptr ); 
     851        if( !p_block ) return 0; 
     852 
     853        /* Unlock */     
     854        if( ioctl( p_sys->i_fd_video, VIDIOC_QBUF, &buf ) < 0 ) 
     855        { 
     856            msg_Err (p_demux, "Failed to unlock (VIDIOC_QBUF)"); 
     857            return 0; 
     858        } 
     859         
     860        break; 
     861        
     862    } 
     863     
     864    /* Timestamp */ 
     865    p_sys->i_video_pts = p_block->i_pts = p_block->i_dts = mdate(); 
     866     
     867    return p_block; 
     868} 
     869 
     870/***************************************************************************** 
     871 * ProcessVideoFrame: Helper function to take a buffer and copy it into 
     872 * a new block 
     873 *****************************************************************************/ 
     874static block_t* ProcessVideoFrame( demux_t *p_demux, uint8_t *p_frame ) 
     875{ 
     876    demux_sys_t *p_sys = p_demux->p_sys; 
     877    block_t *p_block; 
     878 
     879    if( !p_frame ) return 0; 
     880             
     881    /* New block */ 
     882    if( !( p_block = block_New( p_demux, p_sys->i_video_frame_size ) ) ) 
     883    { 
     884        msg_Warn( p_demux, "Cannot get new block" ); 
     885        return 0; 
     886    } 
     887 
     888    /* Copy frame */ 
     889    memcpy( p_block->p_buffer, p_frame, p_sys->i_video_frame_size ); 
     890     
     891    return p_block; 
     892} 
     893 
     894/***************************************************************************** 
     895 * GrabAudio: Grab an audio frame 
     896 *****************************************************************************/ 
     897static block_t* GrabAudio( demux_t *p_demux ) 
     898{ 
     899    demux_sys_t *p_sys = p_demux->p_sys; 
     900    struct audio_buf_info buf_info; 
     901    int i_read, i_correct; 
     902    block_t *p_block; 
     903     
     904    /* Copied from v4l.c */ 
     905 
     906    if( p_sys->p_block_audio ) p_block = p_sys->p_block_audio; 
     907    else p_block = block_New( p_demux, p_sys->i_audio_max_frame_size ); 
     908 
     909    if( !p_block ) 
     910    { 
     911        msg_Warn( p_demux, "cannot get block" ); 
     912        return 0; 
     913    } 
     914 
     915    p_sys->p_block_audio = p_block; 
     916 
     917    i_read = read( p_sys->i_fd_audio, p_block->p_buffer, 
     918                   p_sys->i_audio_max_frame_size );                   
     919 
     920    if( i_read <= 0 ) return 0; 
     921 
     922    p_block->i_buffer = i_read; 
     923    p_sys->p_block_audio = 0; 
     924 
     925    /* Correct the date because of kernel buffering */ 
     926    i_correct = i_read; 
     927    if( ioctl( p_sys->i_fd_audio, SNDCTL_DSP_GETISPACE, &buf_info ) == 0 ) 
     928    { 
     929        i_correct += buf_info.bytes; 
     930    } 
     931 
     932    /* Timestamp */ 
     933    p_block->i_pts = p_block->i_dts = 
     934        mdate() - I64C(1000000) * (mtime_t)i_correct / 
     935        2 / ( p_sys->b_stereo ? 2 : 1) / p_sys->i_sample_rate; 
     936 
     937    return p_block; 
     938} 
     939 
     940/***************************************************************************** 
     941 * Helper function to initalise video IO using the Read method 
     942 *****************************************************************************/ 
     943static int InitRead( demux_t *p_demux, int i_fd, unsigned int i_buffer_size )  
     944{ 
     945    demux_sys_t *p_sys = p_demux->p_sys; 
     946 
     947    p_sys->p_buffers = calloc( 1, sizeof( *p_sys->p_buffers ) ); 
     948    if( !p_sys->p_buffers ) 
     949    { 
     950        msg_Err( p_demux, "Out of memory" ); 
     951        goto open_failed; 
     952    } 
     953     
     954    p_sys->p_buffers[0].length = i_buffer_size; 
     955    p_sys->p_buffers[0].start = malloc( i_buffer_size ); 
     956    if( !p_sys->p_buffers[0].start ) 
     957    { 
     958        msg_Err( p_demux, "Out of memory" ); 
     959        goto open_failed; 
     960    }     
     961 
     962    return VLC_SUCCESS; 
     963     
     964open_failed: 
     965    return VLC_EGENERIC; 
     966     
     967} 
     968 
     969/***************************************************************************** 
     970 * Helper function to initalise video IO using the mmap method 
     971 *****************************************************************************/ 
     972static int InitMmap( demux_t *p_demux, int i_fd )  
     973{ 
     974    demux_sys_t *p_sys = p_demux->p_sys; 
     975    struct v4l2_requestbuffers req; 
     976     
     977    memset( &req, 0, sizeof(req) ); 
     978    req.count = 4; 
     979    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
     980    req.memory = V4L2_MEMORY_MMAP; 
     981     
     982    if( ioctl( i_fd, VIDIOC_REQBUFS, &req ) < 0 ) 
     983    { 
     984        msg_Err( p_demux, "device does not support mmap i/o" ); 
     985        goto open_failed; 
     986    } 
     987                             
     988    if( req.count < 2 ) 
     989    { 
     990        msg_Err( p_demux, "Insufficient buffer memory" ); 
     991        goto open_failed; 
     992    } 
     993     
     994    p_sys->p_buffers = calloc( req.count, sizeof( *p_sys->p_buffers ) ); 
     995    if( !p_sys->p_buffers ) 
     996    { 
     997        msg_Err( p_demux, "Out of memory" ); 
     998        goto open_failed; 
     999    } 
     1000     
     1001    for( p_sys->i_nbuffers = 0; p_sys->i_nbuffers < req.count; ++p_sys->i_nbuffers ) 
     1002    { 
     1003        struct v4l2_buffer buf; 
     1004     
     1005        memset( &buf, 0, sizeof(buf) ); 
     1006        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
     1007        buf.memory = V4L2_MEMORY_MMAP; 
     1008        buf.index = p_sys->i_nbuffers; 
     1009         
     1010        if( ioctl( i_fd, VIDIOC_QUERYBUF, &buf ) < 0 ) 
     1011        { 
     1012            msg_Err( p_demux, "VIDIOC_QUERYBUF" ); 
     1013            goto open_failed; 
     1014        } 
     1015         
     1016        p_sys->p_buffers[p_sys->i_nbuffers].length = buf.length; 
     1017        p_sys->p_buffers[p_sys->i_nbuffers].start =  
     1018            mmap( NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, p_sys->i_fd_video, buf.m