📄 transcode.c
字号:
if( val.psz_string ) free( val.psz_string ); var_Get( p_stream, SOUT_CFG_PREFIX "ab", &val ); p_sys->i_abitrate = val.i_int; if( p_sys->i_abitrate < 4000 ) p_sys->i_abitrate *= 1000; var_Get( p_stream, SOUT_CFG_PREFIX "samplerate", &val ); p_sys->i_sample_rate = val.i_int; var_Get( p_stream, SOUT_CFG_PREFIX "channels", &val ); p_sys->i_channels = val.i_int; if( p_sys->i_acodec ) { msg_Dbg( p_stream, "codec audio=%4.4s %dHz %d channels %dKb/s", (char *)&p_sys->i_acodec, p_sys->i_sample_rate, p_sys->i_channels, p_sys->i_abitrate / 1000 ); } /* Video transcoding parameters */ var_Get( p_stream, SOUT_CFG_PREFIX "venc", &val ); p_sys->psz_venc = NULL; p_sys->p_video_cfg = NULL; if( val.psz_string && *val.psz_string ) { char *psz_next; psz_next = sout_CfgCreate( &p_sys->psz_venc, &p_sys->p_video_cfg, val.psz_string ); if( psz_next ) free( psz_next ); } if( val.psz_string ) free( val.psz_string ); var_Get( p_stream, SOUT_CFG_PREFIX "vcodec", &val ); p_sys->i_vcodec = 0; if( val.psz_string && *val.psz_string ) { char fcc[4] = " "; memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) ); p_sys->i_vcodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] ); } if( val.psz_string ) free( val.psz_string ); var_Get( p_stream, SOUT_CFG_PREFIX "vb", &val ); p_sys->i_vbitrate = val.i_int; if( p_sys->i_vbitrate < 16000 ) p_sys->i_vbitrate *= 1000; var_Get( p_stream, SOUT_CFG_PREFIX "scale", &val ); p_sys->f_scale = val.f_float; var_Get( p_stream, SOUT_CFG_PREFIX "fps", &val ); p_sys->f_fps = val.f_float; var_Get( p_stream, SOUT_CFG_PREFIX "hurry-up", &val ); p_sys->b_hurry_up = val.b_bool; var_Get( p_stream, SOUT_CFG_PREFIX "width", &val ); p_sys->i_width = val.i_int; var_Get( p_stream, SOUT_CFG_PREFIX "height", &val ); p_sys->i_height = val.i_int; var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace", &val ); p_sys->b_deinterlace = val.b_bool; var_Get( p_stream, SOUT_CFG_PREFIX "deinterlace-module", &val ); p_sys->psz_deinterlace = NULL; p_sys->p_deinterlace_cfg = NULL; if( val.psz_string && *val.psz_string ) { char *psz_next; psz_next = sout_CfgCreate( &p_sys->psz_deinterlace, &p_sys->p_deinterlace_cfg, val.psz_string ); if( psz_next ) free( psz_next ); } if( val.psz_string ) free( val.psz_string ); var_Get( p_stream, SOUT_CFG_PREFIX "croptop", &val ); p_sys->i_crop_top = val.i_int; var_Get( p_stream, SOUT_CFG_PREFIX "cropbottom", &val ); p_sys->i_crop_bottom = val.i_int; var_Get( p_stream, SOUT_CFG_PREFIX "cropleft", &val ); p_sys->i_crop_left = val.i_int; var_Get( p_stream, SOUT_CFG_PREFIX "cropright", &val ); p_sys->i_crop_right = val.i_int; var_Get( p_stream, SOUT_CFG_PREFIX "threads", &val ); p_sys->i_threads = val.i_int; if( p_sys->i_vcodec ) { msg_Dbg( p_stream, "codec video=%4.4s %dx%d scaling: %f %dkb/s", (char *)&p_sys->i_vcodec, p_sys->i_width, p_sys->i_height, p_sys->f_scale, p_sys->i_vbitrate / 1000 ); } /* Subpictures transcoding parameters */ p_sys->p_spu = 0; p_sys->psz_senc = NULL; p_sys->p_spu_cfg = NULL; p_sys->i_scodec = 0; var_Get( p_stream, SOUT_CFG_PREFIX "senc", &val ); if( val.psz_string && *val.psz_string ) { char *psz_next; psz_next = sout_CfgCreate( &p_sys->psz_senc, &p_sys->p_spu_cfg, val.psz_string ); if( psz_next ) free( psz_next ); } if( val.psz_string ) free( val.psz_string ); var_Get( p_stream, SOUT_CFG_PREFIX "scodec", &val ); if( val.psz_string && *val.psz_string ) { char fcc[4] = " "; memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) ); p_sys->i_scodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] ); } if( val.psz_string ) free( val.psz_string ); if( p_sys->i_scodec ) { msg_Dbg( p_stream, "codec spu=%4.4s", (char *)&p_sys->i_scodec ); } var_Get( p_stream, SOUT_CFG_PREFIX "soverlay", &val ); p_sys->b_soverlay = val.b_bool; var_Get( p_stream, SOUT_CFG_PREFIX "sfilter", &val ); if( val.psz_string && *val.psz_string ) { p_sys->p_spu = spu_Create( p_stream ); var_Create( p_sys->p_spu, "sub-filter", VLC_VAR_STRING ); var_Set( p_sys->p_spu, "sub-filter", val ); spu_Init( p_sys->p_spu ); } if( val.psz_string ) free( val.psz_string ); var_Get( p_stream, SOUT_CFG_PREFIX "audio-sync", &val ); p_sys->b_master_sync = val.b_bool; if( p_sys->f_fps > 0 ) p_sys->b_master_sync = VLC_TRUE; p_stream->pf_add = Add; p_stream->pf_del = Del; p_stream->pf_send = Send; p_stream->p_sys = p_sys; return VLC_SUCCESS;}/***************************************************************************** * Close: *****************************************************************************/static void Close( vlc_object_t * p_this ){ sout_stream_t *p_stream = (sout_stream_t*)p_this; sout_stream_sys_t *p_sys = p_stream->p_sys; sout_StreamDelete( p_sys->p_out ); while( p_sys->p_audio_cfg != NULL ) { sout_cfg_t *p_next = p_sys->p_audio_cfg->p_next; if( p_sys->p_audio_cfg->psz_name ) free( p_sys->p_audio_cfg->psz_name ); if( p_sys->p_audio_cfg->psz_value ) free( p_sys->p_audio_cfg->psz_value ); free( p_sys->p_audio_cfg ); p_sys->p_audio_cfg = p_next; } if( p_sys->psz_aenc ) free( p_sys->psz_aenc ); while( p_sys->p_video_cfg != NULL ) { sout_cfg_t *p_next = p_sys->p_video_cfg->p_next; if( p_sys->p_video_cfg->psz_name ) free( p_sys->p_video_cfg->psz_name ); if( p_sys->p_video_cfg->psz_value ) free( p_sys->p_video_cfg->psz_value ); free( p_sys->p_video_cfg ); p_sys->p_video_cfg = p_next; } if( p_sys->psz_venc ) free( p_sys->psz_venc ); while( p_sys->p_deinterlace_cfg != NULL ) { sout_cfg_t *p_next = p_sys->p_deinterlace_cfg->p_next; if( p_sys->p_deinterlace_cfg->psz_name ) free( p_sys->p_deinterlace_cfg->psz_name ); if( p_sys->p_deinterlace_cfg->psz_value ) free( p_sys->p_deinterlace_cfg->psz_value ); free( p_sys->p_deinterlace_cfg ); p_sys->p_deinterlace_cfg = p_next; } if( p_sys->psz_deinterlace ) free( p_sys->psz_deinterlace ); while( p_sys->p_spu_cfg != NULL ) { sout_cfg_t *p_next = p_sys->p_spu_cfg->p_next; if( p_sys->p_spu_cfg->psz_name ) free( p_sys->p_spu_cfg->psz_name ); if( p_sys->p_spu_cfg->psz_value ) free( p_sys->p_spu_cfg->psz_value ); free( p_sys->p_spu_cfg ); p_sys->p_spu_cfg = p_next; } if( p_sys->psz_senc ) free( p_sys->psz_senc ); if( p_sys->p_spu ) spu_Destroy( p_sys->p_spu ); vlc_object_destroy( p_sys );}struct sout_stream_id_t{ vlc_fourcc_t b_transcode; /* id of the out stream */ void *id; /* Decoder */ decoder_t *p_decoder; /* Filters */ filter_t *pp_filter[10]; int i_filter; /* Encoder */ encoder_t *p_encoder; /* Sync */ date_t interpolated_pts;};static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt ){ sout_stream_sys_t *p_sys = p_stream->p_sys; sout_stream_id_t *id; id = malloc( sizeof( sout_stream_id_t ) ); memset( id, 0, sizeof(sout_stream_id_t) ); id->id = NULL; id->p_decoder = NULL; id->p_encoder = NULL; /* Create decoder object */ id->p_decoder = vlc_object_create( p_stream, VLC_OBJECT_DECODER ); if( !id->p_decoder ) { msg_Err( p_stream, "out of memory" ); 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 = VLC_TRUE; /* Create encoder object */ id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER ); if( !id->p_encoder ) { msg_Err( p_stream, "out of memory" ); 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 : (int)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 = VLC_TRUE; if( !id->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; id->p_encoder->fmt_out.video.i_height = p_sys->i_height; 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 = VLC_TRUE; if( p_sys->f_fps > 0 ) { id->p_encoder->fmt_out.video.i_frame_rate = (p_sys->f_fps * 1001) + 0.5; id->p_encoder->fmt_out.video.i_frame_rate_base = 1001; } } 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" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -