1 /*****************************************************************************
2 * encoder.c: video and audio encoder using the ffmpeg library
3 *****************************************************************************
4 * Copyright (C) 1999-2004 the VideoLAN team
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)
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.
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.
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 *****************************************************************************/
28 /*****************************************************************************
30 *****************************************************************************/
39 #include <vlc_codec.h>
40 #include <vlc_interface.h>
44 #ifdef HAVE_LIBAVCODEC_AVCODEC_H
45 # include <libavcodec/avcodec.h>
46 #elif defined(HAVE_FFMPEG_AVCODEC_H)
47 # include <ffmpeg/avcodec.h>
54 #define HURRY_UP_GUARD1 (450000)
55 #define HURRY_UP_GUARD2 (300000)
56 #define HURRY_UP_GUARD3 (100000)
58 #define MAX_FRAME_DELAY (FF_MAX_B_FRAMES + 2)
60 /*****************************************************************************
62 *****************************************************************************/
63 int E_(OpenEncoder) ( vlc_object_t * );
64 void E_(CloseEncoder)( vlc_object_t * );
66 static block_t *EncodeVideo( encoder_t *, picture_t * );
67 static block_t *EncodeAudio( encoder_t *, aout_buffer_t * );
69 struct thread_context_t;
70 static int FfmpegThread( struct thread_context_t *p_context );
71 static int FfmpegExecute( AVCodecContext *s,
72 int (*pf_func)(AVCodecContext *c2, void *arg2),
73 void **arg, int *ret, int count );
75 /*****************************************************************************
76 * thread_context_t : for multithreaded encoding
77 *****************************************************************************/
78 struct thread_context_t
82 AVCodecContext *p_context;
83 int (* pf_func)(AVCodecContext *c, void *arg);
89 vlc_bool_t b_work, b_done;
92 /*****************************************************************************
93 * encoder_sys_t : ffmpeg encoder descriptor
94 *****************************************************************************/
101 AVCodecContext *p_context;
112 mtime_t i_last_ref_pts;
113 mtime_t i_buggy_pts_detect;
124 /* Encoding settings */
131 vlc_bool_t b_strict_rc;
132 int i_rc_buffer_size;
133 float f_rc_buffer_aggressivity;
135 vlc_bool_t b_hurry_up;
136 vlc_bool_t b_interlace, b_interlace_me;
137 float f_i_quant_factor;
138 int i_noise_reduction;
139 vlc_bool_t b_mpeg4_matrix;
140 vlc_bool_t b_trellis;
141 int i_quality; /* for VBR */
142 float f_lumi_masking, f_dark_masking, f_p_masking, f_border_masking;
143 int i_luma_elim, i_chroma_elim;
145 /* Used to work around stupid timestamping behaviour in libavcodec */
147 mtime_t pi_delay_pts[MAX_FRAME_DELAY];
150 static const char *ppsz_enc_options[] = {
151 "keyint", "bframes", "vt", "qmin", "qmax", "hq", "strict-rc",
152 "rc-buffer-size", "rc-buffer-aggressivity", "pre-me", "hurry-up",
153 "interlace", "i-quant-factor", "noise-reduction", "mpeg4-matrix",
154 "trellis", "qscale", "strict", "lumi-masking", "dark-masking",
155 "p-masking", "border-masking", "luma-elim-threshold",
156 "chroma-elim-threshold", NULL
159 static const uint16_t mpa_bitrate_tab[2][15] =
161 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384},
162 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
165 static const uint16_t mpa_freq_tab[6] =
166 { 44100, 48000, 32000, 22050, 24000, 16000 };
168 static const uint16_t mpeg4_default_intra_matrix[64] = {
169 8, 17, 18, 19, 21, 23, 25, 27,
170 17, 18, 19, 21, 23, 25, 27, 28,
171 20, 21, 22, 23, 24, 26, 28, 30,
172 21, 22, 23, 24, 26, 28, 30, 32,
173 22, 23, 24, 26, 28, 30, 32, 35,
174 23, 24, 26, 28, 30, 32, 35, 38,
175 25, 26, 28, 30, 32, 35, 38, 41,
176 27, 28, 30, 32, 35, 38, 41, 45,
179 static const uint16_t mpeg4_default_non_intra_matrix[64] = {
180 16, 17, 18, 19, 20, 21, 22, 23,
181 17, 18, 19, 20, 21, 22, 23, 24,
182 18, 19, 20, 21, 22, 23, 24, 25,
183 19, 20, 21, 22, 23, 24, 26, 27,
184 20, 21, 22, 23, 25, 26, 27, 28,
185 21, 22, 23, 24, 26, 27, 28, 30,
186 22, 23, 24, 26, 27, 28, 30, 31,
187 23, 24, 25, 27, 28, 30, 31, 33,
191 /*****************************************************************************
192 * OpenEncoder: probe the encoder
193 *****************************************************************************/
195 int E_(OpenEncoder)( vlc_object_t *p_this )
197 encoder_t *p_enc = (encoder_t *)p_this;
198 encoder_sys_t *p_sys = p_enc->p_sys;
199 AVCodecContext *p_context;
201 int i_codec_id, i_cat;
202 const char *psz_namecodec;
205 if( !E_(GetFfmpegCodec)( p_enc->fmt_out.i_codec, &i_cat, &i_codec_id,
208 if( E_(GetFfmpegChroma)( p_enc->fmt_out.i_codec ) < 0 )
210 /* handed chroma output */
214 i_codec_id = CODEC_ID_RAWVIDEO;
215 psz_namecodec = "Raw video";
218 if( p_enc->fmt_out.i_cat == VIDEO_ES && i_cat != VIDEO_ES )
220 msg_Err( p_enc, "\"%s\" is not a video encoder", psz_namecodec );
221 intf_UserFatal( p_enc, VLC_FALSE, _("Streaming / Transcoding failed"),
222 _("\"%s\" is no video encoder."), psz_namecodec );
226 if( p_enc->fmt_out.i_cat == AUDIO_ES && i_cat != AUDIO_ES )
228 msg_Err( p_enc, "\"%s\" is not an audio encoder", psz_namecodec );
229 intf_UserFatal( p_enc, VLC_FALSE, _("Streaming / Transcoding failed"),
230 _("\"%s\" is no audio encoder."), psz_namecodec );
234 /* Initialization must be done before avcodec_find_encoder() */
235 E_(InitLibavcodec)(p_this);
237 p_codec = avcodec_find_encoder( i_codec_id );
240 msg_Err( p_enc, "cannot find encoder %s", psz_namecodec );
241 intf_UserFatal( p_enc, VLC_FALSE, _("Streaming / Transcoding failed"),
242 _("VLC could not find encoder \"%s\"."), psz_namecodec );
246 /* Allocate the memory needed to store the encoder's structure */
247 if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
249 msg_Err( p_enc, "out of memory" );
252 memset( p_sys, 0, sizeof(encoder_sys_t) );
253 p_enc->p_sys = p_sys;
254 p_sys->p_codec = p_codec;
256 p_enc->pf_encode_video = EncodeVideo;
257 p_enc->pf_encode_audio = EncodeAudio;
259 p_sys->p_buffer_out = NULL;
260 p_sys->p_buffer = NULL;
262 p_sys->p_context = p_context = avcodec_alloc_context();
263 p_context->debug = config_GetInt( p_enc, "ffmpeg-debug" );
264 p_context->opaque = (void *)p_this;
266 /* Set CPU capabilities */
267 unsigned i_cpu = vlc_CPU();
268 p_context->dsp_mask = 0;
269 if( !(i_cpu & CPU_CAPABILITY_MMX) )
271 p_context->dsp_mask |= FF_MM_MMX;
273 if( !(i_cpu & CPU_CAPABILITY_MMXEXT) )
275 p_context->dsp_mask |= FF_MM_MMXEXT;
277 if( !(i_cpu & CPU_CAPABILITY_3DNOW) )
279 p_context->dsp_mask |= FF_MM_3DNOW;
281 if( !(i_cpu & CPU_CAPABILITY_SSE) )
283 p_context->dsp_mask |= FF_MM_SSE;
284 p_context->dsp_mask |= FF_MM_SSE2;
287 config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
289 var_Get( p_enc, ENC_CFG_PREFIX "keyint", &val );
290 p_sys->i_key_int = val.i_int;
292 var_Get( p_enc, ENC_CFG_PREFIX "bframes", &val );
293 p_sys->i_b_frames = val.i_int;
295 var_Get( p_enc, ENC_CFG_PREFIX "vt", &val );
296 p_sys->i_vtolerance = val.i_int;
298 var_Get( p_enc, ENC_CFG_PREFIX "interlace", &val );
299 p_sys->b_interlace = val.b_bool;
301 var_Get( p_enc, ENC_CFG_PREFIX "interlace-me", &val );
302 p_sys->b_interlace_me = val.b_bool;
304 var_Get( p_enc, ENC_CFG_PREFIX "pre-me", &val );
305 p_sys->b_pre_me = val.b_bool;
307 var_Get( p_enc, ENC_CFG_PREFIX "hurry-up", &val );
308 p_sys->b_hurry_up = val.b_bool;
309 if( p_sys->b_hurry_up )
311 /* hurry up mode needs noise reduction, even small */
312 p_sys->i_noise_reduction = 1;
315 var_Get( p_enc, ENC_CFG_PREFIX "strict-rc", &val );
316 p_sys->b_strict_rc = val.b_bool;
317 var_Get( p_enc, ENC_CFG_PREFIX "rc-buffer-size", &val );
318 p_sys->i_rc_buffer_size = val.i_int;
319 var_Get( p_enc, ENC_CFG_PREFIX "rc-buffer-aggressivity", &val );
320 p_sys->f_rc_buffer_aggressivity = val.f_float;
322 var_Get( p_enc, ENC_CFG_PREFIX "i-quant-factor", &val );
323 p_sys->f_i_quant_factor = val.f_float;
325 var_Get( p_enc, ENC_CFG_PREFIX "noise-reduction", &val );
326 p_sys->i_noise_reduction = val.i_int;
328 var_Get( p_enc, ENC_CFG_PREFIX "mpeg4-matrix", &val );
329 p_sys->b_mpeg4_matrix = val.b_bool;
331 var_Get( p_enc, ENC_CFG_PREFIX "qscale", &val );
332 if( val.f_float < 0.01 || val.f_float > 255.0 ) val.f_float = 0;
333 p_sys->i_quality = (int)(FF_QP2LAMBDA * val.f_float + 0.5);
335 var_Get( p_enc, ENC_CFG_PREFIX "hq", &val );
336 if( val.psz_string && *val.psz_string )
338 if( !strcmp( val.psz_string, "rd" ) )
339 p_sys->i_hq = FF_MB_DECISION_RD;
340 else if( !strcmp( val.psz_string, "bits" ) )
341 p_sys->i_hq = FF_MB_DECISION_BITS;
342 else if( !strcmp( val.psz_string, "simple" ) )
343 p_sys->i_hq = FF_MB_DECISION_SIMPLE;
345 p_sys->i_hq = FF_MB_DECISION_RD;
348 p_sys->i_hq = FF_MB_DECISION_RD;
349 if( val.psz_string ) free( val.psz_string );
351 var_Get( p_enc, ENC_CFG_PREFIX "qmin", &val );
352 p_sys->i_qmin = val.i_int;
353 var_Get( p_enc, ENC_CFG_PREFIX "qmax", &val );
354 p_sys->i_qmax = val.i_int;
355 var_Get( p_enc, ENC_CFG_PREFIX "trellis", &val );
356 p_sys->b_trellis = val.b_bool;
358 var_Get( p_enc, ENC_CFG_PREFIX "strict", &val );
359 if( val.i_int < - 1 || val.i_int > 1 ) val.i_int = 0;
360 p_context->strict_std_compliance = val.i_int;
362 var_Get( p_enc, ENC_CFG_PREFIX "lumi-masking", &val );
363 p_sys->f_lumi_masking = val.f_float;
364 var_Get( p_enc, ENC_CFG_PREFIX "dark-masking", &val );
365 p_sys->f_dark_masking = val.f_float;
366 var_Get( p_enc, ENC_CFG_PREFIX "p-masking", &val );
367 p_sys->f_p_masking = val.f_float;
368 var_Get( p_enc, ENC_CFG_PREFIX "border-masking", &val );
369 p_sys->f_border_masking = val.f_float;
370 var_Get( p_enc, ENC_CFG_PREFIX "luma-elim-threshold", &val );
371 p_sys->i_luma_elim = val.i_int;
372 var_Get( p_enc, ENC_CFG_PREFIX "chroma-elim-threshold", &val );
373 p_sys->i_chroma_elim = val.i_int;
375 if( p_enc->fmt_in.i_cat == VIDEO_ES )
377 int i_aspect_num, i_aspect_den;
379 if( !p_enc->fmt_in.video.i_width || !p_enc->fmt_in.video.i_height )
381 msg_Warn( p_enc, "invalid size %ix%i", p_enc->fmt_in.video.i_width,
382 p_enc->fmt_in.video.i_height );
387 p_context->width = p_enc->fmt_in.video.i_width;
388 p_context->height = p_enc->fmt_in.video.i_height;
389 if( p_enc->fmt_out.i_codec == VLC_FOURCC('m', 'p', '2', 'v')
390 && (p_context->width > 720 || p_context->height > 576) )
391 p_context->level = 4; /* High level */
393 p_context->time_base.num = p_enc->fmt_in.video.i_frame_rate_base;
394 p_context->time_base.den = p_enc->fmt_in.video.i_frame_rate;
396 /* Defaults from ffmpeg.c */
397 p_context->qblur = 0.5;
398 p_context->qcompress = 0.5;
399 p_context->b_quant_offset = 1.25;
400 p_context->b_quant_factor = 1.25;
401 p_context->i_quant_offset = 0.0;
402 p_context->i_quant_factor = -0.8;
404 p_context->lumi_masking = p_sys->f_lumi_masking;
405 p_context->dark_masking = p_sys->f_dark_masking;
406 p_context->p_masking = p_sys->f_p_masking;
407 p_context->border_masking = p_sys->f_border_masking;
408 p_context->luma_elim_threshold = p_sys->i_luma_elim;
409 p_context->chroma_elim_threshold = p_sys->i_chroma_elim;
411 if( p_sys->i_key_int > 0 )
412 p_context->gop_size = p_sys->i_key_int;
413 p_context->max_b_frames =
414 __MAX( __MIN( p_sys->i_b_frames, FF_MAX_B_FRAMES ), 0 );
415 p_context->b_frame_strategy = 0;
416 if( !p_context->max_b_frames &&
417 ( p_enc->fmt_out.i_codec == VLC_FOURCC('m', 'p', '2', 'v') ||
418 p_enc->fmt_out.i_codec == VLC_FOURCC('m', 'p', '1', 'v') ) )
419 p_context->flags |= CODEC_FLAG_LOW_DELAY;
421 av_reduce( &i_aspect_num, &i_aspect_den,
422 p_enc->fmt_in.video.i_aspect,
423 VOUT_ASPECT_FACTOR, 1 << 30 /* something big */ );
424 av_reduce( &p_context->sample_aspect_ratio.num,
425 &p_context->sample_aspect_ratio.den,
426 i_aspect_num * (int64_t)p_context->height,
427 i_aspect_den * (int64_t)p_context->width, 1 << 30 );
429 p_sys->p_buffer_out = malloc( p_context->height * p_context->width * 3 );
431 p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','0');
432 p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->fmt_in.i_codec );
433 if( p_codec->pix_fmts )
435 const enum PixelFormat *p = p_codec->pix_fmts;
436 for( ; *p != -1; p++ )
438 if( *p == p_context->pix_fmt ) break;
440 if( *p == -1 ) p_context->pix_fmt = p_codec->pix_fmts[0];
441 p_enc->fmt_in.i_codec = E_(GetVlcChroma)( p_context->pix_fmt );
444 if ( p_sys->b_strict_rc )
446 p_context->rc_max_rate = p_enc->fmt_out.i_bitrate;
447 p_context->rc_min_rate = p_enc->fmt_out.i_bitrate;
448 p_context->rc_buffer_size = p_sys->i_rc_buffer_size;
449 /* This is from ffmpeg's ffmpeg.c : */
450 p_context->rc_initial_buffer_occupancy
451 = p_sys->i_rc_buffer_size * 3/4;
452 p_context->rc_buffer_aggressivity = p_sys->f_rc_buffer_aggressivity;
455 if ( p_sys->f_i_quant_factor != 0.0 )
456 p_context->i_quant_factor = p_sys->f_i_quant_factor;
458 p_context->noise_reduction = p_sys->i_noise_reduction;
460 if ( p_sys->b_mpeg4_matrix )
462 p_context->intra_matrix = mpeg4_default_intra_matrix;
463 p_context->inter_matrix = mpeg4_default_non_intra_matrix;
466 if ( p_sys->b_pre_me )
468 p_context->pre_me = 1;
469 p_context->me_pre_cmp = FF_CMP_CHROMA;
472 if ( p_sys->b_interlace )
474 if ( p_context->height <= 280 )
476 if ( p_context->height != 16 || p_context->width != 16 )
478 "disabling interlaced video because height=%d <= 280",
483 p_context->flags |= CODEC_FLAG_INTERLACED_DCT;
484 if ( p_sys->b_interlace_me )
485 p_context->flags |= CODEC_FLAG_INTERLACED_ME;
489 if ( p_sys->b_trellis )
490 p_context->flags |= CODEC_FLAG_TRELLIS_QUANT;
492 if ( p_sys->i_qmin > 0 && p_sys->i_qmin == p_sys->i_qmax )
493 p_context->flags |= CODEC_FLAG_QSCALE;
495 if ( p_enc->i_threads >= 1 )
496 p_context->thread_count = p_enc->i_threads;
498 if( p_sys->i_vtolerance > 0 )
499 p_context->bit_rate_tolerance = p_sys->i_vtolerance;
501 /* usually if someone sets bitrate, he likes more to get that bitrate over quality
502 * should help 'normal' user to get asked bitrate
504 if( p_enc->fmt_out.i_bitrate > 0 && p_sys->i_qmax == 0 && p_sys->i_qmin == 0 )
510 if( p_sys->i_qmin > 0 )
512 p_context->mb_qmin = p_context->qmin = p_sys->i_qmin;
513 p_context->mb_lmin = p_context->lmin = p_sys->i_qmin * FF_QP2LAMBDA;
515 if( p_sys->i_qmax > 0 )
517 p_context->mb_qmax = p_context->qmax = p_sys->i_qmax;
518 p_context->mb_lmax = p_context->lmax = p_sys->i_qmax * FF_QP2LAMBDA;
520 p_context->max_qdiff = 3;
522 p_context->mb_decision = p_sys->i_hq;
524 if( p_sys->i_quality )
526 p_context->flags |= CODEC_FLAG_QSCALE;
527 p_context->global_quality = p_sys->i_quality;
530 else if( p_enc->fmt_in.i_cat == AUDIO_ES )
532 /* work around bug in libmp3lame encoding */
533 if( i_codec_id == CODEC_ID_MP3 && p_enc->fmt_in.audio.i_channels > 2 )
534 p_enc->fmt_in.audio.i_channels = 2;
536 p_enc->fmt_in.i_codec = AOUT_FMT_S16_NE;
537 p_context->sample_rate = p_enc->fmt_in.audio.i_rate;
538 p_context->channels = p_enc->fmt_in.audio.i_channels;
541 /* Misc parameters */
542 p_context->bit_rate = p_enc->fmt_out.i_bitrate;
544 if( i_codec_id == CODEC_ID_RAWVIDEO )
546 /* XXX: hack: Force same codec (will be handled by transcode) */
547 p_enc->fmt_in.i_codec = p_enc->fmt_out.i_codec;
548 p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->fmt_in.i_codec );
551 /* Make sure we get extradata filled by the encoder */
552 p_context->extradata_size = 0;
553 p_context->extradata = NULL;
554 p_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
556 vlc_mutex_t *lock = var_AcquireMutex( "avcodec" );
558 if( avcodec_open( p_context, p_codec ) )
560 vlc_mutex_unlock( lock );
561 if( p_enc->fmt_in.i_cat == AUDIO_ES &&
562 (p_context->channels > 2 || i_codec_id == CODEC_ID_MP2
563 || i_codec_id == CODEC_ID_MP3) )
565 if( p_context->channels > 2 )
567 p_context->channels = 2;
568 p_enc->fmt_in.audio.i_channels = 2; // FIXME
569 msg_Warn( p_enc, "stereo mode selected (codec limitation)" );
572 if( i_codec_id == CODEC_ID_MP2 || i_codec_id == CODEC_ID_MP3 )
576 for ( i_frequency = 0; i_frequency < 6; i_frequency++ )
578 if ( p_enc->fmt_out.audio.i_rate
579 == mpa_freq_tab[i_frequency] )
582 if ( i_frequency == 6 )
584 msg_Err( p_enc, "MPEG audio doesn't support frequency=%d",
585 p_enc->fmt_out.audio.i_rate );
590 for ( i = 1; i < 14; i++ )
592 if ( p_enc->fmt_out.i_bitrate / 1000
593 <= mpa_bitrate_tab[i_frequency / 3][i] )
596 if ( p_enc->fmt_out.i_bitrate / 1000
597 != mpa_bitrate_tab[i_frequency / 3][i] )
600 "MPEG audio doesn't support bitrate=%d, using %d",
601 p_enc->fmt_out.i_bitrate,
602 mpa_bitrate_tab[i_frequency / 3][i] * 1000 );
603 p_enc->fmt_out.i_bitrate =
604 mpa_bitrate_tab[i_frequency / 3][i] * 1000;
605 p_context->bit_rate = p_enc->fmt_out.i_bitrate;
609 p_context->codec = NULL;
610 vlc_mutex_lock( lock );
611 if( avcodec_open( p_context, p_codec ) )
613 vlc_mutex_unlock( lock );
614 msg_Err( p_enc, "cannot open encoder" );
615 intf_UserFatal( p_enc, VLC_FALSE, _("Streaming / Transcoding failed"),
616 _("VLC could not open the encoder.") );
623 msg_Err( p_enc, "cannot open encoder" );
624 intf_UserFatal( p_enc, VLC_FALSE, _("Streaming / Transcoding failed"),
625 _("VLC could not open the encoder.") );
630 vlc_mutex_unlock( lock);
632 p_enc->fmt_out.i_extra = p_context->extradata_size;
633 if( p_enc->fmt_out.i_extra )
635 p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra );
636 memcpy( p_enc->fmt_out.p_extra, p_context->extradata,
637 p_enc->fmt_out.i_extra );
639 p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
641 if( p_enc->fmt_in.i_cat == AUDIO_ES )
643 p_sys->p_buffer_out = malloc( 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE );
644 p_sys->i_frame_size = p_context->frame_size * 2 * p_context->channels;
645 p_sys->p_buffer = malloc( p_sys->i_frame_size );
646 p_enc->fmt_out.audio.i_blockalign = p_context->block_align;
649 msg_Dbg( p_enc, "found encoder %s", psz_namecodec );
654 /****************************************************************************
655 * Ffmpeg threading system
656 ****************************************************************************/
657 static int FfmpegThread( struct thread_context_t *p_context )
659 while ( !p_context->b_die && !p_context->b_error )
661 vlc_mutex_lock( &p_context->lock );
662 while ( !p_context->b_work && !p_context->b_die && !p_context->b_error )
664 vlc_cond_wait( &p_context->cond, &p_context->lock );
666 p_context->b_work = 0;
667 vlc_mutex_unlock( &p_context->lock );
668 if ( p_context->b_die || p_context->b_error )
671 if ( p_context->pf_func )
673 p_context->i_ret = p_context->pf_func( p_context->p_context,
677 vlc_mutex_lock( &p_context->lock );
678 p_context->b_done = 1;
679 vlc_cond_signal( &p_context->cond );
680 vlc_mutex_unlock( &p_context->lock );
686 static int FfmpegExecute( AVCodecContext *s,
687 int (*pf_func)(AVCodecContext *c2, void *arg2),
688 void **arg, int *ret, int count )
690 struct thread_context_t ** pp_contexts =
691 (struct thread_context_t **)s->thread_opaque;
694 /* Note, we can be certain that this is not called with the same
695 * AVCodecContext by different threads at the same time */
696 for ( i = 0; i < count; i++ )
698 vlc_mutex_lock( &pp_contexts[i]->lock );
699 pp_contexts[i]->arg = arg[i];
700 pp_contexts[i]->pf_func = pf_func;
701 pp_contexts[i]->i_ret = 12345;
702 pp_contexts[i]->b_work = 1;
703 vlc_cond_signal( &pp_contexts[i]->cond );
704 vlc_mutex_unlock( &pp_contexts[i]->lock );
706 for ( i = 0; i < count; i++ )
708 vlc_mutex_lock( &pp_contexts[i]->lock );
709 while ( !pp_contexts[i]->b_done )
711 vlc_cond_wait( &pp_contexts[i]->cond, &pp_contexts[i]->lock );
713 pp_contexts[i]->b_done = 0;
714 pp_contexts[i]->pf_func = NULL;
715 vlc_mutex_unlock( &pp_contexts[i]->lock );
719 ret[i] = pp_contexts[i]->i_ret;
726 /****************************************************************************
727 * EncodeVideo: the whole thing
728 ****************************************************************************/
729 static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
731 encoder_sys_t *p_sys = p_enc->p_sys;
735 if ( !p_sys->b_inited && p_enc->i_threads >= 1 )
737 struct thread_context_t ** pp_contexts;
741 pp_contexts = malloc( sizeof(struct thread_context_t *)
742 * p_enc->i_threads );
743 p_sys->p_context->thread_opaque = (void *)pp_contexts;
745 for ( i = 0; i < p_enc->i_threads; i++ )
747 pp_contexts[i] = vlc_object_create( p_enc,
748 sizeof(struct thread_context_t) );
749 pp_contexts[i]->p_context = p_sys->p_context;
750 vlc_mutex_init( p_enc, &pp_contexts[i]->lock );
751 vlc_cond_init( p_enc, &pp_contexts[i]->cond );
752 pp_contexts[i]->b_work = 0;
753 pp_contexts[i]->b_done = 0;
754 if ( vlc_thread_create( pp_contexts[i], "encoder", FfmpegThread,
755 VLC_THREAD_PRIORITY_VIDEO, VLC_FALSE ) )
757 msg_Err( p_enc, "cannot spawn encoder thread, expect to die soon" );
762 p_sys->p_context->execute = FfmpegExecute;
765 memset( &frame, 0, sizeof( AVFrame ) );
766 for( i_plane = 0; i_plane < p_pict->i_planes; i_plane++ )
768 frame.data[i_plane] = p_pict->p[i_plane].p_pixels;
769 frame.linesize[i_plane] = p_pict->p[i_plane].i_pitch;
772 /* Let ffmpeg select the frame type */
775 frame.repeat_pict = p_pict->i_nb_fields - 2;
776 frame.interlaced_frame = !p_pict->b_progressive;
777 frame.top_field_first = !!p_pict->b_top_field_first;
779 /* Set the pts of the frame being encoded (segfaults with mpeg4!)*/
780 if( p_enc->fmt_out.i_codec != VLC_FOURCC( 'm', 'p', '4', 'v' ) )
782 frame.pts = p_pict->date ? p_pict->date : (int64_t)AV_NOPTS_VALUE;
784 if ( p_sys->b_hurry_up && frame.pts != (int64_t)AV_NOPTS_VALUE )
786 mtime_t current_date = mdate();
788 if ( current_date + HURRY_UP_GUARD3 > frame.pts )
790 p_sys->p_context->mb_decision = FF_MB_DECISION_SIMPLE;
791 p_sys->p_context->flags &= ~CODEC_FLAG_TRELLIS_QUANT;
792 msg_Dbg( p_enc, "hurry up mode 3" );
796 p_sys->p_context->mb_decision = p_sys->i_hq;
798 if ( current_date + HURRY_UP_GUARD2 > frame.pts )
800 p_sys->p_context->flags &= ~CODEC_FLAG_TRELLIS_QUANT;
801 p_sys->p_context->noise_reduction = p_sys->i_noise_reduction
802 + (HURRY_UP_GUARD2 + current_date - frame.pts) / 500;
803 msg_Dbg( p_enc, "hurry up mode 2" );
807 if ( p_sys->b_trellis )
808 p_sys->p_context->flags |= CODEC_FLAG_TRELLIS_QUANT;
810 p_sys->p_context->noise_reduction =
811 p_sys->i_noise_reduction;
815 if ( current_date + HURRY_UP_GUARD1 > frame.pts )
817 frame.pict_type = FF_P_TYPE;
818 /* msg_Dbg( p_enc, "hurry up mode 1 %lld", current_date + HURRY_UP_GUARD1 - frame.pts ); */
824 frame.pts = (int64_t)AV_NOPTS_VALUE;
827 if ( frame.pts != (int64_t)AV_NOPTS_VALUE && frame.pts != 0 )
829 if ( p_sys->i_last_pts == frame.pts )
831 msg_Warn( p_enc, "almost fed libavcodec with two frames with the "
832 "same PTS (" I64Fd ")", frame.pts );
835 else if ( p_sys->i_last_pts > frame.pts )
837 msg_Warn( p_enc, "almost fed libavcodec with a frame in the "
838 "past (current: " I64Fd ", last: "I64Fd")",
839 frame.pts, p_sys->i_last_pts );
844 p_sys->i_last_pts = frame.pts;
848 frame.quality = p_sys->i_quality;
850 /* Ugly work-around for stupid libavcodec behaviour */
852 p_sys->pi_delay_pts[p_sys->i_framenum % MAX_FRAME_DELAY] = frame.pts;
853 frame.pts = p_sys->i_framenum * AV_TIME_BASE *
854 p_enc->fmt_in.video.i_frame_rate_base;
855 frame.pts += p_enc->fmt_in.video.i_frame_rate - 1;
856 frame.pts /= p_enc->fmt_in.video.i_frame_rate;
857 /* End work-around */
859 i_out = avcodec_encode_video( p_sys->p_context, (uint8_t*)p_sys->p_buffer_out,
860 p_sys->p_context->height * p_sys->p_context->width * 3, &frame );
864 block_t *p_block = block_New( p_enc, i_out );
865 memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );
867 /* FIXME, 3-2 pulldown is not handled correctly */
868 p_block->i_length = I64C(1000000) *
869 p_enc->fmt_in.video.i_frame_rate_base /
870 p_enc->fmt_in.video.i_frame_rate;
872 if( !p_sys->p_context->max_b_frames || !p_sys->p_context->delay )
874 /* No delay -> output pts == input pts */
875 p_block->i_pts = p_block->i_dts = p_pict->date;
877 else if( p_sys->p_context->coded_frame->pts != (int64_t)AV_NOPTS_VALUE &&
878 p_sys->p_context->coded_frame->pts != 0 &&
879 p_sys->i_buggy_pts_detect != p_sys->p_context->coded_frame->pts )
881 p_sys->i_buggy_pts_detect = p_sys->p_context->coded_frame->pts;
882 p_block->i_pts = p_sys->p_context->coded_frame->pts;
884 /* Ugly work-around for stupid libavcodec behaviour */
886 int64_t i_framenum = p_block->i_pts *
887 p_enc->fmt_in.video.i_frame_rate /
888 p_enc->fmt_in.video.i_frame_rate_base / AV_TIME_BASE;
890 p_block->i_pts = p_sys->pi_delay_pts[i_framenum % MAX_FRAME_DELAY];
892 /* End work-around */
894 if( p_sys->p_context->coded_frame->pict_type != FF_I_TYPE &&
895 p_sys->p_context->coded_frame->pict_type != FF_P_TYPE )
897 p_block->i_dts = p_block->i_pts;
901 if( p_sys->i_last_ref_pts )
903 p_block->i_dts = p_sys->i_last_ref_pts;
907 /* Let's put something sensible */
908 p_block->i_dts = p_block->i_pts;
911 p_sys->i_last_ref_pts = p_block->i_pts;
916 /* Buggy libavcodec which doesn't update coded_frame->pts
918 p_block->i_dts = p_block->i_pts = p_pict->date;
921 switch ( p_sys->p_context->coded_frame->pict_type )
924 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
927 p_block->i_flags |= BLOCK_FLAG_TYPE_P;
930 p_block->i_flags |= BLOCK_FLAG_TYPE_B;
940 /****************************************************************************
941 * EncodeAudio: the whole thing
942 ****************************************************************************/
943 static block_t *EncodeAudio( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
945 encoder_sys_t *p_sys = p_enc->p_sys;
946 block_t *p_block, *p_chain = NULL;
948 uint8_t *p_buffer = p_aout_buf->p_buffer;
949 int i_samples = p_aout_buf->i_nb_samples;
950 int i_samples_delay = p_sys->i_samples_delay;
952 p_sys->i_pts = p_aout_buf->start_date -
953 (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
954 (mtime_t)p_enc->fmt_in.audio.i_rate;
956 p_sys->i_samples_delay += i_samples;
958 while( p_sys->i_samples_delay >= p_sys->p_context->frame_size )
963 if( i_samples_delay )
965 /* Take care of the left-over from last time */
966 int i_delay_size = i_samples_delay * 2 *
967 p_sys->p_context->channels;
968 int i_size = p_sys->i_frame_size - i_delay_size;
970 p_samples = (int16_t *)p_sys->p_buffer;
971 memcpy( p_sys->p_buffer + i_delay_size, p_buffer, i_size );
972 p_buffer -= i_delay_size;
973 i_samples += i_samples_delay;
978 p_samples = (int16_t *)p_buffer;
981 i_out = avcodec_encode_audio( p_sys->p_context, (uint8_t *)p_sys->p_buffer_out,
982 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE,
986 msg_Warn( p_enc, "avcodec_encode_audio: %d", i_out );
988 if( i_out < 0 ) break;
990 p_buffer += p_sys->i_frame_size;
991 p_sys->i_samples_delay -= p_sys->p_context->frame_size;
992 i_samples -= p_sys->p_context->frame_size;
994 if( i_out == 0 ) continue;
996 p_block = block_New( p_enc, i_out );
997 memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );
999 p_block->i_length = (mtime_t)1000000 *
1000 (mtime_t)p_sys->p_context->frame_size /
1001 (mtime_t)p_sys->p_context->sample_rate;
1003 p_block->i_dts = p_block->i_pts = p_sys->i_pts;
1006 p_sys->i_pts += p_block->i_length;
1007 block_ChainAppend( &p_chain, p_block );
1010 /* Backup the remaining raw samples */
1013 memcpy( p_sys->p_buffer + i_samples_delay * 2 *
1014 p_sys->p_context->channels, p_buffer,
1015 i_samples * 2 * p_sys->p_context->channels );
1021 /*****************************************************************************
1022 * CloseEncoder: ffmpeg encoder destruction
1023 *****************************************************************************/
1024 void E_(CloseEncoder)( vlc_object_t *p_this )
1026 encoder_t *p_enc = (encoder_t *)p_this;
1027 encoder_sys_t *p_sys = p_enc->p_sys;
1029 if ( p_sys->b_inited && p_enc->i_threads >= 1 )
1032 struct thread_context_t ** pp_contexts =
1033 (struct thread_context_t **)p_sys->p_context->thread_opaque;
1034 for ( i = 0; i < p_enc->i_threads; i++ )
1036 vlc_object_kill( pp_contexts[i] );
1037 vlc_cond_signal( &pp_contexts[i]->cond );
1038 vlc_thread_join( pp_contexts[i] );
1039 vlc_mutex_destroy( &pp_contexts[i]->lock );
1040 vlc_cond_destroy( &pp_contexts[i]->cond );
1041 vlc_object_release( pp_contexts[i] );
1044 free( pp_contexts );
1047 vlc_mutex_t *lock = var_AcquireMutex( "avcodec" );
1048 avcodec_close( p_sys->p_context );
1049 vlc_mutex_unlock( lock );
1050 av_free( p_sys->p_context );
1052 if( p_sys->p_buffer ) free( p_sys->p_buffer );
1053 if( p_sys->p_buffer_out ) free( p_sys->p_buffer_out );