📄 transcode.c
字号:
es_format_Clean( &id->p_encoder->fmt_out ); 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 = NULL; if( !id->b_transcode && id->id ) { /* Transcode OSD menu pictures. */ if( p_sys->b_es_osd ) { transcode_osd_process( p_stream, id, p_buffer, &p_out ); } 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: 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 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_t* (*) (filter_t*, int))__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_audio_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 (%s)", p_sys->psz_aenc ); module_Unneed( id->p_decoder, id->p_decoder->p_module ); id->p_decoder->p_module = NULL; 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 ) {#if 1 module_Unneed( id->p_encoder, id->p_encoder->p_module ); id->p_encoder->p_module = NULL; /* 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; msg_Dbg( p_stream, "number of audio channels for mixing changed, " "trying to reopen the encoder for mixing %i to %i channels", fmt_last.audio.i_channels, id->p_encoder->fmt_in.audio.i_channels ); /* reload encoder */ 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 (%s)", p_sys->psz_aenc ); transcode_audio_close( p_stream, id ); 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 );#else 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 ); 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 */ if( id->p_encoder->fmt_out.i_codec == VLC_FOURCC( 'm','p','3',' ' ) ) id->p_encoder->fmt_out.i_codec = VLC_FOURCC( 'm','p','g','a' ); return VLC_SUCCESS;}static void transcode_audio_close( sout_stream_t *p_stream, sout_stream_id_t *id ){ int i; /* Close decoder */ if( id->p_decoder->p_module ) module_Unneed( id->p_decoder, id->p_decoder->p_module ); id->p_decoder->p_module = NULL; /* Close encoder */ if( id->p_encoder->p_module ) module_Unneed( id->p_encoder, id->p_encoder->p_module ); id->p_encoder->p_module = NULL; /* Close filters */ for( i = 0; i < id->i_filter; i++ ) { vlc_object_detach( id->pp_filter[i] ); if( id->pp_filter[i]->p_module ) module_Unneed( id->pp_filter[i], id->pp_filter[i]->p_module ); vlc_object_destroy( id->pp_filter[i] ); }}static int transcode_audio_process( sout_stream_t *p_stream, sout_stream_id_t *id, block_t *in, block_t **out ){ sout_stream_sys_t *p_sys = p_stream->p_sys; aout_buffer_t *p_audio_buf; block_t *p_block, *p_audio_block; int i; *out = NULL; while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder, &in )) ) { stats_UpdateInteger( p_stream->p_parent->p_parent, STATS_DECODED_AUDIO, 1, NULL ); if( p_sys->b_master_sync ) { mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1; if ( p_audio_buf->start_date - i_dts > MASTER_SYNC_MAX_DRIFT || p_audio_buf->start_date - i_dts < -MASTER_SYNC_MAX_DRIFT ) { msg_Dbg( p_stream, "drift is too high, resetting master sync" ); date_Set( &id->interpolated_pts, p_audio_buf->start_date ); i_dts = p_audio_buf->start_date + 1; } p_sys->i_master_drift = p_audio_buf->start_date - i_dts; date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples ); p_audio_buf->start_date -= p_sys->i_master_drift; p_audio_buf->end_date -= p_sys->i_master_drift; } p_audio_block = p_audio_buf->p_sys;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -