00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <vlc/vlc.h>
00030 #include <vlc/vout.h>
00031 #include <vlc/aout.h>
00032 #include <vlc/sout.h>
00033 #include <vlc/decoder.h>
00034
00035
00036 #define HAVE_MMX 1
00037 #ifdef HAVE_FFMPEG_AVCODEC_H
00038 # include <ffmpeg/avcodec.h>
00039 #else
00040 # include <avcodec.h>
00041 #endif
00042
00043 #if LIBAVCODEC_BUILD < 4704
00044 # define AV_NOPTS_VALUE 0
00045 #endif
00046 #if LIBAVCODEC_BUILD < 4684
00047 # define FF_QP2LAMBDA 118
00048 #endif
00049
00050 #include "ffmpeg.h"
00051
00052 #define AVCODEC_MAX_VIDEO_FRAME_SIZE (3*1024*1024)
00053 #define HURRY_UP_GUARD1 (450000)
00054 #define HURRY_UP_GUARD2 (300000)
00055 #define HURRY_UP_GUARD3 (100000)
00056
00057 #define MAX_FRAME_DELAY (FF_MAX_B_FRAMES + 2)
00058
00059
00060
00061
00062 int E_(OpenEncoder) ( vlc_object_t * );
00063 void E_(CloseEncoder)( vlc_object_t * );
00064
00065 static block_t *EncodeVideo( encoder_t *, picture_t * );
00066 static block_t *EncodeAudio( encoder_t *, aout_buffer_t * );
00067
00068 struct thread_context_t;
00069 static int FfmpegThread( struct thread_context_t *p_context );
00070 static int FfmpegExecute( AVCodecContext *s,
00071 int (*pf_func)(AVCodecContext *c2, void *arg2),
00072 void **arg, int *ret, int count );
00073
00074
00075
00076
00077 #if LIBAVCODEC_BUILD >= 4702
00078 struct thread_context_t
00079 {
00080 VLC_COMMON_MEMBERS
00081
00082 AVCodecContext *p_context;
00083 int (* pf_func)(AVCodecContext *c, void *arg);
00084 void *arg;
00085 int i_ret;
00086
00087 vlc_mutex_t lock;
00088 vlc_cond_t cond;
00089 vlc_bool_t b_work, b_done;
00090 };
00091 #endif
00092
00093
00094
00095
00096 struct encoder_sys_t
00097 {
00098
00099
00100
00101 AVCodec *p_codec;
00102 AVCodecContext *p_context;
00103
00104
00105
00106
00107 char *p_buffer;
00108 char *p_buffer_out;
00109
00110
00111
00112
00113 mtime_t i_last_ref_pts;
00114 mtime_t i_buggy_pts_detect;
00115 mtime_t i_last_pts;
00116 vlc_bool_t b_inited;
00117
00118
00119
00120
00121 int i_frame_size;
00122 int i_samples_delay;
00123 mtime_t i_pts;
00124
00125
00126 int i_key_int;
00127 int i_b_frames;
00128 int i_vtolerance;
00129 int i_qmin;
00130 int i_qmax;
00131 int i_hq;
00132 vlc_bool_t b_strict_rc;
00133 int i_rc_buffer_size;
00134 float f_rc_buffer_aggressivity;
00135 vlc_bool_t b_pre_me;
00136 vlc_bool_t b_hurry_up;
00137 vlc_bool_t b_interlace, b_interlace_me;
00138 float f_i_quant_factor;
00139 int i_noise_reduction;
00140 vlc_bool_t b_mpeg4_matrix;
00141 vlc_bool_t b_trellis;
00142 int i_quality;
00143 float f_lumi_masking, f_dark_masking, f_p_masking, f_border_masking;
00144 int i_luma_elim, i_chroma_elim;
00145
00146
00147 uint64_t i_framenum;
00148 mtime_t pi_delay_pts[MAX_FRAME_DELAY];
00149 };
00150
00151 static const char *ppsz_enc_options[] = {
00152 "keyint", "bframes", "vt", "qmin", "qmax", "hq", "strict-rc",
00153 "rc-buffer-size", "rc-buffer-aggressivity", "pre-me", "hurry-up",
00154 "interlace", "i-quant-factor", "noise-reduction", "mpeg4-matrix",
00155 "trellis", "qscale", "strict", "lumi-masking", "dark-masking",
00156 "p-masking", "border-masking", "luma-elim-threshold",
00157 "chroma-elim-threshold", NULL
00158 };
00159
00160 static const uint16_t mpa_bitrate_tab[2][15] =
00161 {
00162 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384},
00163 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
00164 };
00165
00166 static const uint16_t mpa_freq_tab[6] =
00167 { 44100, 48000, 32000, 22050, 24000, 16000 };
00168
00169
00170
00171
00172 extern int16_t IMPORT_SYMBOL ff_mpeg4_default_intra_matrix[];
00173 extern int16_t IMPORT_SYMBOL ff_mpeg4_default_non_intra_matrix[];
00174
00175 int E_(OpenEncoder)( vlc_object_t *p_this )
00176 {
00177 encoder_t *p_enc = (encoder_t *)p_this;
00178 encoder_sys_t *p_sys = p_enc->p_sys;
00179 AVCodecContext *p_context;
00180 AVCodec *p_codec;
00181 int i_codec_id, i_cat;
00182 char *psz_namecodec;
00183 vlc_value_t val;
00184 vlc_value_t lockval;
00185
00186 var_Get( p_enc->p_libvlc, "avcodec", &lockval );
00187
00188 if( !E_(GetFfmpegCodec)( p_enc->fmt_out.i_codec, &i_cat, &i_codec_id,
00189 &psz_namecodec ) )
00190 {
00191 if( E_(GetFfmpegChroma)( p_enc->fmt_out.i_codec ) < 0 )
00192 {
00193
00194 return VLC_EGENERIC;
00195 }
00196 i_cat = VIDEO_ES;
00197 i_codec_id = CODEC_ID_RAWVIDEO;
00198 psz_namecodec = "Raw video";
00199 }
00200
00201
00202 if( p_enc->fmt_out.i_cat == VIDEO_ES && i_cat != VIDEO_ES )
00203 {
00204 msg_Err( p_enc, "\"%s\" is not a video encoder", psz_namecodec );
00205 return VLC_EGENERIC;
00206 }
00207
00208 if( p_enc->fmt_out.i_cat == AUDIO_ES && i_cat != AUDIO_ES )
00209 {
00210 msg_Err( p_enc, "\"%s\" is not an audio encoder", psz_namecodec );
00211 return VLC_EGENERIC;
00212 }
00213
00214
00215 E_(InitLibavcodec)(p_this);
00216
00217 p_codec = avcodec_find_encoder( i_codec_id );
00218 if( !p_codec )
00219 {
00220 msg_Err( p_enc, "cannot find encoder %s", psz_namecodec );
00221 return VLC_EGENERIC;
00222 }
00223
00224
00225 if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
00226 {
00227 msg_Err( p_enc, "out of memory" );
00228 return VLC_EGENERIC;
00229 }
00230 memset( p_sys, 0, sizeof(encoder_sys_t) );
00231 p_enc->p_sys = p_sys;
00232 p_sys->p_codec = p_codec;
00233
00234 p_enc->pf_encode_video = EncodeVideo;
00235 p_enc->pf_encode_audio = EncodeAudio;
00236
00237 p_sys->p_buffer_out = NULL;
00238 p_sys->p_buffer = NULL;
00239
00240 p_sys->p_context = p_context = avcodec_alloc_context();
00241 p_context->debug = config_GetInt( p_enc, "ffmpeg-debug" );
00242 p_context->opaque = (void *)p_this;
00243
00244
00245 p_context->dsp_mask = 0;
00246 if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_MMX) )
00247 {
00248 p_context->dsp_mask |= FF_MM_MMX;
00249 }
00250 if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_MMXEXT) )
00251 {
00252 p_context->dsp_mask |= FF_MM_MMXEXT;
00253 }
00254 if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_3DNOW) )
00255 {
00256 p_context->dsp_mask |= FF_MM_3DNOW;
00257 }
00258 if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_SSE) )
00259 {
00260 p_context->dsp_mask |= FF_MM_SSE;
00261 p_context->dsp_mask |= FF_MM_SSE2;
00262 }
00263
00264 sout_CfgParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
00265
00266 var_Get( p_enc, ENC_CFG_PREFIX "keyint", &val );
00267 p_sys->i_key_int = val.i_int;
00268
00269 var_Get( p_enc, ENC_CFG_PREFIX "bframes", &val );
00270 p_sys->i_b_frames = val.i_int;
00271
00272 var_Get( p_enc, ENC_CFG_PREFIX "vt", &val );
00273 p_sys->i_vtolerance = val.i_int;
00274
00275 var_Get( p_enc, ENC_CFG_PREFIX "interlace", &val );
00276 p_sys->b_interlace = val.b_bool;
00277
00278 var_Get( p_enc, ENC_CFG_PREFIX "interlace-me", &val );
00279 p_sys->b_interlace_me = val.b_bool;
00280
00281 var_Get( p_enc, ENC_CFG_PREFIX "pre-me", &val );
00282 p_sys->b_pre_me = val.b_bool;
00283
00284 var_Get( p_enc, ENC_CFG_PREFIX "hurry-up", &val );
00285 p_sys->b_hurry_up = val.b_bool;
00286 if( p_sys->b_hurry_up )
00287 {
00288
00289 p_sys->i_noise_reduction = 1;
00290 }
00291
00292 var_Get( p_enc, ENC_CFG_PREFIX "strict-rc", &val );
00293 p_sys->b_strict_rc = val.b_bool;
00294 var_Get( p_enc, ENC_CFG_PREFIX "rc-buffer-size", &val );
00295 p_sys->i_rc_buffer_size = val.i_int;
00296 var_Get( p_enc, ENC_CFG_PREFIX "rc-buffer-aggressivity", &val );
00297 p_sys->f_rc_buffer_aggressivity = val.f_float;
00298
00299 var_Get( p_enc, ENC_CFG_PREFIX "i-quant-factor", &val );
00300 p_sys->f_i_quant_factor = val.f_float;
00301
00302 var_Get( p_enc, ENC_CFG_PREFIX "noise-reduction", &val );
00303 p_sys->i_noise_reduction = val.i_int;
00304
00305 var_Get( p_enc, ENC_CFG_PREFIX "mpeg4-matrix", &val );
00306 p_sys->b_mpeg4_matrix = val.b_bool;
00307
00308 var_Get( p_enc, ENC_CFG_PREFIX "qscale", &val );
00309 if( val.f_float < 0.01 || val.f_float > 255.0 ) val.f_float = 0;
00310 p_sys->i_quality = (int)(FF_QP2LAMBDA * val.f_float + 0.5);
00311
00312 var_Get( p_enc, ENC_CFG_PREFIX "hq", &val );
00313 if( val.psz_string && *val.psz_string )
00314 {
00315 if( !strcmp( val.psz_string, "rd" ) )
00316 p_sys->i_hq = FF_MB_DECISION_RD;
00317 else if( !strcmp( val.psz_string, "bits" ) )
00318 p_sys->i_hq = FF_MB_DECISION_BITS;
00319 else if( !strcmp( val.psz_string, "simple" ) )
00320 p_sys->i_hq = FF_MB_DECISION_SIMPLE;
00321 else
00322 p_sys->i_hq = FF_MB_DECISION_RD;
00323 }
00324 if( val.psz_string ) free( val.psz_string );
00325
00326 var_Get( p_enc, ENC_CFG_PREFIX "qmin", &val );
00327 p_sys->i_qmin = val.i_int;
00328 var_Get( p_enc, ENC_CFG_PREFIX "qmax", &val );
00329 p_sys->i_qmax = val.i_int;
00330 var_Get( p_enc, ENC_CFG_PREFIX "trellis", &val );
00331 p_sys->b_trellis = val.b_bool;
00332
00333 var_Get( p_enc, ENC_CFG_PREFIX "strict", &val );
00334 if( val.i_int < - 1 || val.i_int > 1 ) val.i_int = 0;
00335 p_context->strict_std_compliance = val.i_int;
00336
00337 var_Get( p_enc, ENC_CFG_PREFIX "lumi-masking", &val );
00338 p_sys->f_lumi_masking = val.f_float;
00339 var_Get( p_enc, ENC_CFG_PREFIX "dark-masking", &val );
00340 p_sys->f_dark_masking = val.f_float;
00341 var_Get( p_enc, ENC_CFG_PREFIX "p-masking", &val );
00342 p_sys->f_p_masking = val.f_float;
00343 var_Get( p_enc, ENC_CFG_PREFIX "border-masking", &val );
00344 p_sys->f_border_masking = val.f_float;
00345 var_Get( p_enc, ENC_CFG_PREFIX "luma-elim-threshold", &val );
00346 p_sys->i_luma_elim = val.i_int;
00347 var_Get( p_enc, ENC_CFG_PREFIX "chroma-elim-threshold", &val );
00348 p_sys->i_chroma_elim = val.i_int;
00349
00350 if( p_enc->fmt_in.i_cat == VIDEO_ES )
00351 {
00352 int i_aspect_num, i_aspect_den;
00353
00354 if( !p_enc->fmt_in.video.i_width || !p_enc->fmt_in.video.i_height )
00355 {
00356 msg_Warn( p_enc, "invalid size %ix%i", p_enc->fmt_in.video.i_width,
00357 p_enc->fmt_in.video.i_height );
00358 free( p_sys );
00359 return VLC_EGENERIC;
00360 }
00361
00362 p_context->width = p_enc->fmt_in.video.i_width;
00363 p_context->height = p_enc->fmt_in.video.i_height;
00364
00365 #if LIBAVCODEC_BUILD >= 4754
00366 p_context->time_base.num = p_enc->fmt_in.video.i_frame_rate_base;
00367 p_context->time_base.den = p_enc->fmt_in.video.i_frame_rate;
00368 #else
00369 p_context->frame_rate = p_enc->fmt_in.video.i_frame_rate;
00370 p_context->frame_rate_base= p_enc->fmt_in.video.i_frame_rate_base;
00371 #endif
00372
00373
00374 p_context->qblur = 0.5;
00375 p_context->qcompress = 0.5;
00376 p_context->b_quant_offset = 1.25;
00377 p_context->b_quant_factor = 1.25;
00378 p_context->i_quant_offset = 0.0;
00379 p_context->i_quant_factor = -0.8;
00380
00381 p_context->lumi_masking = p_sys->f_lumi_masking;
00382 p_context->dark_masking = p_sys->f_dark_masking;
00383 p_context->p_masking = p_sys->f_p_masking;
00384 #if LIBAVCODEC_BUILD >= 4741
00385 p_context->border_masking = p_sys->f_border_masking;
00386 #endif
00387 p_context->luma_elim_threshold = p_sys->i_luma_elim;
00388 p_context->chroma_elim_threshold = p_sys->i_chroma_elim;
00389
00390 if( p_sys->i_key_int > 0 )
00391 p_context->gop_size = p_sys->i_key_int;
00392 p_context->max_b_frames =
00393 __MAX( __MIN( p_sys->i_b_frames, FF_MAX_B_FRAMES ), 0 );
00394 p_context->b_frame_strategy = 0;
00395
00396 #if LIBAVCODEC_BUILD >= 4687
00397 av_reduce( &i_aspect_num, &i_aspect_den,
00398 p_enc->fmt_in.video.i_aspect,
00399 VOUT_ASPECT_FACTOR, 1 << 30 );
00400 av_reduce( &p_context->sample_aspect_ratio.num,
00401 &p_context->sample_aspect_ratio.den,
00402 i_aspect_num * (int64_t)p_context->height,
00403 i_aspect_den * (int64_t)p_context->width, 1 << 30 );
00404 #else
00405 p_context->aspect_ratio = ((float)p_enc->fmt_in.video.i_aspect) /
00406 VOUT_ASPECT_FACTOR;
00407 #endif
00408
00409 p_sys->p_buffer_out = malloc( AVCODEC_MAX_VIDEO_FRAME_SIZE );
00410
00411 p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','0');
00412 p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->fmt_in.i_codec );
00413 #if LIBAVCODEC_BUILD >= 4714
00414 if( p_codec->pix_fmts )
00415 {
00416 const enum PixelFormat *p = p_codec->pix_fmts;
00417 for( ; *p != -1; p++ )
00418 {
00419 if( *p == p_context->pix_fmt ) break;
00420 }
00421 if( *p == -1 ) p_context->pix_fmt = p_codec->pix_fmts[0];
00422 p_enc->fmt_in.i_codec = E_(GetVlcChroma)( p_context->pix_fmt );
00423 }
00424 #else
00425 p_enc->fmt_in.i_codec = E_(GetVlcChroma)( p_context->pix_fmt );
00426 #endif
00427
00428 if ( p_sys->b_strict_rc )
00429 {
00430 p_context->rc_max_rate = p_enc->fmt_out.i_bitrate;
00431 p_context->rc_buffer_size = p_sys->i_rc_buffer_size;
00432
00433 p_context->rc_initial_buffer_occupancy
00434 = p_sys->i_rc_buffer_size * 3/4;
00435 p_context->rc_buffer_aggressivity = p_sys->f_rc_buffer_aggressivity;
00436 }
00437
00438 if ( p_sys->f_i_quant_factor != 0.0 )
00439 p_context->i_quant_factor = p_sys->f_i_quant_factor;
00440
00441 #if LIBAVCODEC_BUILD >= 4690
00442 p_context->noise_reduction = p_sys->i_noise_reduction;
00443 #endif
00444
00445 if ( p_sys->b_mpeg4_matrix )
00446 {
00447 p_context->intra_matrix = ff_mpeg4_default_intra_matrix;
00448 p_context->inter_matrix = ff_mpeg4_default_non_intra_matrix;
00449 }
00450
00451 if ( p_sys->b_pre_me )
00452 {
00453 p_context->pre_me = 1;
00454 p_context->me_pre_cmp = FF_CMP_CHROMA;
00455 }
00456
00457 if ( p_sys->b_interlace )
00458 {
00459 if ( p_context->height <= 280 )
00460 {
00461 if ( p_context->height != 16 || p_context->width != 16 )
00462 msg_Warn( p_enc,
00463 "disabling interlaced video because height=%d <= 280",
00464 p_context->height );
00465 }
00466 else
00467 {
00468 p_context->flags |= CODEC_FLAG_INTERLACED_DCT;
00469 #if LIBAVCODEC_BUILD >= 4698
00470 if ( p_sys->b_interlace_me )
00471 p_context->flags |= CODEC_FLAG_INTERLACED_ME;
00472 }
00473 #endif
00474 }
00475
00476 if ( p_sys->b_trellis )
00477 p_context->flags |= CODEC_FLAG_TRELLIS_QUANT;
00478
00479 if ( p_sys->i_qmin > 0 && p_sys->i_qmin == p_sys->i_qmax )
00480 p_context->flags |= CODEC_FLAG_QSCALE;
00481
00482 #if LIBAVCODEC_BUILD >= 4702
00483 if ( p_enc->i_threads >= 1 )
00484 p_context->thread_count = p_enc->i_threads;
00485 #endif
00486
00487 if( p_sys->i_vtolerance > 0 )
00488 p_context->bit_rate_tolerance = p_sys->i_vtolerance;
00489
00490 if( p_sys->i_qmin > 0 )
00491 p_context->mb_qmin = p_context->qmin = p_sys->i_qmin;
00492 if( p_sys->i_qmax > 0 )
00493 p_context->mb_qmax = p_context->qmax = p_sys->i_qmax;
00494 p_context->max_qdiff = 3;
00495
00496 p_context->mb_decision = p_sys->i_hq;
00497
00498 if( p_sys->i_quality )
00499 {
00500 p_context->flags |= CODEC_FLAG_QSCALE;
00501 #if LIBAVCODEC_BUILD >= 4668
00502 p_context->global_quality = p_sys->i_quality;
00503 #endif
00504 }
00505 }
00506 else if( p_enc->fmt_in.i_cat == AUDIO_ES )
00507 {
00508
00509 if( i_codec_id == CODEC_ID_MP3 && p_enc->fmt_in.audio.i_channels > 2 )
00510 p_enc->fmt_in.audio.i_channels = 2;
00511
00512 p_enc->fmt_in.i_codec = AOUT_FMT_S16_NE;
00513 p_context->sample_rate = p_enc->fmt_in.audio.i_rate;
00514 p_context->channels = p_enc->fmt_in.audio.i_channels;
00515 }
00516
00517
00518 p_context->bit_rate = p_enc->fmt_out.i_bitrate;
00519
00520 if( i_codec_id == CODEC_ID_RAWVIDEO )
00521 {
00522
00523 p_enc->fmt_in.i_codec = p_enc->fmt_out.i_codec;
00524 p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->fmt_in.i_codec );
00525 }
00526
00527
00528 p_context->extradata_size = 0;
00529 p_context->extradata = NULL;
00530 p_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
00531
00532 vlc_mutex_lock( lockval.p_address );
00533 if( avcodec_open( p_context, p_codec ) )
00534 {
00535 vlc_mutex_unlock( lockval.p_address );
00536 if( p_enc->fmt_in.i_cat == AUDIO_ES &&
00537 (p_context->channels > 2 || i_codec_id == CODEC_ID_MP2
00538 || i_codec_id == CODEC_ID_MP3) )
00539 {
00540 if( p_context->channels > 2 )
00541 {
00542 p_context->channels = 2;
00543 p_enc->fmt_in.audio.i_channels = 2;
00544 msg_Warn( p_enc, "stereo mode selected (codec limitation)" );
00545 }
00546
00547 if( i_codec_id == CODEC_ID_MP2 || i_codec_id == CODEC_ID_MP3 )
00548 {
00549 int i_frequency, i;
00550
00551 for ( i_frequency = 0; i_frequency < 6; i_frequency++ )
00552 {
00553 if ( p_enc->fmt_out.audio.i_rate
00554 == mpa_freq_tab[i_frequency] )
00555 break;
00556 }
00557 if ( i_frequency == 6 )
00558 {
00559 msg_Err( p_enc, "MPEG audio doesn't support frequency=%d",
00560 p_enc->fmt_out.audio.i_rate );
00561 free( p_sys );
00562 return VLC_EGENERIC;
00563 }
00564
00565 for ( i = 1; i < 14; i++ )
00566 {
00567 if ( p_enc->fmt_out.i_bitrate / 1000
00568 <= mpa_bitrate_tab[i_frequency / 3][i] )
00569 break;
00570 }
00571 if ( p_enc->fmt_out.i_bitrate / 1000
00572 != mpa_bitrate_tab[i_frequency / 3][i] )
00573 {
00574 msg_Warn( p_enc,
00575 "MPEG audio doesn't support bitrate=%d, using %d",
00576 p_enc->fmt_out.i_bitrate,
00577 mpa_bitrate_tab[i_frequency / 3][i] * 1000 );
00578 p_enc->fmt_out.i_bitrate =
00579 mpa_bitrate_tab[i_frequency / 3][i] * 1000;
00580 p_context->bit_rate = p_enc->fmt_out.i_bitrate;
00581 }
00582 }
00583
00584 p_context->codec = NULL;
00585 vlc_mutex_lock( lockval.p_address );
00586 if( avcodec_open( p_context, p_codec ) )
00587 {
00588 vlc_mutex_unlock( lockval.p_address );
00589 msg_Err( p_enc, "cannot open encoder" );
00590 free( p_sys );
00591 return VLC_EGENERIC;
00592 }
00593 }
00594 else
00595 {
00596 msg_Err( p_enc, "cannot open encoder" );
00597 free( p_sys );
00598 return VLC_EGENERIC;
00599 }
00600 }
00601 vlc_mutex_unlock( lockval.p_address );
00602
00603 p_enc->fmt_out.i_extra = p_context->extradata_size;
00604 if( p_enc->fmt_out.i_extra )
00605 {
00606 p_enc->fmt_out.p_extra = malloc( p_enc->fmt_out.i_extra );
00607 memcpy( p_enc->fmt_out.p_extra, p_context->extradata,
00608 p_enc->fmt_out.i_extra );
00609 }
00610 p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER;
00611
00612 if( p_enc->fmt_in.i_cat == AUDIO_ES )
00613 {
00614 p_sys->p_buffer_out = malloc( 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE );
00615 p_sys->i_frame_size = p_context->frame_size * 2 * p_context->channels;
00616 p_sys->p_buffer = malloc( p_sys->i_frame_size );
00617 }
00618
00619 msg_Dbg( p_enc, "found encoder %s", psz_namecodec );
00620
00621 return VLC_SUCCESS;
00622 }
00623
00624
00625
00626
00627 #if LIBAVCODEC_BUILD >= 4702
00628 static int FfmpegThread( struct thread_context_t *p_context )
00629 {
00630 while ( !p_context->b_die && !p_context->b_error )
00631 {
00632 vlc_mutex_lock( &p_context->lock );
00633 while ( !p_context->b_work && !p_context->b_die && !p_context->b_error )
00634 {
00635 vlc_cond_wait( &p_context->cond, &p_context->lock );
00636 }
00637 p_context->b_work = 0;
00638 vlc_mutex_unlock( &p_context->lock );
00639 if ( p_context->b_die || p_context->b_error )
00640 break;
00641
00642 if ( p_context->pf_func )
00643 {
00644 p_context->i_ret = p_context->pf_func( p_context->p_context,
00645 p_context->arg );
00646 }
00647
00648 vlc_mutex_lock( &p_context->lock );
00649 p_context->b_done = 1;
00650 vlc_cond_signal( &p_context->cond );
00651 vlc_mutex_unlock( &p_context->lock );
00652 }
00653
00654 return 0;
00655 }
00656
00657 static int FfmpegExecute( AVCodecContext *s,
00658 int (*pf_func)(AVCodecContext *c2, void *arg2),
00659 void **arg, int *ret, int count )
00660 {
00661 struct thread_context_t ** pp_contexts =
00662 (struct thread_context_t **)s->thread_opaque;
00663 int i;
00664
00665
00666
00667 for ( i = 0; i < count; i++ )
00668 {
00669 vlc_mutex_lock( &pp_contexts[i]->lock );
00670 pp_contexts[i]->arg = arg[i];
00671 pp_contexts[i]->pf_func = pf_func;
00672 pp_contexts[i]->i_ret = 12345;
00673 pp_contexts[i]->b_work = 1;
00674 vlc_cond_signal( &pp_contexts[i]->cond );
00675 vlc_mutex_unlock( &pp_contexts[i]->lock );
00676 }
00677 for ( i = 0; i < count; i++ )
00678 {
00679 vlc_mutex_lock( &pp_contexts[i]->lock );
00680 while ( !pp_contexts[i]->b_done )
00681 {
00682 vlc_cond_wait( &pp_contexts[i]->cond, &pp_contexts[i]->lock );
00683 }
00684 pp_contexts[i]->b_done = 0;
00685 pp_contexts[i]->pf_func = NULL;
00686 vlc_mutex_unlock( &pp_contexts[i]->lock );
00687
00688 if ( ret )
00689 {
00690 ret[i] = pp_contexts[i]->i_ret;
00691 }
00692 }
00693
00694 return 0;
00695 }
00696 #endif
00697
00698
00699
00700
00701 static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
00702 {
00703 encoder_sys_t *p_sys = p_enc->p_sys;
00704 AVFrame frame;
00705 int i_out, i_plane;
00706
00707 #if LIBAVCODEC_BUILD >= 4702
00708 if ( !p_sys->b_inited && p_enc->i_threads >= 1 )
00709 {
00710 struct thread_context_t ** pp_contexts;
00711 int i;
00712
00713 p_sys->b_inited = 1;
00714 pp_contexts = malloc( sizeof(struct thread_context_t *)
00715 * p_enc->i_threads );
00716 p_sys->p_context->thread_opaque = (void *)pp_contexts;
00717
00718 for ( i = 0; i < p_enc->i_threads; i++ )
00719 {
00720 pp_contexts[i] = vlc_object_create( p_enc,
00721 sizeof(struct thread_context_t) );
00722 pp_contexts[i]->p_context = p_sys->p_context;
00723 vlc_mutex_init( p_enc, &pp_contexts[i]->lock );
00724 vlc_cond_init( p_enc, &pp_contexts[i]->cond );
00725 pp_contexts[i]->b_work = 0;
00726 pp_contexts[i]->b_done = 0;
00727 if ( vlc_thread_create( pp_contexts[i], "encoder", FfmpegThread,
00728 VLC_THREAD_PRIORITY_VIDEO, VLC_FALSE ) )
00729 {
00730 msg_Err( p_enc, "cannot spawn encoder thread, expect to die soon" );
00731 return NULL;
00732 }
00733 }
00734
00735 p_sys->p_context->execute = FfmpegExecute;
00736 }
00737 #endif
00738
00739 memset( &frame, 0, sizeof( AVFrame ) );
00740 for( i_plane = 0; i_plane < p_pict->i_planes; i_plane++ )
00741 {
00742 frame.data[i_plane] = p_pict->p[i_plane].p_pixels;
00743 frame.linesize[i_plane] = p_pict->p[i_plane].i_pitch;
00744 }
00745
00746
00747 frame.pict_type = 0;
00748
00749 frame.repeat_pict = p_pict->i_nb_fields - 2;
00750
00751 #if LIBAVCODEC_BUILD >= 4685
00752 frame.interlaced_frame = !p_pict->b_progressive;
00753 frame.top_field_first = !!p_pict->b_top_field_first;
00754 #endif
00755
00756 #if LIBAVCODEC_BUILD < 4702
00757
00758 if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', 'g', 'v' ) ||
00759 p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', '1', 'v' ) ||
00760 p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', '2', 'v' ) )
00761 #else
00762 if( 1 )
00763 #endif
00764 {
00765 frame.pts = p_pict->date ? p_pict->date : (signed int) AV_NOPTS_VALUE;
00766
00767 if ( p_sys->b_hurry_up && frame.pts != (signed int) AV_NOPTS_VALUE )
00768 {
00769 mtime_t current_date = mdate();
00770
00771 if ( current_date + HURRY_UP_GUARD3 > frame.pts )
00772 {
00773 p_sys->p_context->mb_decision = FF_MB_DECISION_SIMPLE;
00774 p_sys->p_context->flags &= ~CODEC_FLAG_TRELLIS_QUANT;
00775 msg_Dbg( p_enc, "hurry up mode 3" );
00776 }
00777 else
00778 {
00779 p_sys->p_context->mb_decision = p_sys->i_hq;
00780
00781 if ( current_date + HURRY_UP_GUARD2 > frame.pts )
00782 {
00783 p_sys->p_context->flags &= ~CODEC_FLAG_TRELLIS_QUANT;
00784 #if LIBAVCODEC_BUILD >= 4690
00785 p_sys->p_context->noise_reduction = p_sys->i_noise_reduction
00786 + (HURRY_UP_GUARD2 + current_date - frame.pts) / 500;
00787 #endif
00788 msg_Dbg( p_enc, "hurry up mode 2" );
00789 }
00790 else
00791 {
00792 if ( p_sys->b_trellis )
00793 p_sys->p_context->flags |= CODEC_FLAG_TRELLIS_QUANT;
00794 #if LIBAVCODEC_BUILD >= 4690
00795 p_sys->p_context->noise_reduction =
00796 p_sys->i_noise_reduction;
00797 #endif
00798 }
00799 }
00800
00801 if ( current_date + HURRY_UP_GUARD1 > frame.pts )
00802 {
00803 frame.pict_type = FF_P_TYPE;
00804
00805 }
00806 }
00807 }
00808 else
00809 {
00810 frame.pts = AV_NOPTS_VALUE;
00811 }
00812
00813 if ( frame.pts != (signed int) AV_NOPTS_VALUE && frame.pts != 0 )
00814 {
00815 if ( p_sys->i_last_pts == frame.pts )
00816 {
00817 msg_Warn( p_enc, "almost fed libavcodec with two frames with the "
00818 "same PTS (" I64Fd ")", frame.pts );
00819 return NULL;
00820 }
00821 else if ( p_sys->i_last_pts > frame.pts )
00822 {
00823 msg_Warn( p_enc, "almost fed libavcodec with a frame in the "
00824 "past (current: " I64Fd ", last: "I64Fd")",
00825 frame.pts, p_sys->i_last_pts );
00826 return NULL;
00827 }
00828 else
00829 {
00830 p_sys->i_last_pts = frame.pts;
00831 }
00832 }
00833
00834 frame.quality = p_sys->i_quality;
00835
00836
00837 #if LIBAVCODEC_BUILD >= 4722
00838 p_sys->i_framenum++;
00839 p_sys->pi_delay_pts[p_sys->i_framenum % MAX_FRAME_DELAY] = frame.pts;
00840 frame.pts = p_sys->i_framenum * AV_TIME_BASE *
00841 p_enc->fmt_in.video.i_frame_rate_base;
00842 frame.pts += p_enc->fmt_in.video.i_frame_rate - 1;
00843 frame.pts /= p_enc->fmt_in.video.i_frame_rate;
00844 #endif
00845
00846
00847 i_out = avcodec_encode_video( p_sys->p_context, p_sys->p_buffer_out,
00848 AVCODEC_MAX_VIDEO_FRAME_SIZE, &frame );
00849
00850 if( i_out > 0 )
00851 {
00852 block_t *p_block = block_New( p_enc, i_out );
00853 memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );
00854
00855
00856 p_block->i_length = I64C(1000000) *
00857 p_enc->fmt_in.video.i_frame_rate_base /
00858 p_enc->fmt_in.video.i_frame_rate;
00859
00860 if( !p_sys->p_context->max_b_frames || !p_sys->p_context->delay )
00861 {
00862
00863 p_block->i_pts = p_block->i_dts = p_pict->date;
00864 }
00865 else if( p_sys->p_context->coded_frame->pts != (signed int) AV_NOPTS_VALUE &&
00866 p_sys->p_context->coded_frame->pts != 0 &&
00867 p_sys->i_buggy_pts_detect != p_sys->p_context->coded_frame->pts )
00868 {
00869 p_sys->i_buggy_pts_detect = p_sys->p_context->coded_frame->pts;
00870 p_block->i_pts = p_sys->p_context->coded_frame->pts;
00871
00872
00873 #if LIBAVCODEC_BUILD >= 4722
00874 {
00875 int64_t i_framenum = p_block->i_pts *
00876 p_enc->fmt_in.video.i_frame_rate /
00877 p_enc->fmt_in.video.i_frame_rate_base / AV_TIME_BASE;
00878
00879 p_block->i_pts = p_sys->pi_delay_pts[i_framenum % MAX_FRAME_DELAY];
00880 }
00881 #endif
00882
00883
00884 if( p_sys->p_context->coded_frame->pict_type != FF_I_TYPE &&
00885 p_sys->p_context->coded_frame->pict_type != FF_P_TYPE )
00886 {
00887 p_block->i_dts = p_block->i_pts;
00888 }
00889 else
00890 {
00891 if( p_sys->i_last_ref_pts )
00892 {
00893 p_block->i_dts = p_sys->i_last_ref_pts;
00894 }
00895 else
00896 {
00897
00898 p_block->i_dts = p_block->i_pts;
00899 }
00900
00901 p_sys->i_last_ref_pts = p_block->i_pts;
00902 }
00903 }
00904 else
00905 {
00906
00907
00908 p_block->i_dts = p_block->i_pts = p_pict->date;
00909 }
00910
00911 switch ( p_sys->p_context->coded_frame->pict_type )
00912 {
00913 case FF_I_TYPE:
00914 p_block->i_flags |= BLOCK_FLAG_TYPE_I;
00915 break;
00916 case FF_P_TYPE:
00917 p_block->i_flags |= BLOCK_FLAG_TYPE_P;
00918 break;
00919 case FF_B_TYPE:
00920 p_block->i_flags |= BLOCK_FLAG_TYPE_B;
00921 break;
00922 }
00923
00924 return p_block;
00925 }
00926
00927 return NULL;
00928 }
00929
00930
00931
00932
00933 static block_t *EncodeAudio( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
00934 {
00935 encoder_sys_t *p_sys = p_enc->p_sys;
00936 block_t *p_block, *p_chain = NULL;
00937
00938 char *p_buffer = p_aout_buf->p_buffer;
00939 int i_samples = p_aout_buf->i_nb_samples;
00940 int i_samples_delay = p_sys->i_samples_delay;
00941
00942 p_sys->i_pts = p_aout_buf->start_date -
00943 (mtime_t)1000000 * (mtime_t)p_sys->i_samples_delay /
00944 (mtime_t)p_enc->fmt_in.audio.i_rate;
00945
00946 p_sys->i_samples_delay += i_samples;
00947
00948 while( p_sys->i_samples_delay >= p_sys->p_context->frame_size )
00949 {
00950 int16_t *p_samples;
00951 int i_out;
00952
00953 if( i_samples_delay )
00954 {
00955
00956 int i_delay_size = i_samples_delay * 2 *
00957 p_sys->p_context->channels;
00958 int i_size = p_sys->i_frame_size - i_delay_size;
00959
00960 p_samples = (int16_t *)p_sys->p_buffer;
00961 memcpy( p_sys->p_buffer + i_delay_size, p_buffer, i_size );
00962 p_buffer -= i_delay_size;
00963 i_samples += i_samples_delay;
00964 i_samples_delay = 0;
00965 }
00966 else
00967 {
00968 p_samples = (int16_t *)p_buffer;
00969 }
00970
00971 i_out = avcodec_encode_audio( p_sys->p_context, p_sys->p_buffer_out,
00972 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE,
00973 p_samples );
00974
00975 #if 0
00976 msg_Warn( p_enc, "avcodec_encode_audio: %d", i_out );
00977 #endif
00978 if( i_out < 0 ) break;
00979
00980 p_buffer += p_sys->i_frame_size;
00981 p_sys->i_samples_delay -= p_sys->p_context->frame_size;
00982 i_samples -= p_sys->p_context->frame_size;
00983
00984 if( i_out == 0 ) continue;
00985
00986 p_block = block_New( p_enc, i_out );
00987 memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );
00988
00989 p_block->i_length = (mtime_t)1000000 *
00990 (mtime_t)p_sys->p_context->frame_size /
00991 (mtime_t)p_sys->p_context->sample_rate;
00992
00993 p_block->i_dts = p_block->i_pts = p_sys->i_pts;
00994
00995
00996 p_sys->i_pts += p_block->i_length;
00997 block_ChainAppend( &p_chain, p_block );
00998 }
00999
01000
01001 if( i_samples )
01002 {
01003 memcpy( p_sys->p_buffer + i_samples_delay * 2 *
01004 p_sys->p_context->channels, p_buffer,
01005 i_samples * 2 * p_sys->p_context->channels );
01006 }
01007
01008 return p_chain;
01009 }
01010
01011
01012
01013
01014 void E_(CloseEncoder)( vlc_object_t *p_this )
01015 {
01016 encoder_t *p_enc = (encoder_t *)p_this;
01017 encoder_sys_t *p_sys = p_enc->p_sys;
01018 vlc_value_t lockval;
01019
01020 var_Get( p_enc->p_libvlc, "avcodec", &lockval );
01021
01022 #if LIBAVCODEC_BUILD >= 4702
01023 if ( p_sys->b_inited && p_enc->i_threads >= 1 )
01024 {
01025 int i;
01026 struct thread_context_t ** pp_contexts =
01027 (struct thread_context_t **)p_sys->p_context->thread_opaque;
01028 for ( i = 0; i < p_enc->i_threads; i++ )
01029 {
01030 pp_contexts[i]->b_die = 1;
01031 vlc_cond_signal( &pp_contexts[i]->cond );
01032 vlc_thread_join( pp_contexts[i] );
01033 vlc_mutex_destroy( &pp_contexts[i]->lock );
01034 vlc_cond_destroy( &pp_contexts[i]->cond );
01035 vlc_object_destroy( pp_contexts[i] );
01036 }
01037
01038 free( pp_contexts );
01039 }
01040 #endif
01041
01042 vlc_mutex_lock( lockval.p_address );
01043 avcodec_close( p_sys->p_context );
01044 vlc_mutex_unlock( lockval.p_address );
01045 av_free( p_sys->p_context );
01046
01047 if( p_sys->p_buffer ) free( p_sys->p_buffer );
01048 if( p_sys->p_buffer_out ) free( p_sys->p_buffer_out );
01049
01050 free( p_sys );
01051 }