📄 transcode.c
字号:
if( !id->p_decoder ) goto error; vlc_object_attach( id->p_decoder, p_stream ); id->p_decoder->p_module = NULL; id->p_decoder->fmt_in = *p_fmt; id->p_decoder->b_pace_control = true; /* Create encoder object */ id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER ); if( !id->p_encoder ) goto error; vlc_object_attach( id->p_encoder, p_stream ); id->p_encoder->p_module = NULL; /* Create destination format */ es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 ); id->p_encoder->fmt_out.i_id = p_fmt->i_id; id->p_encoder->fmt_out.i_group = p_fmt->i_group; if( p_fmt->psz_language ) id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language ); if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) ) { msg_Dbg( p_stream, "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'", (char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec ); /* Complete destination format */ id->p_encoder->fmt_out.i_codec = p_sys->i_acodec; id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ? p_sys->i_sample_rate : p_fmt->audio.i_rate; id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate; id->p_encoder->fmt_out.audio.i_bitspersample = p_fmt->audio.i_bitspersample; id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ? p_sys->i_channels : p_fmt->audio.i_channels; /* Sanity check for audio channels */ id->p_encoder->fmt_out.audio.i_channels = __MIN( id->p_encoder->fmt_out.audio.i_channels, id->p_decoder->fmt_in.audio.i_channels ); id->p_encoder->fmt_out.audio.i_original_channels = id->p_decoder->fmt_in.audio.i_physical_channels; if( id->p_decoder->fmt_in.audio.i_channels == id->p_encoder->fmt_out.audio.i_channels ) { id->p_encoder->fmt_out.audio.i_physical_channels = id->p_decoder->fmt_in.audio.i_physical_channels; } else { id->p_encoder->fmt_out.audio.i_physical_channels = pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels]; } /* Build decoder -> filter -> encoder chain */ if( transcode_audio_new( p_stream, id ) ) { msg_Err( p_stream, "cannot create audio chain" ); goto error; } /* Open output stream */ id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out ); id->b_transcode = true; if( !id->id ) { transcode_audio_close( id ); goto error; } date_Init( &id->interpolated_pts, p_fmt->audio.i_rate, 1 ); } else if( p_fmt->i_cat == VIDEO_ES && (p_sys->i_vcodec != 0 || p_sys->psz_venc) ) { msg_Dbg( p_stream, "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'", (char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec ); /* Complete destination format */ id->p_encoder->fmt_out.i_codec = p_sys->i_vcodec; id->p_encoder->fmt_out.video.i_width = p_sys->i_width & ~1; id->p_encoder->fmt_out.video.i_height = p_sys->i_height & ~1; id->p_encoder->fmt_out.i_bitrate = p_sys->i_vbitrate; /* Build decoder -> filter -> encoder chain */ if( transcode_video_new( p_stream, id ) ) { msg_Err( p_stream, "cannot create video chain" ); goto error; } /* Stream will be added later on because we don't know * all the characteristics of the decoded stream yet */ id->b_transcode = true; if( p_sys->f_fps > 0 ) { id->p_encoder->fmt_out.video.i_frame_rate = (p_sys->f_fps * 1000) + 0.5; id->p_encoder->fmt_out.video.i_frame_rate_base = ENC_FRAMERATE_BASE; } } else if( ( p_fmt->i_cat == SPU_ES ) && ( p_sys->i_scodec || p_sys->psz_senc ) ) { msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' " "to fcc=`%4.4s'", (char*)&p_fmt->i_codec, (char*)&p_sys->i_scodec ); /* Complete destination format */ id->p_encoder->fmt_out.i_codec = p_sys->i_scodec; /* build decoder -> filter -> encoder */ if( transcode_spu_new( p_stream, id ) ) { msg_Err( p_stream, "cannot create subtitles chain" ); goto error; } /* open output stream */ id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out ); id->b_transcode = true; if( !id->id ) { transcode_spu_close( id ); goto error; } } else if( p_fmt->i_cat == SPU_ES && p_sys->b_soverlay ) { msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying", (char*)&p_fmt->i_codec ); id->b_transcode = true; /* Build decoder -> filter -> overlaying chain */ if( transcode_spu_new( p_stream, id ) ) { msg_Err( p_stream, "cannot create subtitles chain" ); goto error; } } else if( !p_sys->b_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) ) { msg_Dbg( p_stream, "creating osd transcoding from fcc=`%4.4s' " "to fcc=`%4.4s'", (char*)&p_fmt->i_codec, (char*)&p_sys->i_scodec ); id->b_transcode = true; /* Create a fake OSD menu elementary stream */ if( transcode_osd_new( p_stream, id ) ) { msg_Err( p_stream, "cannot create osd chain" ); goto error; } p_sys->b_osd = true; } else { msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')", (char*)&p_fmt->i_codec ); id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt ); id->b_transcode = false; if( !id->id ) goto error; } return id;error: if( id ) { if( id->p_decoder ) { vlc_object_detach( id->p_decoder ); vlc_object_release( id->p_decoder ); id->p_decoder = NULL; } if( id->p_encoder ) { vlc_object_detach( id->p_encoder ); es_format_Clean( &id->p_encoder->fmt_out ); vlc_object_release( id->p_encoder ); id->p_encoder = NULL; } free( id ); } return NULL;}static int Del( sout_stream_t *p_stream, sout_stream_id_t *id ){ sout_stream_sys_t *p_sys = p_stream->p_sys; if( id->b_transcode ) { switch( id->p_decoder->fmt_in.i_cat ) { case AUDIO_ES: transcode_audio_close( id ); break; case VIDEO_ES: transcode_video_close( p_stream, id ); break; case SPU_ES: if( p_sys->b_osd ) transcode_osd_close( p_stream, id ); else transcode_spu_close( id ); break; } } if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id ); if( id->p_decoder ) { vlc_object_detach( id->p_decoder ); vlc_object_release( id->p_decoder ); id->p_decoder = NULL; } if( id->p_encoder ) { vlc_object_detach( id->p_encoder ); es_format_Clean( &id->p_encoder->fmt_out ); vlc_object_release( id->p_encoder ); id->p_encoder = NULL; } free( id ); return VLC_SUCCESS;}static int Send( sout_stream_t *p_stream, sout_stream_id_t *id, block_t *p_buffer ){ sout_stream_sys_t *p_sys = p_stream->p_sys; block_t *p_out = NULL; if( !id->b_transcode && id->id ) { return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer ); } else if( !id->b_transcode ) { block_Release( p_buffer ); return VLC_EGENERIC; } switch( id->p_decoder->fmt_in.i_cat ) { case AUDIO_ES: transcode_audio_process( p_stream, id, p_buffer, &p_out ); break; case VIDEO_ES: if( transcode_video_process( p_stream, id, p_buffer, &p_out ) != VLC_SUCCESS ) { return VLC_EGENERIC; } break; case SPU_ES: /* Transcode OSD menu pictures. */ if( p_sys->b_osd ) { if( transcode_osd_process( p_stream, id, p_buffer, &p_out ) != VLC_SUCCESS ) { return VLC_EGENERIC; } } else if ( transcode_spu_process( p_stream, id, p_buffer, &p_out ) != VLC_SUCCESS ) { return VLC_EGENERIC; } break; default: p_out = NULL; block_Release( p_buffer ); break; } if( p_out ) return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_out ); return VLC_SUCCESS;}/**************************************************************************** * decoder helper ****************************************************************************/static inline void video_timer_start( encoder_t * p_encoder ){ stats_TimerStart( p_encoder, "encoding video frame", STATS_TIMER_VIDEO_FRAME_ENCODING );}static inline void video_timer_stop( encoder_t * p_encoder ){ stats_TimerStop( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );}static inline void video_timer_close( encoder_t * p_encoder ){ stats_TimerDump( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING ); stats_TimerClean( p_encoder, STATS_TIMER_VIDEO_FRAME_ENCODING );}static inline void audio_timer_start( encoder_t * p_encoder ){ stats_TimerStart( p_encoder, "encoding audio frame", STATS_TIMER_AUDIO_FRAME_ENCODING );}static inline void audio_timer_stop( encoder_t * p_encoder ){ stats_TimerStop( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );}static inline void audio_timer_close( encoder_t * p_encoder ){ stats_TimerDump( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING ); stats_TimerClean( p_encoder, STATS_TIMER_AUDIO_FRAME_ENCODING );}/**************************************************************************** * decoder reencoder part ****************************************************************************/static block_t *transcode_audio_alloc( filter_t *p_filter, int size ){ VLC_UNUSED( p_filter ); return block_Alloc( size );}static int transcode_audio_filter_allocation_init( filter_t *p_filter, void *data ){ VLC_UNUSED(data); p_filter->pf_audio_buffer_new = transcode_audio_alloc; return VLC_SUCCESS;}static int transcode_audio_new( sout_stream_t *p_stream, sout_stream_id_t *id ){ sout_stream_sys_t *p_sys = p_stream->p_sys; es_format_t fmt_last; int i; /* * Open decoder */ /* Initialization of decoder structures */ id->p_decoder->fmt_out = id->p_decoder->fmt_in; id->p_decoder->fmt_out.i_extra = 0; id->p_decoder->fmt_out.p_extra = 0; id->p_decoder->pf_decode_audio = NULL; id->p_decoder->pf_aout_buffer_new = audio_new_buffer; id->p_decoder->pf_aout_buffer_del = audio_del_buffer; /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */ id->p_decoder->p_module = module_Need( id->p_decoder, "decoder", "$codec", 0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -