1 /*****************************************************************************
2 * ffmpeg.c: video decoder using ffmpeg library
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN
5 * $Id: ffmpeg.c,v 1.53 2003/10/02 18:07:26 hartman Exp $
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
32 #include <vlc/decoder.h>
33 #include <vlc/input.h>
37 #ifdef HAVE_SYS_TIMES_H
38 # include <sys/times.h>
42 #ifdef HAVE_FFMPEG_AVCODEC_H
43 # include <ffmpeg/avcodec.h>
48 #if LIBAVCODEC_BUILD < 4655
49 # error You must have a libavcodec >= 4655 (get CVS)
56 # ifdef HAVE_POSTPROC_POSTPROCESS_H
57 # include <postproc/postprocess.h>
59 # include <libpostproc/postprocess.h>
63 #include "video.h" // video ffmpeg specific
64 #include "audio.h" // audio ffmpeg specific
69 int E_(OpenChroma) ( vlc_object_t * );
70 void E_(ffmpeg_InitLibavcodec) ( vlc_object_t *p_object );
72 static int OpenDecoder ( vlc_object_t * );
73 static int RunDecoder ( decoder_fifo_t * );
75 static int InitThread ( generic_thread_t * );
76 static void EndThread ( generic_thread_t * );
78 static int b_ffmpeginit = 0;
80 static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t, int *, int *, char ** );
82 /*****************************************************************************
84 *****************************************************************************/
85 #define DR_TEXT N_("Direct rendering")
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).")
94 #define BUGS_TEXT N_("Workaround bugs")
95 #define BUGS_LONGTEXT N_( \
96 "Try to fix some bugs\n" \
99 "4 xvid interlaced\n" \
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.")
111 #define TRUNC_TEXT N_("Truncated stream")
112 #define TRUNC_LONGTEXT N_("truncated stream -1:auto,0:disable,:1:enable")
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." )
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" \
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"
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)") );
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 );
169 add_category_hint( N_("Post processing"), NULL, VLC_FALSE );
171 add_integer( "ffmpeg-pp-q", 0, NULL, PP_Q_TEXT, PP_Q_LONGTEXT, VLC_FALSE );
173 add_string( "ffmpeg-pp-name", "default", NULL, LIBAVCODEC_PP_TEXT, LIBAVCODEC_PP_LONGTEXT, VLC_TRUE );
176 /* chroma conversion submodule */
178 set_capability( "chroma", 50 );
179 set_callbacks( E_(OpenChroma), NULL );
180 set_description( _("ffmpeg chroma conversion") );
182 var_Create( p_module->p_libvlc, "avcodec", VLC_VAR_MUTEX );
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
190 *****************************************************************************/
191 static int OpenDecoder( vlc_object_t *p_this )
193 decoder_t *p_dec = (decoder_t*) p_this;
195 if( !ffmpeg_GetFfmpegCodec( p_dec->p_fifo->i_fourcc, NULL, NULL, NULL ) )
200 p_dec->pf_run = RunDecoder;
205 typedef union decoder_thread_u
207 generic_thread_t gen;
213 /*****************************************************************************
214 * RunDecoder: this function is called just after the thread is created
215 *****************************************************************************/
216 static int RunDecoder( decoder_fifo_t *p_fifo )
218 generic_thread_t *p_decoder;
221 if ( !(p_decoder = malloc( sizeof( decoder_thread_t ) ) ) )
223 msg_Err( p_fifo, "out of memory" );
224 DecoderError( p_fifo );
227 memset( p_decoder, 0, sizeof( decoder_thread_t ) );
229 p_decoder->p_fifo = p_fifo;
231 if( InitThread( p_decoder ) != 0 )
233 msg_Err( p_fifo, "initialization failed" );
234 DecoderError( p_fifo );
238 while( (!p_decoder->p_fifo->b_die) && (!p_decoder->p_fifo->b_error) )
240 switch( p_decoder->i_cat )
243 E_( DecodeThread_Video )( (vdec_thread_t*)p_decoder );
246 E_( DecodeThread_Audio )( (adec_thread_t*)p_decoder );
251 if( ( b_error = p_decoder->p_fifo->b_error ) )
253 DecoderError( p_decoder->p_fifo );
256 EndThread( p_decoder );
266 /*****************************************************************************
268 * Functions that initialize, decode and end the decoding process
270 *****************************************************************************/
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.
279 * ffmpeg codec will be open, some memory allocated. But Vout is not yet
280 * open (done after the first decoded frame)
281 *****************************************************************************/
283 static int InitThread( generic_thread_t *p_decoder )
287 E_(ffmpeg_InitLibavcodec)(VLC_OBJECT(p_decoder->p_fifo));
289 /* *** determine codec type *** */
290 ffmpeg_GetFfmpegCodec( p_decoder->p_fifo->i_fourcc,
292 &p_decoder->i_codec_id,
293 &p_decoder->psz_namecodec );
295 /* *** ask ffmpeg for a decoder *** */
296 if( !( p_decoder->p_codec =
297 avcodec_find_decoder( p_decoder->i_codec_id ) ) )
299 msg_Err( p_decoder->p_fifo,
300 "codec not found (%s)",
301 p_decoder->psz_namecodec );
305 /* *** Get a p_context *** */
306 p_decoder->p_context = avcodec_alloc_context();
308 switch( p_decoder->i_cat )
311 i_result = E_( InitThread_Video )( (vdec_thread_t*)p_decoder );
314 i_result = E_( InitThread_Audio )( (adec_thread_t*)p_decoder );
321 p_decoder->p_buffer = NULL;
322 p_decoder->i_buffer = 0;
323 p_decoder->i_buffer_size = 0;
328 /*****************************************************************************
329 * EndThread: thread destruction
330 *****************************************************************************
331 * This function is called when the thread ends after a sucessful
333 *****************************************************************************/
334 static void EndThread( generic_thread_t *p_decoder )
342 if( p_decoder->p_context != NULL)
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 );
352 FREE( p_decoder->p_buffer );
354 switch( p_decoder->i_cat )
357 E_( EndThread_Audio )( (adec_thread_t*)p_decoder );
360 E_( EndThread_Video )( (vdec_thread_t*)p_decoder );
367 /*****************************************************************************
369 *****************************************************************************/
371 int E_( GetPESData )( u8 *p_buf, int i_max, pes_packet_t *p_pes )
376 data_packet_t *p_data;
379 p_data = p_pes->p_first;
380 while( p_data != NULL && i_count < i_max )
383 i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
389 p_data->p_payload_start,
393 p_data = p_data->p_next;
398 if( i_count < i_max )
400 memset( p_buf, 0, i_max - i_count );
406 static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t i_fourcc,
408 int *pi_ffmpeg_codec,
419 i_codec = CODEC_ID_MPEG1VIDEO;
420 psz_name = "MPEG-1/2 Video";
428 i_codec = CODEC_ID_MSMPEG4V1;
429 psz_name = "MS MPEG-4 v1";
437 i_codec = CODEC_ID_MSMPEG4V2;
438 psz_name = "MS MPEG-4 v2";
459 i_codec = CODEC_ID_MSMPEG4V3;
460 psz_name = "MS MPEG-4 v3";
465 i_codec = CODEC_ID_SVQ1;
466 psz_name = "SVQ-1 (Sorenson Video v1)";
468 #if LIBAVCODEC_BUILD >= 4666
471 i_codec = CODEC_ID_SVQ3;
472 psz_name = "SVQ-3 (Sorenson Video v3)";
490 /* 3iv1 is unsupported by ffmpeg
491 putting it here gives extreme distorted images
498 i_codec = CODEC_ID_MPEG4;
502 /* FIXME FOURCC_H263P exist but what fourcc ? */
507 i_codec = CODEC_ID_H263;
514 i_codec = CODEC_ID_H263I;
519 i_codec = CODEC_ID_WMV1;
520 psz_name ="Windows Media Video 1";
524 i_codec = CODEC_ID_WMV2;
525 psz_name ="Windows Media Video 2";
535 i_codec = CODEC_ID_MJPEG;
536 psz_name = "Motion JPEG";
540 i_codec = CODEC_ID_MJPEGB;
541 psz_name = "Motion JPEG B";
551 i_codec = CODEC_ID_DVVIDEO;
552 psz_name = "DV video";
557 i_codec = CODEC_ID_MACE3;
558 psz_name = "MACE-3 audio";
562 i_codec = CODEC_ID_MACE6;
563 psz_name = "MACE-6 audio";
567 i_codec = CODEC_ID_DVAUDIO;
568 psz_name = "DV audio";
574 i_codec = CODEC_ID_WMAV1;
575 psz_name ="Windows Media Audio 1";
580 i_codec = CODEC_ID_WMAV2;
581 psz_name ="Windows Media Audio 2";
586 i_codec = CODEC_ID_HUFFYUV;
587 psz_name ="Huff YUV";
592 i_codec = CODEC_ID_CYUV;
593 psz_name ="Creative YUV";
597 #if( ( LIBAVCODEC_BUILD >= 4663 ) && ( !defined( WORDS_BIGENDIAN ) ) )
598 /* Quality of this decoder on ppc is not good */
604 i_codec = CODEC_ID_INDEO3;
605 psz_name = "Indeo v3";
609 #if LIBAVCODEC_BUILD >= 4668
614 i_codec = CODEC_ID_VP3;
615 psz_name = "On2's VP3 Video";
618 #if ( !defined( WORDS_BIGENDIAN ) )
619 /* Another thing that doesn't work */
622 i_codec = CODEC_ID_ASV1;
623 psz_name = "Asus V1";
629 i_codec = CODEC_ID_FFV1;
630 psz_name = "FFMpeg Video 1";
635 i_codec = CODEC_ID_RA_144;
636 psz_name = "RealAudio 1.0";
641 i_codec = CODEC_ID_RA_288;
642 psz_name = "RealAudio 2.0";
646 #if LIBAVCODEC_BUILD >= 4669
649 i_codec = CODEC_ID_FLV1;
650 psz_name = "Flash Video";
655 i_codec = CODEC_ID_VCR1;
656 psz_name = "ATI VCR1";
661 #if LIBAVCODEC_BUILD >= 4672
664 i_codec = CODEC_ID_CLJR;
665 psz_name = "Creative Logic AccuPak";
669 #if LIBAVCODEC_BUILD >= 4677
672 i_codec = CODEC_ID_ASV2;
673 psz_name = "Asus V2";
677 #if LIBAVCODEC_BUILD >= 4683
680 i_codec = CODEC_ID_RPZA;
681 psz_name = "Apple Video";
686 i_codec = CODEC_ID_CINEPAK;
687 psz_name = "Cinepak";
693 i_codec = CODEC_ID_MSRLE;
694 psz_name = "Microsoft RLE";
704 i_codec = CODEC_ID_MSVIDEO1;
705 psz_name = "Microsoft Video 1";
710 i_codec = CODEC_ID_NONE;
715 if( i_codec != CODEC_ID_NONE )
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;
726 void E_ (ffmpeg_InitLibavcodec) ( vlc_object_t *p_object )
730 var_Get( p_object->p_libvlc, "avcodec", &lockval );
731 vlc_mutex_lock( lockval.p_address );
733 /* *** init ffmpeg library (libavcodec) *** */
737 avcodec_register_all();
740 msg_Dbg( p_object, "libavcodec initialized (interface %d )",
745 msg_Dbg( p_object, "libavcodec already initialized" );
748 vlc_mutex_unlock( lockval.p_address );