/***************************************************************************** * OpenFilter: *****************************************************************************/ static int OpenFilter( vlc_object_t *p_this ) { filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys; int i_ret; if( p_filter->fmt_in.i_codec != VLC_CODEC_A52 || p_filter->fmt_out.audio.i_format == VLC_CODEC_SPDIFB || p_filter->fmt_out.audio.i_format == VLC_CODEC_SPDIFL ) { return VLC_EGENERIC; } p_filter->fmt_out.audio.i_format = #ifdef LIBA52_FIXED p_filter->fmt_out.i_codec = VLC_CODEC_FI32; #else p_filter->fmt_out.i_codec = VLC_CODEC_FL32; #endif p_filter->fmt_out.audio.i_bitspersample = aout_BitsPerSample( p_filter->fmt_out.i_codec ); /* Allocate the memory needed to store the module's structure */ p_filter->p_sys = p_sys = malloc( sizeof(filter_sys_t) ); if( p_sys == NULL ) return VLC_ENOMEM; i_ret = Open( VLC_OBJECT(p_filter), p_sys, p_filter->fmt_in.audio, p_filter->fmt_out.audio ); p_filter->pf_audio_filter = Convert; p_filter->fmt_out.audio.i_rate = p_filter->fmt_in.audio.i_rate; return i_ret; }
/***************************************************************************** * aout_FormatPrepare : compute the number of bytes per frame & frame length *****************************************************************************/ void aout_FormatPrepare( audio_sample_format_t * p_format ) { p_format->i_channels = aout_FormatNbChannels( p_format ); p_format->i_bitspersample = aout_BitsPerSample( p_format->i_format ); if( p_format->i_bitspersample > 0 ) { p_format->i_bytes_per_frame = ( p_format->i_bitspersample / 8 ) * aout_FormatNbChannels( p_format ); p_format->i_frame_length = 1; } }
/***************************************************************************** * OpenDecoder : *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { decoder_t *p_dec = (decoder_t *)p_this; decoder_sys_t *p_sys; if( p_dec->fmt_in.i_codec != VLC_CODEC_MPGA && p_dec->fmt_in.i_codec != VLC_CODEC_MP3 ) return VLC_EGENERIC; /* Initialize libmpg123 */ if( InitMPG123() != MPG123_OK ) return VLC_EGENERIC; /* Allocate the memory needed to store the module's structure */ p_sys = p_dec->p_sys = malloc( sizeof(decoder_sys_t) ); if( p_sys == NULL ) return VLC_ENOMEM; p_sys->p_out = NULL; date_Set( &p_sys->end_date, VLC_TS_INVALID ); if( MPG123Open( p_dec ) ) goto error; p_dec->fmt_out.i_codec = VLC_CODEC_FL32; p_dec->fmt_out.audio.i_rate = 0; /* So end_date gets initialized */ p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec; p_dec->pf_decode = DecodeBlock; p_dec->pf_flush = Flush; msg_Dbg( p_this, "%4.4s->%4.4s, bits per sample: %i", (char *)&p_dec->fmt_in.i_codec, (char *)&p_dec->fmt_out.i_codec, aout_BitsPerSample( p_dec->fmt_out.i_codec ) ); return VLC_SUCCESS; error: ExitMPG123(); free( p_sys ); return VLC_EGENERIC; }
/***************************************************************************** * OpenFilter: *****************************************************************************/ static int OpenFilter( vlc_object_t *p_this ) { filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys; if( p_filter->fmt_in.i_codec != VLC_CODEC_MPGA && p_filter->fmt_in.i_codec != VLC_FOURCC('m','p','g','3') ) return VLC_EGENERIC; if( !AOUT_FMTS_SIMILAR( &p_filter->fmt_in.audio, &p_filter->fmt_out.audio ) ) return VLC_EGENERIC; /* Allocate the memory needed to store the module's structure */ p_sys = p_filter->p_sys = malloc( sizeof(filter_sys_t) ); if( p_sys == NULL ) return -1; p_sys->i_reject_count = 0; p_filter->pf_audio_filter = Convert; /* Initialize libmad */ mad_stream_init( &p_sys->mad_stream ); mad_frame_init( &p_sys->mad_frame ); mad_synth_init( &p_sys->mad_synth ); mad_stream_options( &p_sys->mad_stream, MAD_OPTION_IGNORECRC ); p_filter->fmt_out.i_codec = HAVE_FPU ? VLC_CODEC_FL32 : VLC_CODEC_FI32; p_filter->fmt_out.audio.i_format = p_filter->fmt_out.i_codec; p_filter->fmt_out.audio.i_bitspersample = aout_BitsPerSample( p_filter->fmt_out.i_codec ); msg_Dbg( p_this, "%4.4s->%4.4s, bits per sample: %i", (char *)&p_filter->fmt_in.i_codec, (char *)&p_filter->fmt_out.i_codec, p_filter->fmt_in.audio.i_bitspersample ); return 0; }
static sout_stream_id_t *AddAudio( sout_stream_t *p_stream, es_format_t *p_fmt ) { char* psz_tmp; sout_stream_id_t* id; int i_bits_per_sample = aout_BitsPerSample( p_fmt->i_codec ); if( !i_bits_per_sample ) { msg_Err( p_stream, "Smem does only support raw audio format" ); return NULL; } id = (sout_stream_id_t *)calloc( 1, sizeof( sout_stream_id_t ) ); // sunqueen modify if( !id ) return NULL; psz_tmp = var_GetString( p_stream, SOUT_PREFIX_AUDIO "data" ); id->p_data = (void *)( intptr_t )atoll( psz_tmp ); free( psz_tmp ); id->format = p_fmt; id->format->audio.i_bitspersample = i_bits_per_sample; return id; }
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; /* * 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_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", false ); if( !id->p_decoder->p_module ) { msg_Err( p_stream, "cannot find audio decoder" ); return VLC_EGENERIC; } id->p_decoder->fmt_out.audio.i_bitspersample = aout_BitsPerSample( id->p_decoder->fmt_out.i_codec ); fmt_last = id->p_decoder->fmt_out; /* Fix AAC SBR changing number of channels and sampling rate */ if( !(id->p_decoder->fmt_in.i_codec == VLC_CODEC_MP4A && fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate && fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) ) 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; 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 = aout_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, true ); if( !id->p_encoder->p_module ) { msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)", 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_in.audio.i_format = id->p_encoder->fmt_in.i_codec; id->p_encoder->fmt_in.audio.i_bitspersample = aout_BitsPerSample( id->p_encoder->fmt_in.i_codec ); /* Load user specified audio filters */ if( p_sys->psz_af ) { es_format_t fmt_fl32 = fmt_last; fmt_fl32.i_codec = fmt_fl32.audio.i_format = VLC_CODEC_FL32; id->p_uf_chain = filter_chain_New( p_stream, "audio filter", false, transcode_audio_filter_allocation_init, NULL, NULL ); filter_chain_Reset( id->p_uf_chain, &fmt_last, &fmt_fl32 ); if( transcode_audio_filter_chain_build( p_stream, id->p_uf_chain, &fmt_fl32, &fmt_last ) ) { transcode_audio_close( id ); return VLC_EGENERIC; } fmt_last = fmt_fl32; if( filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af ) > 0 ) fmt_last = *filter_chain_GetFmtOut( id->p_uf_chain ); } /* Load conversion filters */ id->p_f_chain = filter_chain_New( p_stream, "audio filter", true, transcode_audio_filter_allocation_init, NULL, NULL ); filter_chain_Reset( id->p_f_chain, &fmt_last, &id->p_encoder->fmt_in ); if( transcode_audio_filter_chain_build( p_stream, id->p_f_chain, &id->p_encoder->fmt_in, &fmt_last ) ) { transcode_audio_close( id ); return VLC_EGENERIC; } fmt_last = id->p_encoder->fmt_in; /* */ id->p_encoder->fmt_out.i_codec = vlc_fourcc_GetCodec( AUDIO_ES, id->p_encoder->fmt_out.i_codec ); return VLC_SUCCESS; }
/***************************************************************************** * OpenDecoder : *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { decoder_t *p_dec = (decoder_t *)p_this; decoder_sys_t *p_sys; if( p_dec->fmt_in.i_codec != VLC_CODEC_MPGA && p_dec->fmt_in.i_codec != VLC_CODEC_MP3 ) return VLC_EGENERIC; p_dec->fmt_out.i_cat = AUDIO_ES; p_dec->fmt_out.i_codec = VLC_CODEC_FL32; /* Initialize libmpg123 */ if( InitMPG123() != MPG123_OK ) return VLC_EGENERIC; /* Allocate the memory needed to store the module's structure */ p_sys = p_dec->p_sys = malloc( sizeof(decoder_sys_t) ); if( p_sys == NULL ) return VLC_ENOMEM; /* Create our mpg123 handle */ if( ( p_sys->p_handle = mpg123_new( NULL, NULL ) ) == NULL ) goto error; /* Open a new bitstream */ if( mpg123_open_feed( p_sys->p_handle ) != MPG123_OK ) { msg_Err( p_this, "mpg123 error: can't open feed" ); goto error; } /* Disable resync stream after error */ mpg123_param( p_sys->p_handle, MPG123_ADD_FLAGS, MPG123_NO_RESYNC, 0 ); /* Setup output format */ mpg123_format_none( p_sys->p_handle ); if( MPG123_OK != mpg123_format( p_sys->p_handle, p_dec->fmt_in.audio.i_rate, MPG123_MONO | MPG123_STEREO, MPG123_ENC_FLOAT_32 ) ) { msg_Err( p_this, "mpg123 error: %s", mpg123_strerror( p_sys->p_handle ) ); mpg123_close( p_sys->p_handle ); goto error; } p_dec->fmt_out.audio.i_rate = 0; /* So end_date gets initialized */ p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec; p_dec->pf_decode_audio = DecodeBlock; msg_Dbg( p_this, "%4.4s->%4.4s, bits per sample: %i", (char *)&p_dec->fmt_in.i_codec, (char *)&p_dec->fmt_out.i_codec, aout_BitsPerSample( p_dec->fmt_out.i_codec ) ); return VLC_SUCCESS; error: mpg123_delete( p_sys->p_handle ); ExitMPG123(); free( p_sys ); return VLC_EGENERIC; }
static int Open(vlc_object_t *obj) { demux_t *demux = (demux_t *)obj; demux_sys_t *sys = malloc(sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; sys->context = vlc_pa_connect(obj, &sys->mainloop); if (sys->context == NULL) { free(sys); return VLC_EGENERIC; } sys->stream = NULL; sys->es = NULL; sys->discontinuity = false; sys->caching = INT64_C(1000) * var_InheritInteger(obj, "live-caching"); demux->p_sys = sys; /* Stream parameters */ struct pa_sample_spec ss; ss.format = PA_SAMPLE_S16NE; ss.rate = 48000; ss.channels = 2; assert(pa_sample_spec_valid(&ss)); struct pa_channel_map map; map.channels = 2; map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; assert(pa_channel_map_valid(&map)); const pa_stream_flags_t flags = PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_ADJUST_LATENCY | PA_STREAM_FIX_FORMAT | PA_STREAM_FIX_RATE /*| PA_STREAM_FIX_CHANNELS*/; const char *dev = NULL; if (demux->psz_location != NULL && demux->psz_location[0] != '\0') dev = demux->psz_location; struct pa_buffer_attr attr = { .maxlength = -1, .fragsize = pa_usec_to_bytes(sys->caching, &ss) / 2, }; es_format_t fmt; /* Create record stream */ pa_stream *s; pa_operation *op; pa_threaded_mainloop_lock(sys->mainloop); s = pa_stream_new(sys->context, "audio stream", &ss, &map); if (s == NULL) goto error; sys->stream = s; pa_stream_set_state_callback(s, stream_state_cb, sys->mainloop); pa_stream_set_read_callback(s, stream_read_cb, demux); pa_stream_set_buffer_attr_callback(s, stream_buffer_attr_cb, demux); pa_stream_set_moved_callback(s, stream_moved_cb, demux); pa_stream_set_overflow_callback(s, stream_overflow_cb, demux); pa_stream_set_started_callback(s, stream_started_cb, demux); pa_stream_set_suspended_callback(s, stream_suspended_cb, demux); pa_stream_set_underflow_callback(s, stream_underflow_cb, demux); if (pa_stream_connect_record(s, dev, &attr, flags) < 0 || stream_wait(s, sys->mainloop)) { vlc_pa_error(obj, "cannot connect record stream", sys->context); goto error; } /* The ES should be initialized before stream_read_cb(), but how? */ const struct pa_sample_spec *pss = pa_stream_get_sample_spec(s); if ((unsigned)pss->format >= sizeof (fourccs) / sizeof (fourccs[0])) { msg_Err(obj, "unknown PulseAudio sample format %u", (unsigned)pss->format); goto error; } vlc_fourcc_t format = fourccs[pss->format]; if (format == 0) { /* FIXME: should renegotiate something else */ msg_Err(obj, "unsupported PulseAudio sample format %u", (unsigned)pss->format); goto error; } es_format_Init(&fmt, AUDIO_ES, format); fmt.audio.i_physical_channels = fmt.audio.i_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; fmt.audio.i_channels = ss.channels; fmt.audio.i_rate = pss->rate; fmt.audio.i_bitspersample = aout_BitsPerSample(format); fmt.audio.i_blockalign = fmt.audio.i_bitspersample * ss.channels / 8; fmt.i_bitrate = fmt.audio.i_bitspersample * ss.channels * pss->rate; sys->framesize = fmt.audio.i_blockalign; sys->es = es_out_Add (demux->out, &fmt); /* Update the buffer attributes according to actual format */ attr.fragsize = pa_usec_to_bytes(sys->caching, pss) / 2; op = pa_stream_set_buffer_attr(s, &attr, stream_success_cb, sys->mainloop); if (likely(op != NULL)) { while (pa_operation_get_state(op) == PA_OPERATION_RUNNING) pa_threaded_mainloop_wait(sys->mainloop); pa_operation_unref(op); } stream_buffer_attr_cb(s, demux); pa_threaded_mainloop_unlock(sys->mainloop); demux->pf_demux = NULL; demux->pf_control = Control; return VLC_SUCCESS; error: pa_threaded_mainloop_unlock(sys->mainloop); Close(obj); return VLC_EGENERIC; } static void Close (vlc_object_t *obj) { demux_t *demux = (demux_t *)obj; demux_sys_t *sys = demux->p_sys; pa_stream *s = sys->stream; if (likely(s != NULL)) { pa_threaded_mainloop_lock(sys->mainloop); pa_stream_disconnect(s); pa_stream_set_state_callback(s, NULL, NULL); pa_stream_set_read_callback(s, NULL, NULL); pa_stream_set_buffer_attr_callback(s, NULL, NULL); pa_stream_set_moved_callback(s, NULL, NULL); pa_stream_set_overflow_callback(s, NULL, NULL); pa_stream_set_started_callback(s, NULL, NULL); pa_stream_set_suspended_callback(s, NULL, NULL); pa_stream_set_underflow_callback(s, NULL, NULL); pa_stream_unref(s); pa_threaded_mainloop_unlock(sys->mainloop); } vlc_pa_disconnect(obj, sys->context, sys->mainloop); free(sys); }
static int Open(vlc_object_t *object) { filter_t *filter = (filter_t *)object; const es_format_t *src = &filter->fmt_in; es_format_t *dst = &filter->fmt_out; if (!AOUT_FMTS_SIMILAR(&src->audio, &dst->audio)) return VLC_EGENERIC; if (src->i_codec == dst->i_codec) return VLC_EGENERIC; cvt_direct_t direct = FindDirect(src->i_codec, dst->i_codec); if (direct) { filter->pf_audio_filter = direct; filter->p_sys = NULL; goto end; } /* */ filter_sys_t *sys = malloc(sizeof(*sys)); if (!sys) return VLC_ENOMEM; /* Find the cost minimal conversion */ for (unsigned mask = 0; mask <= 0x07; mask++) { memset(sys, 0, sizeof(*sys)); vlc_fourcc_t fsrc = src->i_codec; vlc_fourcc_t fdst = dst->i_codec; if (mask & 0x01) { sys->pre = FindSwap(&fsrc, fsrc); if (!sys->pre) continue; } if (mask & 0x02) { sys->post = FindSwap(&fdst, fdst); if (!sys->post) continue; } const bool has_middle = mask & 0x04; for (int i = 0; fsrc != fdst && i < 1 + has_middle; i++) { /* XXX Hardcoded middle format: native 16 bits */ vlc_fourcc_t ftarget = has_middle && i == 0 ? VLC_CODEC_S16N : fdst; sys->directs[i] = FindDirect(fsrc, ftarget); if (!sys->directs[i]) { sys->indirects[i] = FindIndirect(fsrc, ftarget); if (!sys->indirects[i]) break; sys->indirects_ratio[i][0] = aout_BitsPerSample(fsrc) / 8; sys->indirects_ratio[i][1] = aout_BitsPerSample(ftarget) / 8; } fsrc = ftarget; } if (fsrc != fdst) continue; /* We have a full conversion */ filter->pf_audio_filter = Filter; filter->p_sys = sys; goto end; } free(sys); return VLC_EGENERIC; end: dst->audio = src->audio; dst->audio.i_format = dst->i_codec; aout_FormatPrepare(&dst->audio); msg_Dbg(filter, "%4.4s->%4.4s, bits per sample: %i->%i", (char *)&src->i_codec, (char *)&dst->i_codec, src->audio.i_bitspersample, dst->audio.i_bitspersample); return VLC_SUCCESS; }