1 /*****************************************************************************
2 * ffmpeg.c: video decoder using ffmpeg library
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN
5 * $Id: ffmpeg.c,v 1.30 2003/04/17 10:58:30 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>
41 #include "avcodec.h" /* ffmpeg */
43 #if LIBAVCODEC_BUILD < 4655
44 # error You must have a libavcodec >= 4655 (get CVS)
51 # include "libpostproc/postprocess.h"
53 # include "postprocessing/postprocessing.h"
56 #include "video.h" // video ffmpeg specific
57 #include "audio.h" // audio ffmpeg specific
62 static int OpenDecoder ( vlc_object_t * );
63 static int RunDecoder ( decoder_fifo_t * );
65 static int InitThread ( generic_thread_t * );
66 static void EndThread ( generic_thread_t * );
69 static int b_ffmpeginit = 0;
71 static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t, int *, int *, char ** );
73 /*****************************************************************************
75 *****************************************************************************/
77 #define ERROR_RESILIENCE_LONGTEXT \
78 "ffmpeg can make errors resiliences. \n" \
79 "Nevertheless, with buggy encoder (like ISO MPEG-4 encoder from M$) " \
80 "this will produce a lot of errors.\n" \
81 "Valid range is -1 to 99 (-1 disable all errors resiliences)."
83 #define HURRY_UP_LONGTEXT \
84 "Allow the decoder to partially decode or skip frame(s) " \
85 "when there not enough time.\n It's usefull with low CPU power " \
86 "but it could produce broken pictures."
88 #define POSTPROCESSING_Q_LONGTEXT \
89 "Quality of post processing\n"\
90 "Valid range is 0 to 6"
92 #define POSTPROCESSING_AQ_LONGTEXT \
93 "Post processing quality is selected upon time left " \
94 "but no more than requested quality\n" \
95 "Not yet implemented !"
97 #define WORKAROUND_BUGS_LONGTEXT \
98 "Try to fix some bugs\n" \
101 "4 xvid interlaced\n" \
107 /* FIXME (cut/past from ffmpeg */
108 #define LIBAVCODEC_PP_LONGHELP \
109 "<filterName>[:<option>[:<option>...]][[,|/][-]<filterName>[:<option>...]]...\n" \
110 "long form example:\n" \
111 "vdeblock:autoq/hdeblock:autoq/linblenddeint default,-vdeblock\n" \
112 "short form example:\n" \
113 "vb:a/hb:a/lb de,-vb\n" \
116 "Filters Options\n" \
117 "short long name short long option Description\n" \
118 "* * a autoq cpu power dependant enabler\n" \
119 " c chrom chrominance filtring enabled\n" \
120 " y nochrom chrominance filtring disabled\n" \
121 "hb hdeblock (2 Threshold) horizontal deblocking filter\n" \
122 " 1. difference factor: default=64, higher -> more deblocking\n" \
123 " 2. flatness threshold: default=40, lower -> more deblocking\n" \
124 " the h & v deblocking filters share these\n" \
125 " so u cant set different thresholds for h / v\n" \
126 "vb vdeblock (2 Threshold) vertical deblocking filter\n" \
127 "h1 x1hdeblock Experimental h deblock filter 1\n" \
128 "v1 x1vdeblock Experimental v deblock filter 1\n" \
129 "dr dering Deringing filter\n" \
130 "al autolevels automatic brightness / contrast\n" \
131 " f fullyrange stretch luminance to (0..255)\n" \
132 "lb linblenddeint linear blend deinterlacer\n" \
133 "li linipoldeint linear interpolating deinterlace\n" \
134 "ci cubicipoldeint cubic interpolating deinterlacer\n" \
135 "md mediandeint median deinterlacer\n" \
136 "fd ffmpegdeint ffmpeg deinterlacer\n" \
137 "de default hb:a,vb:a,dr:a,al\n" \
138 "fa fast h1:a,v1:a,dr:a,al\n" \
139 "tn tmpnoise (3 Thresholds) Temporal Noise Reducer\n" \
140 " 1. <= 2. <= 3. larger -> stronger filtering\n" \
141 "fq forceQuant <quantizer> Force quantizer\n"
144 add_category_hint( N_("ffmpeg"), NULL, VLC_FALSE );
145 add_bool( "ffmpeg-dr", 0, NULL,
147 "direct rendering", VLC_TRUE );
148 add_integer ( "ffmpeg-error-resilience", -1, NULL,
149 "error resilience", ERROR_RESILIENCE_LONGTEXT, VLC_TRUE );
150 add_integer ( "ffmpeg-workaround-bugs", 1, NULL,
151 "workaround bugs", WORKAROUND_BUGS_LONGTEXT, VLC_FALSE );
152 add_bool( "ffmpeg-hurry-up", 0, NULL, "hurry up", HURRY_UP_LONGTEXT, VLC_FALSE );
154 add_category_hint( N_("Post processing"), NULL, VLC_FALSE );
156 add_integer( "ffmpeg-pp-q", 0, NULL,
157 "post processing quality", POSTPROCESSING_Q_LONGTEXT, VLC_FALSE );
159 add_string( "ffmpeg-pp-name", "default", NULL,
160 "ffmpeg postproc filter chains", LIBAVCODEC_PP_LONGHELP, VLC_TRUE );
162 add_module( "ffmpeg-pp", "postprocessing",NULL, NULL,
163 N_( "ffmpeg postprocessing module" ), NULL, VLC_FALSE );
164 add_bool( "ffmpeg-pp-auto", 0, NULL,
165 "auto-level Post processing quality", POSTPROCESSING_AQ_LONGTEXT, VLC_FALSE );
166 add_bool( "ffmpeg-db-yv", 0, NULL,
167 "force vertical luminance deblocking",
168 "force vertical luminance deblocking (override other settings)", VLC_TRUE );
169 add_bool( "ffmpeg-db-yh", 0, NULL,
170 "force horizontal luminance deblocking",
171 "force horizontal luminance deblocking (override other settings)", VLC_TRUE );
172 add_bool( "ffmpeg-db-cv", 0, NULL,
173 "force vertical chrominance deblocking",
174 "force vertical chrominance deblocking (override other settings)", VLC_TRUE );
175 add_bool( "ffmpeg-db-ch", 0, NULL,
176 "force horizontal chrominance deblocking",
177 "force horizontal chrominance deblocking (override other settings) ", VLC_TRUE );
178 add_bool( "ffmpeg-dr-y", 0, NULL,
179 "force luminance deringing",
180 "force luminance deringing (override other settings)", VLC_TRUE );
181 add_bool( "ffmpeg-dr-c", 0, NULL,
182 "force chrominance deringing",
183 "force chrominance deringing (override other settings)", VLC_TRUE );
185 set_description( _("ffmpeg audio/video decoder((MS)MPEG4,SVQ1,H263,WMV,WMA)") );
186 set_capability( "decoder", 70 );
187 set_callbacks( OpenDecoder, NULL );
190 /*****************************************************************************
191 * OpenDecoder: probe the decoder and return score
192 *****************************************************************************
193 * Tries to launch a decoder and return score so that the interface is able
195 *****************************************************************************/
196 static int OpenDecoder( vlc_object_t *p_this )
198 decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
200 if( ffmpeg_GetFfmpegCodec( p_fifo->i_fourcc, NULL, NULL, NULL ) )
202 p_fifo->pf_run = RunDecoder;
209 typedef union decoder_thread_u
211 generic_thread_t gen;
218 /*****************************************************************************
219 * RunDecoder: this function is called just after the thread is created
220 *****************************************************************************/
221 static int RunDecoder( decoder_fifo_t *p_fifo )
223 generic_thread_t *p_decoder;
226 if ( !(p_decoder = malloc( sizeof( decoder_thread_t ) ) ) )
228 msg_Err( p_fifo, "out of memory" );
229 DecoderError( p_fifo );
232 memset( p_decoder, 0, sizeof( decoder_thread_t ) );
234 p_decoder->p_fifo = p_fifo;
236 if( InitThread( p_decoder ) != 0 )
238 msg_Err( p_fifo, "initialization failed" );
239 DecoderError( p_fifo );
243 while( (!p_decoder->p_fifo->b_die) && (!p_decoder->p_fifo->b_error) )
245 switch( p_decoder->i_cat )
248 E_( DecodeThread_Video )( (vdec_thread_t*)p_decoder );
251 E_( DecodeThread_Audio )( (adec_thread_t*)p_decoder );
256 if( ( b_error = p_decoder->p_fifo->b_error ) )
258 DecoderError( p_decoder->p_fifo );
261 EndThread( p_decoder );
271 /*****************************************************************************
273 * Functions that initialize, decode and end the decoding process
275 *****************************************************************************/
277 /*****************************************************************************
278 * InitThread: initialize vdec output thread
279 *****************************************************************************
280 * This function is called from decoder_Run and performs the second step
281 * of the initialization. It returns 0 on success. Note that the thread's
282 * flag are not modified inside this function.
284 * ffmpeg codec will be open, some memory allocated. But Vout is not yet
285 * open (done after the first decoded frame)
286 *****************************************************************************/
288 static int InitThread( generic_thread_t *p_decoder )
292 /* *** 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" );
307 /* *** determine codec type *** */
308 ffmpeg_GetFfmpegCodec( p_decoder->p_fifo->i_fourcc,
310 &p_decoder->i_codec_id,
311 &p_decoder->psz_namecodec );
313 /* *** ask ffmpeg for a decoder *** */
314 if( !( p_decoder->p_codec =
315 avcodec_find_decoder( p_decoder->i_codec_id ) ) )
317 msg_Err( p_decoder->p_fifo,
318 "codec not found (%s)",
319 p_decoder->psz_namecodec );
323 /* *** Get a p_context *** */
324 p_decoder->p_context = avcodec_alloc_context();
326 switch( p_decoder->i_cat )
329 i_result = E_( InitThread_Video )( (vdec_thread_t*)p_decoder );
332 i_result = E_( InitThread_Audio )( (adec_thread_t*)p_decoder );
339 p_decoder->p_buffer = NULL;
340 p_decoder->i_buffer = 0;
341 p_decoder->i_buffer_size = 0;
346 /*****************************************************************************
347 * EndThread: thread destruction
348 *****************************************************************************
349 * This function is called when the thread ends after a sucessful
351 *****************************************************************************/
352 static void EndThread( generic_thread_t *p_decoder )
360 if( p_decoder->p_context != NULL)
362 FREE( p_decoder->p_context->extradata );
363 avcodec_close( p_decoder->p_context );
364 msg_Dbg( p_decoder->p_fifo,
365 "ffmpeg codec (%s) stopped",
366 p_decoder->psz_namecodec );
367 free( p_decoder->p_context );
370 FREE( p_decoder->p_buffer );
372 switch( p_decoder->i_cat )
375 E_( EndThread_Audio )( (adec_thread_t*)p_decoder );
378 E_( EndThread_Video )( (vdec_thread_t*)p_decoder );
385 /*****************************************************************************
387 *****************************************************************************/
389 int E_( GetPESData )( u8 *p_buf, int i_max, pes_packet_t *p_pes )
394 data_packet_t *p_data;
397 p_data = p_pes->p_first;
398 while( p_data != NULL && i_count < i_max )
401 i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
407 p_data->p_payload_start,
411 p_data = p_data->p_next;
416 if( i_count < i_max )
418 memset( p_buf, 0, i_max - i_count );
424 static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t i_fourcc,
426 int *pi_ffmpeg_codec,
436 /* XXX don't use it */
439 i_codec = CODEC_ID_MPEG1VIDEO;
440 psz_name = "MPEG-1/2 Video";
448 i_codec = CODEC_ID_MSMPEG4V1;
449 psz_name = "MS MPEG-4 v1";
457 i_codec = CODEC_ID_MSMPEG4V2;
458 psz_name = "MS MPEG-4 v2";
479 i_codec = CODEC_ID_MSMPEG4V3;
480 psz_name = "MS MPEG-4 v3";
485 i_codec = CODEC_ID_SVQ1;
486 psz_name = "SVQ-1 (Sorenson Video v1)";
501 /* 3iv1 is unsupported by ffmpeg
502 putting it here gives extreme distorted images
509 i_codec = CODEC_ID_MPEG4;
512 /* FIXME FOURCC_H263P exist but what fourcc ? */
517 i_codec = CODEC_ID_H263;
524 i_codec = CODEC_ID_H263I;
529 i_codec = CODEC_ID_WMV1;
530 psz_name ="Windows Media Video 1";
535 i_codec = CODEC_ID_WMV2;
536 psz_name ="Windows Media Video 2";
545 i_codec = CODEC_ID_MJPEG;
546 psz_name = "Motion JPEG";
550 i_codec = CODEC_ID_MJPEGB;
551 psz_name = "Motion JPEG B";
560 i_codec = CODEC_ID_DVVIDEO;
561 psz_name = "DV video";
566 i_codec = CODEC_ID_MACE3;
567 psz_name = "MACE-3 audio";
571 i_codec = CODEC_ID_MACE6;
572 psz_name = "MACE-6 audio";
576 i_codec = CODEC_ID_DVAUDIO;
577 psz_name = "DV audio";
583 i_codec = CODEC_ID_WMAV1;
584 psz_name ="Windows Media Audio 1";
589 i_codec = CODEC_ID_WMAV2;
590 psz_name ="Windows Media Audio 2";
593 #if LIBAVCODEC_BUILD >= 4663
599 i_codec = CODEC_ID_INDEO3;
600 psz_name = "Indeo v3";
605 i_codec = CODEC_ID_NONE;
610 if( i_codec != CODEC_ID_NONE )
612 if( pi_cat ) *pi_cat = i_cat;
613 if( pi_ffmpeg_codec ) *pi_ffmpeg_codec = i_codec;
614 if( ppsz_name ) *ppsz_name = psz_name;