]> git.sesse.net Git - vlc/blob - modules/codec/ffmpeg/ffmpeg.c
* include/vlc_common.h:
[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.54 2003/10/25 00:49:13 sam 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 #endif
62
63 #include "video.h" // video ffmpeg specific
64 #include "audio.h" // audio ffmpeg specific
65
66 /*
67  * Local prototypes
68  */
69 int             E_(OpenChroma)  ( vlc_object_t * );
70 void            E_(ffmpeg_InitLibavcodec) ( vlc_object_t *p_object );
71
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 static int      b_ffmpeginit = 0;
79
80 static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t, int *, int *, char ** );
81
82 /*****************************************************************************
83  * Module descriptor
84  *****************************************************************************/
85 #define DR_TEXT N_("Direct rendering")
86
87 #define ERROR_TEXT N_("Error resilience")
88 #define ERROR_LONGTEXT N_( \
89     "ffmpeg can make errors resiliences.          \n" \
90     "Nevertheless, with a buggy encoder (like ISO MPEG-4 encoder from M$) " \
91     "this will produce a lot of errors.\n" \
92     "Valid range is -1 to 99 (-1 disables all errors resiliences).")
93
94 #define BUGS_TEXT N_("Workaround bugs")
95 #define BUGS_LONGTEXT N_( \
96     "Try to fix some bugs\n" \
97     "1  autodetect\n" \
98     "2  old msmpeg4\n" \
99     "4  xvid interlaced\n" \
100     "8  ump4 \n" \
101     "16 no padding\n" \
102     "32 ac vlc\n" \
103     "64 Qpel chroma")
104
105 #define HURRYUP_TEXT N_("Hurry up")
106 #define HURRYUP_LONGTEXT N_( \
107     "Allow the decoder to partially decode or skip frame(s) " \
108     "when there is not enough time. It's useful with low CPU power " \
109     "but it can produce distorted pictures.")
110
111 #define TRUNC_TEXT N_("Truncated stream")
112 #define TRUNC_LONGTEXT N_("truncated stream -1:auto,0:disable,:1:enable")
113
114 #define PP_Q_TEXT N_("Post processing quality")
115 #define PP_Q_LONGTEXT N_( \
116     "Quality of post processing. Valid range is 0 to 6\n" \
117     "Higher levels require considerable more CPU power, but produce " \
118     "better looking pictures." )
119
120 #define LIBAVCODEC_PP_TEXT N_("Ffmpeg postproc filter chains")
121 /* FIXME (cut/past from ffmpeg */
122 #define LIBAVCODEC_PP_LONGTEXT \
123 "<filterName>[:<option>[:<option>...]][[,|/][-]<filterName>[:<option>...]]...\n" \
124 "long form example:\n" \
125 "vdeblock:autoq/hdeblock:autoq/linblenddeint    default,-vdeblock\n" \
126 "short form example:\n" \
127 "vb:a/hb:a/lb de,-vb\n" \
128 "more examples:\n" \
129 "tn:64:128:256\n" \
130 "Filters                        Options\n" \
131 "short  long name       short   long option     Description\n" \
132 "*      *               a       autoq           cpu power dependant enabler\n" \
133 "                       c       chrom           chrominance filtring enabled\n" \
134 "                       y       nochrom         chrominance filtring disabled\n" \
135 "hb     hdeblock        (2 Threshold)           horizontal deblocking filter\n" \
136 "       1. difference factor: default=64, higher -> more deblocking\n" \
137 "       2. flatness threshold: default=40, lower -> more deblocking\n" \
138 "                       the h & v deblocking filters share these\n" \
139 "                       so u cant set different thresholds for h / v\n" \
140 "vb     vdeblock        (2 Threshold)           vertical deblocking filter\n" \
141 "h1     x1hdeblock                              Experimental h deblock filter 1\n" \
142 "v1     x1vdeblock                              Experimental v deblock filter 1\n" \
143 "dr     dering                                  Deringing filter\n" \
144 "al     autolevels                              automatic brightness / contrast\n" \
145 "                       f       fullyrange      stretch luminance to (0..255)\n" \
146 "lb     linblenddeint                           linear blend deinterlacer\n" \
147 "li     linipoldeint                            linear interpolating deinterlace\n" \
148 "ci     cubicipoldeint                          cubic interpolating deinterlacer\n" \
149 "md     mediandeint                             median deinterlacer\n" \
150 "fd     ffmpegdeint                             ffmpeg deinterlacer\n" \
151 "de     default                                 hb:a,vb:a,dr:a,al\n" \
152 "fa     fast                                    h1:a,v1:a,dr:a,al\n" \
153 "tn     tmpnoise        (3 Thresholds)          Temporal Noise Reducer\n" \
154 "                       1. <= 2. <= 3.          larger -> stronger filtering\n" \
155 "fq     forceQuant      <quantizer>             Force quantizer\n"
156
157 vlc_module_begin();
158     add_category_hint( N_("ffmpeg"), NULL, VLC_FALSE );
159     set_capability( "decoder", 70 );
160     set_callbacks( OpenDecoder, NULL );
161     set_description( _("ffmpeg audio/video decoder((MS)MPEG4,SVQ1,H263,WMV,WMA)") );
162
163     add_bool( "ffmpeg-dr", 1, NULL, DR_TEXT, DR_TEXT, VLC_TRUE );
164     add_integer ( "ffmpeg-error-resilience", -1, NULL, ERROR_TEXT, ERROR_LONGTEXT, VLC_TRUE );
165     add_integer ( "ffmpeg-workaround-bugs", 1, NULL, BUGS_TEXT, BUGS_LONGTEXT, VLC_FALSE );
166     add_bool( "ffmpeg-hurry-up", 0, NULL, HURRYUP_TEXT, HURRYUP_LONGTEXT, VLC_FALSE );
167     add_integer( "ffmpeg-truncated", -1, NULL, TRUNC_TEXT, TRUNC_LONGTEXT, VLC_FALSE );
168
169     add_category_hint( N_("Post processing"), NULL, VLC_FALSE );
170
171     add_integer( "ffmpeg-pp-q", 0, NULL, PP_Q_TEXT, PP_Q_LONGTEXT, VLC_FALSE );
172 #ifdef LIBAVCODEC_PP
173     add_string( "ffmpeg-pp-name", "default", NULL, LIBAVCODEC_PP_TEXT, LIBAVCODEC_PP_LONGTEXT, VLC_TRUE );
174 #endif
175
176     /* chroma conversion submodule */
177     add_submodule();
178     set_capability( "chroma", 50 );
179     set_callbacks( E_(OpenChroma), NULL );
180     set_description( _("ffmpeg chroma conversion") );
181
182     var_Create( p_module->p_libvlc, "avcodec", VLC_VAR_MUTEX );
183 vlc_module_end();
184
185 /*****************************************************************************
186  * OpenDecoder: probe the decoder and return score
187  *****************************************************************************
188  * Tries to launch a decoder and return score so that the interface is able
189  * to chose.
190  *****************************************************************************/
191 static int OpenDecoder( vlc_object_t *p_this )
192 {
193     decoder_t *p_dec = (decoder_t*) p_this;
194
195     if( !ffmpeg_GetFfmpegCodec( p_dec->p_fifo->i_fourcc, NULL, NULL, NULL ) )
196     {
197         return VLC_EGENERIC;
198     }
199
200     p_dec->pf_run = RunDecoder;
201
202     return VLC_SUCCESS;
203 }
204
205 typedef union decoder_thread_u
206 {
207     generic_thread_t gen;
208     adec_thread_t    audio;
209     vdec_thread_t    video;
210
211 } decoder_thread_t;
212
213 /*****************************************************************************
214  * RunDecoder: this function is called just after the thread is created
215  *****************************************************************************/
216 static int RunDecoder( decoder_fifo_t *p_fifo )
217 {
218     generic_thread_t *p_decoder;
219     int b_error;
220
221     if ( !(p_decoder = malloc( sizeof( decoder_thread_t ) ) ) )
222     {
223         msg_Err( p_fifo, "out of memory" );
224         DecoderError( p_fifo );
225         return( -1 );
226     }
227     memset( p_decoder, 0, sizeof( decoder_thread_t ) );
228
229     p_decoder->p_fifo = p_fifo;
230
231     if( InitThread( p_decoder ) != 0 )
232     {
233         msg_Err( p_fifo, "initialization failed" );
234         DecoderError( p_fifo );
235         return( -1 );
236     }
237
238     while( (!p_decoder->p_fifo->b_die) && (!p_decoder->p_fifo->b_error) )
239     {
240         switch( p_decoder->i_cat )
241         {
242             case VIDEO_ES:
243                 E_( DecodeThread_Video )( (vdec_thread_t*)p_decoder );
244                 break;
245             case AUDIO_ES:
246                 E_( DecodeThread_Audio )( (adec_thread_t*)p_decoder );
247                 break;
248         }
249     }
250
251     if( ( b_error = p_decoder->p_fifo->b_error ) )
252     {
253         DecoderError( p_decoder->p_fifo );
254     }
255
256     EndThread( p_decoder );
257
258     if( b_error )
259     {
260         return( -1 );
261     }
262
263     return( 0 );
264 }
265
266 /*****************************************************************************
267  *
268  * Functions that initialize, decode and end the decoding process
269  *
270  *****************************************************************************/
271
272 /*****************************************************************************
273  * InitThread: initialize vdec output thread
274  *****************************************************************************
275  * This function is called from decoder_Run and performs the second step
276  * of the initialization. It returns 0 on success. Note that the thread's
277  * flag are not modified inside this function.
278  *
279  * ffmpeg codec will be open, some memory allocated. But Vout is not yet
280  *   open (done after the first decoded frame)
281  *****************************************************************************/
282
283 static int InitThread( generic_thread_t *p_decoder )
284 {
285     int i_result;
286
287     E_(ffmpeg_InitLibavcodec)(VLC_OBJECT(p_decoder->p_fifo));
288
289     /* *** determine codec type *** */
290     ffmpeg_GetFfmpegCodec( p_decoder->p_fifo->i_fourcc,
291                            &p_decoder->i_cat,
292                            &p_decoder->i_codec_id,
293                            &p_decoder->psz_namecodec );
294
295     /* *** ask ffmpeg for a decoder *** */
296     if( !( p_decoder->p_codec =
297                 avcodec_find_decoder( p_decoder->i_codec_id ) ) )
298     {
299         msg_Err( p_decoder->p_fifo,
300                  "codec not found (%s)",
301                  p_decoder->psz_namecodec );
302         return( -1 );
303     }
304
305      /* *** Get a p_context *** */
306     p_decoder->p_context = avcodec_alloc_context();
307
308     switch( p_decoder->i_cat )
309     {
310         case VIDEO_ES:
311             i_result = E_( InitThread_Video )( (vdec_thread_t*)p_decoder );
312             break;
313         case AUDIO_ES:
314             i_result = E_( InitThread_Audio )( (adec_thread_t*)p_decoder );
315             break;
316         default:
317             i_result = -1;
318     }
319
320     p_decoder->pts = 0;
321     p_decoder->p_buffer = NULL;
322     p_decoder->i_buffer = 0;
323     p_decoder->i_buffer_size = 0;
324
325     return( i_result );
326 }
327
328 /*****************************************************************************
329  * EndThread: thread destruction
330  *****************************************************************************
331  * This function is called when the thread ends after a sucessful
332  * initialization.
333  *****************************************************************************/
334 static void EndThread( generic_thread_t *p_decoder )
335 {
336
337     if( !p_decoder )
338     {
339         return;
340     }
341
342     if( p_decoder->p_context != NULL)
343     {
344         FREE( p_decoder->p_context->extradata );
345         avcodec_close( p_decoder->p_context );
346         msg_Dbg( p_decoder->p_fifo,
347                  "ffmpeg codec (%s) stopped",
348                  p_decoder->psz_namecodec );
349         free( p_decoder->p_context );
350     }
351
352     FREE( p_decoder->p_buffer );
353
354     switch( p_decoder->i_cat )
355     {
356         case AUDIO_ES:
357             E_( EndThread_Audio )( (adec_thread_t*)p_decoder );
358             break;
359         case VIDEO_ES:
360             E_( EndThread_Video )( (vdec_thread_t*)p_decoder );
361             break;
362     }
363
364     free( p_decoder );
365 }
366
367 /*****************************************************************************
368  * locales Functions
369  *****************************************************************************/
370
371 int E_( GetPESData )( uint8_t *p_buf, int i_max, pes_packet_t *p_pes )
372 {
373     int i_copy;
374     int i_count;
375
376     data_packet_t   *p_data;
377
378     i_count = 0;
379     p_data = p_pes->p_first;
380     while( p_data != NULL && i_count < i_max )
381     {
382
383         i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
384                         i_max - i_count );
385
386         if( i_copy > 0 )
387         {
388             memcpy( p_buf,
389                     p_data->p_payload_start,
390                     i_copy );
391         }
392
393         p_data = p_data->p_next;
394         i_count += i_copy;
395         p_buf   += i_copy;
396     }
397
398     if( i_count < i_max )
399     {
400         memset( p_buf, 0, i_max - i_count );
401     }
402     return( i_count );
403 }
404
405
406 static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t i_fourcc,
407                                   int *pi_cat,
408                                   int *pi_ffmpeg_codec,
409                                   char **ppsz_name )
410 {
411     int i_cat;
412     int i_codec;
413     char *psz_name;
414
415     switch( i_fourcc )
416     {
417         case FOURCC_mpgv:
418             i_cat = VIDEO_ES;
419             i_codec = CODEC_ID_MPEG1VIDEO;
420             psz_name = "MPEG-1/2 Video";
421             break;
422
423         case FOURCC_DIV1:
424         case FOURCC_div1:
425         case FOURCC_MPG4:
426         case FOURCC_mpg4:
427             i_cat = VIDEO_ES;
428             i_codec = CODEC_ID_MSMPEG4V1;
429             psz_name = "MS MPEG-4 v1";
430             break;
431
432         case FOURCC_DIV2:
433         case FOURCC_div2:
434         case FOURCC_MP42:
435         case FOURCC_mp42:
436             i_cat = VIDEO_ES;
437             i_codec = CODEC_ID_MSMPEG4V2;
438             psz_name = "MS MPEG-4 v2";
439             break;
440
441         case FOURCC_MPG3:
442         case FOURCC_mpg3:
443         case FOURCC_div3:
444         case FOURCC_MP43:
445         case FOURCC_mp43:
446         case FOURCC_DIV3:
447         case FOURCC_DIV4:
448         case FOURCC_div4:
449         case FOURCC_DIV5:
450         case FOURCC_div5:
451         case FOURCC_DIV6:
452         case FOURCC_div6:
453         case FOURCC_AP41:
454         case FOURCC_3VID:
455         case FOURCC_3vid:
456         case FOURCC_3IVD:
457         case FOURCC_3ivd:
458             i_cat = VIDEO_ES;
459             i_codec = CODEC_ID_MSMPEG4V3;
460             psz_name = "MS MPEG-4 v3";
461             break;
462
463         case FOURCC_SVQ1:
464             i_cat = VIDEO_ES;
465             i_codec = CODEC_ID_SVQ1;
466             psz_name = "SVQ-1 (Sorenson Video v1)";
467             break;
468 #if LIBAVCODEC_BUILD >= 4666
469         case FOURCC_SVQ3:
470             i_cat = VIDEO_ES;
471             i_codec = CODEC_ID_SVQ3;
472             psz_name = "SVQ-3 (Sorenson Video v3)";
473             break;
474 #endif
475
476         case FOURCC_DIVX:
477         case FOURCC_divx:
478         case FOURCC_MP4S:
479         case FOURCC_mp4s:
480         case FOURCC_M4S2:
481         case FOURCC_m4s2:
482         case FOURCC_xvid:
483         case FOURCC_XVID:
484         case FOURCC_XviD:
485         case FOURCC_DX50:
486         case FOURCC_mp4v:
487         case FOURCC_4:
488         case FOURCC_m4cc:
489         case FOURCC_M4CC:
490         /* 3iv1 is unsupported by ffmpeg
491            putting it here gives extreme distorted images
492         case FOURCC_3IV1:
493         case FOURCC_3iv1:
494         */
495         case FOURCC_3IV2:
496         case FOURCC_3iv2:
497             i_cat = VIDEO_ES;
498             i_codec = CODEC_ID_MPEG4;
499             psz_name = "MPEG-4";
500             break;
501
502 /* FIXME FOURCC_H263P exist but what fourcc ? */
503         case FOURCC_H263:
504         case FOURCC_h263:
505         case FOURCC_U263:
506             i_cat = VIDEO_ES;
507             i_codec = CODEC_ID_H263;
508             psz_name = "H263";
509             break;
510
511         case FOURCC_I263:
512         case FOURCC_i263:
513             i_cat = VIDEO_ES;
514             i_codec = CODEC_ID_H263I;
515             psz_name = "I263.I";
516             break;
517         case FOURCC_WMV1:
518             i_cat = VIDEO_ES;
519             i_codec = CODEC_ID_WMV1;
520             psz_name ="Windows Media Video 1";
521             break;
522         case FOURCC_WMV2:
523             i_cat = VIDEO_ES;
524             i_codec = CODEC_ID_WMV2;
525             psz_name ="Windows Media Video 2";
526             break;
527         case FOURCC_MJPG:
528         case FOURCC_mjpg:
529         case FOURCC_mjpa:
530         case FOURCC_jpeg:
531         case FOURCC_JPEG:
532         case FOURCC_JFIF:
533         case FOURCC_JPGL:
534             i_cat = VIDEO_ES;
535             i_codec = CODEC_ID_MJPEG;
536             psz_name = "Motion JPEG";
537             break;
538         case FOURCC_mjpb:
539             i_cat = VIDEO_ES;
540             i_codec = CODEC_ID_MJPEGB;
541             psz_name = "Motion JPEG B";
542             break;
543         case FOURCC_dvsl:
544         case FOURCC_dvsd:
545         case FOURCC_DVSD:
546         case FOURCC_dvhd:
547         case FOURCC_dvc:
548         case FOURCC_dvp:
549         case FOURCC_CDVC:
550             i_cat = VIDEO_ES;
551             i_codec = CODEC_ID_DVVIDEO;
552             psz_name = "DV video";
553             break;
554
555         case FOURCC_MAC3:
556             i_cat = AUDIO_ES;
557             i_codec = CODEC_ID_MACE3;
558             psz_name = "MACE-3 audio";
559             break;
560         case FOURCC_MAC6:
561             i_cat = AUDIO_ES;
562             i_codec = CODEC_ID_MACE6;
563             psz_name = "MACE-6 audio";
564             break;
565         case FOURCC_dvau:
566             i_cat = AUDIO_ES;
567             i_codec = CODEC_ID_DVAUDIO;
568             psz_name = "DV audio";
569             break;
570
571         case FOURCC_WMA1:
572         case FOURCC_wma1:
573             i_cat = AUDIO_ES;
574             i_codec = CODEC_ID_WMAV1;
575             psz_name ="Windows Media Audio 1";
576             break;
577         case FOURCC_WMA2:
578         case FOURCC_wma2:
579             i_cat = AUDIO_ES;
580             i_codec = CODEC_ID_WMAV2;
581             psz_name ="Windows Media Audio 2";
582             break;
583
584         case FOURCC_HFYU:
585             i_cat = VIDEO_ES;
586             i_codec = CODEC_ID_HUFFYUV;
587             psz_name ="Huff YUV";
588             break;
589
590         case FOURCC_CYUV:
591             i_cat = VIDEO_ES;
592             i_codec = CODEC_ID_CYUV;
593             psz_name ="Creative YUV";
594             break;
595
596
597 #if( ( LIBAVCODEC_BUILD >= 4663 ) && ( !defined( WORDS_BIGENDIAN ) ) )
598         /* Quality of this decoder on ppc is not good */
599         case FOURCC_IV31:
600         case FOURCC_iv31:
601         case FOURCC_IV32:
602         case FOURCC_iv32:
603             i_cat    = VIDEO_ES;
604             i_codec  = CODEC_ID_INDEO3;
605             psz_name = "Indeo v3";
606             break;
607 #endif
608
609 #if LIBAVCODEC_BUILD >= 4668
610 /* Sorta works */
611         case FOURCC_vp31:
612         case FOURCC_VP31:
613             i_cat    = VIDEO_ES;
614             i_codec  = CODEC_ID_VP3;
615             psz_name = "On2's VP3 Video";
616             break;
617
618 #if ( !defined( WORDS_BIGENDIAN ) )
619 /* Another thing that doesn't work */
620         case FOURCC_ASV1:
621             i_cat    = VIDEO_ES;
622             i_codec  = CODEC_ID_ASV1;
623             psz_name = "Asus V1";
624             break;
625 #endif
626
627         case FOURCC_FFV1:
628             i_cat    = VIDEO_ES;
629             i_codec  = CODEC_ID_FFV1;
630             psz_name = "FFMpeg Video 1";
631             break;
632
633         case FOURCC_RA10:
634             i_cat    = AUDIO_ES;
635             i_codec  = CODEC_ID_RA_144;
636             psz_name = "RealAudio 1.0";
637             break;
638
639         case FOURCC_RA20:
640             i_cat    = AUDIO_ES;
641             i_codec  = CODEC_ID_RA_288;
642             psz_name = "RealAudio 2.0";
643             break;
644 #endif
645
646 #if LIBAVCODEC_BUILD >= 4669
647         case FOURCC_FLV1:
648             i_cat    = VIDEO_ES;
649             i_codec  = CODEC_ID_FLV1;
650             psz_name = "Flash Video";
651             break;
652
653         case FOURCC_VCR1:
654             i_cat    = VIDEO_ES;
655             i_codec  = CODEC_ID_VCR1;
656             psz_name = "ATI VCR1";
657             break;
658
659 #endif
660
661 #if LIBAVCODEC_BUILD >= 4672
662         case FOURCC_CLJR:
663             i_cat    = VIDEO_ES;
664             i_codec  = CODEC_ID_CLJR;
665             psz_name = "Creative Logic AccuPak";
666             break;
667 #endif
668
669 #if LIBAVCODEC_BUILD >= 4677
670         case FOURCC_ASV2:
671             i_cat    = VIDEO_ES;
672             i_codec  = CODEC_ID_ASV2;
673             psz_name = "Asus V2";
674             break;
675 #endif
676
677 #if LIBAVCODEC_BUILD >= 4683
678         case FOURCC_rpza:
679             i_cat    = VIDEO_ES;
680             i_codec  = CODEC_ID_RPZA;
681             psz_name = "Apple Video";
682             break;
683
684         case FOURCC_cvid:
685             i_cat    = VIDEO_ES;
686             i_codec  = CODEC_ID_CINEPAK;
687             psz_name = "Cinepak";
688             break;
689
690         case FOURCC_mrle:
691         case FOURCC_1000:
692             i_cat    = VIDEO_ES;
693             i_codec  = CODEC_ID_MSRLE;
694             psz_name = "Microsoft RLE";
695             break;
696
697         case FOURCC_cram:
698         case FOURCC_CRAM:
699         case FOURCC_msvc:
700         case FOURCC_MSVC:
701         case FOURCC_wham:
702         case FOURCC_WHAM:
703             i_cat    = VIDEO_ES;
704             i_codec  = CODEC_ID_MSVIDEO1;
705             psz_name = "Microsoft Video 1";
706             break;
707 #endif
708         default:
709             i_cat = UNKNOWN_ES;
710             i_codec = CODEC_ID_NONE;
711             psz_name = NULL;
712             break;
713     }
714
715     if( i_codec != CODEC_ID_NONE )
716     {
717         if( pi_cat ) *pi_cat = i_cat;
718         if( pi_ffmpeg_codec ) *pi_ffmpeg_codec = i_codec;
719         if( ppsz_name ) *ppsz_name = psz_name;
720         return( VLC_TRUE );
721     }
722
723     return( VLC_FALSE );
724 }
725
726 void E_ (ffmpeg_InitLibavcodec) ( vlc_object_t *p_object )
727 {
728     vlc_value_t lockval;
729
730     var_Get( p_object->p_libvlc, "avcodec", &lockval );
731     vlc_mutex_lock( lockval.p_address );
732
733      /* *** init ffmpeg library (libavcodec) *** */
734     if( !b_ffmpeginit )
735     {
736         avcodec_init();
737         avcodec_register_all();
738         b_ffmpeginit = 1;
739
740         msg_Dbg( p_object, "libavcodec initialized (interface %d )",
741                  LIBAVCODEC_BUILD );
742     }
743     else
744     {
745         msg_Dbg( p_object, "libavcodec already initialized" );
746     }
747
748     vlc_mutex_unlock( lockval.p_address );
749 }