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