]> git.sesse.net Git - vlc/commitdiff
* configure.ac: detect if libavformat is present.
authorGildas Bazin <gbazin@videolan.org>
Thu, 8 Jan 2004 00:12:50 +0000 (00:12 +0000)
committerGildas Bazin <gbazin@videolan.org>
Thu, 8 Jan 2004 00:12:50 +0000 (00:12 +0000)
* modules/codec/ffmpeg/demux.c: new experimental demuxer using libavformat (most of the work done by fenrir).
   This demuxer should allow us to support "frindge" formats (FLIC, SWF, etc...).
   The demuxer has been put here because of its dependancy on libavformat and libavcodec.
* modules/codec/ffmpeg/ffmpeg.c: re-arranged the codecs list.

configure.ac
modules/codec/ffmpeg/Modules.am
modules/codec/ffmpeg/demux.c [new file with mode: 0644]
modules/codec/ffmpeg/ffmpeg.c
modules/codec/ffmpeg/ffmpeg.h
modules/codec/ffmpeg/video.c

index 5d5a37bb376caa3a6a4571e007c6dd74b6803b8d..7c0a0dad525be325d7ad0576443c44ad541988fb 100644 (file)
@@ -1,5 +1,5 @@
 dnl Autoconf settings for vlc
-dnl $Id: configure.ac,v 1.145 2004/01/05 17:42:36 gbazin Exp $
+dnl $Id: configure.ac,v 1.146 2004/01/08 00:12:50 gbazin Exp $
 
 AC_INIT(vlc,0.7.1-cvs)
 
@@ -1746,7 +1746,7 @@ AC_CHECK_HEADERS(id3tag.h, [
     AX_ADD_PLUGINS([id3tag])]) ])
 
 dnl
-dnl  ffmpeg decoder plugin
+dnl  ffmpeg decoder/demuxer plugin
 dnl
 AC_ARG_ENABLE(ffmpeg,
 [  --enable-ffmpeg         ffmpeg codec (default enabled)])
@@ -1785,6 +1785,10 @@ then
       dnl       linker would miserably barf on multiple definitions.
       AX_ADD_LDFLAGS([stream_out_transcode],[]) ],
        [ AC_MSG_ERROR([Could not find ffmpeg on your system: you may get it from http://ffmpeg.sf.net/ (cvs version is recommended). Alternatively you can use --disable-ffmpeg to disable the ffmpeg plugins.]) ])
+    AC_CHECK_LIB(avformat, av_open_input_stream, [
+      AC_DEFINE(HAVE_LIBAVFORMAT, 1,
+      [Define if you have ffmpeg's libavformat.])
+      AX_ADD_LDFLAGS([ffmpeg],[-lavformat -lz]) ])
     LDFLAGS="${LDFLAGS_save}"
     CPPFLAGS="${CPPFLAGS_save}"
   fi
@@ -1807,6 +1811,13 @@ then
       AX_ADD_LDFLAGS([ffmpeg],[-L${real_ffmpeg_tree}/libavcodec -lavcodec])
       AX_ADD_CPPFLAGS([ffmpeg],[-I${real_ffmpeg_tree}/libavcodec])
 
+      if test -f "${real_ffmpeg_tree}/libavformat/libavformat.a"; then
+        AC_DEFINE(HAVE_LIBAVFORMAT, 1,
+        [Define if you have ffmpeg's libavformat.])
+        AX_ADD_LDFLAGS([ffmpeg],[-L${real_ffmpeg_tree}/libavformat -lavformat -lz])
+        AX_ADD_CPPFLAGS([ffmpeg],[-I${real_ffmpeg_tree}/libavformat])
+      fi
+
       dnl  XXX: we don't link with -lavcodec a 2nd time because the OS X
       dnl       linker would miserably barf on multiple definitions.
       AX_ADD_LDFLAGS([stream_out_transcode],[-L${real_ffmpeg_tree}/libavcodec])
index 1a674bd32ea967c0f528c39f642b376bab5def85..63c6a0b2dd5d682eb2876f1160bf9ad1e49a0650 100644 (file)
@@ -6,5 +6,6 @@ SOURCES_ffmpeg = \
        chroma.c \
        encoder.c \
        postprocess.c \
+       demux.c \
        $(NULL)
 
diff --git a/modules/codec/ffmpeg/demux.c b/modules/codec/ffmpeg/demux.c
new file mode 100644 (file)
index 0000000..b3721d5
--- /dev/null
@@ -0,0 +1,353 @@
+/*****************************************************************************
+ * demux.c: demuxer using ffmpeg (libavformat).
+ *****************************************************************************
+ * Copyright (C) 2004 VideoLAN
+ * $Id: demux.c,v 1.1 2004/01/08 00:12:50 gbazin Exp $
+ *
+ * Authors: Laurent Aimar <fenrir@via.ecp.fr>
+ *          Gildas Bazin <gbazin@netcourrier.com>
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>                                      /* malloc(), free() */
+
+#include <vlc/vlc.h>
+#include <vlc/input.h>
+
+/* ffmpeg header */
+#ifdef HAVE_FFMPEG_AVCODEC_H
+#   include <ffmpeg/avformat.h>
+#else
+#   include <avformat.h>
+#endif
+
+/* Version checking */
+#if (LIBAVFORMAT_BUILD >= 4611) && defined(HAVE_LIBAVFORMAT)
+
+/*****************************************************************************
+ * demux_sys_t: demux descriptor
+ *****************************************************************************/
+struct demux_sys_t
+{
+    ByteIOContext   io;
+    int             io_buffer_size;
+    uint8_t        *io_buffer;
+
+    AVInputFormat  *fmt;
+    AVFormatContext *ic;
+
+    int             i_tk;
+    es_out_id_t     **tk;
+
+    int64_t     i_pcr;
+    int64_t     i_pcr_inc;
+    int         i_pcr_tk;
+};
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int Demux  ( demux_t *p_demux );
+static int Control( demux_t *p_demux, int i_query, va_list args );
+
+static int IORead( void *opaque, uint8_t *buf, int buf_size );
+static int IOSeek( void *opaque, offset_t offset, int whence );
+
+/*****************************************************************************
+ * Open
+ *****************************************************************************/
+int E_(OpenDemux)( vlc_object_t *p_this )
+{
+    demux_t       *p_demux = (demux_t*)p_this;
+    demux_sys_t   *p_sys;
+    AVProbeData   pd;
+    AVInputFormat *fmt;
+    int i, b_forced;
+
+    b_forced = ( p_demux->psz_demux && *p_demux->psz_demux &&
+                 !strcmp( p_demux->psz_demux, "ffmpeg" ) ) ? 1 : 0;
+
+    /* Init Probe data */
+    pd.filename = p_demux->psz_path;
+    if( ( pd.buf_size = stream_Peek( p_demux->s, &pd.buf, 2048 ) ) <= 0 )
+    {
+        msg_Warn( p_demux, "cannot peek" );
+        return VLC_EGENERIC;
+    }
+
+    /* Should we call it only once ? */
+    av_register_all();
+
+    /* Guess format */
+    if( !( fmt = av_probe_input_format( &pd, 1 ) ) )
+    {
+        msg_Dbg( p_demux, "couldn't guess format" );
+        return VLC_EGENERIC;
+    }
+
+    /* Don't try to handle MPEG unless forced */
+    if( !b_forced &&
+        ( !strcmp( fmt->name, "mpeg" ) ||
+          !strcmp( fmt->name, "vcd" ) ||
+          !strcmp( fmt->name, "vob" ) ||
+          !strcmp( fmt->name, "mpegts" ) ) )
+    {
+        return VLC_EGENERIC;
+    }
+
+    /* Fill p_demux fields */
+    p_demux->pf_demux = Demux;
+    p_demux->pf_control = Control;
+    p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
+    p_sys->fmt = fmt;
+    p_sys->i_tk = 0;
+    p_sys->tk = NULL;
+    p_sys->i_pcr_tk = -1;
+
+    /* Create I/O wrapper */
+    p_sys->io_buffer_size = 32768;  /* FIXME */
+    p_sys->io_buffer = malloc( p_sys->io_buffer_size );
+    init_put_byte( &p_sys->io, p_sys->io_buffer, p_sys->io_buffer_size,
+                   0, p_demux, IORead, NULL, IOSeek );
+
+    p_sys->fmt->flags |= AVFMT_NOFILE; /* libavformat must not fopen/fclose */
+
+    /* Open it */
+    if( av_open_input_stream( &p_sys->ic, &p_sys->io, p_demux->psz_path,
+                              p_sys->fmt, NULL ) )
+    {
+        msg_Err( p_demux, "av_open_input_stream failed" );
+        return VLC_EGENERIC;
+    }
+
+    if( av_find_stream_info( p_sys->ic ) )
+    {
+        msg_Err( p_demux, "av_find_stream_info failed" );
+        return VLC_EGENERIC;
+    }
+
+    for( i = 0; i < p_sys->ic->nb_streams; i++ )
+    {
+        AVCodecContext *cc = &p_sys->ic->streams[i]->codec;
+        es_out_id_t  *es;
+        es_format_t  fmt;
+        vlc_fourcc_t fcc;
+
+        if( !E_(GetVlcFourcc)( cc->codec_id, NULL, &fcc, NULL ) )
+            fcc = VLC_FOURCC( 'u', 'n', 'd', 'f' );
+
+        switch( cc->codec_type )
+        {
+        case CODEC_TYPE_AUDIO:
+            es_format_Init( &fmt, AUDIO_ES, fcc );
+            break;
+        case CODEC_TYPE_VIDEO:
+            es_format_Init( &fmt, VIDEO_ES, fcc );
+            break;
+        default:
+            break;
+        }
+
+        fmt.video.i_width = cc->width;
+        fmt.video.i_height = cc->height;
+        fmt.i_extra = cc->extradata_size;
+        fmt.p_extra = cc->extradata;
+        es = es_out_Add( p_demux->out, &fmt );
+
+        msg_Dbg( p_demux, "adding es: %s codec = %4.4s",
+                 cc->codec_type == CODEC_TYPE_AUDIO ? "audio" : "video",
+                 (char*)&fcc );
+        TAB_APPEND( p_sys->i_tk, p_sys->tk, es );
+    }
+
+    msg_Dbg( p_demux, "AVFormat supported stream" );
+    msg_Dbg( p_demux, "    - format = %s (%s)",
+             p_sys->fmt->name, p_sys->fmt->long_name );
+    msg_Dbg( p_demux, "    - start time=%lld",
+             p_sys->ic->start_time / AV_TIME_BASE );
+    msg_Dbg( p_demux, "    - duration = %lld",
+             p_sys->ic->duration / AV_TIME_BASE );
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Close
+ *****************************************************************************/
+void E_(CloseDemux)( vlc_object_t *p_this )
+{
+    demux_t     *p_demux = (demux_t*)p_this;
+    demux_sys_t *p_sys = p_demux->p_sys;
+
+    av_close_input_file( p_sys->ic );
+
+    free( p_sys->io_buffer );
+    free( p_sys );
+}
+
+/*****************************************************************************
+ * Demux:
+ *****************************************************************************/
+static int Demux( demux_t *p_demux )
+{
+    demux_sys_t *p_sys = p_demux->p_sys;
+    AVPacket    pkt;
+    block_t     *p_frame;
+
+    /* Read a frame */
+    if( av_read_frame( p_sys->ic, &pkt ) )
+    {
+        return 0;
+    }
+    if( pkt.stream_index < 0 || pkt.stream_index >= p_sys->i_tk )
+    {
+        av_free_packet( &pkt );
+        return 1;
+    }
+    if( ( p_frame = block_New( p_demux, pkt.size ) ) == NULL )
+    {
+        return 0;
+    }
+
+    memcpy( p_frame->p_buffer, pkt.data, pkt.size );
+    p_frame->i_dts = pkt.dts * 1000000 / AV_TIME_BASE;
+    p_frame->i_pts = pkt.pts * 1000000 / AV_TIME_BASE;
+    msg_Dbg( p_demux, "tk[%d] dts=%lld pts=%lld",
+             pkt.stream_index, p_frame->i_dts, p_frame->i_pts );
+
+    if( pkt.dts > 0 &&
+        ( pkt.stream_index == p_sys->i_pcr_tk || p_sys->i_pcr_tk < 0 ) )
+    {
+        p_sys->i_pcr_tk = pkt.stream_index;
+        p_sys->i_pcr = pkt.dts;
+
+        es_out_Control( p_demux->out, ES_OUT_SET_PCR, (int64_t)p_sys->i_pcr );
+    }
+
+    es_out_Send( p_demux->out, p_sys->tk[pkt.stream_index], p_frame );
+    av_free_packet( &pkt );
+    return 1;
+}
+
+/*****************************************************************************
+ * Control:
+ *****************************************************************************/
+static int Control( demux_t *p_demux, int i_query, va_list args )
+{
+    demux_sys_t *p_sys = p_demux->p_sys;
+    double f, *pf;
+    int64_t i64, *pi64;
+
+    switch( i_query )
+    {
+        case DEMUX_GET_POSITION:
+            pf = (double*) va_arg( args, double* );
+            i64 = stream_Size( p_demux->s );
+            if( i64 > 0 )
+            {
+                *pf = (double)stream_Tell( p_demux->s ) / (double)i64;
+            }
+            else
+            {
+                *pf = 0.0;
+            }
+            return VLC_SUCCESS;
+
+        case DEMUX_SET_POSITION:
+            f = (double) va_arg( args, double );
+            i64 = stream_Size( p_demux->s );
+
+            es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
+            av_seek_frame( p_sys->ic, -1, -1 );
+            if( stream_Seek( p_demux->s, (int64_t)(i64 * f) ) )
+            {
+                return VLC_EGENERIC;
+            }
+            p_sys->i_pcr = -1; /* Invalidate time display */
+            return VLC_SUCCESS;
+
+        case DEMUX_GET_TIME:
+            pi64 = (int64_t*)va_arg( args, int64_t * );
+            *pi64 = p_sys->i_pcr;
+            return VLC_SUCCESS;
+
+        case DEMUX_SET_TIME:
+            i64 = (int64_t)va_arg( args, int64_t );
+            if( av_seek_frame( p_sys->ic, -1, i64 ) < 0 )
+            {
+                return VLC_EGENERIC;
+            }
+            p_sys->i_pcr = -1; /* Invalidate time display */
+            return VLC_SUCCESS;
+
+        default:
+            return VLC_EGENERIC;
+    }
+}
+
+/*****************************************************************************
+ * I/O wrappers for libavformat
+ *****************************************************************************/
+static int IORead( void *opaque, uint8_t *buf, int buf_size )
+{
+    demux_t *p_demux = opaque;
+    return stream_Read( p_demux->s, buf, buf_size );
+}
+
+static int IOSeek( void *opaque, offset_t offset, int whence )
+{
+    demux_t *p_demux = opaque;
+    int64_t i_absolute;
+
+    switch( whence )
+    {
+        case SEEK_SET:
+            i_absolute = offset;
+            break;
+        case SEEK_CUR:
+            i_absolute = stream_Tell( p_demux->s ) + offset;
+            break;
+        case SEEK_END:
+            i_absolute = stream_Size( p_demux->s ) - offset;
+            break;
+        default:
+            return -1;
+
+    }
+
+    if( stream_Seek( p_demux->s, i_absolute ) )
+    {
+        return -1;
+    }
+
+    return 0;
+}
+
+#else /* LIBAVFORMAT_BUILD >= 4611 */
+
+int E_(OpenDemux)( vlc_object_t *p_this )
+{
+    return VLC_EGENERIC;
+}
+
+void E_(CloseDemux)( vlc_object_t *p_this )
+{
+}
+
+#endif /* LIBAVFORMAT_BUILD >= 4611 */
index 136ec64c936a9a4bc265cf422994fa9f86aa44b2..b57f84229162f2a1e8c80e60e48c6c696ebccd6e 100644 (file)
@@ -2,7 +2,7 @@
  * ffmpeg.c: video decoder using ffmpeg library
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: ffmpeg.c,v 1.68 2003/12/16 12:38:18 gbazin Exp $
+ * $Id: ffmpeg.c,v 1.69 2004/01/08 00:12:50 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
@@ -109,6 +109,11 @@ vlc_module_begin();
     set_capability( "encoder", 100 );
     set_callbacks( E_(OpenEncoder), E_(CloseEncoder) );
 
+    /* demux submodule */
+    set_description( _("ffmpeg demuxer" ) );
+    set_capability( "demux2", 1 );
+    set_callbacks( E_(OpenDemux), E_(CloseDemux) );
+
     var_Create( p_module->p_libvlc, "avcodec", VLC_VAR_MUTEX );
 vlc_module_end();
 
@@ -219,131 +224,195 @@ static void CloseDecoder( vlc_object_t *p_this )
 /*****************************************************************************
  * local Functions
  *****************************************************************************/
-int E_(GetFfmpegCodec)( vlc_fourcc_t i_fourcc, int *pi_cat,
-                        int *pi_ffmpeg_codec, char **ppsz_name )
+int E_(GetFfmpegChroma)( vlc_fourcc_t i_chroma )
 {
-    int i_cat;
-    int i_codec;
-    char *psz_name;
+    switch( i_chroma )
+    {
+    case VLC_FOURCC( 'I', '4', '2', '0' ):
+        return PIX_FMT_YUV420P;
+    case VLC_FOURCC( 'I', '4', '2', '2' ):
+        return PIX_FMT_YUV422P;
+    case VLC_FOURCC( 'I', '4', '4', '4' ):
+        return PIX_FMT_YUV444P;
+    case VLC_FOURCC( 'R', 'V', '1', '5' ):
+        return PIX_FMT_RGB555;
+    case VLC_FOURCC( 'R', 'V', '1', '6' ):
+        return PIX_FMT_RGB565;
+    case VLC_FOURCC( 'R', 'V', '2', '4' ):
+        return PIX_FMT_RGB24;
+    case VLC_FOURCC( 'R', 'V', '3', '2' ):
+        return PIX_FMT_RGBA32;
+    case VLC_FOURCC( 'G', 'R', 'E', 'Y' ):
+        return PIX_FMT_GRAY8;
+    case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
+        return PIX_FMT_YUV422;
+    default:
+        return -1;
+    }
+}
+
+void E_(InitLibavcodec)( vlc_object_t *p_object )
+{
+    static int b_ffmpeginit = 0;
+    vlc_value_t lockval;
+
+    var_Get( p_object->p_libvlc, "avcodec", &lockval );
+    vlc_mutex_lock( lockval.p_address );
+
+    /* *** init ffmpeg library (libavcodec) *** */
+    if( !b_ffmpeginit )
+    {
+        avcodec_init();
+        avcodec_register_all();
+        b_ffmpeginit = 1;
 
-    switch( i_fourcc )
+        msg_Dbg( p_object, "libavcodec initialized (interface %d )",
+                 LIBAVCODEC_BUILD );
+    }
+    else
     {
+        msg_Dbg( p_object, "libavcodec already initialized" );
+    }
 
-    /*
-     *  Video Codecs
-     */
+    vlc_mutex_unlock( lockval.p_address );
+}
+
+
+static struct
+{
+    vlc_fourcc_t  i_fourcc;
+    int  i_codec;
+    int  i_cat;
+    char *psz_name;
 
+} codecs_table[] =
+{
     /* MPEG-1 Video */
-    case VLC_FOURCC('m','p','1','v'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_MPEG1VIDEO;
-        psz_name = "MPEG-1 Video";
-        break;
+    { VLC_FOURCC('m','p','1','v'), CODEC_ID_MPEG1VIDEO,
+      VIDEO_ES, "MPEG-1 Video" },
 
     /* MPEG-2 Video */
-    case VLC_FOURCC('m','p','2','v'):
-    case VLC_FOURCC('m','p','g','v'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_MPEG2VIDEO;
-        psz_name = "MPEG-2 Video";
-        break;
+    { VLC_FOURCC('m','p','2','v'), CODEC_ID_MPEG2VIDEO,
+      VIDEO_ES, "MPEG-2 Video" },
+    { VLC_FOURCC('m','p','g','v'), CODEC_ID_MPEG2VIDEO,
+      VIDEO_ES, "MPEG-2 Video" },
 
     /* MPEG-4 Video */
-    case VLC_FOURCC('D','I','V','X'):
-    case VLC_FOURCC('d','i','v','x'):
-    case VLC_FOURCC('M','P','4','S'):
-    case VLC_FOURCC('m','p','4','s'):
-    case VLC_FOURCC('M','4','S','2'):
-    case VLC_FOURCC('m','4','s','2'):
-    case VLC_FOURCC('x','v','i','d'):
-    case VLC_FOURCC('X','V','I','D'):
-    case VLC_FOURCC('X','v','i','D'):
-    case VLC_FOURCC('D','X','5','0'):
-    case VLC_FOURCC('d','x','5','0'):
-    case VLC_FOURCC('m','p','4','v'):
-    case VLC_FOURCC( 4,  0,  0,  0 ):
-    case VLC_FOURCC('m','4','c','c'):
-    case VLC_FOURCC('M','4','C','C'):
+    { VLC_FOURCC('D','I','V','X'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC('d','i','v','x'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC('M','P','4','S'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC('m','p','4','s'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC('M','4','S','2'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC('m','4','s','2'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC('x','v','i','d'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC('X','V','I','D'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC('X','v','i','D'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC('D','X','5','0'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC('d','x','5','0'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC('m','p','4','v'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC( 4,  0,  0,  0 ), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC('m','4','c','c'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC('M','4','C','C'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
     /* 3ivx delta 3.5 Unsupported
      * putting it here gives extreme distorted images
-    case VLC_FOURCC('3','I','V','1'):
-    case VLC_FOURCC('3','i','v','1'): */
+    { VLC_FOURCC('3','I','V','1'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC('3','i','v','1'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" }, */
     /* 3ivx delta 4 */
-    case VLC_FOURCC('3','I','V','2'):
-    case VLC_FOURCC('3','i','v','2'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_MPEG4;
-        psz_name = "MPEG-4";
-        break;
+    { VLC_FOURCC('3','I','V','2'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
+    { VLC_FOURCC('3','i','v','2'), CODEC_ID_MPEG4,
+      VIDEO_ES, "MPEG-4 Video" },
 
     /* MSMPEG4 v1 */
-    case VLC_FOURCC('D','I','V','1'):
-    case VLC_FOURCC('d','i','v','1'):
-    case VLC_FOURCC('M','P','G','4'):
-    case VLC_FOURCC('m','p','g','4'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_MSMPEG4V1;
-        psz_name = "MS MPEG-4 v1";
-        break;
+    { VLC_FOURCC('D','I','V','1'), CODEC_ID_MSMPEG4V1,
+      VIDEO_ES, "MS MPEG-4 Video v1" },
+    { VLC_FOURCC('d','i','v','1'), CODEC_ID_MSMPEG4V1,
+      VIDEO_ES, "MS MPEG-4 Video v1" },
+    { VLC_FOURCC('M','P','G','4'), CODEC_ID_MSMPEG4V1,
+      VIDEO_ES, "MS MPEG-4 Video v1" },
+    { VLC_FOURCC('m','p','g','4'), CODEC_ID_MSMPEG4V1,
+      VIDEO_ES, "MS MPEG-4 Video v1" },
 
     /* MSMPEG4 v2 */
-    case VLC_FOURCC('D','I','V','2'):
-    case VLC_FOURCC('d','i','v','2'):
-    case VLC_FOURCC('M','P','4','2'):
-    case VLC_FOURCC('m','p','4','2'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_MSMPEG4V2;
-        psz_name = "MS MPEG-4 v2";
-        break;
+    { VLC_FOURCC('D','I','V','2'), CODEC_ID_MSMPEG4V2,
+      VIDEO_ES, "MS MPEG-4 Video v2" },
+    { VLC_FOURCC('d','i','v','2'), CODEC_ID_MSMPEG4V2,
+      VIDEO_ES, "MS MPEG-4 Video v2" },
+    { VLC_FOURCC('M','P','4','2'), CODEC_ID_MSMPEG4V2,
+      VIDEO_ES, "MS MPEG-4 Video v2" },
+    { VLC_FOURCC('m','p','4','2'), CODEC_ID_MSMPEG4V2,
+      VIDEO_ES, "MS MPEG-4 Video v2" },
 
     /* MSMPEG4 v3 / M$ mpeg4 v3 */
-    case VLC_FOURCC('M','P','G','3'):
-    case VLC_FOURCC('m','p','g','3'):
-    case VLC_FOURCC('d','i','v','3'):
-    case VLC_FOURCC('M','P','4','3'):
-    case VLC_FOURCC('m','p','4','3'):
+    { VLC_FOURCC('M','P','G','3'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
+    { VLC_FOURCC('m','p','g','3'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
+    { VLC_FOURCC('d','i','v','3'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
+    { VLC_FOURCC('M','P','4','3'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
+    { VLC_FOURCC('m','p','4','3'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
     /* DivX 3.20 */
-    case VLC_FOURCC('D','I','V','3'):
-    case VLC_FOURCC('D','I','V','4'):
-    case VLC_FOURCC('d','i','v','4'):
-    case VLC_FOURCC('D','I','V','5'):
-    case VLC_FOURCC('d','i','v','5'):
-    case VLC_FOURCC('D','I','V','6'):
-    case VLC_FOURCC('d','i','v','6'):
+    { VLC_FOURCC('D','I','V','3'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
+    { VLC_FOURCC('D','I','V','4'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
+    { VLC_FOURCC('d','i','v','4'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
+    { VLC_FOURCC('D','I','V','5'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
+    { VLC_FOURCC('d','i','v','5'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
+    { VLC_FOURCC('D','I','V','6'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
+    { VLC_FOURCC('d','i','v','6'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
     /* AngelPotion stuff */
-    case VLC_FOURCC('A','P','4','1'):
+    { VLC_FOURCC('A','P','4','1'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
     /* 3ivx doctered divx files */
-    case VLC_FOURCC('3','I','V','D'):
-    case VLC_FOURCC('3','i','v','d'):
+    { VLC_FOURCC('3','I','V','D'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
+    { VLC_FOURCC('3','i','v','d'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
     /* who knows? */
-    case VLC_FOURCC('3','V','I','D'):
-    case VLC_FOURCC('3','v','i','d'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_MSMPEG4V3;
-        psz_name = "MS MPEG-4 v3";
-        break;
+    { VLC_FOURCC('3','V','I','D'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
+    { VLC_FOURCC('3','v','i','d'), CODEC_ID_MSMPEG4V3,
+      VIDEO_ES, "MS MPEG-4 Video v3" },
 
     /* Sorenson v1 */
-    case VLC_FOURCC('S','V','Q','1'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_SVQ1;
-        psz_name = "SVQ-1 (Sorenson Video v1)";
-        break;
+    { VLC_FOURCC('S','V','Q','1'), CODEC_ID_SVQ1,
+      VIDEO_ES, "SVQ-1 (Sorenson Video v1)" },
 
     /* Sorenson v3 */
-    case VLC_FOURCC('S','V','Q','3'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_SVQ3;
-        psz_name = "SVQ-3 (Sorenson Video v3)";
-        break;
+    { VLC_FOURCC('S','V','Q','3'), CODEC_ID_SVQ3,
+      VIDEO_ES, "SVQ-3 (Sorenson Video v3)" },
 
     /* h264 */
-    case VLC_FOURCC('h','2','6','4'):
-    case VLC_FOURCC('H','2','6','4'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_H264;
-        psz_name = "h264";
-        break;
+    { VLC_FOURCC('h','2','6','4'), CODEC_ID_H264,
+      VIDEO_ES, "h264" },
+    { VLC_FOURCC('H','2','6','4'), CODEC_ID_H264,
+      VIDEO_ES, "h264" },
 
 /* H263 and H263i */
 /* H263(+) is also known as Real Video 1.0 */
@@ -351,195 +420,158 @@ int E_(GetFfmpegCodec)( vlc_fourcc_t i_fourcc, int *pi_cat,
 /* FIXME FOURCC_H263P exist but what fourcc ? */
 
     /* H263 */
-    case VLC_FOURCC('H','2','6','3'):
-    case VLC_FOURCC('h','2','6','3'):
-    case VLC_FOURCC('U','2','6','3'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_H263;
-        psz_name = "H263";
-        break;
+    { VLC_FOURCC('H','2','6','3'), CODEC_ID_H263,
+      VIDEO_ES, "H263" },
+    { VLC_FOURCC('h','2','6','3'), CODEC_ID_H263,
+      VIDEO_ES, "H263" },
+    { VLC_FOURCC('U','2','6','3'), CODEC_ID_H263,
+      VIDEO_ES, "H263" },
 
     /* H263i */
-    case VLC_FOURCC('I','2','6','3'):
-    case VLC_FOURCC('i','2','6','3'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_H263I;
-        psz_name = "I263.I";
-        break;
+    { VLC_FOURCC('I','2','6','3'), CODEC_ID_H263I,
+      VIDEO_ES, "I263.I" },
+    { VLC_FOURCC('i','2','6','3'), CODEC_ID_H263I,
+      VIDEO_ES, "I263.I" },
 
     /* Flash (H263) variant */
-    case VLC_FOURCC('F','L','V','1'):
-        i_cat    = VIDEO_ES;
-        i_codec  = CODEC_ID_FLV1;
-        psz_name = "Flash Video";
-        break;
+    { VLC_FOURCC('F','L','V','1'), CODEC_ID_FLV1,
+      VIDEO_ES, "Flash Video" },
+
+    /* Flash (H263) variant */
+    { VLC_FOURCC('F','L','I','C'), CODEC_ID_FLIC,
+      VIDEO_ES, "Flic Video" },
 
     /* MJPEG */
-    case VLC_FOURCC( 'M', 'J', 'P', 'G' ):
-    case VLC_FOURCC( 'm', 'j', 'p', 'g' ):
-    case VLC_FOURCC( 'm', 'j', 'p', 'a' ): /* for mov file */
-    case VLC_FOURCC( 'j', 'p', 'e', 'g' ):
-    case VLC_FOURCC( 'J', 'P', 'E', 'G' ):
-    case VLC_FOURCC( 'J', 'F', 'I', 'F' ):
-    case VLC_FOURCC( 'J', 'P', 'G', 'L' ):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_MJPEG;
-        psz_name = "Motion JPEG";
-        break;
-    case VLC_FOURCC( 'm', 'j', 'p', 'b' ): /* for mov file */
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_MJPEGB;
-        psz_name = "Motion JPEG B";
-        break;
+    { VLC_FOURCC( 'M', 'J', 'P', 'G' ), CODEC_ID_MJPEG,
+      VIDEO_ES, "Motion JPEG Video" },
+    { VLC_FOURCC( 'm', 'j', 'p', 'g' ), CODEC_ID_MJPEG,
+      VIDEO_ES, "Motion JPEG Video" },
+    { VLC_FOURCC( 'm', 'j', 'p', 'a' ), CODEC_ID_MJPEG, /* for mov file */
+      VIDEO_ES, "Motion JPEG Video" },
+    { VLC_FOURCC( 'j', 'p', 'e', 'g' ), CODEC_ID_MJPEG,
+      VIDEO_ES, "Motion JPEG Video" },
+    { VLC_FOURCC( 'J', 'P', 'E', 'G' ), CODEC_ID_MJPEG,
+      VIDEO_ES, "Motion JPEG Video" },
+    { VLC_FOURCC( 'J', 'F', 'I', 'F' ), CODEC_ID_MJPEG,
+      VIDEO_ES, "Motion JPEG Video" },
+    { VLC_FOURCC( 'J', 'P', 'G', 'L' ), CODEC_ID_MJPEG,
+      VIDEO_ES, "Motion JPEG Video" },
+
+    { VLC_FOURCC( 'm', 'j', 'p', 'b' ), CODEC_ID_MJPEGB, /* for mov file */
+      VIDEO_ES, "Motion JPEG B Video" },
 
     /* DV */
-    case VLC_FOURCC('d','v','s','l'):
-    case VLC_FOURCC('d','v','s','d'):
-    case VLC_FOURCC('D','V','S','D'):
-    case VLC_FOURCC('d','v','h','d'):
-    case VLC_FOURCC('d','v','c',' '):
-    case VLC_FOURCC('d','v','p',' '):
-    case VLC_FOURCC('C','D','V','C'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_DVVIDEO;
-        psz_name = "DV video";
-        break;
+    { VLC_FOURCC('d','v','s','l'), CODEC_ID_DVVIDEO,
+      VIDEO_ES, "DV Video" },
+    { VLC_FOURCC('d','v','s','d'), CODEC_ID_DVVIDEO,
+      VIDEO_ES, "DV Video" },
+    { VLC_FOURCC('D','V','S','D'), CODEC_ID_DVVIDEO,
+      VIDEO_ES, "DV Video" },
+    { VLC_FOURCC('d','v','h','d'), CODEC_ID_DVVIDEO,
+      VIDEO_ES, "DV Video" },
+    { VLC_FOURCC('d','v','c',' '), CODEC_ID_DVVIDEO,
+      VIDEO_ES, "DV Video" },
+    { VLC_FOURCC('d','v','p',' '), CODEC_ID_DVVIDEO,
+      VIDEO_ES, "DV Video" },
+    { VLC_FOURCC('C','D','V','C'), CODEC_ID_DVVIDEO,
+      VIDEO_ES, "DV Video" },
 
     /* Windows Media Video */
-    case VLC_FOURCC('W','M','V','1'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_WMV1;
-        psz_name ="Windows Media Video 1";
-        break;
-    case VLC_FOURCC('W','M','V','2'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_WMV2;
-        psz_name ="Windows Media Video 2";
-        break;
+    { VLC_FOURCC('W','M','V','1'), CODEC_ID_WMV1,
+      VIDEO_ES, "Windows Media Video 1" },
+    { VLC_FOURCC('W','M','V','2'), CODEC_ID_WMV2,
+      VIDEO_ES, "Windows Media Video 2" },
 
 #if LIBAVCODEC_BUILD >= 4683
     /* Microsoft Video 1 */
-    case VLC_FOURCC('M','S','V','C'):
-    case VLC_FOURCC('m','s','v','c'):
-    case VLC_FOURCC('C','R','A','M'):
-    case VLC_FOURCC('c','r','a','m'):
-    case VLC_FOURCC('W','H','A','M'):
-    case VLC_FOURCC('w','h','a','m'):
-        i_cat    = VIDEO_ES;
-        i_codec  = CODEC_ID_MSVIDEO1;
-        psz_name = "Microsoft Video 1";
-        break;
+    { VLC_FOURCC('M','S','V','C'), CODEC_ID_MSVIDEO1,
+      VIDEO_ES, "Microsoft Video 1" },
+    { VLC_FOURCC('m','s','v','c'), CODEC_ID_MSVIDEO1,
+      VIDEO_ES, "Microsoft Video 1" },
+    { VLC_FOURCC('C','R','A','M'), CODEC_ID_MSVIDEO1,
+      VIDEO_ES, "Microsoft Video 1" },
+    { VLC_FOURCC('c','r','a','m'), CODEC_ID_MSVIDEO1,
+      VIDEO_ES, "Microsoft Video 1" },
+    { VLC_FOURCC('W','H','A','M'), CODEC_ID_MSVIDEO1,
+      VIDEO_ES, "Microsoft Video 1" },
+    { VLC_FOURCC('w','h','a','m'), CODEC_ID_MSVIDEO1,
+      VIDEO_ES, "Microsoft Video 1" },
 
     /* Microsoft RLE */
-    case VLC_FOURCC('m','r','l','e'):
-    case VLC_FOURCC(0x1,0x0,0x0,0x0):
-        i_cat    = VIDEO_ES;
-        i_codec  = CODEC_ID_MSRLE;
-        psz_name = "Microsoft RLE";
-        break;
+    { VLC_FOURCC('m','r','l','e'), CODEC_ID_MSRLE,
+      VIDEO_ES, "Microsoft RLE Video" },
+    { VLC_FOURCC(0x1,0x0,0x0,0x0), CODEC_ID_MSRLE,
+      VIDEO_ES, "Microsoft RLE Video" },
 #endif
 
 #if( !defined( WORDS_BIGENDIAN ) )
     /* Indeo Video Codecs (Quality of this decoder on ppc is not good) */
-    case VLC_FOURCC('I','V','3','1'):
-    case VLC_FOURCC('i','v','3','1'):
-    case VLC_FOURCC('I','V','3','2'):
-    case VLC_FOURCC('i','v','3','2'):
-        i_cat    = VIDEO_ES;
-        i_codec  = CODEC_ID_INDEO3;
-        psz_name = "Indeo v3";
-        break;
+    { VLC_FOURCC('I','V','3','1'), CODEC_ID_INDEO3,
+      VIDEO_ES, "Indeo Video v3" },
+    { VLC_FOURCC('i','v','3','1'), CODEC_ID_INDEO3,
+      VIDEO_ES, "Indeo Video v3" },
+    { VLC_FOURCC('I','V','3','2'), CODEC_ID_INDEO3,
+      VIDEO_ES, "Indeo Video v3" },
+    { VLC_FOURCC('i','v','3','2'), CODEC_ID_INDEO3,
+      VIDEO_ES, "Indeo Video v3" },
 #endif
 
     /* Huff YUV */
-    case VLC_FOURCC('H','F','Y','U'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_HUFFYUV;
-        psz_name ="Huff YUV";
-        break;
+    { VLC_FOURCC('H','F','Y','U'), CODEC_ID_HUFFYUV,
+      VIDEO_ES, "Huff YUV Video" },
 
     /* Creative YUV */
-    case VLC_FOURCC('C','Y','U','V'):
-        i_cat = VIDEO_ES;
-        i_codec = CODEC_ID_CYUV;
-        psz_name ="Creative YUV";
-        break;
+    { VLC_FOURCC('C','Y','U','V'), CODEC_ID_CYUV,
+      VIDEO_ES, "Creative YUV Video" },
 
     /* On2 VP3 Video Codecs */
-    case VLC_FOURCC('V','P','3','1'):
-    case VLC_FOURCC('v','p','3','1'):
-        i_cat    = VIDEO_ES;
-        i_codec  = CODEC_ID_VP3;
-        psz_name = "On2's VP3 Video";
-        break;
+    { VLC_FOURCC('V','P','3','1'), CODEC_ID_VP3,
+      VIDEO_ES, "On2's VP3 Video" },
+    { VLC_FOURCC('v','p','3','1'), CODEC_ID_VP3,
+      VIDEO_ES, "On2's VP3 Video" },
 
 #if LIBAVCODEC_BUILD >= 4685
     /* Xiph.org theora */
-    case VLC_FOURCC('t','h','e','o'):
-        i_cat    = VIDEO_ES;
-        i_codec  = CODEC_ID_THEORA;
-        psz_name = "Xiph.org's Theora Video";
-        break;
+    { VLC_FOURCC('t','h','e','o'), CODEC_ID_THEORA,
+      VIDEO_ES, "Xiph.org's Theora Video" },
 #endif
 
 #if ( !defined( WORDS_BIGENDIAN ) )
     /* Asus Video (Another thing that doesn't work on PPC) */
-    case VLC_FOURCC('A','S','V','1'):
-        i_cat    = VIDEO_ES;
-        i_codec  = CODEC_ID_ASV1;
-        psz_name = "Asus V1";
-        break;
-    case VLC_FOURCC('A','S','V','2'):
-        i_cat    = VIDEO_ES;
-        i_codec  = CODEC_ID_ASV2;
-        psz_name = "Asus V2";
-        break;
+    { VLC_FOURCC('A','S','V','1'), CODEC_ID_ASV1,
+      VIDEO_ES, "Asus V1 Video" },
+    { VLC_FOURCC('A','S','V','2'), CODEC_ID_ASV2,
+      VIDEO_ES, "Asus V2 Video" },
 #endif
 
     /* FFMPEG Video 1 (lossless codec) */
-    case VLC_FOURCC('F','F','V','1'):
-        i_cat    = VIDEO_ES;
-        i_codec  = CODEC_ID_FFV1;
-        psz_name = "FFMpeg Video 1";
-        break;
+    { VLC_FOURCC('F','F','V','1'), CODEC_ID_FFV1,
+      VIDEO_ES, "FFMpeg Video 1" },
 
     /* ATI VCR1 */
-    case VLC_FOURCC('V','C','R','1'):
-        i_cat    = VIDEO_ES;
-        i_codec  = CODEC_ID_VCR1;
-        psz_name = "ATI VCR1";
-        break;
+    { VLC_FOURCC('V','C','R','1'), CODEC_ID_VCR1,
+      VIDEO_ES, "ATI VCR1 Video" },
 
     /* Cirrus Logic AccuPak */
-    case VLC_FOURCC('C','L','J','R'):
-        i_cat    = VIDEO_ES;
-        i_codec  = CODEC_ID_CLJR;
-        psz_name = "Creative Logic AccuPak";
-        break;
+    { VLC_FOURCC('C','L','J','R'), CODEC_ID_CLJR,
+      VIDEO_ES, "Creative Logic AccuPak" },
 
-    case VLC_FOURCC('R','V','1','0'):
-    case VLC_FOURCC('R','V','1','3'):
-        i_cat    = VIDEO_ES;
-        i_codec  = CODEC_ID_RV10;
-        psz_name = "Real video";
-        break;
+    /* Real Video */
+    { VLC_FOURCC('R','V','1','0'), CODEC_ID_RV10,
+      VIDEO_ES, "Real Video 10" },
+    { VLC_FOURCC('R','V','1','3'), CODEC_ID_RV10,
+      VIDEO_ES, "Real Video 13" },
 
 #if LIBAVCODEC_BUILD >= 4683
     /* Apple Video */
-    case VLC_FOURCC('r','p','z','a'):
-        i_cat    = VIDEO_ES;
-        i_codec  = CODEC_ID_RPZA;
-        psz_name = "Apple Video";
-        break;
+    { VLC_FOURCC('r','p','z','a'), CODEC_ID_RPZA,
+      VIDEO_ES, "Apple Video" },
 #endif
 
 #if LIBAVCODEC_BUILD >= 4683
     /* Cinepak */
-    case VLC_FOURCC('c','v','i','d'):
-        i_cat    = VIDEO_ES;
-        i_codec  = CODEC_ID_CINEPAK;
-        psz_name = "Cinepak";
-        break;
+    { VLC_FOURCC('c','v','i','d'), CODEC_ID_CINEPAK,
+      VIDEO_ES, "Cinepak Video" },
 #endif
 
     /*
@@ -547,150 +579,110 @@ int E_(GetFfmpegCodec)( vlc_fourcc_t i_fourcc, int *pi_cat,
      */
 
     /* Windows Media Audio 1 */
-    case VLC_FOURCC('W','M','A','1'):
-    case VLC_FOURCC('w','m','a','1'):
-        i_cat = AUDIO_ES;
-        i_codec = CODEC_ID_WMAV1;
-        psz_name ="Windows Media Audio 1";
-        break;
+    { VLC_FOURCC('W','M','A','1'), CODEC_ID_WMAV1,
+      AUDIO_ES, "Windows Media Audio 1" },
+    { VLC_FOURCC('w','m','a','1'), CODEC_ID_WMAV1,
+      AUDIO_ES, "Windows Media Audio 1" },
 
     /* Windows Media Audio 2 */
-    case VLC_FOURCC('W','M','A','2'):
-    case VLC_FOURCC('w','m','a','2'):
-        i_cat = AUDIO_ES;
-        i_codec = CODEC_ID_WMAV2;
-        psz_name ="Windows Media Audio 2";
-        break;
+    { VLC_FOURCC('W','M','A','2'), CODEC_ID_WMAV2,
+      AUDIO_ES, "Windows Media Audio 2" },
+    { VLC_FOURCC('w','m','a','2'), CODEC_ID_WMAV2,
+      AUDIO_ES, "Windows Media Audio 2" },
 
     /* DV Audio */
-    case VLC_FOURCC('d','v','a','u'):
-        i_cat = AUDIO_ES;
-        i_codec = CODEC_ID_DVAUDIO;
-        psz_name = "DV audio";
-        break;
+    { VLC_FOURCC('d','v','a','u'), CODEC_ID_DVAUDIO,
+      AUDIO_ES, "DV Audio" },
 
     /* MACE-3 Audio */
-    case VLC_FOURCC('M','A','C','3'):
-        i_cat = AUDIO_ES;
-        i_codec = CODEC_ID_MACE3;
-        psz_name = "MACE-3 audio";
-        break;
+    { VLC_FOURCC('M','A','C','3'), CODEC_ID_MACE3,
+      AUDIO_ES, "MACE-3 Audio" },
 
     /* MACE-6 Audio */
-    case VLC_FOURCC('M','A','C','6'):
-        i_cat = AUDIO_ES;
-        i_codec = CODEC_ID_MACE6;
-        psz_name = "MACE-6 audio";
-        break;
+    { VLC_FOURCC('M','A','C','6'), CODEC_ID_MACE6,
+      AUDIO_ES, "MACE-6 Audio" },
 
     /* RealAudio 1.0 */
-    case VLC_FOURCC('1','4','_','4'):
-        i_cat    = AUDIO_ES;
-        i_codec  = CODEC_ID_RA_144;
-        psz_name = "RealAudio 1.0";
-        break;
+    { VLC_FOURCC('1','4','_','4'), CODEC_ID_RA_144,
+      AUDIO_ES, "RealAudio 1.0" },
 
     /* RealAudio 2.0 */
-    case VLC_FOURCC('2','8','_','8'):
-        i_cat    = AUDIO_ES;
-        i_codec  = CODEC_ID_RA_288;
-        psz_name = "RealAudio 2.0";
-        break;
+    { VLC_FOURCC('2','8','_','8'), CODEC_ID_RA_288,
+      AUDIO_ES, "RealAudio 2.0" },
 
     /* MPEG Audio layer 1/2/3 */
-    case VLC_FOURCC('m','p','g','a'):
-        i_cat    = AUDIO_ES;
-        i_codec  = CODEC_ID_MP2;
-        psz_name = "MPEG Audio layer 1/2";
-        break;
-    case VLC_FOURCC('m','p','3',' '):
-        i_cat    = AUDIO_ES;
-        i_codec  = CODEC_ID_MP3;
-        psz_name = "MPEG Audio layer 1/2/3";
-        break;
+    { VLC_FOURCC('m','p','g','a'), CODEC_ID_MP2,
+      AUDIO_ES, "MPEG Audio layer 1/2" },
+    { VLC_FOURCC('m','p','3',' '), CODEC_ID_MP3,
+      AUDIO_ES, "MPEG Audio layer 1/2/3" },
 
     /* A52 Audio (aka AC3) */
-    case VLC_FOURCC('a','5','2',' '):
-    case VLC_FOURCC('a','5','2','b'): /* VLC specific hack */
-        i_cat    = AUDIO_ES;
-        i_codec  = CODEC_ID_AC3;
-        psz_name = "A52 Audio (aka AC3)";
-        break;
+    { VLC_FOURCC('a','5','2',' '), CODEC_ID_AC3,
+      AUDIO_ES, "A52 Audio (aka AC3)" },
+    { VLC_FOURCC('a','5','2','b'), CODEC_ID_AC3, /* VLC specific hack */
+      AUDIO_ES, "A52 Audio (aka AC3)" },
 
     /* AAC audio */
-    case VLC_FOURCC('m','p','4','a'):
-        i_cat    = AUDIO_ES;
-        i_codec  = CODEC_ID_AAC;
-        psz_name = "MPEG AAC Audio";
-        break;
-
-    default:
-        i_cat = UNKNOWN_ES;
-        i_codec = CODEC_ID_NONE;
-        psz_name = NULL;
-        break;
-    }
-
-    if( i_codec != CODEC_ID_NONE )
-    {
-        if( pi_cat ) *pi_cat = i_cat;
-        if( pi_ffmpeg_codec ) *pi_ffmpeg_codec = i_codec;
-        if( ppsz_name ) *ppsz_name = psz_name;
-        return VLC_TRUE;
-    }
+    { VLC_FOURCC('m','p','4','a'), CODEC_ID_AAC,
+      AUDIO_ES, "MPEG AAC Audio" },
+
+#if 0
+    /* PCM */
+    { VLC_FOURCC('s','8',' ',' '), CODEC_ID_PCM_S8,
+      AUDIO_ES, "PCM S8" },
+    { VLC_FOURCC('u','8',' ',' '), CODEC_ID_PCM_U8,
+      AUDIO_ES, "PCM U8" },
+    { VLC_FOURCC('s','1','6','l'), CODEC_ID_PCM_S16LE,
+      AUDIO_ES, "PCM S16 LE" },
+    { VLC_FOURCC('s','1','6','b'), CODEC_ID_PCM_S16BE,
+      AUDIO_ES, "PCM S16 BE" },
+    { VLC_FOURCC('u','1','6','l'), CODEC_ID_PCM_U16LE,
+      AUDIO_ES, "PCM U16 LE" },
+    { VLC_FOURCC('u','1','6','b'), CODEC_ID_PCM_U16BE,
+      AUDIO_ES, "PCM U16 BE" },
+    { VLC_FOURCC('a','l','a','w'), CODEC_ID_PCM_ALAW,
+      AUDIO_ES, "PCM ALAW" },
+    { VLC_FOURCC('u','l','a','w'), CODEC_ID_PCM_MULAW,
+      AUDIO_ES, "PCM ULAW" },
+#endif
 
-    return VLC_FALSE;
-}
+    {0}
+};
 
-int E_(GetFfmpegChroma)( vlc_fourcc_t i_chroma )
+int E_(GetFfmpegCodec)( vlc_fourcc_t i_fourcc, int *pi_cat,
+                        int *pi_ffmpeg_codec, char **ppsz_name )
 {
-    switch( i_chroma )
+    int i;
+
+    for( i = 0; codecs_table[i].i_fourcc != 0; i++ )
     {
-    case VLC_FOURCC( 'I', '4', '2', '0' ):
-        return PIX_FMT_YUV420P;
-    case VLC_FOURCC( 'I', '4', '2', '2' ):
-        return PIX_FMT_YUV422P;
-    case VLC_FOURCC( 'I', '4', '4', '4' ):
-        return PIX_FMT_YUV444P;
-    case VLC_FOURCC( 'R', 'V', '1', '5' ):
-        return PIX_FMT_RGB555;
-    case VLC_FOURCC( 'R', 'V', '1', '6' ):
-        return PIX_FMT_RGB565;
-    case VLC_FOURCC( 'R', 'V', '2', '4' ):
-        return PIX_FMT_RGB24;
-    case VLC_FOURCC( 'R', 'V', '3', '2' ):
-        return PIX_FMT_RGBA32;
-    case VLC_FOURCC( 'G', 'R', 'E', 'Y' ):
-        return PIX_FMT_GRAY8;
-    case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
-        return PIX_FMT_YUV422;
-    default:
-        return -1;
+        if( codecs_table[i].i_fourcc == i_fourcc )
+        {
+            if( pi_cat ) *pi_cat = codecs_table[i].i_cat;
+            if( pi_ffmpeg_codec ) *pi_ffmpeg_codec = codecs_table[i].i_codec;
+            if( ppsz_name ) *ppsz_name = codecs_table[i].psz_name;
+
+            return VLC_TRUE;
+        }
     }
+    return VLC_FALSE;
 }
 
-void E_(InitLibavcodec)( vlc_object_t *p_object )
+int E_(GetVlcFourcc)( int i_ffmpeg_codec, int *pi_cat,
+                      vlc_fourcc_t *pi_fourcc, char **ppsz_name )
 {
-    static int b_ffmpeginit = 0;
-    vlc_value_t lockval;
-
-    var_Get( p_object->p_libvlc, "avcodec", &lockval );
-    vlc_mutex_lock( lockval.p_address );
-
-    /* *** init ffmpeg library (libavcodec) *** */
-    if( !b_ffmpeginit )
-    {
-        avcodec_init();
-        avcodec_register_all();
-        b_ffmpeginit = 1;
+    int i;
 
-        msg_Dbg( p_object, "libavcodec initialized (interface %d )",
-                 LIBAVCODEC_BUILD );
-    }
-    else
+    for( i = 0; codecs_table[i].i_codec != 0; i++ )
     {
-        msg_Dbg( p_object, "libavcodec already initialized" );
+        if( codecs_table[i].i_codec == i_ffmpeg_codec )
+        {
+            if( pi_cat ) *pi_cat = codecs_table[i].i_cat;
+            if( pi_fourcc ) *pi_fourcc = codecs_table[i].i_fourcc;
+            if( ppsz_name ) *ppsz_name = codecs_table[i].psz_name;
+
+            return VLC_TRUE;
+        }
     }
-
-    vlc_mutex_unlock( lockval.p_address );
+    return VLC_FALSE;
 }
index 15f9ddc8f457e4dbf2028f2ecdfed09edc0e61f0..c7139f12cf0617c8127bf2ec0b538c4064137a34 100644 (file)
@@ -2,7 +2,7 @@
  * ffmpeg.h: decoder using the ffmpeg library
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: ffmpeg.h,v 1.30 2003/11/26 22:12:48 gbazin Exp $
+ * $Id: ffmpeg.h,v 1.31 2004/01/08 00:12:50 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -35,7 +35,8 @@ struct AVCodecContext;
 struct AVCodec;
 
 void E_(InitLibavcodec)( vlc_object_t * );
-int E_(GetFfmpegCodec)( vlc_fourcc_t, int *, int *, char ** );
+int E_(GetFfmpegCodec) ( vlc_fourcc_t, int *, int *, char ** );
+int E_(GetVlcFourcc)   ( int, int *, vlc_fourcc_t *, char ** );
 int E_(GetFfmpegChroma)( vlc_fourcc_t );
 
 /* Video decoder module */
@@ -62,6 +63,10 @@ void E_(CloseEncoder)( vlc_object_t * );
 int  E_(OpenAudioEncoder) ( vlc_object_t * );
 void E_(CloseAudioEncoder)( vlc_object_t * );
 
+/* Demux module */
+int  E_(OpenDemux) ( vlc_object_t * );
+void E_(CloseDemux)( vlc_object_t * );
+
 /* Postprocessing module */
 void *E_(OpenPostproc)( decoder_t *, vlc_bool_t * );
 int E_(InitPostproc)( decoder_t *, void *, int, int, int );
index c64dfdaf0d6bf7a0e44c310e2e626ba67baf6db2..8ba3eb19cd2a86a525c25edab641549c47a20175 100644 (file)
@@ -2,7 +2,7 @@
  * video.c: video decoder using the ffmpeg library
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: video.c,v 1.57 2003/12/02 10:55:21 gbazin Exp $
+ * $Id: video.c,v 1.58 2004/01/08 00:12:50 gbazin Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
@@ -615,8 +615,9 @@ static void ffmpeg_CopyPicture( decoder_t *p_dec,
         /* we need to convert to I420 */
         switch( p_sys->p_context->pix_fmt )
         {
-        case( PIX_FMT_YUV410P ):
-        case( PIX_FMT_YUV411P ):
+        case PIX_FMT_YUV410P:
+        case PIX_FMT_YUV411P:
+        case PIX_FMT_PAL8:
             for( i = 0; i < p_pic->i_planes; i++ )
             {
                 dest_pic.data[i] = p_pic->p[i].p_pixels;