1 /*****************************************************************************
2 * ffmpeg.c: video decoder using ffmpeg library
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN
5 * $Id: ffmpeg.c,v 1.47 2003/08/08 17:08:32 gbazin 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 static int OpenDecoder ( vlc_object_t * );
71 static int RunDecoder ( decoder_fifo_t * );
73 static int InitThread ( generic_thread_t * );
74 static void EndThread ( generic_thread_t * );
77 static int b_ffmpeginit = 0;
79 static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t, int *, int *, char ** );
81 /*****************************************************************************
83 *****************************************************************************/
84 #define DR_TEXT N_("Direct rendering")
86 #define ERROR_TEXT N_("Error resilience")
87 #define ERROR_LONGTEXT N_( \
88 "ffmpeg can make errors resiliences. \n" \
89 "Nevertheless, with a buggy encoder (like ISO MPEG-4 encoder from M$) " \
90 "this will produce a lot of errors.\n" \
91 "Valid range is -1 to 99 (-1 disables all errors resiliences).")
93 #define BUGS_TEXT N_("Workaround bugs")
94 #define BUGS_LONGTEXT N_( \
95 "Try to fix some bugs\n" \
98 "4 xvid interlaced\n" \
104 #define HURRYUP_TEXT N_("Hurry up")
105 #define HURRYUP_LONGTEXT N_( \
106 "Allow the decoder to partially decode or skip frame(s) " \
107 "when there is not enough time. It's useful with low CPU power " \
108 "but it can produce distorted pictures.")
110 #define TRUNC_TEXT N_("Truncated stream")
111 #define TRUNC_LONGTEXT N_("truncated stream -1:auto,0:disable,:1:enable")
113 #define PP_Q_TEXT N_("Post processing quality")
114 #define PP_Q_LONGTEXT N_( \
115 "Quality of post processing. Valid range is 0 to 6\n" \
116 "Higher levels require considerable more CPU power, but produce " \
117 "better looking pictures." )
119 #define LIBAVCODEC_PP_TEXT N_("Ffmpeg postproc filter chains")
120 /* FIXME (cut/past from ffmpeg */
121 #define LIBAVCODEC_PP_LONGTEXT \
122 "<filterName>[:<option>[:<option>...]][[,|/][-]<filterName>[:<option>...]]...\n" \
123 "long form example:\n" \
124 "vdeblock:autoq/hdeblock:autoq/linblenddeint default,-vdeblock\n" \
125 "short form example:\n" \
126 "vb:a/hb:a/lb de,-vb\n" \
129 "Filters Options\n" \
130 "short long name short long option Description\n" \
131 "* * a autoq cpu power dependant enabler\n" \
132 " c chrom chrominance filtring enabled\n" \
133 " y nochrom chrominance filtring disabled\n" \
134 "hb hdeblock (2 Threshold) horizontal deblocking filter\n" \
135 " 1. difference factor: default=64, higher -> more deblocking\n" \
136 " 2. flatness threshold: default=40, lower -> more deblocking\n" \
137 " the h & v deblocking filters share these\n" \
138 " so u cant set different thresholds for h / v\n" \
139 "vb vdeblock (2 Threshold) vertical deblocking filter\n" \
140 "h1 x1hdeblock Experimental h deblock filter 1\n" \
141 "v1 x1vdeblock Experimental v deblock filter 1\n" \
142 "dr dering Deringing filter\n" \
143 "al autolevels automatic brightness / contrast\n" \
144 " f fullyrange stretch luminance to (0..255)\n" \
145 "lb linblenddeint linear blend deinterlacer\n" \
146 "li linipoldeint linear interpolating deinterlace\n" \
147 "ci cubicipoldeint cubic interpolating deinterlacer\n" \
148 "md mediandeint median deinterlacer\n" \
149 "fd ffmpegdeint ffmpeg deinterlacer\n" \
150 "de default hb:a,vb:a,dr:a,al\n" \
151 "fa fast h1:a,v1:a,dr:a,al\n" \
152 "tn tmpnoise (3 Thresholds) Temporal Noise Reducer\n" \
153 " 1. <= 2. <= 3. larger -> stronger filtering\n" \
154 "fq forceQuant <quantizer> Force quantizer\n"
157 add_category_hint( N_("ffmpeg"), NULL, VLC_FALSE );
158 set_capability( "decoder", 70 );
159 set_callbacks( OpenDecoder, NULL );
160 set_description( _("ffmpeg audio/video decoder((MS)MPEG4,SVQ1,H263,WMV,WMA)") );
162 add_bool( "ffmpeg-dr", 1, NULL, DR_TEXT, DR_TEXT, VLC_TRUE );
163 add_integer ( "ffmpeg-error-resilience", -1, NULL, ERROR_TEXT, ERROR_LONGTEXT, VLC_TRUE );
164 add_integer ( "ffmpeg-workaround-bugs", 1, NULL, BUGS_TEXT, BUGS_LONGTEXT, VLC_FALSE );
165 add_bool( "ffmpeg-hurry-up", 0, NULL, HURRYUP_TEXT, HURRYUP_LONGTEXT, VLC_FALSE );
166 add_integer( "ffmpeg-truncated", -1, NULL, TRUNC_TEXT, TRUNC_LONGTEXT, VLC_FALSE );
168 add_category_hint( N_("Post processing"), NULL, VLC_FALSE );
170 add_integer( "ffmpeg-pp-q", 0, NULL, PP_Q_TEXT, PP_Q_LONGTEXT, VLC_FALSE );
172 add_string( "ffmpeg-pp-name", "default", NULL, LIBAVCODEC_PP_TEXT, LIBAVCODEC_PP_LONGTEXT, VLC_TRUE );
175 /* chroma conversion submodule */
177 set_capability( "chroma", 50 );
178 set_callbacks( E_(OpenChroma), NULL );
179 set_description( _("ffmpeg chroma conversion") );
181 var_Create( p_module->p_libvlc, "avcodec", VLC_VAR_MUTEX );
184 /*****************************************************************************
185 * OpenDecoder: probe the decoder and return score
186 *****************************************************************************
187 * Tries to launch a decoder and return score so that the interface is able
189 *****************************************************************************/
190 static int OpenDecoder( vlc_object_t *p_this )
192 decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
194 if( ffmpeg_GetFfmpegCodec( p_fifo->i_fourcc, NULL, NULL, NULL ) )
196 p_fifo->pf_run = RunDecoder;
203 typedef union decoder_thread_u
205 generic_thread_t gen;
212 /*****************************************************************************
213 * RunDecoder: this function is called just after the thread is created
214 *****************************************************************************/
215 static int RunDecoder( decoder_fifo_t *p_fifo )
217 generic_thread_t *p_decoder;
220 if ( !(p_decoder = malloc( sizeof( decoder_thread_t ) ) ) )
222 msg_Err( p_fifo, "out of memory" );
223 DecoderError( p_fifo );
226 memset( p_decoder, 0, sizeof( decoder_thread_t ) );
228 p_decoder->p_fifo = p_fifo;
230 if( InitThread( p_decoder ) != 0 )
232 msg_Err( p_fifo, "initialization failed" );
233 DecoderError( p_fifo );
237 while( (!p_decoder->p_fifo->b_die) && (!p_decoder->p_fifo->b_error) )
239 switch( p_decoder->i_cat )
242 E_( DecodeThread_Video )( (vdec_thread_t*)p_decoder );
245 E_( DecodeThread_Audio )( (adec_thread_t*)p_decoder );
250 if( ( b_error = p_decoder->p_fifo->b_error ) )
252 DecoderError( p_decoder->p_fifo );
255 EndThread( p_decoder );
265 /*****************************************************************************
267 * Functions that initialize, decode and end the decoding process
269 *****************************************************************************/
271 /*****************************************************************************
272 * InitThread: initialize vdec output thread
273 *****************************************************************************
274 * This function is called from decoder_Run and performs the second step
275 * of the initialization. It returns 0 on success. Note that the thread's
276 * flag are not modified inside this function.
278 * ffmpeg codec will be open, some memory allocated. But Vout is not yet
279 * open (done after the first decoded frame)
280 *****************************************************************************/
282 static int InitThread( generic_thread_t *p_decoder )
288 var_Get( p_decoder->p_fifo->p_libvlc, "avcodec", &lockval );
289 vlc_mutex_lock( lockval.p_address );
291 /* *** init ffmpeg library (libavcodec) *** */
296 avcodec_register_all();
299 msg_Dbg( p_decoder->p_fifo, "libavcodec initialized (interface "
300 LIBAVCODEC_BUILD_STR ")" );
304 msg_Dbg( p_decoder->p_fifo, "libavcodec already initialized" );
306 vlc_mutex_unlock( lockval.p_address );
308 /* *** determine codec type *** */
309 ffmpeg_GetFfmpegCodec( p_decoder->p_fifo->i_fourcc,
311 &p_decoder->i_codec_id,
312 &p_decoder->psz_namecodec );
314 /* *** ask ffmpeg for a decoder *** */
315 if( !( p_decoder->p_codec =
316 avcodec_find_decoder( p_decoder->i_codec_id ) ) )
318 msg_Err( p_decoder->p_fifo,
319 "codec not found (%s)",
320 p_decoder->psz_namecodec );
324 /* *** Get a p_context *** */
325 p_decoder->p_context = avcodec_alloc_context();
327 switch( p_decoder->i_cat )
330 i_result = E_( InitThread_Video )( (vdec_thread_t*)p_decoder );
333 i_result = E_( InitThread_Audio )( (adec_thread_t*)p_decoder );
340 p_decoder->p_buffer = NULL;
341 p_decoder->i_buffer = 0;
342 p_decoder->i_buffer_size = 0;
347 /*****************************************************************************
348 * EndThread: thread destruction
349 *****************************************************************************
350 * This function is called when the thread ends after a sucessful
352 *****************************************************************************/
353 static void EndThread( generic_thread_t *p_decoder )
361 if( p_decoder->p_context != NULL)
363 FREE( p_decoder->p_context->extradata );
364 avcodec_close( p_decoder->p_context );
365 msg_Dbg( p_decoder->p_fifo,
366 "ffmpeg codec (%s) stopped",
367 p_decoder->psz_namecodec );
368 free( p_decoder->p_context );
371 FREE( p_decoder->p_buffer );
373 switch( p_decoder->i_cat )
376 E_( EndThread_Audio )( (adec_thread_t*)p_decoder );
379 E_( EndThread_Video )( (vdec_thread_t*)p_decoder );
386 /*****************************************************************************
388 *****************************************************************************/
390 int E_( GetPESData )( u8 *p_buf, int i_max, pes_packet_t *p_pes )
395 data_packet_t *p_data;
398 p_data = p_pes->p_first;
399 while( p_data != NULL && i_count < i_max )
402 i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
408 p_data->p_payload_start,
412 p_data = p_data->p_next;
417 if( i_count < i_max )
419 memset( p_buf, 0, i_max - i_count );
425 static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t i_fourcc,
427 int *pi_ffmpeg_codec,
438 i_codec = CODEC_ID_MPEG1VIDEO;
439 psz_name = "MPEG-1/2 Video";
447 i_codec = CODEC_ID_MSMPEG4V1;
448 psz_name = "MS MPEG-4 v1";
456 i_codec = CODEC_ID_MSMPEG4V2;
457 psz_name = "MS MPEG-4 v2";
478 i_codec = CODEC_ID_MSMPEG4V3;
479 psz_name = "MS MPEG-4 v3";
484 i_codec = CODEC_ID_SVQ1;
485 psz_name = "SVQ-1 (Sorenson Video v1)";
487 #if LIBAVCODEC_BUILD >= 4666
490 i_codec = CODEC_ID_SVQ3;
491 psz_name = "SVQ-3 (Sorenson Video v3)";
507 /* 3iv1 is unsupported by ffmpeg
508 putting it here gives extreme distorted images
515 i_codec = CODEC_ID_MPEG4;
518 /* FIXME FOURCC_H263P exist but what fourcc ? */
523 i_codec = CODEC_ID_H263;
530 i_codec = CODEC_ID_H263I;
535 i_codec = CODEC_ID_WMV1;
536 psz_name ="Windows Media Video 1";
541 i_codec = CODEC_ID_WMV2;
542 psz_name ="Windows Media Video 2";
551 i_codec = CODEC_ID_MJPEG;
552 psz_name = "Motion JPEG";
556 i_codec = CODEC_ID_MJPEGB;
557 psz_name = "Motion JPEG B";
567 i_codec = CODEC_ID_DVVIDEO;
568 psz_name = "DV video";
573 i_codec = CODEC_ID_MACE3;
574 psz_name = "MACE-3 audio";
578 i_codec = CODEC_ID_MACE6;
579 psz_name = "MACE-6 audio";
583 i_codec = CODEC_ID_DVAUDIO;
584 psz_name = "DV audio";
590 i_codec = CODEC_ID_WMAV1;
591 psz_name ="Windows Media Audio 1";
596 i_codec = CODEC_ID_WMAV2;
597 psz_name ="Windows Media Audio 2";
600 #if( ( LIBAVCODEC_BUILD >= 4663 ) && ( !defined( WORDS_BIGENDIAN ) ) )
601 /* Quality of this decoder on ppc is not good */
607 i_codec = CODEC_ID_INDEO3;
608 psz_name = "Indeo v3";
612 #if LIBAVCODEC_BUILD >= 4668
617 i_codec = CODEC_ID_VP3;
618 psz_name = "On2's VP3 Video";
624 i_codec = CODEC_ID_ASV1;
625 psz_name = "Asus V1";
631 i_codec = CODEC_ID_NONE;
636 if( i_codec != CODEC_ID_NONE )
638 if( pi_cat ) *pi_cat = i_cat;
639 if( pi_ffmpeg_codec ) *pi_ffmpeg_codec = i_codec;
640 if( ppsz_name ) *ppsz_name = psz_name;