]> git.sesse.net Git - vlc/blobdiff - modules/access/v4l.c
v4l: attempt to fix strict aliasing warnings.
[vlc] / modules / access / v4l.c
index 69eb305f9e4a116c2817be626a1a9f7598f8ebb4..2edf2503201ff4f18083146964bf03c2d426b1ce 100644 (file)
 #include <vlc_input.h>
 #include <vlc_demux.h>
 #include <vlc_access.h>
-#include <vlc_vout.h>
-#include <vlc_codecs.h>
+#include <vlc_picture.h>
+#include <vlc_charset.h>
 
-#include <sys/types.h>
-#include <sys/stat.h>
 #include <sys/ioctl.h>
-#include <unistd.h>
 #include <sys/mman.h>
-#include <errno.h>
 #include <fcntl.h>
 #include <arpa/inet.h>
-
-#include <poll.h>
+#include <errno.h>
 
 /* 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;