1 /*****************************************************************************
2 * ffmpeg.c: video decoder using ffmpeg library
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN
5 * $Id: ffmpeg.c,v 1.35 2003/05/07 15:44:59 fenrir 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>
62 # include "postprocessing/postprocessing.h"
65 #include "video.h" // video ffmpeg specific
66 #include "audio.h" // audio ffmpeg specific
71 int E_(OpenChroma) ( vlc_object_t * );
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 * );
79 static int b_ffmpeginit = 0;
81 static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t, int *, int *, char ** );
83 /*****************************************************************************
85 *****************************************************************************/
87 #define ERROR_RESILIENCE_LONGTEXT \
88 "ffmpeg can make errors resiliences. \n" \
89 "Nevertheless, with 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 disable all errors resiliences)."
93 #define HURRY_UP_LONGTEXT \
94 "Allow the decoder to partially decode or skip frame(s) " \
95 "when there not enough time.\n It's usefull with low CPU power " \
96 "but it could produce broken pictures."
98 #define POSTPROCESSING_Q_LONGTEXT \
99 "Quality of post processing\n"\
100 "Valid range is 0 to 6"
102 #define POSTPROCESSING_AQ_LONGTEXT \
103 "Post processing quality is selected upon time left " \
104 "but no more than requested quality\n" \
105 "Not yet implemented !"
107 #define WORKAROUND_BUGS_LONGTEXT \
108 "Try to fix some bugs\n" \
111 "4 xvid interlaced\n" \
117 /* FIXME (cut/past from ffmpeg */
118 #define LIBAVCODEC_PP_LONGHELP \
119 "<filterName>[:<option>[:<option>...]][[,|/][-]<filterName>[:<option>...]]...\n" \
120 "long form example:\n" \
121 "vdeblock:autoq/hdeblock:autoq/linblenddeint default,-vdeblock\n" \
122 "short form example:\n" \
123 "vb:a/hb:a/lb de,-vb\n" \
126 "Filters Options\n" \
127 "short long name short long option Description\n" \
128 "* * a autoq cpu power dependant enabler\n" \
129 " c chrom chrominance filtring enabled\n" \
130 " y nochrom chrominance filtring disabled\n" \
131 "hb hdeblock (2 Threshold) horizontal deblocking filter\n" \
132 " 1. difference factor: default=64, higher -> more deblocking\n" \
133 " 2. flatness threshold: default=40, lower -> more deblocking\n" \
134 " the h & v deblocking filters share these\n" \
135 " so u cant set different thresholds for h / v\n" \
136 "vb vdeblock (2 Threshold) vertical deblocking filter\n" \
137 "h1 x1hdeblock Experimental h deblock filter 1\n" \
138 "v1 x1vdeblock Experimental v deblock filter 1\n" \
139 "dr dering Deringing filter\n" \
140 "al autolevels automatic brightness / contrast\n" \
141 " f fullyrange stretch luminance to (0..255)\n" \
142 "lb linblenddeint linear blend deinterlacer\n" \
143 "li linipoldeint linear interpolating deinterlace\n" \
144 "ci cubicipoldeint cubic interpolating deinterlacer\n" \
145 "md mediandeint median deinterlacer\n" \
146 "fd ffmpegdeint ffmpeg deinterlacer\n" \
147 "de default hb:a,vb:a,dr:a,al\n" \
148 "fa fast h1:a,v1:a,dr:a,al\n" \
149 "tn tmpnoise (3 Thresholds) Temporal Noise Reducer\n" \
150 " 1. <= 2. <= 3. larger -> stronger filtering\n" \
151 "fq forceQuant <quantizer> Force quantizer\n"
154 add_category_hint( N_("ffmpeg"), NULL, VLC_FALSE );
155 set_capability( "decoder", 70 );
156 set_callbacks( OpenDecoder, NULL );
157 set_description( _("ffmpeg audio/video decoder((MS)MPEG4,SVQ1,H263,WMV,WMA)") );
159 add_bool( "ffmpeg-dr", 0, NULL,
161 "direct rendering", VLC_TRUE );
162 add_integer ( "ffmpeg-error-resilience", -1, NULL,
163 "error resilience", ERROR_RESILIENCE_LONGTEXT, VLC_TRUE );
164 add_integer ( "ffmpeg-workaround-bugs", 1, NULL,
165 "workaround bugs", WORKAROUND_BUGS_LONGTEXT, VLC_FALSE );
166 add_bool( "ffmpeg-hurry-up", 0, NULL, "hurry up", HURRY_UP_LONGTEXT, VLC_FALSE );
167 add_integer( "ffmpeg-truncated", -1, NULL, "truncated stream", "truncated stream -1:auto,0:disable,:1:enable", VLC_FALSE );
168 add_category_hint( N_("Post processing"), NULL, VLC_FALSE );
170 add_integer( "ffmpeg-pp-q", 0, NULL,
171 "post processing quality", POSTPROCESSING_Q_LONGTEXT, VLC_FALSE );
173 add_string( "ffmpeg-pp-name", "default", NULL,
174 "ffmpeg postproc filter chains", LIBAVCODEC_PP_LONGHELP, VLC_TRUE );
176 add_module( "ffmpeg-pp", "postprocessing",NULL, NULL,
177 N_( "ffmpeg postprocessing module" ), NULL, VLC_FALSE );
178 add_bool( "ffmpeg-pp-auto", 0, NULL,
179 "auto-level Post processing quality", POSTPROCESSING_AQ_LONGTEXT, VLC_FALSE );
180 add_bool( "ffmpeg-db-yv", 0, NULL,
181 "force vertical luminance deblocking",
182 "force vertical luminance deblocking (override other settings)", VLC_TRUE );
183 add_bool( "ffmpeg-db-yh", 0, NULL,
184 "force horizontal luminance deblocking",
185 "force horizontal luminance deblocking (override other settings)", VLC_TRUE );
186 add_bool( "ffmpeg-db-cv", 0, NULL,
187 "force vertical chrominance deblocking",
188 "force vertical chrominance deblocking (override other settings)", VLC_TRUE );
189 add_bool( "ffmpeg-db-ch", 0, NULL,
190 "force horizontal chrominance deblocking",
191 "force horizontal chrominance deblocking (override other settings) ", VLC_TRUE );
192 add_bool( "ffmpeg-dr-y", 0, NULL,
193 "force luminance deringing",
194 "force luminance deringing (override other settings)", VLC_TRUE );
195 add_bool( "ffmpeg-dr-c", 0, NULL,
196 "force chrominance deringing",
197 "force chrominance deringing (override other settings)", VLC_TRUE );
200 /* chroma conversion submodule */
202 set_capability( "chroma", 50 );
203 set_callbacks( E_(OpenChroma), NULL );
204 set_description( _("ffmpeg chroma conversion") );
208 /*****************************************************************************
209 * OpenDecoder: probe the decoder and return score
210 *****************************************************************************
211 * Tries to launch a decoder and return score so that the interface is able
213 *****************************************************************************/
214 static int OpenDecoder( vlc_object_t *p_this )
216 decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
218 if( ffmpeg_GetFfmpegCodec( p_fifo->i_fourcc, NULL, NULL, NULL ) )
220 p_fifo->pf_run = RunDecoder;
227 typedef union decoder_thread_u
229 generic_thread_t gen;
236 /*****************************************************************************
237 * RunDecoder: this function is called just after the thread is created
238 *****************************************************************************/
239 static int RunDecoder( decoder_fifo_t *p_fifo )
241 generic_thread_t *p_decoder;
244 if ( !(p_decoder = malloc( sizeof( decoder_thread_t ) ) ) )
246 msg_Err( p_fifo, "out of memory" );
247 DecoderError( p_fifo );
250 memset( p_decoder, 0, sizeof( decoder_thread_t ) );
252 p_decoder->p_fifo = p_fifo;
254 if( InitThread( p_decoder ) != 0 )
256 msg_Err( p_fifo, "initialization failed" );
257 DecoderError( p_fifo );
261 while( (!p_decoder->p_fifo->b_die) && (!p_decoder->p_fifo->b_error) )
263 switch( p_decoder->i_cat )
266 E_( DecodeThread_Video )( (vdec_thread_t*)p_decoder );
269 E_( DecodeThread_Audio )( (adec_thread_t*)p_decoder );
274 if( ( b_error = p_decoder->p_fifo->b_error ) )
276 DecoderError( p_decoder->p_fifo );
279 EndThread( p_decoder );
289 /*****************************************************************************
291 * Functions that initialize, decode and end the decoding process
293 *****************************************************************************/
295 /*****************************************************************************
296 * InitThread: initialize vdec output thread
297 *****************************************************************************
298 * This function is called from decoder_Run and performs the second step
299 * of the initialization. It returns 0 on success. Note that the thread's
300 * flag are not modified inside this function.
302 * ffmpeg codec will be open, some memory allocated. But Vout is not yet
303 * open (done after the first decoded frame)
304 *****************************************************************************/
306 static int InitThread( generic_thread_t *p_decoder )
310 /* *** init ffmpeg library (libavcodec) *** */
314 avcodec_register_all();
317 msg_Dbg( p_decoder->p_fifo, "libavcodec initialized (interface "
318 LIBAVCODEC_BUILD_STR ")" );
322 msg_Dbg( p_decoder->p_fifo, "libavcodec already initialized" );
325 /* *** determine codec type *** */
326 ffmpeg_GetFfmpegCodec( p_decoder->p_fifo->i_fourcc,
328 &p_decoder->i_codec_id,
329 &p_decoder->psz_namecodec );
331 /* *** ask ffmpeg for a decoder *** */
332 if( !( p_decoder->p_codec =
333 avcodec_find_decoder( p_decoder->i_codec_id ) ) )
335 msg_Err( p_decoder->p_fifo,
336 "codec not found (%s)",
337 p_decoder->psz_namecodec );
341 /* *** Get a p_context *** */
342 p_decoder->p_context = avcodec_alloc_context();
344 switch( p_decoder->i_cat )
347 i_result = E_( InitThread_Video )( (vdec_thread_t*)p_decoder );
350 i_result = E_( InitThread_Audio )( (adec_thread_t*)p_decoder );
357 p_decoder->p_buffer = NULL;
358 p_decoder->i_buffer = 0;
359 p_decoder->i_buffer_size = 0;
364 /*****************************************************************************
365 * EndThread: thread destruction
366 *****************************************************************************
367 * This function is called when the thread ends after a sucessful
369 *****************************************************************************/
370 static void EndThread( generic_thread_t *p_decoder )
378 if( p_decoder->p_context != NULL)
380 FREE( p_decoder->p_context->extradata );
381 avcodec_close( p_decoder->p_context );
382 msg_Dbg( p_decoder->p_fifo,
383 "ffmpeg codec (%s) stopped",
384 p_decoder->psz_namecodec );
385 free( p_decoder->p_context );
388 FREE( p_decoder->p_buffer );
390 switch( p_decoder->i_cat )
393 E_( EndThread_Audio )( (adec_thread_t*)p_decoder );
396 E_( EndThread_Video )( (vdec_thread_t*)p_decoder );
403 /*****************************************************************************
405 *****************************************************************************/
407 int E_( GetPESData )( u8 *p_buf, int i_max, pes_packet_t *p_pes )
412 data_packet_t *p_data;
415 p_data = p_pes->p_first;
416 while( p_data != NULL && i_count < i_max )
419 i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
425 p_data->p_payload_start,
429 p_data = p_data->p_next;
434 if( i_count < i_max )
436 memset( p_buf, 0, i_max - i_count );
442 static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t i_fourcc,
444 int *pi_ffmpeg_codec,
454 /* XXX don't use it */
457 i_codec = CODEC_ID_MPEG1VIDEO;
458 psz_name = "MPEG-1/2 Video";
466 i_codec = CODEC_ID_MSMPEG4V1;
467 psz_name = "MS MPEG-4 v1";
475 i_codec = CODEC_ID_MSMPEG4V2;
476 psz_name = "MS MPEG-4 v2";
497 i_codec = CODEC_ID_MSMPEG4V3;
498 psz_name = "MS MPEG-4 v3";
503 i_codec = CODEC_ID_SVQ1;
504 psz_name = "SVQ-1 (Sorenson Video v1)";
519 /* 3iv1 is unsupported by ffmpeg
520 putting it here gives extreme distorted images
527 i_codec = CODEC_ID_MPEG4;
530 /* FIXME FOURCC_H263P exist but what fourcc ? */
535 i_codec = CODEC_ID_H263;
542 i_codec = CODEC_ID_H263I;
547 i_codec = CODEC_ID_WMV1;
548 psz_name ="Windows Media Video 1";
553 i_codec = CODEC_ID_WMV2;
554 psz_name ="Windows Media Video 2";
563 i_codec = CODEC_ID_MJPEG;
564 psz_name = "Motion JPEG";
568 i_codec = CODEC_ID_MJPEGB;
569 psz_name = "Motion JPEG B";
578 i_codec = CODEC_ID_DVVIDEO;
579 psz_name = "DV video";
584 i_codec = CODEC_ID_MACE3;
585 psz_name = "MACE-3 audio";
589 i_codec = CODEC_ID_MACE6;
590 psz_name = "MACE-6 audio";
594 i_codec = CODEC_ID_DVAUDIO;
595 psz_name = "DV audio";
601 i_codec = CODEC_ID_WMAV1;
602 psz_name ="Windows Media Audio 1";
607 i_codec = CODEC_ID_WMAV2;
608 psz_name ="Windows Media Audio 2";
611 #if LIBAVCODEC_BUILD >= 4663
617 i_codec = CODEC_ID_INDEO3;
618 psz_name = "Indeo v3";
623 i_codec = CODEC_ID_NONE;
628 if( i_codec != CODEC_ID_NONE )
630 if( pi_cat ) *pi_cat = i_cat;
631 if( pi_ffmpeg_codec ) *pi_ffmpeg_codec = i_codec;
632 if( ppsz_name ) *ppsz_name = psz_name;