1 /*****************************************************************************
2 * ffmpeg.c: video decoder using ffmpeg library
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN
5 * $Id: ffmpeg.c,v 1.26 2003/03/11 05:52:37 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 #include "postprocessing/postprocessing.h"
46 #include "video.h" // video ffmpeg specific
47 #include "audio.h" // audio ffmpeg specific
52 static int OpenDecoder ( vlc_object_t * );
53 static int RunDecoder ( decoder_fifo_t * );
55 static int InitThread ( generic_thread_t * );
56 static void EndThread ( generic_thread_t * );
59 static int b_ffmpeginit = 0;
61 static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t, int *, int *, char ** );
63 /*****************************************************************************
65 *****************************************************************************/
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)."
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."
78 #define POSTPROCESSING_Q_LONGTEXT \
79 "Quality of post processing\n"\
80 "Valid range is 0 to 6\n" \
81 "(Overridden by others setting)"
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 !"
88 #define WORKAROUND_BUGS_LONGTEXT \
89 "Try to fix some bugs\n" \
92 "4 xvid interlaced\n" \
99 add_category_hint( N_("ffmpeg"), NULL, VLC_FALSE );
100 #if LIBAVCODEC_BUILD >= 4615
101 add_bool( "ffmpeg-dr", 0, NULL,
103 "direct rendering", VLC_TRUE );
105 #if LIBAVCODEC_BUILD >= 4611
106 add_integer ( "ffmpeg-error-resilience", -1, NULL,
107 "error resilience", ERROR_RESILIENCE_LONGTEXT, VLC_TRUE );
108 add_integer ( "ffmpeg-workaround-bugs", 1, NULL,
109 "workaround bugs", WORKAROUND_BUGS_LONGTEXT, VLC_FALSE );
111 add_bool( "ffmpeg-hurry-up", 0, NULL, "hurry up", HURRY_UP_LONGTEXT, VLC_FALSE );
113 add_category_hint( N_("Post processing"), NULL, VLC_FALSE );
114 add_module( "ffmpeg-pp", "postprocessing",NULL, NULL,
115 N_( "ffmpeg postprocessing module" ), NULL, VLC_FALSE );
116 add_integer( "ffmpeg-pp-q", 0, NULL,
117 "post processing quality", POSTPROCESSING_Q_LONGTEXT, VLC_FALSE );
118 add_bool( "ffmpeg-pp-auto", 0, NULL,
119 "auto-level Post processing quality", POSTPROCESSING_AQ_LONGTEXT, VLC_FALSE );
120 add_bool( "ffmpeg-db-yv", 0, NULL,
121 "force vertical luminance deblocking",
122 "force vertical luminance deblocking (override other settings)", VLC_TRUE );
123 add_bool( "ffmpeg-db-yh", 0, NULL,
124 "force horizontal luminance deblocking",
125 "force horizontal luminance deblocking (override other settings)", VLC_TRUE );
126 add_bool( "ffmpeg-db-cv", 0, NULL,
127 "force vertical chrominance deblocking",
128 "force vertical chrominance deblocking (override other settings)", VLC_TRUE );
129 add_bool( "ffmpeg-db-ch", 0, NULL,
130 "force horizontal chrominance deblocking",
131 "force horizontal chrominance deblocking (override other settings) ", VLC_TRUE );
132 add_bool( "ffmpeg-dr-y", 0, NULL,
133 "force luminance deringing",
134 "force luminance deringing (override other settings)", VLC_TRUE );
135 add_bool( "ffmpeg-dr-c", 0, NULL,
136 "force chrominance deringing",
137 "force chrominance deringing (override other settings)", VLC_TRUE );
139 set_description( _("ffmpeg audio/video decoder((MS)MPEG4,SVQ1,H263,WMV,WMA)") );
140 set_capability( "decoder", 70 );
141 set_callbacks( OpenDecoder, NULL );
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
149 *****************************************************************************/
150 static int OpenDecoder( vlc_object_t *p_this )
152 decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
154 if( ffmpeg_GetFfmpegCodec( p_fifo->i_fourcc, NULL, NULL, NULL ) )
156 p_fifo->pf_run = RunDecoder;
163 typedef union decoder_thread_u
165 generic_thread_t gen;
172 /*****************************************************************************
173 * RunDecoder: this function is called just after the thread is created
174 *****************************************************************************/
175 static int RunDecoder( decoder_fifo_t *p_fifo )
177 generic_thread_t *p_decoder;
180 if ( !(p_decoder = malloc( sizeof( decoder_thread_t ) ) ) )
182 msg_Err( p_fifo, "out of memory" );
183 DecoderError( p_fifo );
186 memset( p_decoder, 0, sizeof( decoder_thread_t ) );
188 p_decoder->p_fifo = p_fifo;
190 if( InitThread( p_decoder ) != 0 )
192 msg_Err( p_fifo, "initialization failed" );
193 DecoderError( p_fifo );
197 while( (!p_decoder->p_fifo->b_die) && (!p_decoder->p_fifo->b_error) )
199 switch( p_decoder->i_cat )
202 E_( DecodeThread_Video )( (vdec_thread_t*)p_decoder );
205 E_( DecodeThread_Audio )( (adec_thread_t*)p_decoder );
210 if( ( b_error = p_decoder->p_fifo->b_error ) )
212 DecoderError( p_decoder->p_fifo );
215 EndThread( p_decoder );
225 /*****************************************************************************
227 * Functions that initialize, decode and end the decoding process
229 *****************************************************************************/
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.
238 * ffmpeg codec will be open, some memory allocated. But Vout is not yet
239 * open (done after the first decoded frame)
240 *****************************************************************************/
242 static int InitThread( generic_thread_t *p_decoder )
246 /* *** init ffmpeg library (libavcodec) *** */
250 avcodec_register_all();
253 msg_Dbg( p_decoder->p_fifo, "libavcodec initialized (interface "
254 LIBAVCODEC_BUILD_STR ")" );
258 msg_Dbg( p_decoder->p_fifo, "libavcodec already initialized" );
261 /* *** determine codec type *** */
262 ffmpeg_GetFfmpegCodec( p_decoder->p_fifo->i_fourcc,
264 &p_decoder->i_codec_id,
265 &p_decoder->psz_namecodec );
267 /* *** ask ffmpeg for a decoder *** */
268 if( !( p_decoder->p_codec =
269 avcodec_find_decoder( p_decoder->i_codec_id ) ) )
271 msg_Err( p_decoder->p_fifo,
272 "codec not found (%s)",
273 p_decoder->psz_namecodec );
277 /* *** Get a p_context *** */
278 #if LIBAVCODEC_BUILD >= 4624
279 p_decoder->p_context = avcodec_alloc_context();
281 p_decoder->p_context = malloc( sizeof( AVCodecContext ) );
282 memset( p_decoder->p_context, 0, sizeof( AVCodecContext ) );
285 switch( p_decoder->i_cat )
288 i_result = E_( InitThread_Video )( (vdec_thread_t*)p_decoder );
291 i_result = E_( InitThread_Audio )( (adec_thread_t*)p_decoder );
298 p_decoder->p_buffer = NULL;
299 p_decoder->i_buffer = 0;
300 p_decoder->i_buffer_size = 0;
305 /*****************************************************************************
306 * EndThread: thread destruction
307 *****************************************************************************
308 * This function is called when the thread ends after a sucessful
310 *****************************************************************************/
311 static void EndThread( generic_thread_t *p_decoder )
319 if( p_decoder->p_context != NULL)
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 );
329 FREE( p_decoder->p_buffer );
331 switch( p_decoder->i_cat )
334 E_( EndThread_Audio )( (adec_thread_t*)p_decoder );
337 E_( EndThread_Video )( (vdec_thread_t*)p_decoder );
344 /*****************************************************************************
346 *****************************************************************************/
348 int E_( GetPESData )( u8 *p_buf, int i_max, pes_packet_t *p_pes )
353 data_packet_t *p_data;
356 p_data = p_pes->p_first;
357 while( p_data != NULL && i_count < i_max )
360 i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
366 p_data->p_payload_start,
370 p_data = p_data->p_next;
375 if( i_count < i_max )
377 memset( p_buf, 0, i_max - i_count );
383 static int ffmpeg_GetFfmpegCodec( vlc_fourcc_t i_fourcc,
385 int *pi_ffmpeg_codec,
395 /* XXX don't use it */
398 i_codec = CODEC_ID_MPEG1VIDEO;
399 psz_name = "MPEG-1/2 Video";
402 #if LIBAVCODEC_BUILD >= 4608
408 i_codec = CODEC_ID_MSMPEG4V1;
409 psz_name = "MS MPEG-4 v1";
417 i_codec = CODEC_ID_MSMPEG4V2;
418 psz_name = "MS MPEG-4 v2";
437 #if LIBAVCODEC_BUILD >= 4608
438 i_codec = CODEC_ID_MSMPEG4V3;
440 i_codec = CODEC_ID_MSMPEG4;
442 psz_name = "MS MPEG-4 v3";
445 #if LIBAVCODEC_BUILD >= 4615
448 i_codec = CODEC_ID_SVQ1;
449 psz_name = "SVQ-1 (Sorenson Video v1)";
467 i_codec = CODEC_ID_MPEG4;
470 /* FIXME FOURCC_H263P exist but what fourcc ? */
475 i_codec = CODEC_ID_H263;
482 i_codec = CODEC_ID_H263I;
487 i_codec = CODEC_ID_WMV1;
488 psz_name ="Windows Media Video 1";
492 i_codec = CODEC_ID_WMV2;
493 psz_name ="Windows Media Video 2";
502 i_codec = CODEC_ID_MJPEG;
503 psz_name = "Motion JPEG";
505 #if LIBAVCODEC_BUILD >= 4640
508 i_codec = CODEC_ID_MJPEGB;
509 psz_name = "Motion JPEG B";
519 i_codec = CODEC_ID_DVVIDEO;
520 psz_name = "DV video";
523 #if LIBAVCODEC_BUILD >= 4655
526 i_codec = CODEC_ID_MACE3;
527 psz_name = "MACE-3 audio";
531 i_codec = CODEC_ID_MACE6;
532 psz_name = "MACE-6 audio";
536 i_codec = CODEC_ID_DVAUDIO;
537 psz_name = "DV audio";
541 #if LIBAVCODEC_BUILD >= 4632
545 i_codec = CODEC_ID_WMAV1;
546 psz_name ="Windows Media Audio 1";
551 i_codec = CODEC_ID_WMAV2;
552 psz_name ="Windows Media Audio 2";
557 i_codec = CODEC_ID_NONE;
562 if( i_codec != CODEC_ID_NONE )
564 if( pi_cat ) *pi_cat = i_cat;
565 if( pi_ffmpeg_codec ) *pi_ffmpeg_codec = i_codec;
566 if( ppsz_name ) *ppsz_name = psz_name;