]> git.sesse.net Git - vlc/blobdiff - modules/demux/rawvid.c
Trigger intf_UserLoginPassword() when authorization of rtsp link failed while using...
[vlc] / modules / demux / rawvid.c
index 521f094237b08679078d79f55af8ccc78b98bb37..fcd8c6d8d07c80477054c915c04e268990663d57 100644 (file)
@@ -25,7 +25,6 @@
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
-#include <stdlib.h>                                      /* malloc(), free() */
 
 #include <vlc/vlc.h>
 #include <vlc_demux.h>
@@ -59,14 +58,14 @@ static void Close( vlc_object_t * );
 vlc_module_begin();
     set_shortname( "Raw Video" );
     set_description( _("Raw video demuxer") );
-    set_capability( "demux2", 2 );
+    set_capability( "demux2", 3 );
     set_category( CAT_INPUT );
     set_subcategory( SUBCAT_INPUT_DEMUX );
     set_callbacks( Open, Close );
     add_shortcut( "rawvideo" );
-    add_float( "rawvid-fps", 25, 0, FPS_TEXT, FPS_LONGTEXT, VLC_FALSE );
-    add_integer( "rawvid-width", 176, 0, WIDTH_TEXT, WIDTH_LONGTEXT, 0 );
-    add_integer( "rawvid-height", 144, 0, HEIGHT_TEXT, HEIGHT_LONGTEXT, 0 );
+    add_float( "rawvid-fps", 0, 0, FPS_TEXT, FPS_LONGTEXT, VLC_FALSE );
+    add_integer( "rawvid-width", 0, 0, WIDTH_TEXT, WIDTH_LONGTEXT, 0 );
+    add_integer( "rawvid-height", 0, 0, HEIGHT_TEXT, HEIGHT_LONGTEXT, 0 );
     add_string( "rawvid-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT,
                 VLC_TRUE );
     add_string( "rawvid-aspect-ratio", NULL, NULL,
@@ -85,6 +84,8 @@ struct demux_sys_t
     es_format_t  fmt_video;
 
     mtime_t i_pcr;
+
+    vlc_bool_t b_y4m;
 };
 
 /*****************************************************************************
@@ -93,6 +94,27 @@ struct demux_sys_t
 static int Demux( demux_t * );
 static int Control( demux_t *, int i_query, va_list args );
 
+struct preset_t
+{
+    const char *psz_ext;
+    int i_width;
+    int i_height;
+    double f_fps;
+    const char *psz_aspect_ratio;
+    const char *psz_chroma;
+};
+
+static struct preset_t p_presets[] =
+{
+    { "sqcif", 128, 96, 29.97, "4:3", "YV12" },
+    { "qcif", 176, 144, 29.97, "4:3", "YV12" },
+    { "cif", 352, 288, 29.97, "4:3", "YV12" },
+    { "4cif", 704, 576, 29.97, "4:3", "YV12" },
+    { "16cif", 1408, 1152, 29.97, "4:3", "YV12" },
+    { "yuv", 176, 144, 25, "4:3", "YV12" },
+    { "", 0, 0, 0., "", "" }
+};
+
 /*****************************************************************************
  * Open: initializes raw DV demux structures
  *****************************************************************************/
@@ -105,15 +127,35 @@ static int Open( vlc_object_t * p_this )
     char *psz_chroma;
     uint32_t i_chroma;
     char *psz_aspect_ratio;
-    unsigned int i_aspect;
+    unsigned int i_aspect = 0;
+    struct preset_t *p_preset = NULL;
+    const uint8_t *p_peek;
+    vlc_bool_t b_valid = VLC_FALSE;
+    vlc_bool_t b_y4m = VLC_FALSE;
+
+    if( stream_Peek( p_demux->s, &p_peek, 9 ) == 9 )
+    {
+        /* http://wiki.multimedia.cx/index.php?title=YUV4MPEG2 */
+        if( !strncmp( (char *)p_peek, "YUV4MPEG2", 9 ) )
+        {
+            b_valid = VLC_TRUE;
+            b_y4m = VLC_TRUE;
+        }
+    }
 
-    /* Check for YUV file extension */
     psz_ext = strrchr( p_demux->psz_path, '.' );
-    if( ( !psz_ext || strcasecmp( psz_ext, ".yuv") ) &&
-        strcmp(p_demux->psz_demux, "rawvid") )
+    if( psz_ext )
     {
-        return VLC_EGENERIC;
+        psz_ext++;
+        for( p_preset = p_presets; *p_preset->psz_ext; p_preset++ )
+            if( !strcasecmp( psz_ext, p_preset->psz_ext ) )
+            {
+                b_valid = VLC_TRUE;
+                break;
+            }
     }
+    if( !b_valid && !p_demux->b_force )
+        return VLC_EGENERIC;
 
     /* Set p_input field */
     p_demux->pf_demux   = Demux;
@@ -121,38 +163,134 @@ static int Open( vlc_object_t * p_this )
     p_demux->p_sys      = p_sys = malloc( sizeof( demux_sys_t ) );
     p_sys->i_pcr = 1;
 
+    p_sys->b_y4m = b_y4m;
     p_sys->f_fps = var_CreateGetFloat( p_demux, "rawvid-fps" );
-
     i_width = var_CreateGetInteger( p_demux, "rawvid-width" );
     i_height = var_CreateGetInteger( p_demux, "rawvid-height" );
+    psz_chroma = var_CreateGetString( p_demux, "rawvid-chroma" );
+    psz_aspect_ratio = var_CreateGetString( p_demux, "rawvid-aspect-ratio" );
+
+    if( b_y4m )
+    {
+        char *psz;
+        char *buf;
+        int a, b;
+        psz = stream_ReadLine( p_demux->s );
+
+        /* TODO: handle interlacing */
+
+#define READ_FRAC( key, num, den ) \
+        buf = strchr( psz+9, key );\
+        if( buf )\
+        {\
+            char *end = strchr( buf, ' ' );\
+            char *sep;\
+            if( end ) *end = '\0';\
+            sep = strchr( buf, ':' );\
+            if( sep )\
+            {\
+                *sep = '\0';\
+                den = atoi( sep+1 );\
+            }\
+            else\
+            {\
+                den = 1;\
+            }\
+            num = atoi( buf+1 );\
+            if( sep ) *sep = ':';\
+            if( end ) *end = ' ';\
+        }
+        READ_FRAC( 'W', i_width, a )
+        READ_FRAC( 'H', i_height, a )
+        READ_FRAC( 'F', a, b )
+        p_sys->f_fps = (double)a/(double)b;
+        READ_FRAC( 'A', a, b )
+        if( b != 0 ) i_aspect = a * VOUT_ASPECT_FACTOR / b;
+
+        buf = strchr( psz+9, 'C' );
+        if( buf )
+        {
+            char *end = strchr( buf, ' ' );
+            if( end ) *end = '\0';
+            buf++;
+            if( !strncmp( buf, "C420jpeg", 8 ) )
+            {
+                psz_chroma = strdup( "I420" );
+            }
+            else if( !strncmp( buf, "C420paldv", 9 ) )
+            {
+                psz_chroma = strdup( "I420" );
+            }
+            else if( !strncmp( buf, "C420", 4 ) )
+            {
+                psz_chroma = strdup( "I420" );
+            }
+            else if( !strncmp( buf, "C422", 4 ) )
+            {
+                psz_chroma = strdup( "I422" );
+            }
+            else if( !strncmp( buf, "C444", 4 ) )
+            {
+                psz_chroma = strdup( "I444" );
+            }
+            else
+            {
+                msg_Warn( p_demux, "Unknown YUV4MPEG2 chroma type \"%s\"",
+                          buf );
+            }
+            if( end ) *end = ' ';
+        }
+
+        free( psz );
+    }
+
+    if( p_preset && *p_preset->psz_ext )
+    {
+        if( !i_width ) i_width = p_preset->i_width;
+        if( !i_height ) i_height = p_preset->i_height;
+        if( !p_sys->f_fps ) p_sys->f_fps = p_preset->f_fps;
+        if( !*psz_aspect_ratio )
+        {
+            free( psz_aspect_ratio );
+            psz_aspect_ratio = strdup( psz_aspect_ratio );
+        }
+        if( !*psz_chroma )
+        {
+            free( psz_chroma );
+            psz_chroma = strdup( psz_chroma );
+        }
+    }
+
     if( i_width <= 0 || i_height <= 0 )
     {
         msg_Err( p_demux, "width and height must be strictly positive." );
+        free( psz_aspect_ratio );
+        free( psz_chroma );
         free( p_sys );
         return VLC_EGENERIC;
     }
 
-    psz_chroma = var_CreateGetString( p_demux, "rawvid-chroma" );
-    psz_aspect_ratio = var_CreateGetString( p_demux, "rawvid-aspect-ratio" );
-
-    if( psz_aspect_ratio && *psz_aspect_ratio )
+    if( !i_aspect )
     {
-        char *psz_parser = strchr( psz_aspect_ratio, ':' );
-        if( psz_parser )
+        if( psz_aspect_ratio && *psz_aspect_ratio )
         {
-            *psz_parser++ = '\0';
-            i_aspect = atoi( psz_aspect_ratio ) * VOUT_ASPECT_FACTOR
-                       / atoi( psz_parser );
+            char *psz_parser = strchr( psz_aspect_ratio, ':' );
+            if( psz_parser )
+            {
+                *psz_parser++ = '\0';
+                i_aspect = atoi( psz_aspect_ratio ) * VOUT_ASPECT_FACTOR
+                           / atoi( psz_parser );
+            }
+            else
+            {
+                i_aspect = atof( psz_aspect_ratio ) * VOUT_ASPECT_FACTOR;
+            }
         }
         else
         {
-            i_aspect = atof( psz_aspect_ratio ) * VOUT_ASPECT_FACTOR;
+            i_aspect = i_width * VOUT_ASPECT_FACTOR / i_height;
         }
     }
-    else
-    {
-        i_aspect = i_width * VOUT_ASPECT_FACTOR / i_height;
-    }
     free( psz_aspect_ratio );
 
     if( psz_chroma && strlen( psz_chroma ) >= 4 )
@@ -209,6 +347,19 @@ static int Demux( demux_t *p_demux )
     /* Call the pace control */
     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );
 
+    if( p_sys->b_y4m )
+    {
+        /* Skip the frame header */
+        unsigned char psz_buf[10];
+        psz_buf[9] = '\0';
+        stream_Read( p_demux->s, psz_buf, strlen( "FRAME" ) );
+        while( psz_buf[0] != 0x0a )
+        {
+            if( stream_Read( p_demux->s, psz_buf, 1 ) < 1 )
+                return 0;
+        }
+    }
+
     if( ( p_block = stream_Block( p_demux->s, p_sys->frame_size ) ) == NULL )
     {
         /* EOF */