📄 transcode.c
字号:
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; } 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; } 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 ); 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( 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 ); vlc_object_destroy( id->p_encoder ); } 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; if( !id->b_transcode && id->id ) { if( p_sys->b_master_sync && p_sys->i_master_drift ) { if( p_buffer->i_dts > 0 ) { p_buffer->i_dts -= p_sys->i_master_drift; if( p_buffer->i_dts < 0 ) { block_Release( p_buffer ); return VLC_EGENERIC; } } if( p_buffer->i_pts > 0 ) { p_buffer->i_pts -= p_sys->i_master_drift; if( p_buffer->i_pts < 0 ) { block_Release( p_buffer ); return VLC_EGENERIC; } } } 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: if( transcode_spu_process( p_stream, id, p_buffer, &p_out ) != VLC_SUCCESS ) { return VLC_EGENERIC; } break; default: 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 reencoder part ****************************************************************************/int audio_BitsPerSample( vlc_fourcc_t i_format ){ switch( i_format ) { case VLC_FOURCC('u','8',' ',' '): case VLC_FOURCC('s','8',' ',' '): return 8; case VLC_FOURCC('u','1','6','l'): case VLC_FOURCC('s','1','6','l'): case VLC_FOURCC('u','1','6','b'): case VLC_FOURCC('s','1','6','b'): return 16; case VLC_FOURCC('u','2','4','l'): case VLC_FOURCC('s','2','4','l'): case VLC_FOURCC('u','2','4','b'): case VLC_FOURCC('s','2','4','b'): return 24; case VLC_FOURCC('u','3','2','l'): case VLC_FOURCC('s','3','2','l'): case VLC_FOURCC('u','3','2','b'): case VLC_FOURCC('s','3','2','b'): case VLC_FOURCC('f','l','3','2'): case VLC_FOURCC('f','i','3','2'): return 32; case VLC_FOURCC('f','l','6','4'): return 64; } return 0;}static filter_t *transcode_audio_filter_new( sout_stream_t *p_stream, sout_stream_id_t *id, es_format_t *p_fmt_in, es_format_t *p_fmt_out ){ filter_t *p_filter = vlc_object_create( p_stream, VLC_OBJECT_FILTER ); vlc_object_attach( p_filter, p_stream ); p_filter->pf_audio_buffer_new = __block_New; p_filter->fmt_in = *p_fmt_in; p_filter->fmt_out = *p_fmt_out; p_filter->p_module = module_Need( p_filter, "audio filter2", 0, 0 ); if( p_filter->p_module ) { p_filter->fmt_out.audio.i_bitspersample = audio_BitsPerSample( p_filter->fmt_out.i_codec ); *p_fmt_in = p_filter->fmt_out; } else { vlc_object_detach( p_filter ); vlc_object_destroy( p_filter ); p_filter = 0; } return p_filter;}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_pass = 6; /* * 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 = 0; 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_video_cfg; id->p_decoder->p_module = module_Need( id->p_decoder, "decoder", "$codec", 0 ); if( !id->p_decoder->p_module ) { msg_Err( p_stream, "cannot find decoder" ); return VLC_EGENERIC; } id->p_decoder->fmt_out.audio.i_bitspersample = audio_BitsPerSample( id->p_decoder->fmt_out.i_codec ); fmt_last = id->p_decoder->fmt_out; /* FIX decoders so we don't have to do this */ fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate; /* * Open encoder */ /* Initialization of encoder format structures */ es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat, id->p_decoder->fmt_out.i_codec ); id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec; /* Initialization of encoder format structures */ es_format_Init( &id->p_encoder->fmt_in, AUDIO_ES, AOUT_FMT_S16_NE ); id->p_encoder->fmt_in.audio.i_format = AOUT_FMT_S16_NE; id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate; id->p_encoder->fmt_in.audio.i_physical_channels = id->p_encoder->fmt_out.audio.i_physical_channels; id->p_encoder->fmt_in.audio.i_original_channels = id->p_encoder->fmt_out.audio.i_original_channels; id->p_encoder->fmt_in.audio.i_channels = id->p_encoder->fmt_out.audio.i_channels; id->p_encoder->fmt_in.audio.i_bitspersample = audio_BitsPerSample( id->p_encoder->fmt_in.i_codec ); id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg; id->p_encoder->p_module = module_Need( id->p_encoder, "encoder", p_sys->psz_aenc, VLC_TRUE ); if( !id->p_encoder->p_module ) { msg_Err( p_stream, "cannot find encoder" ); module_Unneed( id->p_decoder, id->p_decoder->p_module ); id->p_decoder->p_module = 0; return VLC_EGENERIC; } id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec; id->p_encoder->fmt_in.audio.i_bitspersample = audio_BitsPerSample( id->p_encoder->fmt_in.i_codec ); /* Load conversion filters */ if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels || fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate ) { /* We'll have to go through fl32 first */ es_format_t fmt_out = id->p_encoder->fmt_in; fmt_out.i_codec = fmt_out.audio.i_format = VLC_FOURCC('f','l','3','2'); id->pp_filter[id->i_filter] = transcode_audio_filter_new( p_stream, id, &fmt_last, &fmt_out ); if( id->pp_filter[id->i_filter] ) id->i_filter++; } while( i_pass-- ) { if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels || fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate || fmt_last.i_codec != id->p_encoder->fmt_in.i_codec ) { id->pp_filter[id->i_filter] = transcode_audio_filter_new( p_stream, id, &fmt_last, &id->p_encoder->fmt_in ); if( id->pp_filter[id->i_filter] ) id->i_filter++; else break; } } /* Final checks to see if conversions were successful */ if( fmt_last.i_codec != id->p_encoder->fmt_in.i_codec ) { msg_Err( p_stream, "no audio filter found (%4.4s->%4.4s)", (char *)&fmt_last.i_codec, (char *)&id->p_encoder->fmt_in.i_codec ); transcode_audio_close( p_stream, id ); return VLC_EGENERIC; } if( fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels ) { msg_Err( p_stream, "no audio filter found for mixing from" " %i to %i channels", fmt_last.audio.i_channels, id->p_encoder->fmt_in.audio.i_channels );#if 0 /* FIXME : this might work, but only if the encoder is restarted */ id->p_encoder->fmt_in.audio.i_channels = fmt_last.audio.i_channels; id->p_encoder->fmt_out.audio.i_channels = fmt_last.audio.i_channels; id->p_encoder->fmt_in.audio.i_physical_channels = id->p_encoder->fmt_in.audio.i_original_channels = fmt_last.audio.i_physical_channels; id->p_encoder->fmt_out.audio.i_physical_channels = id->p_encoder->fmt_out.audio.i_original_channels = fmt_last.audio.i_physical_channels;#else transcode_audio_close( p_stream, id ); return VLC_EGENERIC;#endif } if( fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate ) { msg_Err( p_stream, "no audio filter found for resampling from" " %iHz to %iHz", fmt_last.audio.i_rate, id->p_encoder->fmt_in.audio.i_rate );#if 0 /* FIXME : this might work, but only if the encoder is restarted */ id->p_encoder->fmt_in.audio.i_rate = fmt_last.audio.i_rate; id->p_encoder->fmt_out.audio.i_rate = fmt_last.audio.i_rate;#else transcode_audio_close( p_stream, id ); return VLC_EGENERIC;#endif } /* FIXME: Hack for mp3 transcoding support */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -