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