int transcode_audio_new( sout_stream_t *p_stream, sout_stream_id_t *id ) { sout_stream_sys_t *p_sys = p_stream->p_sys; audio_sample_format_t fmt_last; /* * 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_format_update = audio_update_format; /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */ id->p_decoder->p_module = module_need( id->p_decoder, "decoder", "$codec", false ); if( !id->p_decoder->p_module ) { msg_Err( p_stream, "cannot find audio decoder" ); return VLC_EGENERIC; } /* decoders don't set audio.i_format, but audio filters use it */ id->p_decoder->fmt_out.audio.i_format = id->p_decoder->fmt_out.i_codec; aout_FormatPrepare( &id->p_decoder->fmt_out.audio ); fmt_last = id->p_decoder->fmt_out.audio; /* Fix AAC SBR changing number of channels and sampling rate */ if( !(id->p_decoder->fmt_in.i_codec == VLC_CODEC_MP4A && fmt_last.i_rate != id->p_encoder->fmt_in.audio.i_rate && fmt_last.i_channels != id->p_encoder->fmt_in.audio.i_channels) ) fmt_last.i_rate = id->p_decoder->fmt_in.audio.i_rate; /* * Open encoder */ if( transcode_audio_initialize_encoder( id, p_stream ) == VLC_EGENERIC ) return VLC_EGENERIC; if( unlikely( transcode_audio_initialize_filters( p_stream, id, p_sys, &fmt_last ) != VLC_SUCCESS ) ) return VLC_EGENERIC; return VLC_SUCCESS; }
int transcode_audio_new( sout_stream_t *p_stream, sout_stream_id_t *id ) { sout_stream_sys_t *p_sys = p_stream->p_sys; audio_sample_format_t fmt_last; /* * 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_format_update = audio_update_format; /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */ id->p_decoder->p_module = module_need( id->p_decoder, "decoder", "$codec", false ); if( !id->p_decoder->p_module ) { msg_Err( p_stream, "cannot find audio decoder" ); return VLC_EGENERIC; } /* decoders don't set audio.i_format, but audio filters use it */ id->p_decoder->fmt_out.audio.i_format = id->p_decoder->fmt_out.i_codec; aout_FormatPrepare( &id->p_decoder->fmt_out.audio ); fmt_last = id->p_decoder->fmt_out.audio; /* Fix AAC SBR changing number of channels and sampling rate */ if( !(id->p_decoder->fmt_in.i_codec == VLC_CODEC_MP4A && fmt_last.i_rate != id->p_encoder->fmt_in.audio.i_rate && fmt_last.i_channels != id->p_encoder->fmt_in.audio.i_channels) ) fmt_last.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; 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; aout_FormatPrepare( &id->p_encoder->fmt_in.audio ); 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, true ); if( !id->p_encoder->p_module ) { msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s). Take a look few lines earlier to see possible reason.", p_sys->psz_aenc ? p_sys->psz_aenc : "any", (char *)&p_sys->i_acodec ); module_unneed( id->p_decoder, id->p_decoder->p_module ); id->p_decoder->p_module = NULL; return VLC_EGENERIC; } id->p_encoder->fmt_out.i_codec = vlc_fourcc_GetCodec( AUDIO_ES, id->p_encoder->fmt_out.i_codec ); /* Fix input format */ id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec; if( !id->p_encoder->fmt_in.audio.i_physical_channels || !id->p_encoder->fmt_in.audio.i_original_channels ) { if( id->p_encoder->fmt_in.audio.i_channels < 6 ) id->p_encoder->fmt_in.audio.i_physical_channels = id->p_encoder->fmt_in.audio.i_original_channels = pi_channels_maps[id->p_encoder->fmt_in.audio.i_channels]; } aout_FormatPrepare( &id->p_encoder->fmt_in.audio ); if( unlikely( transcode_audio_initialize_filters( p_stream, id, p_sys, &fmt_last ) != VLC_SUCCESS ) ) return VLC_EGENERIC; return VLC_SUCCESS; }
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; block_t *p_block, *p_audio_buf; *out = NULL; if( unlikely( in == NULL ) ) { block_t *p_block; do { p_block = id->p_encoder->pf_encode_audio(id->p_encoder, NULL ); block_ChainAppend( out, p_block ); } while( p_block ); return VLC_SUCCESS; } while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder, &in )) ) { if( p_sys->b_master_sync ) { mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1; mtime_t i_drift = 0; if( likely( p_audio_buf->i_pts != VLC_TS_INVALID ) ) i_drift = p_audio_buf->i_pts - i_pts; if ( unlikely(i_drift > MASTER_SYNC_MAX_DRIFT || i_drift < -MASTER_SYNC_MAX_DRIFT) ) { msg_Dbg( p_stream, "audio drift is too high (%"PRId64"), resetting master sync", i_drift ); date_Set( &id->interpolated_pts, p_audio_buf->i_pts ); i_pts = p_audio_buf->i_pts + 1; } if( likely(p_audio_buf->i_pts != VLC_TS_INVALID ) ) p_sys->i_master_drift = p_audio_buf->i_pts - i_pts; date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples ); p_audio_buf->i_pts = i_pts; } p_audio_buf->i_dts = p_audio_buf->i_pts; /* Check if audio format has changed, and filters need reinit */ if( unlikely( ( id->p_decoder->fmt_out.audio.i_rate != p_sys->fmt_audio.i_rate ) || ( id->p_decoder->fmt_out.audio.i_physical_channels != p_sys->fmt_audio.i_physical_channels ) ) ) { msg_Info( p_stream, "Audio changed, trying to reinitialize filters" ); if( id->p_af_chain != NULL ) aout_FiltersDelete( (vlc_object_t *)NULL, id->p_af_chain ); /* decoders don't set audio.i_format, but audio filters use it */ id->p_decoder->fmt_out.audio.i_format = id->p_decoder->fmt_out.i_codec; aout_FormatPrepare( &id->p_decoder->fmt_out.audio ); if( transcode_audio_initialize_filters( p_stream, id, p_sys, &id->p_decoder->fmt_out.audio ) != VLC_SUCCESS ) return VLC_EGENERIC; } /* Run filter chain */ p_audio_buf = aout_FiltersPlay( id->p_af_chain, p_audio_buf, INPUT_RATE_DEFAULT ); if( !p_audio_buf ) abort(); p_audio_buf->i_dts = p_audio_buf->i_pts; p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf ); block_ChainAppend( out, p_block ); block_Release( p_audio_buf ); } return VLC_SUCCESS; }