]> git.sesse.net Git - vlc/blob - modules/codec/ffmpeg/encoder.c
A bit of headers cleanup
[vlc] / modules / codec / ffmpeg / encoder.c
1 /*****************************************************************************
2  * encoder.c: video and audio encoder using the ffmpeg library
3  *****************************************************************************
4  * Copyright (C) 1999-2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Gildas Bazin <gbazin@videolan.org>
9  *          Christophe Massiot <massiot@via.ecp.fr>
10  * Part of the file Copyright (C) FFMPEG Project Developers
11  * (mpeg4_default matrixes)
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26  *****************************************************************************/
27
28 /*****************************************************************************
29  * Preamble
30  *****************************************************************************/
31 #include <vlc/vlc.h>
32 #include <vlc_vout.h>
33 #include <vlc_aout.h>
34 #include <vlc_sout.h>
35 #include <vlc_codec.h>
36 #include <vlc_interface.h>
37
38 /* ffmpeg header */
39 #define HAVE_MMX 1
40 #ifdef HAVE_FFMPEG_AVCODEC_H
41 #   include <ffmpeg/avcodec.h>
42 #else
43 #   include <avcodec.h>
44 #endif
45
46 #include "ffmpeg.h"
47
48 #define HURRY_UP_GUARD1 (450000)
49 #define HURRY_UP_GUARD2 (300000)
50 #define HURRY_UP_GUARD3 (100000)
51
52 #define MAX_FRAME_DELAY (FF_MAX_B_FRAMES + 2)
53
54 /*****************************************************************************
55  * Local prototypes
56  *****************************************************************************/
57 int  E_(OpenEncoder) ( vlc_object_t * );
58 void E_(CloseEncoder)( vlc_object_t * );
59
60 static block_t *EncodeVideo( encoder_t *, picture_t * );
61 static block_t *EncodeAudio( encoder_t *, aout_buffer_t * );
62
63 struct thread_context_t;
64 static int FfmpegThread( struct thread_context_t *p_context );
65 static int FfmpegExecute( AVCodecContext *s,
66                           int (*pf_func)(AVCodecContext *c2, void *arg2),
67                           void **arg, int *ret, int count );
68
69 /*****************************************************************************
70  * thread_context_t : for multithreaded encoding
71  *****************************************************************************/
72 struct thread_context_t
73 {
74     VLC_COMMON_MEMBERS
75
76     AVCodecContext  *p_context;
77     int             (* pf_func)(AVCodecContext *c, void *arg);
78     void            *arg;
79     int             i_ret;
80
81     vlc_mutex_t     lock;
82     vlc_cond_t      cond;
83     vlc_bool_t      b_work, b_done;
84 };
85
86 /*****************************************************************************
87  * encoder_sys_t : ffmpeg encoder descriptor
88  *****************************************************************************/
89 struct encoder_sys_t
90 {
91     /*
92      * Ffmpeg properties
93      */
94     AVCodec         *p_codec;
95     AVCodecContext  *p_context;
96
97     /*
98      * Common properties
99      */
100     char *p_buffer;
101     char *p_buffer_out;
102
103     /*
104      * Video properties
105      */
106     mtime_t i_last_ref_pts;
107     mtime_t i_buggy_pts_detect;
108     mtime_t i_last_pts;
109     vlc_bool_t b_inited;
110
111     /*
112      * Audio properties
113      */
114     int i_frame_size;
115     int i_samples_delay;
116     mtime_t i_pts;
117
118     /* Encoding settings */
119     int        i_key_int;
120     int        i_b_frames;
121     int        i_vtolerance;
122     int        i_qmin;
123     int        i_qmax;
124     int        i_hq;
125     vlc_bool_t b_strict_rc;
126     int        i_rc_buffer_size;
127     float      f_rc_buffer_aggressivity;
128     vlc_bool_t b_pre_me;
129     vlc_bool_t b_hurry_up;
130     vlc_bool_t b_interlace, b_interlace_me;
131     float      f_i_quant_factor;
132     int        i_noise_reduction;
133     vlc_bool_t b_mpeg4_matrix;
134     vlc_bool_t b_trellis;
135     int        i_quality; /* for VBR */
136     float      f_lumi_masking, f_dark_masking, f_p_masking, f_border_masking;
137     int        i_luma_elim, i_chroma_elim;
138
139     /* Used to work around stupid timestamping behaviour in libavcodec */
140     uint64_t i_framenum;
141     mtime_t  pi_delay_pts[MAX_FRAME_DELAY];
142 };
143
144 static const char *ppsz_enc_options[] = {
145     "keyint", "bframes", "vt", "qmin", "qmax", "hq", "strict-rc",
146     "rc-buffer-size", "rc-buffer-aggressivity", "pre-me", "hurry-up",
147     "interlace", "i-quant-factor", "noise-reduction", "mpeg4-matrix",
148     "trellis", "qscale", "strict", "lumi-masking", "dark-masking",
149     "p-masking", "border-masking", "luma-elim-threshold",
150     "chroma-elim-threshold", NULL
151 };
152
153 static const uint16_t mpa_bitrate_tab[2][15] =
154 {
155     {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384},
156     {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
157 };
158
159 static const uint16_t mpa_freq_tab[6] =
160 { 44100, 48000, 32000, 22050, 24000, 16000 };
161
162 static const int16_t mpeg4_default_intra_matrix[64] = {
163   8, 17, 18, 19, 21, 23, 25, 27,
164  17, 18, 19, 21, 23, 25, 27, 28,
165  20, 21, 22, 23, 24, 26, 28, 30,
166  21, 22, 23, 24, 26, 28, 30, 32,
167  22, 23, 24, 26, 28, 30, 32, 35,
168  23, 24, 26, 28, 30, 32, 35, 38,
169  25, 26, 28, 30, 32, 35, 38, 41,
170  27, 28, 30, 32, 35, 38, 41, 45,
171 };
172
173 static const int16_t mpeg4_default_non_intra_matrix[64] = {
174  16, 17, 18, 19, 20, 21, 22, 23,
175  17, 18, 19, 20, 21, 22, 23, 24,
176  18, 19, 20, 21, 22, 23, 24, 25,
177  19, 20, 21, 22, 23, 24, 26, 27,
178  20, 21, 22, 23, 25, 26, 27, 28,
179  21, 22, 23, 24, 26, 27, 28, 30,
180  22, 23, 24, 26, 27, 28, 30, 31,
181  23, 24, 25, 27, 28, 30, 31, 33,
182 };
183
184
185 /*****************************************************************************
186  * OpenEncoder: probe the encoder
187  *****************************************************************************/
188
189 int E_(OpenEncoder)( vlc_object_t *p_this )
190 {
191     encoder_t *p_enc = (encoder_t *)p_this;
192     encoder_sys_t *p_sys = p_enc->p_sys;
193     AVCodecContext *p_context;
194     AVCodec *p_codec;
195     int i_codec_id, i_cat;
196     const char *psz_namecodec;
197     vlc_value_t val;
198     vlc_value_t lockval;
199
200     var_Get( p_enc->p_libvlc_global, "avcodec", &lockval );
201
202     if( !E_(GetFfmpegCodec)( p_enc->fmt_out.i_codec, &i_cat, &i_codec_id,
203                              &psz_namecodec ) )
204     {
205         if( E_(GetFfmpegChroma)( p_enc->fmt_out.i_codec ) < 0 )
206         {
207             /* handed chroma output */
208             return VLC_EGENERIC;
209         }
210         i_cat      = VIDEO_ES;
211         i_codec_id = CODEC_ID_RAWVIDEO;
212         psz_namecodec = "Raw video";
213     }
214
215     if( p_enc->fmt_out.i_cat == VIDEO_ES && i_cat != VIDEO_ES )
216     {
217         msg_Err( p_enc, "\"%s\" is not a video encoder", psz_namecodec );
218         intf_UserFatal( p_enc, VLC_FALSE, _("Streaming / Transcoding failed"), 
219                         _("\"%s\" is no video encoder."), psz_namecodec );
220         return VLC_EGENERIC;
221     }
222
223     if( p_enc->fmt_out.i_cat == AUDIO_ES && i_cat != AUDIO_ES )
224     {
225         msg_Err( p_enc, "\"%s\" is not an audio encoder", psz_namecodec );
226         intf_UserFatal( p_enc, VLC_FALSE, _("Streaming / Transcoding failed"), 
227                         _("\"%s\" is no audio encoder."), psz_namecodec );
228         return VLC_EGENERIC;
229     }
230
231     /* Initialization must be done before avcodec_find_encoder() */
232     E_(InitLibavcodec)(p_this);
233
234     p_codec = avcodec_find_encoder( i_codec_id );
235     if( !p_codec )
236     {
237         msg_Err( p_enc, "cannot find encoder %s", psz_namecodec );
238         intf_UserFatal( p_enc, VLC_FALSE, _("Streaming / Transcoding failed"), 
239                         _("VLC could not find encoder \"%s\"."), psz_namecodec );
240         return VLC_EGENERIC;
241     }
242
243     /* Allocate the memory needed to store the encoder's structure */
244     if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
245     {
246         msg_Err( p_enc, "out of memory" );
247         return VLC_EGENERIC;
248     }
249     memset( p_sys, 0, sizeof(encoder_sys_t) );
250     p_enc->p_sys = p_sys;
251     p_sys->p_codec = p_codec;
252
253     p_enc->pf_encode_video = EncodeVideo;
254     p_enc->pf_encode_audio = EncodeAudio;
255
256     p_sys->p_buffer_out = NULL;
257     p_sys->p_buffer = NULL;
258
259     p_sys->p_context = p_context = avcodec_alloc_context();
260     p_context->debug = config_GetInt( p_enc, "ffmpeg-debug" );
261     p_context->opaque = (void *)p_this;
262
263     /* Set CPU capabilities */
264     p_context->dsp_mask = 0;
265     if( !(p_enc->p_libvlc_global->i_cpu & CPU_CAPABILITY_MMX) )
266     {
267         p_context->dsp_mask |= FF_MM_MMX;
268     }
269     if( !(p_enc->p_libvlc_global->i_cpu & CPU_CAPABILITY_MMXEXT) )
270     {
271         p_context->dsp_mask |= FF_MM_MMXEXT;
272     }
273     if( !(p_enc->p_libvlc_global->i_cpu & CPU_CAPABILITY_3DNOW) )
274     {
275         p_context->dsp_mask |= FF_MM_3DNOW;
276     }
277     if( !(p_enc->p_libvlc_global->i_cpu & CPU_CAPABILITY_SSE) )
278     {
279         p_context->dsp_mask |= FF_MM_SSE;
280         p_context->dsp_mask |= FF_MM_SSE2;
281     }
282
283     config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
284
285     var_Get( p_enc, ENC_CFG_PREFIX "keyint", &val );
286     p_sys->i_key_int = val.i_int;
287
288     var_Get( p_enc, ENC_CFG_PREFIX "bframes", &val );
289     p_sys->i_b_frames = val.i_int;
290
291     var_Get( p_enc, ENC_CFG_PREFIX "vt", &val );
292     p_sys->i_vtolerance = val.i_int;
293
294     var_Get( p_enc, ENC_CFG_PREFIX "interlace", &val );
295     p_sys->b_interlace = val.b_bool;
296
297     var_Get( p_enc, ENC_CFG_PREFIX "interlace-me", &val );
298     p_sys->b_interlace_me = val.b_bool;
299
300     var_Get( p_enc, ENC_CFG_PREFIX "pre-me", &val );
301     p_sys->b_pre_me = val.b_bool;
302
303     var_Get( p_enc, ENC_CFG_PREFIX "hurry-up", &val );
304     p_sys->b_hurry_up = val.b_bool;
305     if( p_sys->b_hurry_up )
306     {
307         /* hurry up mode needs noise reduction, even small */
308         p_sys->i_noise_reduction = 1;
309     }
310
311     var_Get( p_enc, ENC_CFG_PREFIX "strict-rc", &val );
312     p_sys->b_strict_rc = val.b_bool;
313     var_Get( p_enc, ENC_CFG_PREFIX "rc-buffer-size", &val );
314     p_sys->i_rc_buffer_size = val.i_int;
315     var_Get( p_enc, ENC_CFG_PREFIX "rc-buffer-aggressivity", &val );
316     p_sys->f_rc_buffer_aggressivity = val.f_float;
317
318     var_Get( p_enc, ENC_CFG_PREFIX "i-quant-factor", &val );
319     p_sys->f_i_quant_factor = val.f_float;
320
321     var_Get( p_enc, ENC_CFG_PREFIX "noise-reduction", &val );
322     p_sys->i_noise_reduction = val.i_int;
323
324     var_Get( p_enc, ENC_CFG_PREFIX "mpeg4-matrix", &val );
325     p_sys->b_mpeg4_matrix = val.b_bool;
326
327     var_Get( p_enc, ENC_CFG_PREFIX "qscale", &val );
328     if( val.f_float < 0.01 || val.f_float > 255.0 ) val.f_float = 0;
329     p_sys->i_quality = (int)(FF_QP2LAMBDA * val.f_float + 0.5);
330
331     var_Get( p_enc, ENC_CFG_PREFIX "hq", &val );
332     if( val.psz_string && *val.psz_string )
333     {
334         if( !strcmp( val.psz_string, "rd" ) )
335             p_sys->i_hq = FF_MB_DECISION_RD;
336         else if( !strcmp( val.psz_string, "bits" ) )
337             p_sys->i_hq = FF_MB_DECISION_BITS;
338         else if( !strcmp( val.psz_string, "simple" ) )
339             p_sys->i_hq = FF_MB_DECISION_SIMPLE;
340         else
341             p_sys->i_hq = FF_MB_DECISION_RD;
342     }
343     if( val.psz_string ) free( val.psz_string );
344
345     var_Get( p_enc, ENC_CFG_PREFIX "qmin", &val );
346     p_sys->i_qmin = val.i_int;
347     var_Get( p_enc, ENC_CFG_PREFIX "qmax", &val );
348     p_sys->i_qmax = val.i_int;
349     var_Get( p_enc, ENC_CFG_PREFIX "trellis", &val );
350     p_sys->b_trellis = val.b_bool;
351
352     var_Get( p_enc, ENC_CFG_PREFIX "strict", &val );
353     if( val.i_int < - 1 || val.i_int > 1 ) val.i_int = 0;
354     p_context->strict_std_compliance = val.i_int;
355
356     var_Get( p_enc, ENC_CFG_PREFIX "lumi-masking", &val );
357     p_sys->f_lumi_masking = val.f_float;
358     var_Get( p_enc, ENC_CFG_PREFIX "dark-masking", &val );
359     p_sys->f_dark_masking = val.f_float;
360     var_Get( p_enc, ENC_CFG_PREFIX "p-masking", &val );
361     p_sys->f_p_masking = val.f_float;
362     var_Get( p_enc, ENC_CFG_PREFIX "border-masking", &val );
363     p_sys->f_border_masking = val.f_float;
364     var_Get( p_enc, ENC_CFG_PREFIX "luma-elim-threshold", &val );
365     p_sys->i_luma_elim = val.i_int;
366     var_Get( p_enc, ENC_CFG_PREFIX "chroma-elim-threshold", &val );
367     p_sys->i_chroma_elim = val.i_int;
368
369     if( p_enc->fmt_in.i_cat == VIDEO_ES )
370     {
371         int i_aspect_num, i_aspect_den;
372
373         if( !p_enc->fmt_in.video.i_width || !p_enc->fmt_in.video.i_height )
374         {
375             msg_Warn( p_enc, "invalid size %ix%i", p_enc->fmt_in.video.i_width,
376                       p_enc->fmt_in.video.i_height );
377             free( p_sys );
378             return VLC_EGENERIC;
379         }
380
381         p_context->width = p_enc->fmt_in.video.i_width;
382         p_context->height = p_enc->fmt_in.video.i_height;
383         if( p_enc->fmt_out.i_codec == VLC_FOURCC('m', 'p', '2', 'v')
384              && (p_context->width > 720 || p_context->height > 576) )
385             p_context->level = 4; /* High level */
386
387         p_context->time_base.num = p_enc->fmt_in.video.i_frame_rate_base;
388         p_context->time_base.den = p_enc->fmt_in.video.i_frame_rate;
389
390         /* Defaults from ffmpeg.c */
391         p_context->qblur = 0.5;
392         p_context->qcompress = 0.5;
393         p_context->b_quant_offset = 1.25;
394         p_context->b_quant_factor = 1.25;
395         p_context->i_quant_offset = 0.0;
396         p_context->i_quant_factor = -0.8;
397
398         p_context->lumi_masking = p_sys->f_lumi_masking;
399         p_context->dark_masking = p_sys->f_dark_masking;
400         p_context->p_masking = p_sys->f_p_masking;
401         p_context->border_masking = p_sys->f_border_masking;
402         p_context->luma_elim_threshold = p_sys->i_luma_elim;
403         p_context->chroma_elim_threshold = p_sys->i_chroma_elim;
404
405         if( p_sys->i_key_int > 0 )
406             p_context->gop_size = p_sys->i_key_int;
407         p_context->max_b_frames =
408             __MAX( __MIN( p_sys->i_b_frames, FF_MAX_B_FRAMES ), 0 );
409         p_context->b_frame_strategy = 0;
410         if( !p_context->max_b_frames  && 
411             (  p_enc->fmt_out.i_codec == VLC_FOURCC('m', 'p', '2', 'v') ||
412                p_enc->fmt_out.i_codec == VLC_FOURCC('m', 'p', '1', 'v') ) )
413             p_context->flags |= CODEC_FLAG_LOW_DELAY;
414
415         av_reduce( &i_aspect_num, &i_aspect_den,
416                    p_enc->fmt_in.video.i_aspect,
417                    VOUT_ASPECT_FACTOR, 1 << 30 /* something big */ );
418         av_reduce( &p_context->sample_aspect_ratio.num,
419                    &p_context->sample_aspect_ratio.den,
420                    i_aspect_num * (int64_t)p_context->height,
421                    i_aspect_den * (int64_t)p_context->width, 1 << 30 );
422
423         p_sys->p_buffer_out = malloc( p_context->height * p_context->width * 3 );
424
425         p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','0');
426         p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->fmt_in.i_codec );
427         if( p_codec->pix_fmts )
428         {
429             const enum PixelFormat *p = p_codec->pix_fmts;
430             for( ; *p != -1; p++ )
431             {
432                 if( *p == p_context->pix_fmt ) break;
433             }
434             if( *p == -1 ) p_context->pix_fmt = p_codec->pix_fmts[0];
435             p_enc->fmt_in.i_codec = E_(GetVlcChroma)( p_context->pix_fmt );
436         }
437
438         if ( p_sys->b_strict_rc )
439         {
440             p_context->rc_max_rate = p_enc->fmt_out.i_bitrate;
441             p_context->rc_buffer_size = p_sys->i_rc_buffer_size;
442             /* This is from ffmpeg's ffmpeg.c : */
443             p_context->rc_initial_buffer_occupancy
444                 = p_sys->i_rc_buffer_size * 3/4;
445             p_context->rc_buffer_aggressivity = p_sys->f_rc_buffer_aggressivity;
446         }
447
448         if ( p_sys->f_i_quant_factor != 0.0 )
449             p_context->i_quant_factor = p_sys->f_i_quant_factor;
450
451         p_context->noise_reduction = p_sys->i_noise_reduction;
452
453         if ( p_sys->b_mpeg4_matrix )
454         {
455             p_context->intra_matrix = mpeg4_default_intra_matrix;
456             p_context->inter_matrix = mpeg4_default_non_intra_matrix;
457         }
458
459         if ( p_sys->b_pre_me )
460         {
461             p_context->pre_me = 1;
462             p_context->me_pre_cmp = FF_CMP_CHROMA;
463         }
464
465         if ( p_sys->b_interlace )
466         {
467             if ( p_context->height <= 280 )
468             {
469                 if ( p_context->height != 16 || p_context->width != 16 )
470                     msg_Warn( p_enc,
471                         "disabling interlaced video because height=%d <= 280",
472                         p_context->height );
473             }
474             else
475             {
476                 p_context->flags |= CODEC_FLAG_INTERLACED_DCT;
477                 if ( p_sys->b_interlace_me )
478                     p_context->flags |= CODEC_FLAG_INTERLACED_ME;
479             }
480         }
481
482         if ( p_sys->b_trellis )
483             p_context->flags |= CODEC_FLAG_TRELLIS_QUANT;
484
485         if ( p_sys->i_qmin > 0 && p_sys->i_qmin == p_sys->i_qmax )
486             p_context->flags |= CODEC_FLAG_QSCALE;
487
488         if ( p_enc->i_threads >= 1 )
489             p_context->thread_count = p_enc->i_threads;
490
491         if( p_sys->i_vtolerance > 0 )
492             p_context->bit_rate_tolerance = p_sys->i_vtolerance;
493
494         if( p_sys->i_qmin > 0 )
495             p_context->mb_qmin = p_context->qmin = p_sys->i_qmin;
496         if( p_sys->i_qmax > 0 )
497             p_context->mb_qmax = p_context->qmax = p_sys->i_qmax;
498         p_context->max_qdiff = 3;
499
500         p_context->mb_decision = p_sys->i_hq;
501
502         if( p_sys->i_quality )
503         {
504             p_context->flags |= CODEC_FLAG_QSCALE;
505             p_context->global_quality = p_sys->i_quality;
506         }
507     }
508     else if( p_enc->fmt_in.i_cat == AUDIO_ES )
509     {
510         /* work around bug in libmp3lame encoding */
511         if( i_codec_id == CODEC_ID_MP3 && p_enc->fmt_in.audio.i_channels > 2 )
512             p_enc->fmt_in.audio.i_channels = 2;
513
514         p_enc->fmt_in.i_codec  = AOUT_FMT_S16_NE;
515         p_context->sample_rate = p_enc->fmt_in.audio.i_rate;
516         p_context->channels    = p_enc->fmt_in.audio.i_channels;
517     }
518
519     /* Misc parameters */
520     p_context->bit_rate = p_enc->fmt_out.i_bitrate;
521
522     if( i_codec_id == CODEC_ID_RAWVIDEO )
523     {
524         /* XXX: hack: Force same codec (will be handled by transcode) */
525         p_enc->fmt_in.i_codec = p_enc->fmt_out.i_codec;
526         p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->fmt_in.i_codec );
527     }
528
529     /* Make sure we get extradata filled by the encoder */
530     p_context->extradata_size = 0;
531     p_context->extradata = NULL;
532     p_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
533
534     vlc_mutex_lock( lockval.p_address );
535     if( avcodec_open( p_context, p_codec ) )
536     {
537         vlc_mutex_unlock( lockval.p_address );
538         if( p_enc->fmt_in.i_cat == AUDIO_ES &&
539              (p_context->channels > 2 || i_codec_id == CODEC_ID_MP2
540                || i_codec_id == CODEC_ID_MP3) )
541         {
542             if( p_context->channels > 2 )
543             {
544                 p_context->channels = 2;
545                 p_enc->fmt_in.audio.i_channels = 2; // FIXME
546                 msg_Warn( p_enc, "stereo mode selected (codec limitation)" );
547             }
548
549             if( i_codec_id == CODEC_ID_MP2 || i_codec_id == CODEC_ID_MP3 )
550             {
551                 int i_frequency, i;
552
553                 for ( i_frequency = 0; i_frequency < 6; i_frequency++ )
554                 {
555                     if ( p_enc->fmt_out.audio.i_rate
556                             == mpa_freq_tab[i_frequency] )
557                         break;
558                 }
559                 if ( i_frequency == 6 )
560                 {
561                     msg_Err( p_enc, "MPEG audio doesn't support frequency=%d",
562                              p_enc->fmt_out.audio.i_rate );
563                     free( p_sys );
564                     return VLC_EGENERIC;
565                 }
566
567                 for ( i = 1; i < 14; i++ )
568                 {
569                     if ( p_enc->fmt_out.i_bitrate / 1000
570                           <= mpa_bitrate_tab[i_frequency / 3][i] )
571                         break;
572                 }
573                 if ( p_enc->fmt_out.i_bitrate / 1000
574                       != mpa_bitrate_tab[i_frequency / 3][i] )
575                 {
576                     msg_Warn( p_enc,
577                               "MPEG audio doesn't support bitrate=%d, using %d",
578                               p_enc->fmt_out.i_bitrate,
579                               mpa_bitrate_tab[i_frequency / 3][i] * 1000 );
580                     p_enc->fmt_out.i_bitrate =
581                         mpa_bitrate_tab[i_frequency / 3][i] * 1000;
582                     p_context->bit_rate = p_enc->fmt_out.i_bitrate;
583                 }
584             }
585
586             p_context->codec = NULL;
587             vlc_mutex_lock( lockval.p_address );
588             if( avcodec_open( p_context, p_codec ) )
589             {
590                 vlc_mutex_unlock( lockval.p_address );
591                 msg_Err( p_enc, "cannot open encoder" );
592                 intf_UserFatal( p_enc, VLC_FALSE, _("Streaming / Transcoding failed"), 
593                                 _("VLC could not open the encoder.") );
594                 free( p_sys );
595                 return VLC_EGENERIC;
596             }
597         }
598         else
599         {
600             msg_Err( p_enc, "cannot open encoder" );
601             intf_UserFatal( p_enc, VLC_FALSE, _("Streaming / Transcoding failed"), 
602                             _("VLC could not open the encoder.") );
603             free( p_sys );
604             return VLC_EGENERIC;
605         }
606     }
607     vlc_mutex_unlock( lockval.p_address );
608
609     p_enc->fmt_out.i_extra = p_context->extradata_size;
610     if( p_enc->fmt_out.i_extra )
611     {
612         p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra );
613         memcpy( p_enc->fmt_out.p_extra, p_context->extradata,
614                 p_enc->fmt_out.i_extra );
615     }
616     p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
617
618     if( p_enc->fmt_in.i_cat == AUDIO_ES )
619     {
620         p_sys->p_buffer_out = malloc( 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE );
621         p_sys->i_frame_size = p_context->frame_size * 2 * p_context->channels;
622         p_sys->p_buffer = malloc( p_sys->i_frame_size );
623     }
624
625     msg_Dbg( p_enc, "found encoder %s", psz_namecodec );
626
627     return VLC_SUCCESS;
628 }
629
630 /****************************************************************************
631  * Ffmpeg threading system
632  ****************************************************************************/
633 static int FfmpegThread( struct thread_context_t *p_context )
634 {
635     while ( !p_context->b_die && !p_context->b_error )
636     {
637         vlc_mutex_lock( &p_context->lock );
638         while ( !p_context->b_work && !p_context->b_die && !p_context->b_error )
639         {
640             vlc_cond_wait( &p_context->cond, &p_context->lock );
641         }
642         p_context->b_work = 0;
643         vlc_mutex_unlock( &p_context->lock );
644         if ( p_context->b_die || p_context->b_error )
645             break;
646
647         if ( p_context->pf_func )
648         {
649             p_context->i_ret = p_context->pf_func( p_context->p_context,
650                                                    p_context->arg );
651         }
652
653         vlc_mutex_lock( &p_context->lock );
654         p_context->b_done = 1;
655         vlc_cond_signal( &p_context->cond );
656         vlc_mutex_unlock( &p_context->lock );
657     }
658
659     return 0;
660 }
661
662 static int FfmpegExecute( AVCodecContext *s,
663                           int (*pf_func)(AVCodecContext *c2, void *arg2),
664                           void **arg, int *ret, int count )
665 {
666     struct thread_context_t ** pp_contexts =
667                          (struct thread_context_t **)s->thread_opaque;
668     int i;
669
670     /* Note, we can be certain that this is not called with the same
671      * AVCodecContext by different threads at the same time */
672     for ( i = 0; i < count; i++ )
673     {
674         vlc_mutex_lock( &pp_contexts[i]->lock );
675         pp_contexts[i]->arg = arg[i];
676         pp_contexts[i]->pf_func = pf_func;
677         pp_contexts[i]->i_ret = 12345;
678         pp_contexts[i]->b_work = 1;
679         vlc_cond_signal( &pp_contexts[i]->cond );
680         vlc_mutex_unlock( &pp_contexts[i]->lock );
681     }
682     for ( i = 0; i < count; i++ )
683     {
684         vlc_mutex_lock( &pp_contexts[i]->lock );
685         while ( !pp_contexts[i]->b_done )
686         {
687             vlc_cond_wait( &pp_contexts[i]->cond, &pp_contexts[i]->lock );
688         }
689         pp_contexts[i]->b_done = 0;
690         pp_contexts[i]->pf_func = NULL;
691         vlc_mutex_unlock( &pp_contexts[i]->lock );
692
693         if ( ret )
694         {
695             ret[i] = pp_contexts[i]->i_ret;
696         }
697     }
698
699     return 0;
700 }
701
702 /****************************************************************************
703  * EncodeVideo: the whole thing
704  ****************************************************************************/
705 static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
706 {
707     encoder_sys_t *p_sys = p_enc->p_sys;
708     AVFrame frame;
709     int i_out, i_plane;
710
711     if ( !p_sys->b_inited && p_enc->i_threads >= 1 )
712     {
713         struct thread_context_t ** pp_contexts;
714         int i;
715
716         p_sys->b_inited = 1;
717         pp_contexts = malloc( sizeof(struct thread_context_t *)
718                                  * p_enc->i_threads );
719         p_sys->p_context->thread_opaque = (void *)pp_contexts;
720
721         for ( i = 0; i < p_enc->i_threads; i++ )
722         {
723             pp_contexts[i] = vlc_object_create( p_enc,
724                                      sizeof(struct thread_context_t) );
725             pp_contexts[i]->p_context = p_sys->p_context;
726             vlc_mutex_init( p_enc, &pp_contexts[i]->lock );
727             vlc_cond_init( p_enc, &pp_contexts[i]->cond );
728             pp_contexts[i]->b_work = 0;
729             pp_contexts[i]->b_done = 0;
730             if ( vlc_thread_create( pp_contexts[i], "encoder", FfmpegThread,
731                                     VLC_THREAD_PRIORITY_VIDEO, VLC_FALSE ) )
732             {
733                 msg_Err( p_enc, "cannot spawn encoder thread, expect to die soon" );
734                 return NULL;
735             }
736         }
737
738         p_sys->p_context->execute = FfmpegExecute;
739     }
740
741     memset( &frame, 0, sizeof( AVFrame ) );
742     for( i_plane = 0; i_plane < p_pict->i_planes; i_plane++ )
743     {
744         frame.data[i_plane] = p_pict->p[i_plane].p_pixels;
745         frame.linesize[i_plane] = p_pict->p[i_plane].i_pitch;
746     }
747
748     /* Let ffmpeg select the frame type */
749     frame.pict_type = 0;
750
751     frame.repeat_pict = p_pict->i_nb_fields - 2;
752     frame.interlaced_frame = !p_pict->b_progressive;
753     frame.top_field_first = !!p_pict->b_top_field_first;
754
755     /* Set the pts of the frame being encoded (segfaults with mpeg4!)*/
756     if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', 'g', 'v' ) ||
757         p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', '1', 'v' ) ||
758         p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', '2', 'v' ) )
759     {
760         frame.pts = p_pict->date ? p_pict->date : (signed int) AV_NOPTS_VALUE;
761
762         if ( p_sys->b_hurry_up && frame.pts != (signed int) AV_NOPTS_VALUE )
763         {
764             mtime_t current_date = mdate();
765
766             if ( current_date + HURRY_UP_GUARD3 > frame.pts )
767             {
768                 p_sys->p_context->mb_decision = FF_MB_DECISION_SIMPLE;
769                 p_sys->p_context->flags &= ~CODEC_FLAG_TRELLIS_QUANT;
770                 msg_Dbg( p_enc, "hurry up mode 3" );
771             }
772             else
773             {
774                 p_sys->p_context->mb_decision = p_sys->i_hq;
775
776                 if ( current_date + HURRY_UP_GUARD2 > frame.pts )
777                 {
778                     p_sys->p_context->flags &= ~CODEC_FLAG_TRELLIS_QUANT;
779                     p_sys->p_context->noise_reduction = p_sys->i_noise_reduction
780                          + (HURRY_UP_GUARD2 + current_date - frame.pts) / 500;
781                     msg_Dbg( p_enc, "hurry up mode 2" );
782                 }
783                 else
784                 {
785                     if ( p_sys->b_trellis )
786                         p_sys->p_context->flags |= CODEC_FLAG_TRELLIS_QUANT;
787                         
788                     p_sys->p_context->noise_reduction =
789                         p_sys->i_noise_reduction;
790                 }
791             }
792
793             if ( current_date + HURRY_UP_GUARD1 > frame.pts )
794             {
795                 frame.pict_type = FF_P_TYPE;
796                 /* msg_Dbg( p_enc, "hurry up mode 1 %lld", current_date + HURRY_UP_GUARD1 - frame.pts ); */
797             }
798         }
799     }
800     else
801     {
802         frame.pts = AV_NOPTS_VALUE;
803     }
804
805     if ( frame.pts != (signed int) AV_NOPTS_VALUE && frame.pts != 0 )
806     {
807         if ( p_sys->i_last_pts == frame.pts )
808         {
809             msg_Warn( p_enc, "almost fed libavcodec with two frames with the "
810                       "same PTS (" I64Fd ")", frame.pts );
811             return NULL;
812         }
813         else if ( p_sys->i_last_pts > frame.pts )
814         {
815             msg_Warn( p_enc, "almost fed libavcodec with a frame in the "
816                       "past (current: " I64Fd ", last: "I64Fd")",
817                       frame.pts, p_sys->i_last_pts );
818             return NULL;
819         }
820         else
821         {
822             p_sys->i_last_pts = frame.pts;
823         }
824     }
825
826     frame.quality = p_sys->i_quality;
827
828     /* Ugly work-around for stupid libavcodec behaviour */
829     p_sys->i_framenum++;
830     p_sys->pi_delay_pts[p_sys->i_framenum % MAX_FRAME_DELAY] = frame.pts;
831     frame.pts = p_sys->i_framenum * AV_TIME_BASE *
832         p_enc->fmt_in.video.i_frame_rate_base;
833     frame.pts += p_enc->fmt_in.video.i_frame_rate - 1;
834     frame.pts /= p_enc->fmt_in.video.i_frame_rate;
835     /* End work-around */
836
837     i_out = avcodec_encode_video( p_sys->p_context, (uint8_t*)p_sys->p_buffer_out,
838                                   p_sys->p_context->height * p_sys->p_context->width * 3, &frame );
839
840     if( i_out > 0 )
841     {
842         block_t *p_block = block_New( p_enc, i_out );
843         memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );
844
845         /* FIXME, 3-2 pulldown is not handled correctly */
846         p_block->i_length = I64C(1000000) *
847             p_enc->fmt_in.video.i_frame_rate_base /
848                 p_enc->fmt_in.video.i_frame_rate;
849
850         if( !p_sys->p_context->max_b_frames || !p_sys->p_context->delay )
851         {
852             /* No delay -> output pts == input pts */
853             p_block->i_pts = p_block->i_dts = p_pict->date;
854         }
855         else if( p_sys->p_context->coded_frame->pts != (signed int) AV_NOPTS_VALUE &&
856             p_sys->p_context->coded_frame->pts != 0 &&
857             p_sys->i_buggy_pts_detect != p_sys->p_context->coded_frame->pts )
858         {
859             p_sys->i_buggy_pts_detect = p_sys->p_context->coded_frame->pts;
860             p_block->i_pts = p_sys->p_context->coded_frame->pts;
861
862             /* Ugly work-around for stupid libavcodec behaviour */
863             {
864             int64_t i_framenum = p_block->i_pts *
865                 p_enc->fmt_in.video.i_frame_rate /
866                 p_enc->fmt_in.video.i_frame_rate_base / AV_TIME_BASE;
867
868             p_block->i_pts = p_sys->pi_delay_pts[i_framenum % MAX_FRAME_DELAY];
869             }
870             /* End work-around */
871
872             if( p_sys->p_context->coded_frame->pict_type != FF_I_TYPE &&
873                 p_sys->p_context->coded_frame->pict_type != FF_P_TYPE )
874             {
875                 p_block->i_dts = p_block->i_pts;
876             }
877             else
878             {
879                 if( p_sys->i_last_ref_pts )
880                 {
881                     p_block->i_dts = p_sys->i_last_ref_pts;
882                 }
883                 else
884                 {
885                     /* Let's put something sensible */
886                     p_block->i_dts = p_block->i_pts;
887                 }
888
889                 p_sys->i_last_ref_pts = p_block->i_pts;
890             }
891         }
892         else
893         {
894             /* Buggy libavcodec which doesn't update coded_frame->pts
895              * correctly */
896             p_block->i_dts = p_block->i_pts = p_pict->date;
897         }
898
899         switch ( p_sys->p_context->coded_frame->pict_type )
900         {
901         case FF_I_TYPE:
902             p_block->i_flags |= BLOCK_FLAG_TYPE_I;
903             break;
904         case FF_P_TYPE:
905             p_block->i_flags |= BLOCK_FLAG_TYPE_P;
906             break;
907         case FF_B_TYPE:
908             p_block->i_flags |= BLOCK_FLAG_TYPE_B;
909             break;
910         }
911
912         return p_block;
913     }
914
915     return NULL;
916 }
917
918 /****************************************************************************
919  * EncodeAudio: the whole thing
920  ****************************************************************************/
921 static block_t *EncodeAudio( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
922 {
923     encoder_sys_t *p_sys = p_enc->p_sys;
924     block_t *p_block, *p_chain = NULL;
925
926     uint8_t *p_buffer = p_aout_buf->p_buffer;
927     int i_samples = p_aout_buf->i_nb_samples;
928     int i_samples_delay = p_sys->i_samples_delay;
929
930     p_sys->i_pts = p_aout_buf->start_date -
931                 (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
932                 (mtime_t)p_enc->fmt_in.audio.i_rate;
933
934     p_sys->i_samples_delay += i_samples;
935
936     while( p_sys->i_samples_delay >= p_sys->p_context->frame_size )
937     {
938         int16_t *p_samples;
939         int i_out;
940
941         if( i_samples_delay )
942         {
943             /* Take care of the left-over from last time */
944             int i_delay_size = i_samples_delay * 2 *
945                                  p_sys->p_context->channels;
946             int i_size = p_sys->i_frame_size - i_delay_size;
947
948             p_samples = (int16_t *)p_sys->p_buffer;
949             memcpy( p_sys->p_buffer + i_delay_size, p_buffer, i_size );
950             p_buffer -= i_delay_size;
951             i_samples += i_samples_delay;
952             i_samples_delay = 0;
953         }
954         else
955         {
956             p_samples = (int16_t *)p_buffer;
957         }
958
959         i_out = avcodec_encode_audio( p_sys->p_context, (uint8_t *)p_sys->p_buffer_out,
960                                       2 * AVCODEC_MAX_AUDIO_FRAME_SIZE,
961                                       p_samples );
962
963 #if 0
964         msg_Warn( p_enc, "avcodec_encode_audio: %d", i_out );
965 #endif
966         if( i_out < 0 ) break;
967
968         p_buffer += p_sys->i_frame_size;
969         p_sys->i_samples_delay -= p_sys->p_context->frame_size;
970         i_samples -= p_sys->p_context->frame_size;
971
972         if( i_out == 0 ) continue;
973
974         p_block = block_New( p_enc, i_out );
975         memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );
976
977         p_block->i_length = (mtime_t)1000000 *
978             (mtime_t)p_sys->p_context->frame_size /
979             (mtime_t)p_sys->p_context->sample_rate;
980
981         p_block->i_dts = p_block->i_pts = p_sys->i_pts;
982
983         /* Update pts */
984         p_sys->i_pts += p_block->i_length;
985         block_ChainAppend( &p_chain, p_block );
986     }
987
988     /* Backup the remaining raw samples */
989     if( i_samples )
990     {
991         memcpy( p_sys->p_buffer + i_samples_delay * 2 *
992                 p_sys->p_context->channels, p_buffer,
993                 i_samples * 2 * p_sys->p_context->channels );
994     }
995
996     return p_chain;
997 }
998
999 /*****************************************************************************
1000  * CloseEncoder: ffmpeg encoder destruction
1001  *****************************************************************************/
1002 void E_(CloseEncoder)( vlc_object_t *p_this )
1003 {
1004     encoder_t *p_enc = (encoder_t *)p_this;
1005     encoder_sys_t *p_sys = p_enc->p_sys;
1006     vlc_value_t lockval;
1007
1008     var_Get( p_enc->p_libvlc_global, "avcodec", &lockval );
1009
1010     if ( p_sys->b_inited && p_enc->i_threads >= 1 )
1011     {
1012         int i;
1013         struct thread_context_t ** pp_contexts =
1014                 (struct thread_context_t **)p_sys->p_context->thread_opaque;
1015         for ( i = 0; i < p_enc->i_threads; i++ )
1016         {
1017             pp_contexts[i]->b_die = 1;
1018             vlc_cond_signal( &pp_contexts[i]->cond );
1019             vlc_thread_join( pp_contexts[i] );
1020             vlc_mutex_destroy( &pp_contexts[i]->lock );
1021             vlc_cond_destroy( &pp_contexts[i]->cond );
1022             vlc_object_destroy( pp_contexts[i] );
1023         }
1024
1025         free( pp_contexts );
1026     }
1027
1028     vlc_mutex_lock( lockval.p_address );
1029     avcodec_close( p_sys->p_context );
1030     vlc_mutex_unlock( lockval.p_address );
1031     av_free( p_sys->p_context );
1032
1033     if( p_sys->p_buffer ) free( p_sys->p_buffer );
1034     if( p_sys->p_buffer_out ) free( p_sys->p_buffer_out );
1035
1036     free( p_sys );
1037 }