]> git.sesse.net Git - vlc/blob - modules/codec/ffmpeg/ffmpeg.c
2d3f492b314a5a05984c6f12dc58054ec08f85c7
[vlc] / modules / codec / ffmpeg / ffmpeg.c
1 /*****************************************************************************
2  * ffmpeg.c: video decoder using ffmpeg library
3  *****************************************************************************
4  * Copyright (C) 1999-2001 VideoLAN
5  * $Id: ffmpeg.c,v 1.42 2003/06/14 15:43:39 gbazin Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                      /* malloc(), free() */
28
29 #include <vlc/vlc.h>
30 #include <vlc/vout.h>
31 #include <vlc/aout.h>
32 #include <vlc/decoder.h>
33 #include <vlc/input.h>
34
35 #include <string.h>
36
37 #ifdef HAVE_SYS_TIMES_H
38 #   include <sys/times.h>
39 #endif
40
41 /* ffmpeg header */
42 #ifdef HAVE_FFMPEG_AVCODEC_H
43 #   include <ffmpeg/avcodec.h>
44 #else
45 #   include <avcodec.h>
46 #endif
47
48 #if LIBAVCODEC_BUILD < 4655
49 #   error You must have a libavcodec >= 4655 (get CVS)
50 #endif
51
52
53 #include "ffmpeg.h"
54
55 #ifdef LIBAVCODEC_PP
56 #   ifdef HAVE_POSTPROC_POSTPROCESS_H
57 #       include <postproc/postprocess.h>
58 #   else
59 #       include <libpostproc/postprocess.h>
60 #   endif
61 #else
62 #   include "postprocessing/postprocessing.h"
63 #endif
64
65 #include "video.h" // video ffmpeg specific
66 #include "audio.h" // audio ffmpeg specific
67
68 /*
69  * Local prototypes
70  */
71 int             E_(OpenChroma)  ( vlc_object_t * );
72 static int      OpenDecoder     ( vlc_object_t * );
73 static int      RunDecoder      ( decoder_fifo_t * );
74
75 static int      InitThread      ( generic_thread_t * );
76 static void     EndThread       ( generic_thread_t * );
77
78
79 static int      b_ffmpeginit = 0;
80
81 static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t, int *, int *, char ** );
82
83 /*****************************************************************************
84  * Module descriptor
85  *****************************************************************************/
86 #define DR_TEXT N_("Direct rendering")
87
88 #define ERROR_TEXT N_("Error resilience")
89 #define ERROR_LONGTEXT N_( \
90     "ffmpeg can make errors resiliences.          \n" \
91     "Nevertheless, with a buggy encoder (like ISO MPEG-4 encoder from M$) " \
92     "this will produce a lot of errors.\n" \
93     "Valid range is -1 to 99 (-1 disables all errors resiliences).")
94
95 #define BUGS_TEXT N_("Workaround bugs")
96 #define BUGS_LONGTEXT N_( \
97     "Try to fix some bugs\n" \
98     "1  autodetect\n" \
99     "2  old msmpeg4\n" \
100     "4  xvid interlaced\n" \
101     "8  ump4 \n" \
102     "16 no padding\n" \
103     "32 ac vlc\n" \
104     "64 Qpel chroma")
105
106 #define HURRYUP_TEXT N_("Hurry up")
107 #define HURRYUP_LONGTEXT N_( \
108     "Allow the decoder to partially decode or skip frame(s) " \
109     "when there is not enough time. It's useful with low CPU power " \
110     "but it can produce distorted pictures.")
111
112 #define TRUNC_TEXT N_("Truncated stream")
113 #define TRUNC_LONGTEXT N_("truncated stream -1:auto,0:disable,:1:enable")
114
115 #define PP_Q_TEXT N_("Post processing quality")
116 #define PP_Q_LONGTEXT N_( \
117     "Quality of post processing. Valid range is 0 to 6\n" \
118     "Higher levels require considerable more CPU power, but produce " \
119     "better looking pictures." )
120
121 #define LIBAVCODEC_PP_TEXT N_("Ffmpeg postproc filter chains")
122 /* FIXME (cut/past from ffmpeg */
123 #define LIBAVCODEC_PP_LONGTEXT \
124 "<filterName>[:<option>[:<option>...]][[,|/][-]<filterName>[:<option>...]]...\n" \
125 "long form example:\n" \
126 "vdeblock:autoq/hdeblock:autoq/linblenddeint    default,-vdeblock\n" \
127 "short form example:\n" \
128 "vb:a/hb:a/lb de,-vb\n" \
129 "more examples:\n" \
130 "tn:64:128:256\n" \
131 "Filters                        Options\n" \
132 "short  long name       short   long option     Description\n" \
133 "*      *               a       autoq           cpu power dependant enabler\n" \
134 "                       c       chrom           chrominance filtring enabled\n" \
135 "                       y       nochrom         chrominance filtring disabled\n" \
136 "hb     hdeblock        (2 Threshold)           horizontal deblocking filter\n" \
137 "       1. difference factor: default=64, higher -> more deblocking\n" \
138 "       2. flatness threshold: default=40, lower -> more deblocking\n" \
139 "                       the h & v deblocking filters share these\n" \
140 "                       so u cant set different thresholds for h / v\n" \
141 "vb     vdeblock        (2 Threshold)           vertical deblocking filter\n" \
142 "h1     x1hdeblock                              Experimental h deblock filter 1\n" \
143 "v1     x1vdeblock                              Experimental v deblock filter 1\n" \
144 "dr     dering                                  Deringing filter\n" \
145 "al     autolevels                              automatic brightness / contrast\n" \
146 "                       f       fullyrange      stretch luminance to (0..255)\n" \
147 "lb     linblenddeint                           linear blend deinterlacer\n" \
148 "li     linipoldeint                            linear interpolating deinterlace\n" \
149 "ci     cubicipoldeint                          cubic interpolating deinterlacer\n" \
150 "md     mediandeint                             median deinterlacer\n" \
151 "fd     ffmpegdeint                             ffmpeg deinterlacer\n" \
152 "de     default                                 hb:a,vb:a,dr:a,al\n" \
153 "fa     fast                                    h1:a,v1:a,dr:a,al\n" \
154 "tn     tmpnoise        (3 Thresholds)          Temporal Noise Reducer\n" \
155 "                       1. <= 2. <= 3.          larger -> stronger filtering\n" \
156 "fq     forceQuant      <quantizer>             Force quantizer\n"
157
158 #define FFMPEG_PP_TEXT N_( "Ffmpeg postprocessing module" )
159
160 #define PP_AQ_TEXT N_("Auto-level Post processing quality")
161 #define PP_AQ_LONGTEXT N_( \
162     "Post processing quality is selected upon time left " \
163     "but no more than requested quality\n" \
164     "Not yet implemented !")
165
166 #define FFMPEG_YV_TEXT N_("Force vertical luminance deblocking")
167 #define FFMPEG_YV_LONGTEXT N_("Force vertical luminance deblocking (override other settings)")
168
169 #define FFMPEG_YH_TEXT N_("Force horizontal luminance deblocking")
170 #define FFMPEG_YH_LONGTEXT N_("Force horizontal luminance deblocking (override other settings)")
171
172 #define FFMPEG_CV_TEXT N_("Force vertical chrominance deblocking")
173 #define FFMPEG_CV_LONGTEXT N_("Force vertical chrominance deblocking (override other settings)")
174
175 #define FFMPEG_CH_TEXT N_("Force horizontal chrominance deblocking")
176 #define FFMPEG_CH_LONGTEXT N_("Force horizontal chrominance deblocking (override other settings)")
177
178 #define FFMPEG_Y_DR_TEXT N_("Force luminance deringing")
179 #define FFMPEG_Y_DR_LONGTEXT N_("Force luminance deringing (override other settings)")
180
181 #define FFMPEG_C_DR_TEXT N_("Force chrominance deringing")
182 #define FFMPEG_C_DR_LONGTEXT N_("Force chrominance deringing (override other settings)")
183
184 vlc_module_begin();
185     add_category_hint( N_("ffmpeg"), NULL, VLC_FALSE );
186     set_capability( "decoder", 70 );
187     set_callbacks( OpenDecoder, NULL );
188     set_description( _("ffmpeg audio/video decoder((MS)MPEG4,SVQ1,H263,WMV,WMA)") );
189
190     add_bool( "ffmpeg-dr", 1, NULL, DR_TEXT, DR_TEXT, VLC_TRUE );
191     add_integer ( "ffmpeg-error-resilience", -1, NULL, ERROR_TEXT, ERROR_LONGTEXT, VLC_TRUE );
192     add_integer ( "ffmpeg-workaround-bugs", 1, NULL, BUGS_TEXT, BUGS_LONGTEXT, VLC_FALSE );
193     add_bool( "ffmpeg-hurry-up", 0, NULL, HURRYUP_TEXT, HURRYUP_LONGTEXT, VLC_FALSE );
194     add_integer( "ffmpeg-truncated", -1, NULL, TRUNC_TEXT, TRUNC_LONGTEXT, VLC_FALSE );
195
196     add_category_hint( N_("Post processing"), NULL, VLC_FALSE );
197
198     add_integer( "ffmpeg-pp-q", 0, NULL, PP_Q_TEXT, PP_Q_LONGTEXT, VLC_FALSE );
199 #ifdef LIBAVCODEC_PP
200     add_string( "ffmpeg-pp-name", "default", NULL, LIBAVCODEC_PP_TEXT, LIBAVCODEC_PP_LONGTEXT, VLC_TRUE );
201 #else
202     add_module( "ffmpeg-pp", "postprocessing",NULL, NULL, FFMPEG_PP_TEXT, NULL, VLC_FALSE );
203     add_bool( "ffmpeg-pp-auto", 0, NULL, PP_AQ_TEXT, PP_AQ_LONGTEXT, VLC_FALSE );
204     add_bool( "ffmpeg-db-yv", 0, NULL, FFMPEG_YV_TEXT, FFMPEG_YV_LONGTEXT, VLC_TRUE );
205     add_bool( "ffmpeg-db-yh", 0, NULL, FFMPEG_YH_TEXT, FFMPEG_YH_LONGTEXT, VLC_TRUE );
206     add_bool( "ffmpeg-db-cv", 0, NULL, FFMPEG_CV_TEXT, FFMPEG_CV_LONGTEXT, VLC_TRUE );
207     add_bool( "ffmpeg-db-ch", 0, NULL, FFMPEG_CH_TEXT, FFMPEG_CH_LONGTEXT, VLC_TRUE );
208     add_bool( "ffmpeg-dr-y", 0, NULL, FFMPEG_Y_DR_TEXT, FFMPEG_Y_DR_LONGTEXT, VLC_TRUE );
209     add_bool( "ffmpeg-dr-c", 0, NULL, FFMPEG_C_DR_TEXT, FFMPEG_C_DR_LONGTEXT, VLC_TRUE );
210 #endif
211
212     /* chroma conversion submodule */
213     add_submodule();
214     set_capability( "chroma", 50 );
215     set_callbacks( E_(OpenChroma), NULL );
216     set_description( _("ffmpeg chroma conversion") );
217
218 vlc_module_end();
219
220 /*****************************************************************************
221  * OpenDecoder: probe the decoder and return score
222  *****************************************************************************
223  * Tries to launch a decoder and return score so that the interface is able
224  * to chose.
225  *****************************************************************************/
226 static int OpenDecoder( vlc_object_t *p_this )
227 {
228     decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
229
230     if( ffmpeg_GetFfmpegCodec( p_fifo->i_fourcc, NULL, NULL, NULL ) )
231     {
232         p_fifo->pf_run = RunDecoder;
233         return VLC_SUCCESS;
234     }
235
236     return VLC_EGENERIC;
237 }
238
239 typedef union decoder_thread_u
240 {
241     generic_thread_t gen;
242     adec_thread_t    audio;
243     vdec_thread_t    video;
244
245 } decoder_thread_t;
246
247
248 /*****************************************************************************
249  * RunDecoder: this function is called just after the thread is created
250  *****************************************************************************/
251 static int RunDecoder( decoder_fifo_t *p_fifo )
252 {
253     generic_thread_t *p_decoder;
254     int b_error;
255
256     if ( !(p_decoder = malloc( sizeof( decoder_thread_t ) ) ) )
257     {
258         msg_Err( p_fifo, "out of memory" );
259         DecoderError( p_fifo );
260         return( -1 );
261     }
262     memset( p_decoder, 0, sizeof( decoder_thread_t ) );
263
264     p_decoder->p_fifo = p_fifo;
265
266     if( InitThread( p_decoder ) != 0 )
267     {
268         msg_Err( p_fifo, "initialization failed" );
269         DecoderError( p_fifo );
270         return( -1 );
271     }
272
273     while( (!p_decoder->p_fifo->b_die) && (!p_decoder->p_fifo->b_error) )
274     {
275         switch( p_decoder->i_cat )
276         {
277             case VIDEO_ES:
278                 E_( DecodeThread_Video )( (vdec_thread_t*)p_decoder );
279                 break;
280             case AUDIO_ES:
281                 E_( DecodeThread_Audio )( (adec_thread_t*)p_decoder );
282                 break;
283         }
284     }
285
286     if( ( b_error = p_decoder->p_fifo->b_error ) )
287     {
288         DecoderError( p_decoder->p_fifo );
289     }
290
291     EndThread( p_decoder );
292
293     if( b_error )
294     {
295         return( -1 );
296     }
297
298     return( 0 );
299 }
300
301 /*****************************************************************************
302  *
303  * Functions that initialize, decode and end the decoding process
304  *
305  *****************************************************************************/
306
307 /*****************************************************************************
308  * InitThread: initialize vdec output thread
309  *****************************************************************************
310  * This function is called from decoder_Run and performs the second step
311  * of the initialization. It returns 0 on success. Note that the thread's
312  * flag are not modified inside this function.
313  *
314  * ffmpeg codec will be open, some memory allocated. But Vout is not yet
315  *   open (done after the first decoded frame)
316  *****************************************************************************/
317
318 static int InitThread( generic_thread_t *p_decoder )
319 {
320     int i_result;
321
322      /* *** init ffmpeg library (libavcodec) *** */
323     if( !b_ffmpeginit )
324     {
325         avcodec_init();
326         avcodec_register_all();
327         b_ffmpeginit = 1;
328
329         msg_Dbg( p_decoder->p_fifo, "libavcodec initialized (interface "
330                                     LIBAVCODEC_BUILD_STR ")" );
331     }
332     else
333     {
334         msg_Dbg( p_decoder->p_fifo, "libavcodec already initialized" );
335     }
336
337     /* *** determine codec type *** */
338     ffmpeg_GetFfmpegCodec( p_decoder->p_fifo->i_fourcc,
339                            &p_decoder->i_cat,
340                            &p_decoder->i_codec_id,
341                            &p_decoder->psz_namecodec );
342
343     /* *** ask ffmpeg for a decoder *** */
344     if( !( p_decoder->p_codec =
345                 avcodec_find_decoder( p_decoder->i_codec_id ) ) )
346     {
347         msg_Err( p_decoder->p_fifo,
348                  "codec not found (%s)",
349                  p_decoder->psz_namecodec );
350         return( -1 );
351     }
352
353      /* *** Get a p_context *** */
354     p_decoder->p_context = avcodec_alloc_context();
355
356     switch( p_decoder->i_cat )
357     {
358         case VIDEO_ES:
359             i_result = E_( InitThread_Video )( (vdec_thread_t*)p_decoder );
360             break;
361         case AUDIO_ES:
362             i_result = E_( InitThread_Audio )( (adec_thread_t*)p_decoder );
363             break;
364         default:
365             i_result = -1;
366     }
367
368     p_decoder->pts = 0;
369     p_decoder->p_buffer = NULL;
370     p_decoder->i_buffer = 0;
371     p_decoder->i_buffer_size = 0;
372
373     return( i_result );
374 }
375
376 /*****************************************************************************
377  * EndThread: thread destruction
378  *****************************************************************************
379  * This function is called when the thread ends after a sucessful
380  * initialization.
381  *****************************************************************************/
382 static void EndThread( generic_thread_t *p_decoder )
383 {
384
385     if( !p_decoder )
386     {
387         return;
388     }
389
390     if( p_decoder->p_context != NULL)
391     {
392         FREE( p_decoder->p_context->extradata );
393         avcodec_close( p_decoder->p_context );
394         msg_Dbg( p_decoder->p_fifo,
395                  "ffmpeg codec (%s) stopped",
396                  p_decoder->psz_namecodec );
397         free( p_decoder->p_context );
398     }
399
400     FREE( p_decoder->p_buffer );
401
402     switch( p_decoder->i_cat )
403     {
404         case AUDIO_ES:
405             E_( EndThread_Audio )( (adec_thread_t*)p_decoder );
406             break;
407         case VIDEO_ES:
408             E_( EndThread_Video )( (vdec_thread_t*)p_decoder );
409             break;
410     }
411
412     free( p_decoder );
413 }
414
415 /*****************************************************************************
416  * locales Functions
417  *****************************************************************************/
418
419 int E_( GetPESData )( u8 *p_buf, int i_max, pes_packet_t *p_pes )
420 {
421     int i_copy;
422     int i_count;
423
424     data_packet_t   *p_data;
425
426     i_count = 0;
427     p_data = p_pes->p_first;
428     while( p_data != NULL && i_count < i_max )
429     {
430
431         i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
432                         i_max - i_count );
433
434         if( i_copy > 0 )
435         {
436             memcpy( p_buf,
437                     p_data->p_payload_start,
438                     i_copy );
439         }
440
441         p_data = p_data->p_next;
442         i_count += i_copy;
443         p_buf   += i_copy;
444     }
445
446     if( i_count < i_max )
447     {
448         memset( p_buf, 0, i_max - i_count );
449     }
450     return( i_count );
451 }
452
453
454 static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t i_fourcc,
455                                   int *pi_cat,
456                                   int *pi_ffmpeg_codec,
457                                   char **ppsz_name )
458 {
459     int i_cat;
460     int i_codec;
461     char *psz_name;
462
463     switch( i_fourcc )
464     {
465 #if 0
466         /* XXX don't use it */
467         case FOURCC_mpgv:
468             i_cat = VIDEO_ES;
469             i_codec = CODEC_ID_MPEG1VIDEO;
470             psz_name = "MPEG-1/2 Video";
471             break;
472 #endif
473         case FOURCC_DIV1:
474         case FOURCC_div1:
475         case FOURCC_MPG4:
476         case FOURCC_mpg4:
477             i_cat = VIDEO_ES;
478             i_codec = CODEC_ID_MSMPEG4V1;
479             psz_name = "MS MPEG-4 v1";
480             break;
481
482         case FOURCC_DIV2:
483         case FOURCC_div2:
484         case FOURCC_MP42:
485         case FOURCC_mp42:
486             i_cat = VIDEO_ES;
487             i_codec = CODEC_ID_MSMPEG4V2;
488             psz_name = "MS MPEG-4 v2";
489             break;
490
491         case FOURCC_MPG3:
492         case FOURCC_mpg3:
493         case FOURCC_div3:
494         case FOURCC_MP43:
495         case FOURCC_mp43:
496         case FOURCC_DIV3:
497         case FOURCC_DIV4:
498         case FOURCC_div4:
499         case FOURCC_DIV5:
500         case FOURCC_div5:
501         case FOURCC_DIV6:
502         case FOURCC_div6:
503         case FOURCC_AP41:
504         case FOURCC_3VID:
505         case FOURCC_3vid:
506         case FOURCC_3IVD:
507         case FOURCC_3ivd:
508             i_cat = VIDEO_ES;
509             i_codec = CODEC_ID_MSMPEG4V3;
510             psz_name = "MS MPEG-4 v3";
511             break;
512
513         case FOURCC_SVQ1:
514             i_cat = VIDEO_ES;
515             i_codec = CODEC_ID_SVQ1;
516             psz_name = "SVQ-1 (Sorenson Video v1)";
517             break;
518 #if LIBAVCODEC_BUILD >= 4666
519         case FOURCC_SVQ3:
520             i_cat = VIDEO_ES;
521             i_codec = CODEC_ID_SVQ3;
522             psz_name = "SVQ-3 (Sorenson Video v3)";
523             break;
524 #endif
525
526         case FOURCC_DIVX:
527         case FOURCC_divx:
528         case FOURCC_MP4S:
529         case FOURCC_mp4s:
530         case FOURCC_M4S2:
531         case FOURCC_m4s2:
532         case FOURCC_xvid:
533         case FOURCC_XVID:
534         case FOURCC_XviD:
535         case FOURCC_DX50:
536         case FOURCC_mp4v:
537         case FOURCC_4:
538         /* 3iv1 is unsupported by ffmpeg
539            putting it here gives extreme distorted images
540         case FOURCC_3IV1:
541         case FOURCC_3iv1:
542         */
543         case FOURCC_3IV2:
544         case FOURCC_3iv2:
545             i_cat = VIDEO_ES;
546             i_codec = CODEC_ID_MPEG4;
547             psz_name = "MPEG-4";
548             break;
549 /* FIXME FOURCC_H263P exist but what fourcc ? */
550         case FOURCC_H263:
551         case FOURCC_h263:
552         case FOURCC_U263:
553             i_cat = VIDEO_ES;
554             i_codec = CODEC_ID_H263;
555             psz_name = "H263";
556             break;
557
558         case FOURCC_I263:
559         case FOURCC_i263:
560             i_cat = VIDEO_ES;
561             i_codec = CODEC_ID_H263I;
562             psz_name = "I263.I";
563             break;
564         case FOURCC_WMV1:
565             i_cat = VIDEO_ES;
566             i_codec = CODEC_ID_WMV1;
567             psz_name ="Windows Media Video 1";
568             break;
569         case FOURCC_WMV2:
570         case FOURCC_MSS1:
571             i_cat = VIDEO_ES;
572             i_codec = CODEC_ID_WMV2;
573             psz_name ="Windows Media Video 2";
574             break;
575         case FOURCC_MJPG:
576         case FOURCC_mjpg:
577         case FOURCC_mjpa:
578         case FOURCC_jpeg:
579         case FOURCC_JPEG:
580         case FOURCC_JFIF:
581             i_cat = VIDEO_ES;
582             i_codec = CODEC_ID_MJPEG;
583             psz_name = "Motion JPEG";
584             break;
585         case FOURCC_mjpb:
586             i_cat = VIDEO_ES;
587             i_codec = CODEC_ID_MJPEGB;
588             psz_name = "Motion JPEG B";
589             break;
590         case FOURCC_dvsl:
591         case FOURCC_dvsd:
592         case FOURCC_DVSD:
593         case FOURCC_dvhd:
594         case FOURCC_dvc:
595         case FOURCC_dvp:
596             i_cat = VIDEO_ES;
597             i_codec = CODEC_ID_DVVIDEO;
598             psz_name = "DV video";
599             break;
600
601         case FOURCC_MAC3:
602             i_cat = AUDIO_ES;
603             i_codec = CODEC_ID_MACE3;
604             psz_name = "MACE-3 audio";
605             break;
606         case FOURCC_MAC6:
607             i_cat = AUDIO_ES;
608             i_codec = CODEC_ID_MACE6;
609             psz_name = "MACE-6 audio";
610             break;
611         case FOURCC_dvau:
612             i_cat = AUDIO_ES;
613             i_codec = CODEC_ID_DVAUDIO;
614             psz_name = "DV audio";
615             break;
616
617         case FOURCC_WMA1:
618         case FOURCC_wma1:
619             i_cat = AUDIO_ES;
620             i_codec = CODEC_ID_WMAV1;
621             psz_name ="Windows Media Audio 1";
622             break;
623         case FOURCC_WMA2:
624         case FOURCC_wma2:
625             i_cat = AUDIO_ES;
626             i_codec = CODEC_ID_WMAV2;
627             psz_name ="Windows Media Audio 2";
628             break;
629
630 #if( ( LIBAVCODEC_BUILD >= 4663 ) && ( defined( WORDS_BIGENDIAN ) ) )
631         /* Quality of this decoder on ppc is not gooed */
632         case FOURCC_IV31:
633         case FOURCC_iv31:
634         case FOURCC_IV32:
635         case FOURCC_iv32:
636             i_cat    = VIDEO_ES;
637             i_codec  = CODEC_ID_INDEO3;
638             psz_name = "Indeo v3";
639             break;
640 #endif
641
642 #if LIBAVCODEC_BUILD >= 4668
643         /* Not yet finished 
644         case FOURCC_vp31:
645         case FOURCC_VP31:
646             i_cat    = VIDEO_ES;
647             i_codec  = CODEC_ID_VP3;
648             psz_name = "On2's VP3 Video";
649             break;
650
651         case FOURCC_asv1:
652         case FOURCC_ASV1:
653             i_cat    = VIDEO_ES;
654             i_codec  = CODEC_ID_ASV1;
655             psz_name = "Asus V1";
656             break;*/
657 #endif
658
659         default:
660             i_cat = UNKNOWN_ES;
661             i_codec = CODEC_ID_NONE;
662             psz_name = NULL;
663             break;
664     }
665
666     if( i_codec != CODEC_ID_NONE )
667     {
668         if( pi_cat ) *pi_cat = i_cat;
669         if( pi_ffmpeg_codec ) *pi_ffmpeg_codec = i_codec;
670         if( ppsz_name ) *ppsz_name = psz_name;
671         return( VLC_TRUE );
672     }
673
674     return( VLC_FALSE );
675 }
676
677
678