Beispiel #1
0
/*****************************************************************************
 * 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;
}
Beispiel #2
0
/*****************************************************************************
 * 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;
    }
}
Beispiel #3
0
/*****************************************************************************
 * 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;
}
Beispiel #5
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
/*****************************************************************************
 * 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;
}
Beispiel #8
0
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);
}
Beispiel #9
0
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;
}