X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faccess%2Fv4l%2Fv4l.c;h=6ea1bc4fe8c449f807d4486e619c20395818faab;hb=4f15591e47d52903b559507bdac13e1f5176de45;hp=8767ad9a78252f011319fb2e67abb4400fc739e1;hpb=323dfafae8386d9d08f10a22d5be02db4e933a5b;p=vlc diff --git a/modules/access/v4l/v4l.c b/modules/access/v4l/v4l.c index 8767ad9a78..6ea1bc4fe8 100644 --- a/modules/access/v4l/v4l.c +++ b/modules/access/v4l/v4l.c @@ -1,12 +1,13 @@ /***************************************************************************** * v4l.c : Video4Linux input module for vlc ***************************************************************************** - * Copyright (C) 2002 VideoLAN - * $Id: v4l.c,v 1.28 2003/11/06 00:12:17 gbazin Exp $ + * Copyright (C) 2002-2004 the VideoLAN team + * $Id$ * * Author: Laurent Aimar * Paul Forgey - * Gildas Bazin + * Gildas Bazin + * Benjamin Pracht * * 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 @@ -20,7 +21,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** @@ -41,69 +42,169 @@ #include #include #include - #include + +/* From GStreamer's v4l plugin: + * Because of some really cool feature in video4linux1, also known as + * 'not including sys/types.h and sys/time.h', we had to include it + * ourselves. In all their intelligence, these people decided to fix + * this in the next version (video4linux2) in such a cool way that it + * breaks all compilations of old stuff... + * The real problem is actually that linux/time.h doesn't use proper + * macro checks before defining types like struct timeval. The proper + * fix here is to either fuck the kernel header (which is what we do + * by defining _LINUX_TIME_H, an innocent little hack) or by fixing it + * upstream, which I'll consider doing later on. If you get compiler + * errors here, check your linux/time.h && sys/time.h header setup. +*/ +#define _LINUX_TIME_H + #include #include "videodev_mjpeg.h" #include -/***************************************************************************** - * Local prototypes - *****************************************************************************/ -static int AccessOpen ( vlc_object_t * ); -static void AccessClose ( vlc_object_t * ); -static int Read ( input_thread_t *, byte_t *, size_t ); - -static void ParseMRL ( input_thread_t * ); -static int OpenVideoDev( input_thread_t *, char * ); -static int OpenAudioDev( input_thread_t *, char * ); - -static int DemuxOpen ( vlc_object_t * ); -static void DemuxClose ( vlc_object_t * ); -static int Demux ( input_thread_t * ); - /***************************************************************************** * Module descriptior *****************************************************************************/ +static int Open ( vlc_object_t * ); +static void Close( vlc_object_t * ); + #define CACHING_TEXT N_("Caching value in ms") #define CACHING_LONGTEXT N_( \ - "Allows you to modify the default caching value for v4l streams. This " \ - "value should be set in miliseconds units." ) + "Caching value for V4L captures. This " \ + "value should be set in milliseconds." ) #define VDEV_TEXT N_("Video device name") #define VDEV_LONGTEXT N_( \ - "Specify the name of the video device that will be used. " \ + "Name of the video device to use. " \ "If you don't specify anything, no video device will be used.") #define ADEV_TEXT N_("Audio device name") #define ADEV_LONGTEXT N_( \ - "Specify the name of the audio device that will be used. " \ - "If you don't specify anything, no video device will be used.") + "Name of the audio device to use. " \ + "If you don't specify anything, no audio device will be used.") +#define CHROMA_TEXT N_("Video input chroma format") +#define CHROMA_LONGTEXT N_( \ + "Force the Video4Linux video device to use a specific chroma format " \ + "(eg. I420 (default), RV24, etc.)") +#define FREQUENCY_TEXT N_( "Frequency" ) +#define FREQUENCY_LONGTEXT N_( \ + "Frequency to capture (in kHz), if applicable." ) +#define CHANNEL_TEXT N_( "Channel" ) +#define CHANNEL_LONGTEXT N_( \ + "Channel of the card to use (Usually, 0 = tuner, " \ + "1 = composite, 2 = svideo)." ) +#define NORM_TEXT N_( "Norm" ) +#define NORM_LONGTEXT N_( \ + "Norm of the stream (Automatic, SECAM, PAL, or NTSC)." ) +#define AUDIO_TEXT N_( "Audio Channel" ) +#define AUDIO_LONGTEXT N_( \ + "Audio Channel to use, if there are several audio inputs." ) +#define WIDTH_TEXT N_( "Width" ) +#define WIDTH_LONGTEXT N_( "Width of the stream to capture " \ + "(-1 for autodetect)." ) +#define HEIGHT_TEXT N_( "Height" ) +#define HEIGHT_LONGTEXT N_( "Height of the stream to capture " \ + "(-1 for autodetect)." ) +#define BRIGHTNESS_TEXT N_( "Brightness" ) +#define BRIGHTNESS_LONGTEXT N_( \ + "Brightness of the video input." ) +#define HUE_TEXT N_( "Hue" ) +#define HUE_LONGTEXT N_( \ + "Hue of the video input." ) +#define COLOUR_TEXT N_( "Color" ) +#define COLOUR_LONGTEXT N_( \ + "Color of the video input." ) +#define CONTRAST_TEXT N_( "Contrast" ) +#define CONTRAST_LONGTEXT N_( \ + "Contrast of the video input." ) +#define TUNER_TEXT N_( "Tuner" ) +#define TUNER_LONGTEXT N_( "Tuner to use, if there are several ones." ) +#define SAMPLERATE_TEXT N_( "Samplerate" ) +#define SAMPLERATE_LONGTEXT N_( \ + "Samplerate of the captured audio stream, in Hz (eg: 11025, 22050, 44100)" ) +#define STEREO_TEXT N_( "Stereo" ) +#define STEREO_LONGTEXT N_( \ + "Capture the audio stream in stereo." ) +#define MJPEG_TEXT N_( "MJPEG" ) +#define MJPEG_LONGTEXT N_( \ + "Set this option if the capture device outputs MJPEG" ) +#define DECIMATION_TEXT N_( "Decimation" ) +#define DECIMATION_LONGTEXT N_( \ + "Decimation level for MJPEG streams" ) +#define QUALITY_TEXT N_( "Quality" ) +#define QUALITY_LONGTEXT N_( "Quality of the stream." ) +#define FPS_TEXT N_( "Framerate" ) +#define FPS_LONGTEXT N_( "Framerate to capture, if applicable " \ + "(-1 for autodetect)." ) + +static int i_norm_list[] = + { VIDEO_MODE_AUTO, VIDEO_MODE_SECAM, VIDEO_MODE_PAL, VIDEO_MODE_NTSC }; +static char *psz_norm_list_text[] = + { N_("Automatic"), N_("SECAM"), N_("PAL"), N_("NTSC") }; vlc_module_begin(); + set_shortname( _("Video4Linux") ); set_description( _("Video4Linux input") ); - add_category_hint( N_("v4l"), NULL, VLC_TRUE ); + set_category( CAT_INPUT ); + set_subcategory( SUBCAT_INPUT_ACCESS ); + add_integer( "v4l-caching", DEFAULT_PTS_DELAY / 1000, NULL, CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE ); - add_shortcut( "v4l" ); - set_capability( "access", 10 ); - set_callbacks( AccessOpen, AccessClose ); - add_string( "v4l-vdev", "/dev/video", 0, VDEV_TEXT, VDEV_LONGTEXT, VLC_FALSE ); add_string( "v4l-adev", "/dev/dsp", 0, ADEV_TEXT, ADEV_LONGTEXT, VLC_FALSE ); + add_string( "v4l-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT, + VLC_TRUE ); + add_float( "v4l-fps", -1.0, NULL, FPS_TEXT, FPS_LONGTEXT, VLC_TRUE ); + add_integer( "v4l-samplerate", 44100, NULL, SAMPLERATE_TEXT, + SAMPLERATE_LONGTEXT, VLC_TRUE ); + add_integer( "v4l-channel", 0, NULL, CHANNEL_TEXT, CHANNEL_LONGTEXT, + VLC_TRUE ); + add_integer( "v4l-tuner", -1, NULL, TUNER_TEXT, TUNER_LONGTEXT, VLC_TRUE ); + add_integer( "v4l-norm", VIDEO_MODE_AUTO, NULL, NORM_TEXT, NORM_LONGTEXT, + VLC_FALSE ); + change_integer_list( i_norm_list, psz_norm_list_text, 0 ); + add_integer( "v4l-frequency", -1, NULL, FREQUENCY_TEXT, FREQUENCY_LONGTEXT, + VLC_FALSE ); + add_integer( "v4l-audio", -1, NULL, AUDIO_TEXT, AUDIO_LONGTEXT, VLC_TRUE ); + add_bool( "v4l-stereo", VLC_TRUE, NULL, STEREO_TEXT, STEREO_LONGTEXT, + VLC_TRUE ); + add_integer( "v4l-width", 0, NULL, WIDTH_TEXT, WIDTH_LONGTEXT, VLC_TRUE ); + add_integer( "v4l-height", 0, NULL, HEIGHT_TEXT, HEIGHT_LONGTEXT, + VLC_TRUE ); + add_integer( "v4l-brightness", -1, NULL, BRIGHTNESS_TEXT, + BRIGHTNESS_LONGTEXT, VLC_TRUE ); + add_integer( "v4l-colour", -1, NULL, COLOUR_TEXT, COLOUR_LONGTEXT, + VLC_TRUE ); + add_integer( "v4l-hue", -1, NULL, HUE_TEXT, HUE_LONGTEXT, VLC_TRUE ); + add_integer( "v4l-contrast", -1, NULL, CONTRAST_TEXT, CONTRAST_LONGTEXT, + VLC_TRUE ); + add_bool( "v4l-mjpeg", VLC_FALSE, NULL, MJPEG_TEXT, MJPEG_LONGTEXT, + VLC_TRUE ); + add_integer( "v4l-decimation", 1, NULL, DECIMATION_TEXT, + DECIMATION_LONGTEXT, VLC_TRUE ); + add_integer( "v4l-quality", 100, NULL, QUALITY_TEXT, QUALITY_LONGTEXT, + VLC_TRUE ); - add_submodule(); - set_description( _("Video4Linux demuxer") ); - add_shortcut( "v4l" ); - set_capability( "demux", 200 ); - set_callbacks( DemuxOpen, DemuxClose ); + add_shortcut( "v4l" ); + set_capability( "access_demux", 10 ); + set_callbacks( Open, Close ); vlc_module_end(); +/***************************************************************************** + * Access: local prototypes + *****************************************************************************/ +static int Demux ( demux_t * ); +static int Control( demux_t *, int, va_list ); + +static void ParseMRL ( demux_t * ); +static int OpenVideoDev( demux_t *, char * ); +static int OpenAudioDev( demux_t *, char * ); + +static block_t *GrabAudio( demux_t * ); +static block_t *GrabVideo( demux_t * ); -/**************************************************************************** - * I. Access Part - ****************************************************************************/ #define MJPEG_BUFFER_SIZE (256*1024) struct quicktime_mjpeg_app1 @@ -120,7 +221,32 @@ struct quicktime_mjpeg_app1 uint32_t i_data_offset; /* following SOS marker data */ }; -struct access_sys_t +static struct +{ + int i_v4l; + int i_fourcc; + +} v4lchroma_to_fourcc[] = +{ + { VIDEO_PALETTE_GREY, VLC_FOURCC( 'G', 'R', 'E', 'Y' ) }, + { 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( 'I', '4', '2', '2' ) }, + { VIDEO_PALETTE_YUYV, VLC_FOURCC( 'Y', 'U', 'Y', 'V' ) }, + { VIDEO_PALETTE_UYVY, VLC_FOURCC( 'U', 'Y', 'V', 'Y' ) }, + { 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' ) }, + { 0, 0 } +}; + +struct demux_sys_t { /* Devices */ char *psz_device; /* Main device from MRL, can be video or audio */ @@ -143,6 +269,11 @@ struct access_sys_t int i_width; int i_height; + int i_brightness; + int i_hue; + int i_colour; + int i_contrast; + float f_fps; /* <= 0.0 mean to grab at full rate */ mtime_t i_video_pts; /* only used when f_fps > 0 */ @@ -160,126 +291,139 @@ struct access_sys_t struct video_mmap vid_mmap; struct video_picture vid_picture; - uint8_t *p_video_frame; - int i_video_frame_size; - int i_video_frame_size_allocated; + int i_video_frame_size; + es_out_id_t *p_es_video; /* Audio properties */ vlc_fourcc_t i_acodec_raw; int i_sample_rate; vlc_bool_t b_stereo; - - uint8_t *p_audio_frame; - int i_audio_frame_size; - int i_audio_frame_size_allocated; - - /* header */ - int i_streams; - int i_header_size; - int i_header_pos; - uint8_t *p_header; // at lest 8 bytes allocated - - /* data */ - int i_data_size; - int i_data_pos; - uint8_t *p_data; // never allocated - + int i_audio_max_frame_size; + block_t *p_block_audio; + es_out_id_t *p_es_audio; }; -/* - * header: - * fcc ".v4l" - * u32 stream count - * fcc "auds"|"vids" 0 - * fcc codec 4 - * if vids - * u32 width 8 - * u32 height 12 - * u32 padding 16 - * if auds - * u32 channels 12 - * u32 samplerate 8 - * u32 samplesize 16 - * - * data: - * u32 stream number - * u32 data size - * u8 data - */ - -static void SetDWBE( uint8_t *p, uint32_t dw ) -{ - p[0] = (dw >> 24)&0xff; - p[1] = (dw >> 16)&0xff; - p[2] = (dw >> 8)&0xff; - p[3] = (dw )&0xff; -} - -static void SetQWBE( uint8_t *p, uint64_t qw ) -{ - SetDWBE( p, (qw >> 32)&0xffffffff ); - SetDWBE( &p[4], qw&0xffffffff); -} - /***************************************************************************** - * AccessOpen: opens v4l device + * Open: opens v4l device ***************************************************************************** * * url: