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