transcode.c
来自「uclinux 下的vlc播放器源代码」· C语言 代码 · 共 1,822 行 · 第 1/5 页
C
1,822 行
} } /* Audio settings */ 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 ); while( p_sys->p_osd_cfg != NULL ) { sout_cfg_t *p_next = p_sys->p_osd_cfg->p_next; if( p_sys->p_osd_cfg->psz_name ) free( p_sys->p_osd_cfg->psz_name ); if( p_sys->p_osd_cfg->psz_value ) free( p_sys->p_osd_cfg->psz_value ); free( p_sys->p_osd_cfg ); p_sys->p_osd_cfg = p_next; } if( p_sys->psz_osdenc ) free( p_sys->psz_osdenc ); 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; filter_t *pp_vfilter[10]; int i_vfilter; /* 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 ) { transcode_audio_close( p_stream, 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 = 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" ); 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 ) { transcode_spu_close( p_stream, 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 = VLC_TRUE; /* Build decoder -> filter -> overlaying chain */ if( transcode_spu_new( p_stream, id ) ) { msg_Err( p_stream, "cannot create subtitles chain" ); goto error; } } 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 = VLC_FALSE; if( !id->id ) goto error; } if( p_sys->b_sout_osd ) { /* Create a fake OSD menu elementary stream */ if( !p_sys->b_es_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) ) { if( transcode_osd_new( p_stream, p_sys->id_osd ) ) { msg_Err( p_stream, "cannot create osd chain" ); goto error; } p_sys->b_es_osd = VLC_TRUE; } } return id; error: if( id->p_decoder ) { vlc_object_detach( id->p_decoder ); vlc_object_destroy( id->p_decoder ); } if( id->p_encoder ) { vlc_object_detach( id->p_encoder ); es_format_Clean( &id->p_encoder->fmt_out ); vlc_object_destroy( id->p_encoder ); } 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( p_sys->b_es_osd ) transcode_osd_close( p_stream, p_sys->id_osd ); if( id->b_transcode ) { switch( id->p_decoder->fmt_in.i_cat ) { case AUDIO_ES: transcode_audio_close( p_stream, id ); break; case VIDEO_ES: transcode_video_close( p_stream, id ); break; case SPU_ES: transcode_spu_close( p_stream, 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_destroy( id->p_decoder ); } if( id->p_encoder ) { vlc_object_detach( id->p_encoder );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?