]> git.sesse.net Git - vlc/blobdiff - modules/demux/rawvid.c
Fix a compilation warning.
[vlc] / modules / demux / rawvid.c
index bbe259e88f62e750d60bb7ee2acb0315a8149010..21bdb4fde15cdf5bf6dd3652459b95a4dfa230f9 100644 (file)
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
-#include <stdlib.h>                                      /* malloc(), free() */
 
-#include <vlc/vlc.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
 #include <vlc_demux.h>
 #include <vlc_vout.h>                                     /* vout_InitFormat */
 
@@ -58,19 +62,19 @@ static void Close( vlc_object_t * );
 
 vlc_module_begin();
     set_shortname( "Raw Video" );
-    set_description( _("Raw video demuxer") );
-    set_capability( "demux2", 2 );
+    set_description( N_("Raw video demuxer") );
+    set_capability( "demux", 10 );
     set_category( CAT_INPUT );
     set_subcategory( SUBCAT_INPUT_DEMUX );
     set_callbacks( Open, Close );
     add_shortcut( "rawvideo" );
-    add_float( "rawvid-fps", 0, 0, FPS_TEXT, FPS_LONGTEXT, VLC_FALSE );
+    add_float( "rawvid-fps", 0, 0, FPS_TEXT, FPS_LONGTEXT, 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 );
+                true );
     add_string( "rawvid-aspect-ratio", NULL, NULL,
-                ASPECT_RATIO_TEXT, ASPECT_RATIO_LONGTEXT, VLC_TRUE );
+                ASPECT_RATIO_TEXT, ASPECT_RATIO_LONGTEXT, true );
 vlc_module_end();
 
 /*****************************************************************************
@@ -85,6 +89,8 @@ struct demux_sys_t
     es_format_t  fmt_video;
 
     mtime_t i_pcr;
+
+    bool b_y4m;
 };
 
 /*****************************************************************************
@@ -126,37 +132,131 @@ 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;
+    bool b_valid = false;
+    bool b_y4m = false;
 
-    /* Check for YUV file extension */
-    psz_ext = strrchr( p_demux->psz_path, '.' );
+    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 = true;
+            b_y4m = true;
+        }
+    }
 
+    psz_ext = strrchr( p_demux->psz_path, '.' );
     if( psz_ext )
     {
         psz_ext++;
         for( p_preset = p_presets; *p_preset->psz_ext; p_preset++ )
             if( !strcasecmp( psz_ext, p_preset->psz_ext ) )
+            {
+                b_valid = true;
                 break;
+            }
     }
-    if( ( !p_preset || !*p_preset->psz_ext ) &&
-        strcmp(p_demux->psz_demux, "rawvid") )
-    {
+    if( !b_valid && !p_demux->b_force )
         return VLC_EGENERIC;
-    }
 
     /* Set p_input field */
     p_demux->pf_demux   = Demux;
     p_demux->pf_control = Control;
     p_demux->p_sys      = p_sys = malloc( sizeof( demux_sys_t ) );
+    if( !p_sys )
+        return VLC_ENOMEM;
+
     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 = 1;
+        int b = 1;
+        psz = stream_ReadLine( p_demux->s );
+
+        /* TODO: handle interlacing */
+
+#define READ_FRAC( key, num, den ) \
+        buf = strstr( psz+9, key );\
+        if( buf )\
+        {\
+            char *end = strchr( buf+1, ' ' );\
+            char *sep;\
+            if( end ) *end = '\0';\
+            sep = strchr( buf+1, ':' );\
+            if( sep )\
+            {\
+                *sep = '\0';\
+                den = atoi( sep+1 );\
+            }\
+            else\
+            {\
+                den = 1;\
+            }\
+            num = atoi( buf+2 );\
+            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 = strstr( psz+9, " C" );
+        if( buf )
+        {
+            char *end = strchr( buf+1, ' ' );
+            if( end ) *end = '\0';
+            buf+=2;
+            if( !strncmp( buf, "420jpeg", 7 ) )
+            {
+                psz_chroma = strdup( "I420" );
+            }
+            else if( !strncmp( buf, "420paldv", 8 ) )
+            {
+                psz_chroma = strdup( "I420" );
+            }
+            else if( !strncmp( buf, "420", 3 ) )
+            {
+                psz_chroma = strdup( "I420" );
+            }
+            else if( !strncmp( buf, "422", 3 ) )
+            {
+                psz_chroma = strdup( "I422" );
+            }
+            else if( !strncmp( buf, "444", 3 ) )
+            {
+                psz_chroma = strdup( "I444" );
+            }
+            else if( !strncmp( buf, "mono", 4 ) )
+            {
+                psz_chroma = strdup( "GREY" );
+            }
+            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;
@@ -183,24 +283,27 @@ static int Open( vlc_object_t * p_this )
         return VLC_EGENERIC;
     }
 
-    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 )
@@ -257,6 +360,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 */
@@ -266,7 +382,7 @@ static int Demux( demux_t *p_demux )
     p_block->i_dts = p_block->i_pts = p_sys->i_pcr;
     es_out_Send( p_demux->out, p_sys->p_es_video, p_block );
 
-    p_sys->i_pcr += ( I64C(1000000) / p_sys->f_fps );
+    p_sys->i_pcr += ( INT64_C(1000000) / p_sys->f_fps );
 
     return 1;
 }
@@ -279,7 +395,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
     demux_sys_t *p_sys  = p_demux->p_sys;
 
     /* XXX: DEMUX_SET_TIME is precise here */
-    return demux2_vaControlHelper( p_demux->s, 0, -1,
+    return demux_vaControlHelper( p_demux->s, 0, -1,
                                    p_sys->frame_size * p_sys->f_fps * 8,
                                    p_sys->frame_size, i_query, args );
 }