X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faccess%2Fv4l.c;h=2edf2503201ff4f18083146964bf03c2d426b1ce;hb=c2d2e2bb4dd925bb4f7bf0ecfc64a99013f76471;hp=69eb305f9e4a116c2817be626a1a9f7598f8ebb4;hpb=92c0a8f51cb1de4e581cd6f89137850338d003f9;p=vlc diff --git a/modules/access/v4l.c b/modules/access/v4l.c index 69eb305f9e..2edf250320 100644 --- a/modules/access/v4l.c +++ b/modules/access/v4l.c @@ -37,19 +37,14 @@ #include #include #include -#include -#include +#include +#include -#include -#include #include -#include #include -#include #include #include - -#include +#include /* From GStreamer's v4l plugin: * Because of some really cool feature in video4linux1, also known as @@ -151,39 +146,39 @@ vlc_module_begin () set_subcategory( SUBCAT_INPUT_ACCESS ) add_integer( "v4l-caching", DEFAULT_PTS_DELAY / 1000, NULL, - CACHING_TEXT, CACHING_LONGTEXT, true ); + CACHING_TEXT, CACHING_LONGTEXT, true ) add_obsolete_string( "v4l-vdev" ); add_obsolete_string( "v4l-adev" ); add_string( "v4l-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT, - true ); + true ) add_float( "v4l-fps", -1.0, NULL, FPS_TEXT, FPS_LONGTEXT, true ) add_obsolete_integer( "v4l-samplerate" ); add_integer( "v4l-channel", 0, NULL, CHANNEL_TEXT, CHANNEL_LONGTEXT, - true ); + true ) add_integer( "v4l-tuner", -1, NULL, TUNER_TEXT, TUNER_LONGTEXT, true ) add_integer( "v4l-norm", VIDEO_MODE_AUTO, NULL, NORM_TEXT, NORM_LONGTEXT, - false ); + false ) change_integer_list( i_norm_list, psz_norm_list_text, NULL ); add_integer( "v4l-frequency", -1, NULL, FREQUENCY_TEXT, FREQUENCY_LONGTEXT, - false ); + false ) add_integer( "v4l-audio", -1, NULL, AUDIO_TEXT, AUDIO_LONGTEXT, true ) add_obsolete_bool( "v4l-stereo" ); add_integer( "v4l-width", 0, NULL, WIDTH_TEXT, WIDTH_LONGTEXT, true ) add_integer( "v4l-height", 0, NULL, HEIGHT_TEXT, HEIGHT_LONGTEXT, - true ); + true ) add_integer( "v4l-brightness", -1, NULL, BRIGHTNESS_TEXT, - BRIGHTNESS_LONGTEXT, true ); + BRIGHTNESS_LONGTEXT, true ) add_integer( "v4l-colour", -1, NULL, COLOUR_TEXT, COLOUR_LONGTEXT, - true ); + true ) add_integer( "v4l-hue", -1, NULL, HUE_TEXT, HUE_LONGTEXT, true ) add_integer( "v4l-contrast", -1, NULL, CONTRAST_TEXT, CONTRAST_LONGTEXT, - true ); + true ) add_bool( "v4l-mjpeg", false, NULL, MJPEG_TEXT, MJPEG_LONGTEXT, - true ); + true ) add_integer( "v4l-decimation", 1, NULL, DECIMATION_TEXT, - DECIMATION_LONGTEXT, true ); + DECIMATION_LONGTEXT, true ) add_integer( "v4l-quality", 100, NULL, QUALITY_TEXT, QUALITY_LONGTEXT, - true ); + true ) add_shortcut( "v4l" ) set_capability( "access_demux", 10 ) @@ -219,27 +214,25 @@ struct quicktime_mjpeg_app1 static const struct { int i_v4l; - int i_fourcc; + vlc_fourcc_t i_fourcc; } v4lchroma_to_fourcc[] = { - { VIDEO_PALETTE_GREY, VLC_FOURCC( 'G', 'R', 'E', 'Y' ) }, + { VIDEO_PALETTE_GREY, VLC_CODEC_GREY }, { VIDEO_PALETTE_HI240, VLC_FOURCC( 'I', '2', '4', '0' ) }, - { VIDEO_PALETTE_RGB565, VLC_FOURCC( 'R', 'V', '1', '6' ) }, - { VIDEO_PALETTE_RGB555, VLC_FOURCC( 'R', 'V', '1', '5' ) }, - { VIDEO_PALETTE_RGB24, VLC_FOURCC( 'R', 'V', '2', '4' ) }, - { VIDEO_PALETTE_RGB32, VLC_FOURCC( 'R', 'V', '3', '2' ) }, - { VIDEO_PALETTE_YUV422, VLC_FOURCC( 'Y', 'U', 'Y', '2' ) }, - { VIDEO_PALETTE_YUV422, VLC_FOURCC( 'Y', 'U', 'Y', 'V' ) }, - { VIDEO_PALETTE_YUYV, VLC_FOURCC( 'Y', 'U', 'Y', '2' ) }, - { VIDEO_PALETTE_YUYV, VLC_FOURCC( 'Y', 'U', 'Y', 'V' ) }, - { VIDEO_PALETTE_UYVY, VLC_FOURCC( 'U', 'Y', 'V', 'Y' ) }, + { VIDEO_PALETTE_RGB565, VLC_CODEC_RGB16 }, + { VIDEO_PALETTE_RGB555, VLC_CODEC_RGB15 }, + { VIDEO_PALETTE_RGB24, VLC_CODEC_RGB24 }, + { VIDEO_PALETTE_RGB32, VLC_CODEC_RGB32 }, + { VIDEO_PALETTE_YUV422, VLC_CODEC_YUYV }, + { VIDEO_PALETTE_YUYV, VLC_CODEC_YUYV }, + { VIDEO_PALETTE_UYVY, VLC_CODEC_UYVY }, { VIDEO_PALETTE_YUV420, VLC_FOURCC( 'I', '4', '2', 'N' ) }, { VIDEO_PALETTE_YUV411, VLC_FOURCC( 'I', '4', '1', 'N' ) }, { VIDEO_PALETTE_RAW, VLC_FOURCC( 'G', 'R', 'A', 'W' ) }, - { VIDEO_PALETTE_YUV422P, VLC_FOURCC( 'I', '4', '2', '2' ) }, - { VIDEO_PALETTE_YUV420P, VLC_FOURCC( 'I', '4', '2', '0' ) }, - { VIDEO_PALETTE_YUV411P, VLC_FOURCC( 'I', '4', '1', '1' ) }, + { VIDEO_PALETTE_YUV422P, VLC_CODEC_I422 }, + { VIDEO_PALETTE_YUV420P, VLC_CODEC_I420 }, + { VIDEO_PALETTE_YUV411P, VLC_CODEC_I411 }, { 0, 0 } }; @@ -298,7 +291,6 @@ static int Open( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t*)p_this; demux_sys_t *p_sys; - vlc_value_t val; /* Only when selected */ if( *p_demux->psz_access == '\0' ) @@ -314,70 +306,25 @@ static int Open( vlc_object_t *p_this ) if( !p_sys ) return VLC_ENOMEM; - var_Create( p_demux, "v4l-audio", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); - var_Get( p_demux, "v4l-audio", &val ); - p_sys->i_audio = val.i_int; - - var_Create( p_demux, "v4l-channel", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); - var_Get( p_demux, "v4l-channel", &val ); - p_sys->i_channel = val.i_int; - - var_Create( p_demux, "v4l-norm", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); - var_Get( p_demux, "v4l-norm", &val ); - p_sys->i_norm = val.i_int; - - var_Create( p_demux, "v4l-tuner", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); - var_Get( p_demux, "v4l-tuner", &val ); - p_sys->i_tuner = val.i_int; - - var_Create( p_demux, "v4l-frequency", - VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); - var_Get( p_demux, "v4l-frequency", &val ); - p_sys->i_frequency = val.i_int; - - var_Create( p_demux, "v4l-fps", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); - var_Get( p_demux, "v4l-fps", &val ); - p_sys->f_fps = val.f_float; - - var_Create( p_demux, "v4l-width", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); - var_Get( p_demux, "v4l-width", &val ); - p_sys->i_width = val.i_int; - - var_Create( p_demux, "v4l-height", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); - var_Get( p_demux, "v4l-height", &val ); - p_sys->i_height = val.i_int; + p_sys->i_audio = var_CreateGetInteger( p_demux, "v4l-audio" ); + p_sys->i_channel = var_CreateGetInteger( p_demux, "v4l-channel" ); + p_sys->i_norm = var_CreateGetInteger( p_demux, "v4l-norm" ); + p_sys->i_tuner = var_CreateGetInteger( p_demux, "v4l-tuner" ); + p_sys->i_frequency = var_CreateGetInteger( p_demux, "v4l-frequency" ); - p_sys->i_video_pts = -1; + p_sys->f_fps = var_CreateGetFloat( p_demux, "v4l-fps" ); + p_sys->i_width = var_CreateGetInteger( p_demux, "v4l-width" ); + p_sys->i_height = var_CreateGetInteger( p_demux, "v4l-height" ); + p_sys->i_video_pts = -1; + p_sys->i_brightness = var_CreateGetInteger( p_demux, "v4l-brightness" ); - var_Create( p_demux, "v4l-brightness", VLC_VAR_INTEGER | - VLC_VAR_DOINHERIT ); - var_Get( p_demux, "v4l-brightness", &val ); - p_sys->i_brightness = val.i_int; + p_sys->i_hue = var_CreateGetInteger( p_demux, "v4l-hue" ); + p_sys->i_colour = var_CreateGetInteger( p_demux, "v4l-colour" ); + p_sys->i_contrast = var_CreateGetInteger( p_demux, "v4l-contrast" ); - var_Create( p_demux, "v4l-hue", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); - var_Get( p_demux, "v4l-hue", &val ); - p_sys->i_hue = -1; - - var_Create( p_demux, "v4l-colour", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); - var_Get( p_demux, "v4l-colour", &val ); - p_sys->i_colour = val.i_int; - - var_Create( p_demux, "v4l-contrast", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); - var_Get( p_demux, "v4l-contrast", &val ); - p_sys->i_contrast = val.i_int; - - var_Create( p_demux, "v4l-mjpeg", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); - var_Get( p_demux, "v4l-mjpeg", &val ); - p_sys->b_mjpeg = val.b_bool; - - var_Create( p_demux, "v4l-decimation", VLC_VAR_INTEGER | - VLC_VAR_DOINHERIT ); - var_Get( p_demux, "v4l-decimation", &val ); - p_sys->i_decimation = val.i_int; - - var_Create( p_demux, "v4l-quality", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); - var_Get( p_demux, "v4l-quality", &val ); - p_sys->i_quality = val.i_int; + p_sys->b_mjpeg = var_CreateGetBool( p_demux, "v4l-mjpeg" ); + p_sys->i_decimation = var_CreateGetInteger( p_demux, "v4l-decimation" ); + p_sys->i_quality = var_CreateGetInteger( p_demux, "v4l-quality" ); p_sys->psz_device = NULL; p_sys->i_fd = -1; @@ -407,18 +354,18 @@ static int Open( vlc_object_t *p_this ) /* Setup rgb mask for RGB formats */ switch( p_sys->i_fourcc ) { - case VLC_FOURCC('R','V','1','5'): + case VLC_CODEC_RGB15: fmt.video.i_rmask = 0x001f; fmt.video.i_gmask = 0x03e0; fmt.video.i_bmask = 0x7c00; break; - case VLC_FOURCC('R','V','1','6'): + case VLC_CODEC_RGB16: fmt.video.i_rmask = 0x001f; fmt.video.i_gmask = 0x07e0; fmt.video.i_bmask = 0xf800; break; - case VLC_FOURCC('R','V','2','4'): - case VLC_FOURCC('R','V','3','2'): + case VLC_CODEC_RGB24: + case VLC_CODEC_RGB32: fmt.video.i_rmask = 0x00ff0000; fmt.video.i_gmask = 0x0000ff00; fmt.video.i_bmask = 0x000000ff; @@ -477,7 +424,6 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) /* Special for access_demux */ case DEMUX_CAN_PAUSE: case DEMUX_CAN_SEEK: - case DEMUX_SET_PAUSE_STATE: case DEMUX_CAN_CONTROL_PACE: pb = (bool*)va_arg( args, bool * ); *pb = false; @@ -508,25 +454,17 @@ static int Demux( demux_t *p_demux ) { demux_sys_t *p_sys = p_demux->p_sys; - struct pollfd fd; - fd.fd = p_sys->i_fd; - fd.events = POLLIN|POLLPRI; - fd.revents = 0; + block_t *p_block = GrabVideo( p_demux ); - /* Wait for data */ - if( poll( &fd, 1, 500 ) ) + if( !p_block ) { - if( fd.revents & (POLLIN|POLLPRI) ) - { - block_t *p_block = GrabVideo( p_demux ); - if( p_block ) - { - es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts ); - es_out_Send( p_demux->out, p_sys->p_es, p_block ); - } - } + msleep( 10000 ); /* Unfortunately v4l doesn't allow polling */ + return 1; } + es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts ); + es_out_Send( p_demux->out, p_sys->p_es, p_block ); + return 1; } @@ -694,8 +632,8 @@ static void ParseMRL( demux_t *p_demux ) } else if( !strncmp( psz_parser, "fps=", strlen( "fps=" ) ) ) { - p_sys->f_fps = strtof( psz_parser + strlen( "fps=" ), - &psz_parser ); + p_sys->f_fps = us_strtof( psz_parser + strlen( "fps=" ), + &psz_parser ); } else if( !strncmp( psz_parser, "adev=", strlen( "adev=" ) ) || !strncmp( psz_parser, "samplerate=", strlen( "samplerate=" ) ) @@ -744,7 +682,7 @@ static int OpenVideoDev( demux_t *p_demux, char *psz_device ) struct mjpeg_params mjpeg; int i; - if( ( i_fd = open( psz_device, O_RDWR ) ) < 0 ) + if( ( i_fd = utf8_open( psz_device, O_RDWR ) ) < 0 ) { msg_Err( p_demux, "cannot open device (%m)" ); goto vdev_failed; @@ -899,7 +837,7 @@ static int OpenVideoDev( demux_t *p_demux, char *psz_device ) * or height */ if( p_sys->b_mjpeg ) { - struct quicktime_mjpeg_app1 *p_app1; + struct quicktime_mjpeg_app1 p_app1; int32_t i_offset; if( ioctl( i_fd, MJPIOC_G_PARAMS, &mjpeg ) < 0 ) @@ -921,12 +859,11 @@ static int OpenVideoDev( demux_t *p_demux, char *psz_device ) mjpeg.APP_len = 40; /* aligned */ - p_app1 = (struct quicktime_mjpeg_app1 *)mjpeg.APP_data; - p_app1->i_reserved = 0; - p_app1->i_tag = VLC_FOURCC( 'm','j','p','g' ); - p_app1->i_field_size = 0; - p_app1->i_padded_field_size = 0; - p_app1->i_next_field = 0; + p_app1.i_reserved = 0; + p_app1.i_tag = VLC_FOURCC( 'm','j','p','g' ); + p_app1.i_field_size = 0; + p_app1.i_padded_field_size = 0; + p_app1.i_next_field = 0; /* XXX WARNING XXX */ /* these's nothing magic about these values. We are dangerously * assuming the encoder card is encoding mjpeg-a and is not throwing @@ -938,15 +875,16 @@ static int OpenVideoDev( demux_t *p_demux, char *psz_device ) * does conform to standards outside of Apple Quicktime. */ i_offset = 0x2e; - p_app1->i_DQT_offset = hton32( i_offset ); + p_app1.i_DQT_offset = hton32( i_offset ); i_offset = 0xb4; - p_app1->i_DHT_offset = hton32( i_offset ); + p_app1.i_DHT_offset = hton32( i_offset ); i_offset = 0x258; - p_app1->i_SOF_offset = hton32( i_offset ); + p_app1.i_SOF_offset = hton32( i_offset ); i_offset = 0x26b; - p_app1->i_SOS_offset = hton32( i_offset ); + p_app1.i_SOS_offset = hton32( i_offset ); i_offset = 0x279; - p_app1->i_data_offset = hton32( i_offset ); + p_app1.i_data_offset = hton32( i_offset ); + memcpy(mjpeg.APP_data, &p_app1, sizeof(struct quicktime_mjpeg_app1)); /* SOF and SOS aren't specified by the mjpeg API because they aren't * optional. They will be present in the output. */ @@ -1038,10 +976,12 @@ static int OpenVideoDev( demux_t *p_demux, char *psz_device ) p_sys->i_fourcc = 0; psz = var_CreateGetString( p_demux, "v4l-chroma" ); - if( strlen( psz ) >= 4 ) + + const vlc_fourcc_t i_chroma = + vlc_fourcc_GetCodecFromString( VIDEO_ES, psz ); + if( i_chroma ) { vid_picture.palette = 0; - int i_chroma = VLC_FOURCC( psz[0], psz[1], psz[2], psz[3] ); /* Find out v4l chroma code */ for( i = 0; v4lchroma_to_fourcc[i].i_v4l != 0; i++ ) @@ -1117,7 +1057,7 @@ static int OpenVideoDev( demux_t *p_demux, char *psz_device ) goto vdev_failed; } - p_sys->i_fourcc = VLC_FOURCC( 'm','j','p','g' ); + p_sys->i_fourcc = VLC_CODEC_MJPG; p_sys->i_frame_pos = -1; /* queue up all the frames */ @@ -1133,10 +1073,9 @@ static int OpenVideoDev( demux_t *p_demux, char *psz_device ) else { /* Fill in picture_t fields */ - 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 ) + if( picture_Setup( &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 ) ) { msg_Err( p_demux, "unsupported chroma" ); goto vdev_failed;