📄 encoder.c
字号:
if( val.i_int < - 1 || val.i_int > 1 ) val.i_int = 0; p_context->strict_std_compliance = val.i_int; if( p_enc->fmt_in.i_cat == VIDEO_ES ) { int i_aspect_num, i_aspect_den; if( !p_enc->fmt_in.video.i_width || !p_enc->fmt_in.video.i_height ) { msg_Warn( p_enc, "invalid size %ix%i", p_enc->fmt_in.video.i_width, p_enc->fmt_in.video.i_height ); free( p_sys ); return VLC_EGENERIC; } p_context->width = p_enc->fmt_in.video.i_width; p_context->height = p_enc->fmt_in.video.i_height;#if LIBAVCODEC_BUILD >= 4754 p_context->time_base.num = p_enc->fmt_in.video.i_frame_rate_base; p_context->time_base.den = p_enc->fmt_in.video.i_frame_rate;#else p_context->frame_rate = p_enc->fmt_in.video.i_frame_rate; p_context->frame_rate_base= p_enc->fmt_in.video.i_frame_rate_base;#endif /* Defaults from ffmpeg.c */ p_context->qblur = 0.5; p_context->qcompress = 0.5; p_context->b_quant_offset = 1.25; p_context->b_quant_factor = 1.25; p_context->i_quant_offset = 0.0; p_context->i_quant_factor = -0.8; if( p_sys->i_key_int > 0 ) p_context->gop_size = p_sys->i_key_int; p_context->max_b_frames = __MAX( __MIN( p_sys->i_b_frames, FF_MAX_B_FRAMES ), 0 ); p_context->b_frame_strategy = 0;#if LIBAVCODEC_BUILD >= 4687 av_reduce( &i_aspect_num, &i_aspect_den, p_enc->fmt_in.video.i_aspect, VOUT_ASPECT_FACTOR, 1 << 30 /* something big */ ); av_reduce( &p_context->sample_aspect_ratio.num, &p_context->sample_aspect_ratio.den, i_aspect_num * (int64_t)p_context->height, i_aspect_den * (int64_t)p_context->width, 1 << 30 );#else p_context->aspect_ratio = ((float)p_enc->fmt_in.video.i_aspect) / VOUT_ASPECT_FACTOR;#endif p_sys->p_buffer_out = malloc( AVCODEC_MAX_VIDEO_FRAME_SIZE ); p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','0'); p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->fmt_in.i_codec );#if LIBAVCODEC_BUILD >= 4714 if( p_codec->pix_fmts ) { const enum PixelFormat *p = p_codec->pix_fmts; for( ; *p != -1; p++ ) { if( *p == p_context->pix_fmt ) break; } if( *p == -1 ) p_context->pix_fmt = p_codec->pix_fmts[0]; p_enc->fmt_in.i_codec = E_(GetVlcChroma)( p_context->pix_fmt ); }#else p_enc->fmt_in.i_codec = E_(GetVlcChroma)( p_context->pix_fmt );#endif if ( p_sys->b_strict_rc ) { p_context->rc_max_rate = p_enc->fmt_out.i_bitrate; p_context->rc_buffer_size = p_sys->i_rc_buffer_size; p_context->rc_buffer_aggressivity = p_sys->f_rc_buffer_aggressivity; } if ( p_sys->f_i_quant_factor != 0.0 ) p_context->i_quant_factor = p_sys->f_i_quant_factor;#if LIBAVCODEC_BUILD >= 4690 p_context->noise_reduction = p_sys->i_noise_reduction;#endif if ( p_sys->b_mpeg4_matrix ) { p_context->intra_matrix = ff_mpeg4_default_intra_matrix; p_context->inter_matrix = ff_mpeg4_default_non_intra_matrix; } if ( p_sys->b_pre_me ) { p_context->pre_me = 1; p_context->me_pre_cmp = FF_CMP_CHROMA; } if ( p_sys->b_interlace ) { p_context->flags |= CODEC_FLAG_INTERLACED_DCT;#if LIBAVCODEC_BUILD >= 4698 p_context->flags |= CODEC_FLAG_INTERLACED_ME;#endif } if ( p_sys->b_trellis ) p_context->flags |= CODEC_FLAG_TRELLIS_QUANT; if ( p_sys->i_qmin > 0 && p_sys->i_qmin == p_sys->i_qmax ) p_context->flags |= CODEC_FLAG_QSCALE;#if LIBAVCODEC_BUILD >= 4702 if ( p_enc->i_threads >= 1 ) p_context->thread_count = p_enc->i_threads;#endif if( p_sys->i_vtolerance > 0 ) p_context->bit_rate_tolerance = p_sys->i_vtolerance; if( p_sys->i_qmin > 0 ) p_context->mb_qmin = p_context->qmin = p_sys->i_qmin; if( p_sys->i_qmax > 0 ) p_context->mb_qmax = p_context->qmax = p_sys->i_qmax; p_context->max_qdiff = 3; p_context->mb_decision = p_sys->i_hq; if( p_sys->i_quality ) { p_context->flags |= CODEC_FLAG_QSCALE;#if LIBAVCODEC_BUILD >= 4668 p_context->global_quality = p_sys->i_quality;#endif } } else if( p_enc->fmt_in.i_cat == AUDIO_ES ) { /* work around bug in libmp3lame encoding */ if( i_codec_id == CODEC_ID_MP3 && p_enc->fmt_in.audio.i_channels > 2 ) p_enc->fmt_in.audio.i_channels = 2; p_enc->fmt_in.i_codec = AOUT_FMT_S16_NE; p_context->sample_rate = p_enc->fmt_in.audio.i_rate; p_context->channels = p_enc->fmt_in.audio.i_channels; } /* Misc parameters */ p_context->bit_rate = p_enc->fmt_out.i_bitrate; if( i_codec_id == CODEC_ID_RAWVIDEO ) { /* XXX: hack: Force same codec (will be handled by transcode) */ p_enc->fmt_in.i_codec = p_enc->fmt_out.i_codec; p_context->pix_fmt = E_(GetFfmpegChroma)( p_enc->fmt_in.i_codec ); } /* Make sure we get extradata filled by the encoder */ p_context->extradata_size = 0; p_context->extradata = NULL; p_context->flags |= CODEC_FLAG_GLOBAL_HEADER; if( avcodec_open( p_context, p_codec ) ) { if( p_enc->fmt_in.i_cat == AUDIO_ES && p_context->channels > 2 ) { p_context->channels = 2; p_enc->fmt_in.audio.i_channels = 2; // FIXME if( avcodec_open( p_context, p_codec ) ) { msg_Err( p_enc, "cannot open encoder" ); free( p_sys ); return VLC_EGENERIC; } msg_Warn( p_enc, "stereo mode selected (codec limitation)" ); } else { msg_Err( p_enc, "cannot open encoder" ); free( p_sys ); return VLC_EGENERIC; } } p_enc->fmt_out.i_extra = p_context->extradata_size; p_enc->fmt_out.p_extra = p_context->extradata; p_context->flags &= ~CODEC_FLAG_GLOBAL_HEADER; if( p_enc->fmt_in.i_cat == AUDIO_ES ) { p_sys->p_buffer_out = malloc( 2 * AVCODEC_MAX_AUDIO_FRAME_SIZE ); p_sys->i_frame_size = p_context->frame_size * 2 * p_context->channels; p_sys->p_buffer = malloc( p_sys->i_frame_size ); } msg_Dbg( p_enc, "found encoder %s", psz_namecodec ); return VLC_SUCCESS;}/**************************************************************************** * Ffmpeg threading system ****************************************************************************/#if LIBAVCODEC_BUILD >= 4702static int FfmpegThread( struct thread_context_t *p_context ){ while ( !p_context->b_die && !p_context->b_error ) { vlc_mutex_lock( &p_context->lock ); while ( !p_context->b_work && !p_context->b_die && !p_context->b_error ) { vlc_cond_wait( &p_context->cond, &p_context->lock ); } p_context->b_work = 0; vlc_mutex_unlock( &p_context->lock ); if ( p_context->b_die || p_context->b_error ) break; if ( p_context->pf_func ) { p_context->i_ret = p_context->pf_func( p_context->p_context, p_context->arg ); } vlc_mutex_lock( &p_context->lock ); p_context->b_done = 1; vlc_cond_signal( &p_context->cond ); vlc_mutex_unlock( &p_context->lock ); } return 0;}static int FfmpegExecute( AVCodecContext *s, int (*pf_func)(AVCodecContext *c2, void *arg2), void **arg, int *ret, int count ){ struct thread_context_t ** pp_contexts = (struct thread_context_t **)s->thread_opaque; int i; /* Note, we can be certain that this is not called with the same * AVCodecContext by different threads at the same time */ for ( i = 0; i < count; i++ ) { vlc_mutex_lock( &pp_contexts[i]->lock ); pp_contexts[i]->arg = arg[i]; pp_contexts[i]->pf_func = pf_func; pp_contexts[i]->i_ret = 12345; pp_contexts[i]->b_work = 1; vlc_cond_signal( &pp_contexts[i]->cond ); vlc_mutex_unlock( &pp_contexts[i]->lock ); } for ( i = 0; i < count; i++ ) { vlc_mutex_lock( &pp_contexts[i]->lock ); while ( !pp_contexts[i]->b_done ) { vlc_cond_wait( &pp_contexts[i]->cond, &pp_contexts[i]->lock ); } pp_contexts[i]->b_done = 0; pp_contexts[i]->pf_func = NULL; vlc_mutex_unlock( &pp_contexts[i]->lock ); if ( ret ) { ret[i] = pp_contexts[i]->i_ret; } } return 0;}#endif/**************************************************************************** * EncodeVideo: the whole thing ****************************************************************************/static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict ){ encoder_sys_t *p_sys = p_enc->p_sys; AVFrame frame; int i_out, i_plane;#if LIBAVCODEC_BUILD >= 4702 if ( !p_sys->b_inited && p_enc->i_threads >= 1 ) { struct thread_context_t ** pp_contexts; int i; p_sys->b_inited = 1; pp_contexts = malloc( sizeof(struct thread_context_t *) * p_enc->i_threads ); p_sys->p_context->thread_opaque = (void *)pp_contexts; for ( i = 0; i < p_enc->i_threads; i++ ) { pp_contexts[i] = vlc_object_create( p_enc, sizeof(struct thread_context_t) ); pp_contexts[i]->p_context = p_sys->p_context; vlc_mutex_init( p_enc, &pp_contexts[i]->lock ); vlc_cond_init( p_enc, &pp_contexts[i]->cond ); pp_contexts[i]->b_work = 0; pp_contexts[i]->b_done = 0; if ( vlc_thread_create( pp_contexts[i], "encoder", FfmpegThread, VLC_THREAD_PRIORITY_VIDEO, VLC_FALSE ) ) { msg_Err( p_enc, "cannot spawn encoder thread, expect to die soon" ); return NULL; } } p_sys->p_context->execute = FfmpegExecute;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -