예제 #1
0
/*****************************************************************************
 * DecodePacket: decodes a Speex packet.
 *****************************************************************************/
static block_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    if( p_oggpacket->bytes )
    {
        /* Copy Ogg packet to Speex bitstream */
        speex_bits_read_from( &p_sys->bits, (char *)p_oggpacket->packet,
                              p_oggpacket->bytes );
        p_sys->i_frame_in_packet = 0;
    }

    /* Decode one frame at a time */
    if( p_sys->i_frame_in_packet < p_sys->p_header->frames_per_packet )
    {
        block_t *p_aout_buffer;
        if( p_sys->p_header->frame_size == 0 )
            return NULL;

        p_aout_buffer =
            decoder_NewAudioBuffer( p_dec, p_sys->p_header->frame_size );
        if( !p_aout_buffer )
        {
            return NULL;
        }

        switch( speex_decode_int( p_sys->p_state, &p_sys->bits,
                                  (int16_t *)p_aout_buffer->p_buffer ) )
        {
            case -2:
                msg_Err( p_dec, "decoding error: corrupted stream?" );
            case -1: /* End of stream */
                return NULL;
        }

        if( speex_bits_remaining( &p_sys->bits ) < 0 )
        {
            msg_Err( p_dec, "decoding overflow: corrupted stream?" );
        }

        if( p_sys->p_header->nb_channels == 2 )
            speex_decode_stereo_int( (int16_t *)p_aout_buffer->p_buffer,
                                     p_sys->p_header->frame_size,
                                     &p_sys->stereo );

        /* Date management */
        p_aout_buffer->i_pts = date_Get( &p_sys->end_date );
        p_aout_buffer->i_length =
            date_Increment( &p_sys->end_date, p_sys->p_header->frame_size )
            - p_aout_buffer->i_pts;

        p_sys->i_frame_in_packet++;

        return p_aout_buffer;
    }
    else
    {
        return NULL;
    }
}
예제 #2
0
파일: audio.c 프로젝트: hustcalm/vlc-player
/*****************************************************************************
 * SplitBuffer: Needed because aout really doesn't like big audio chunk and
 * wma produces easily > 30000 samples...
 *****************************************************************************/
static aout_buffer_t *SplitBuffer( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    int i_samples = __MIN( p_sys->i_samples, 4096 );
    aout_buffer_t *p_buffer;

    if( i_samples == 0 ) return NULL;

    if( ( p_buffer = decoder_NewAudioBuffer( p_dec, i_samples ) ) == NULL )
        return NULL;

    p_buffer->i_pts = date_Get( &p_sys->end_date );
    p_buffer->i_length = date_Increment( &p_sys->end_date, i_samples )
                         - p_buffer->i_pts;

    if( p_sys->b_extract )
        aout_ChannelExtract( p_buffer->p_buffer, p_dec->fmt_out.audio.i_channels,
                             p_sys->p_samples, p_sys->p_context->channels, i_samples,
                             p_sys->pi_extraction, p_dec->fmt_out.audio.i_bitspersample );
    else
        memcpy( p_buffer->p_buffer, p_sys->p_samples, p_buffer->i_buffer );

    p_sys->p_samples += i_samples * p_sys->p_context->channels * ( p_dec->fmt_out.audio.i_bitspersample / 8 );
    p_sys->i_samples -= i_samples;

    return p_buffer;
}
예제 #3
0
파일: gme.c 프로젝트: 0xheart0/vlc
static int Demux (demux_t *demux)
{
    demux_sys_t *sys = demux->p_sys;

    /* Next track */
    if (gme_track_ended (sys->emu))
    {
        msg_Dbg (demux, "track %u ended", sys->track_id);
        if (++sys->track_id >= (unsigned)gme_track_count (sys->emu))
            return 0;

        demux->info.i_update |= INPUT_UPDATE_TITLE;
        demux->info.i_title = sys->track_id;
        gme_start_track (sys->emu, sys->track_id);
    }


    block_t *block = block_Alloc (2 * 2 * SAMPLES);
    if (unlikely(block == NULL))
        return 0;

    gme_err_t ret = gme_play (sys->emu, 2 * SAMPLES, (void *)block->p_buffer);
    if (ret != NULL)
    {
        block_Release (block);
        msg_Err (demux, "%s", ret);
        return 0;
    }

    block->i_pts = block->i_dts = VLC_TS_0 + date_Get (&sys->pts);
    es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts);
    es_out_Send (demux->out, sys->es, block);
    date_Increment (&sys->pts, SAMPLES);
    return 1;
}
예제 #4
0
파일: mod.c 프로젝트: mstorsjo/vlc
/*****************************************************************************
 * Demux:
 *****************************************************************************/
static int Demux( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    block_t     *p_frame;
    const int i_bk = ( p_sys->fmt.audio.i_bitspersample / 8 ) *
                       p_sys->fmt.audio.i_channels;

    p_frame = block_Alloc( p_sys->fmt.audio.i_rate / 10 * i_bk );
    if( !p_frame )
        return VLC_DEMUXER_EGENERIC;

    const int i_read = ModPlug_Read( p_sys->f, p_frame->p_buffer, p_frame->i_buffer );
    if( i_read <= 0 )
    {
        /* EOF */
        block_Release( p_frame );
        return VLC_DEMUXER_EOF;
    }
    p_frame->i_buffer = i_read;
    p_frame->i_dts =
    p_frame->i_pts = date_Get( &p_sys->pts );

    es_out_SetPCR( p_demux->out, p_frame->i_pts );
    es_out_Send( p_demux->out, p_sys->es, p_frame );
    date_Increment( &p_sys->pts, i_read / i_bk );
    return VLC_DEMUXER_SUCCESS;
}
예제 #5
0
파일: sid.cpp 프로젝트: chouquette/vlc
static int Demux (demux_t *demux)
{
    demux_sys_t *sys = demux->p_sys;

    block_t *block = block_Alloc( sys->block_size);
    if (unlikely(block==NULL))
        return 0;

    if (!sys->tune->getStatus()) {
        block_Release (block);
        return 0;
    }

    int i_read = sys->player->play ((void*)block->p_buffer, block->i_buffer);
    if (i_read <= 0) {
        block_Release (block);
        return 0;
    }
    block->i_buffer = i_read;
    block->i_pts = block->i_dts = VLC_TS_0 + date_Get (&sys->pts);

    es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts);

    es_out_Send (demux->out, sys->es, block);

    date_Increment (&sys->pts, i_read / sys->bytes_per_frame);

    return 1;
}
예제 #6
0
파일: timecode.c 프로젝트: IAPark/vlc
static int DemuxOnce (demux_t *demux, bool master)
{
    demux_sys_t *sys = demux->p_sys;
    mtime_t pts = date_Get (&sys->date);
    lldiv_t d;
    unsigned h, m, s, f;

    d = lldiv (pts, CLOCK_FREQ);
    f = d.rem * sys->date.i_divider_num / sys->date.i_divider_den / CLOCK_FREQ;
    d = lldiv (d.quot, 60);
    s = d.rem;
    d = lldiv (d.quot, 60);
    m = d.rem;
    h = d.quot;

    char *str;
    int len = asprintf (&str, "%02u:%02u:%02u:%02u", h, m, s, f);
    if (len == -1)
        return -1;

    block_t *block = block_heap_Alloc (str, len + 1);
    if (unlikely(block == NULL))
        return -1;

    block->i_buffer = len;
    assert(str[len] == '\0');

    block->i_pts = block->i_dts = pts;
    block->i_length = date_Increment (&sys->date, 1) - pts;
    es_out_Send (demux->out, sys->es, block);
    if (master)
        es_out_SetPCR(demux->out, pts);
    return 1;
}
예제 #7
0
파일: xa.c 프로젝트: mstorsjo/vlc
/*****************************************************************************
 * Demux: read packet and send them to decoders
 *****************************************************************************
 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
 *****************************************************************************/
static int Demux( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    block_t     *p_block;
    int64_t     i_offset = vlc_stream_Tell( p_demux->s );
    unsigned    i_frames = p_sys->i_block_frames;

    if( p_sys->i_data_size > 0 &&
        (i_offset - HEADER_LENGTH) >= p_sys->i_data_size )
    {
        return VLC_DEMUXER_EOF;
    }

    p_block = vlc_stream_Block( p_demux->s, p_sys->i_frame_size * i_frames );
    if( p_block == NULL )
    {
        msg_Warn( p_demux, "cannot read data" );
        return VLC_DEMUXER_EOF;
    }

    i_frames = p_block->i_buffer / p_sys->i_frame_size;
    p_block->i_dts = p_block->i_pts = date_Get( &p_sys->pts );
    es_out_SetPCR( p_demux->out, p_block->i_pts );
    es_out_Send( p_demux->out, p_sys->p_es, p_block );

    date_Increment( &p_sys->pts, i_frames * FRAME_LENGTH );

    return VLC_DEMUXER_SUCCESS;
}
예제 #8
0
파일: xa.c 프로젝트: paa/vlc
/*****************************************************************************
 * Demux: read packet and send them to decoders
 *****************************************************************************
 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
 *****************************************************************************/
static int Demux( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    block_t     *p_block;
    int64_t     i_offset;
    unsigned    i_frames = p_sys->i_block_frames;

    i_offset = stream_Tell( p_demux->s );

    if( p_sys->i_data_size > 0 &&
        i_offset >= p_sys->i_data_offset + p_sys->i_data_size )
    {
        /* EOF */
        return 0;
    }

    p_block = stream_Block( p_demux->s, p_sys->fmt.audio.i_bytes_per_frame *
                            i_frames );
    if( p_block == NULL )
    {
        msg_Warn( p_demux, "cannot read data" );
        return 0;
    }

    i_frames = p_block->i_buffer / p_sys->fmt.audio.i_bytes_per_frame;
    p_block->i_dts = p_block->i_pts = VLC_TS_0 + date_Get( &p_sys->pts );
    es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );
    es_out_Send( p_demux->out, p_sys->p_es, p_block );

    date_Increment( &p_sys->pts, i_frames * p_sys->fmt.audio.i_frame_length );

    return 1;
}
예제 #9
0
파일: mjpeg.c 프로젝트: mstorsjo/vlc
static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t *p_block )
{
    decoder_t *p_dec = p_private;
    decoder_sys_t *p_sys = p_dec->p_sys;

    const uint8_t *p_buf = &p_block->p_buffer[2];
    size_t i_buf = p_block->i_buffer - 2;

    while( i_buf > 4 && p_buf[0] == 0xFF )
    {
        size_t i_size = 2 + GetWBE( &p_buf[2] );
        if( i_size > i_buf )
            break;
        if( p_buf[1] == 0xC0 && i_buf > 9 )
        {
            uint16_t i_height = GetWBE( &p_buf[5] );
            uint16_t i_width = GetWBE( &p_buf[7] );
            if( i_height && i_width &&
                (p_dec->fmt_out.video.i_height != i_height ||
                 p_dec->fmt_out.video.i_width != i_width) )
            {
                p_dec->fmt_out.video.i_width =
                p_dec->fmt_out.video.i_visible_width = i_width;
                p_dec->fmt_out.video.i_height =
                p_dec->fmt_out.video.i_visible_height = i_height;
            }
            break;
        }
        i_buf -= i_size;
        p_buf += i_size;
    }

    if( p_block->i_dts == VLC_TICK_INVALID )
        p_block->i_dts = p_block->i_pts;
    else if( p_block->i_pts == VLC_TICK_INVALID )
        p_block->i_pts = p_block->i_dts;

    vlc_tick_t i_prev_dts = date_Get( &p_sys->date );
    if( p_block->i_dts != VLC_TICK_INVALID )
    {
        date_Set( &p_sys->date, p_block->i_dts );
    }
    else if( p_dec->fmt_in.video.i_frame_rate &&
             p_dec->fmt_in.video.i_frame_rate_base )
    {
        date_Increment( &p_sys->date, 1 );
        p_block->i_dts = p_block->i_pts = date_Get( &p_sys->date );
    }

    if( i_prev_dts != VLC_TICK_INVALID && p_block->i_dts != VLC_TICK_INVALID )
        p_block->i_length = p_block->i_dts - i_prev_dts;

    *pb_ts_used = true;

    p_block->i_flags = p_sys->i_next_block_flags | BLOCK_FLAG_TYPE_I;
    p_sys->i_next_block_flags = 0;

    return p_block;
}
예제 #10
0
파일: opus.c 프로젝트: fabsther/vlc-mort
/*****************************************************************************
 * DecodePacket: decodes a Opus packet.
 *****************************************************************************/
static block_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
                              int i_nb_samples, int i_end_trim )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    if( !p_oggpacket->bytes )
        return NULL;

    int spp;
    spp=opus_packet_get_nb_frames(p_oggpacket->packet,p_oggpacket->bytes);
    if(spp>0)spp*=opus_packet_get_samples_per_frame(p_oggpacket->packet,48000);
    if(spp<120||spp>120*48)return NULL;

    block_t *p_aout_buffer=decoder_NewAudioBuffer( p_dec, spp );
    if ( !p_aout_buffer )
    {
        msg_Err(p_dec, "Oops: No new buffer was returned!");
        return NULL;
    }

    spp=opus_multistream_decode_float(p_sys->p_st, p_oggpacket->packet,
         p_oggpacket->bytes, (float *)p_aout_buffer->p_buffer, spp, 0);
    if( spp < 0 || i_nb_samples <= 0 || i_end_trim >= i_nb_samples)
    {
        block_Release(p_aout_buffer);
        if( spp < 0 )
            msg_Err( p_dec, "Error: corrupted stream?" );
        return NULL;
    }

    p_aout_buffer->i_buffer = (i_nb_samples - i_end_trim) *
                              p_sys->header.channels * sizeof(float);

    if( spp > i_nb_samples )
    {
        memmove(p_aout_buffer->p_buffer,
            p_aout_buffer->p_buffer
            + (spp - i_nb_samples)*p_sys->header.channels*sizeof(float),
            (i_nb_samples - i_end_trim)*p_sys->header.channels*sizeof(float));
    }
    i_nb_samples -= i_end_trim;

#ifndef OPUS_SET_GAIN
    if(p_sys->header.gain!=0)
    {
        float gain = pow(10., p_sys->header.gain/5120.);
        float *buf =(float *)p_aout_buffer->p_buffer;
        int i;
        for( i = 0; i < i_nb_samples*p_sys->header.channels; i++)
            buf[i] *= gain;
    }
#endif
    p_aout_buffer->i_nb_samples = i_nb_samples;
    p_aout_buffer->i_pts = date_Get( &p_sys->end_date );
    p_aout_buffer->i_length = date_Increment( &p_sys->end_date, i_nb_samples )
        - p_aout_buffer->i_pts;
    return p_aout_buffer;
}
예제 #11
0
/****************************************************************************
 * DecodeBlock: the whole thing
 ****************************************************************************
 * This function must be fed with complete frames.
 ****************************************************************************/
static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_block;
    void *p_buf;

    if( !pp_block || !*pp_block ) return NULL;

    p_block = *pp_block;


    if( p_block->i_pts <= VLC_TS_INVALID && p_block->i_dts <= VLC_TS_INVALID &&
        !date_Get( &p_sys->pts ) )
    {
        /* We've just started the stream, wait for the first PTS. */
        block_Release( p_block );
        return NULL;
    }

    /* Date management: If there is a pts avaliable, use that. */
    if( p_block->i_pts > VLC_TS_INVALID )
    {
        date_Set( &p_sys->pts, p_block->i_pts );
    }
    else if( p_block->i_dts > VLC_TS_INVALID )
    {
        /* NB, davidf doesn't quite agree with this in general, it is ok
         * for rawvideo since it is in order (ie pts=dts), however, it
         * may not be ok for an out-of-order codec, so don't copy this
         * without thinking */
        date_Set( &p_sys->pts, p_block->i_dts );
    }

    if( p_block->i_buffer < p_sys->i_raw_size )
    {
        msg_Warn( p_dec, "invalid frame size (%zu < %zu)",
                  p_block->i_buffer, p_sys->i_raw_size );

        block_Release( p_block );
        return NULL;
    }

    if( p_sys->b_packetizer )
    {
        p_buf = SendFrame( p_dec, p_block );
    }
    else
    {
        p_buf = DecodeFrame( p_dec, p_block );
    }

    /* Date management: 1 frame per packet */
    date_Increment( &p_sys->pts, 1 );
    *pp_block = NULL;

    return p_buf;
}
/****************************************************************************
 * DecodeBlock: the whole thing
 ****************************************************************************
 * This function must be fed with whole samples (see nBlockAlign).
 ****************************************************************************/
static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    if( !pp_block || !*pp_block ) return NULL;

    block_t *p_block = *pp_block;

    if( p_block->i_pts > VLC_TS_INVALID &&
        p_block->i_pts != date_Get( &p_sys->end_date ) )
    {
        date_Set( &p_sys->end_date, p_block->i_pts );
    }
    else if( !date_Get( &p_sys->end_date ) )
    {
        /* We've just started the stream, wait for the first PTS. */
        block_Release( p_block );
        return NULL;
    }

    /* Don't re-use the same pts twice */
    p_block->i_pts = VLC_TS_INVALID;

    unsigned samples = (8 * p_block->i_buffer) / p_sys->framebits;
    if( samples == 0 )
    {
        block_Release( p_block );
        return NULL;
    }

    /* Create chunks of max 1024 samples */
    if( samples > 1024 ) samples = 1024;

    block_t *p_out = decoder_NewAudioBuffer( p_dec, samples );
    if( p_out == NULL )
    {
        block_Release( p_block );
        return NULL;
    }

    p_out->i_pts = date_Get( &p_sys->end_date );
    p_out->i_length = date_Increment( &p_sys->end_date, samples )
                      - p_out->i_pts;

    if( p_sys->decode != NULL )
        p_sys->decode( p_out->p_buffer, p_block->p_buffer,
                       samples * p_dec->fmt_in.audio.i_channels );
    else
        memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_buffer );

    samples = (samples * p_sys->framebits) / 8;
    p_block->p_buffer += samples;
    p_block->i_buffer -= samples;

    return p_out;
}
예제 #13
0
파일: araw.c 프로젝트: chouquette/vlc
/****************************************************************************
 * DecodeBlock: the whole thing
 ****************************************************************************
 * This function must be fed with whole samples (see nBlockAlign).
 ****************************************************************************/
static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    if( p_block == NULL ) /* No Drain */
        return VLCDEC_SUCCESS;

    if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED|BLOCK_FLAG_DISCONTINUITY) )
    {
        Flush( p_dec );
        if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
            goto skip;
    }

    if( p_block->i_pts > VLC_TS_INVALID &&
        p_block->i_pts != date_Get( &p_sys->end_date ) )
    {
        date_Set( &p_sys->end_date, p_block->i_pts );
    }
    else if( !date_Get( &p_sys->end_date ) )
        /* We've just started the stream, wait for the first PTS. */
        goto skip;

    unsigned samples = (8 * p_block->i_buffer) / p_sys->framebits;
    if( samples == 0 )
        goto skip;

    if( p_sys->decode != NULL )
    {
        if( decoder_UpdateAudioFormat( p_dec ) )
            goto skip;
        block_t *p_out = decoder_NewAudioBuffer( p_dec, samples );
        if( p_out == NULL )
            goto skip;

        p_sys->decode( p_out->p_buffer, p_block->p_buffer,
                       samples * p_dec->fmt_in.audio.i_channels );
        block_Release( p_block );
        p_block = p_out;
    }
    else
    {
        decoder_UpdateAudioFormat( p_dec );
        p_block->i_nb_samples = samples;
        p_block->i_buffer = samples * (p_sys->framebits / 8);
    }

    p_block->i_pts = date_Get( &p_sys->end_date );
    p_block->i_length = date_Increment( &p_sys->end_date, samples )
                      - p_block->i_pts;
    decoder_QueueAudio( p_dec, p_block );
    return VLCDEC_SUCCESS;
skip:
    block_Release( p_block );
    return VLCDEC_SUCCESS;
}
예제 #14
0
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;

    while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
                                                          &in )) )
    {
        sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_AUDIO, 1 );
        if( p_sys->b_master_sync )
        {
            mtime_t i_dts = date_Get( &id->interpolated_pts ) + 1;
            if ( p_audio_buf->i_pts - i_dts > MASTER_SYNC_MAX_DRIFT
                  || p_audio_buf->i_pts - 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->i_pts );
                i_dts = p_audio_buf->i_pts + 1;
            }
            p_sys->i_master_drift = p_audio_buf->i_pts - i_dts;
            date_Increment( &id->interpolated_pts, p_audio_buf->i_nb_samples );
            p_audio_buf->i_pts -= p_sys->i_master_drift;
        }

        p_audio_buf->i_dts = p_audio_buf->i_pts;

        /* Run filter chain */
        if( id->p_uf_chain )
        {
            p_audio_buf = filter_chain_AudioFilter( id->p_uf_chain,
                                                    p_audio_buf );
            if( !p_audio_buf )
                abort();
        }

        p_audio_buf = filter_chain_AudioFilter( id->p_f_chain, p_audio_buf );
        if( !p_audio_buf )
            abort();

        p_audio_buf->i_dts = p_audio_buf->i_pts;

        audio_timer_start( id->p_encoder );
        p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
        audio_timer_stop( id->p_encoder );

        block_ChainAppend( out, p_block );
        block_Release( p_audio_buf );
    }

    return VLC_SUCCESS;
}
예제 #15
0
/*****************************************************************************
 * Fill buffer
 *****************************************************************************/
static int FillBuffer( int16_t *p_data, int *pi_data,
                       date_t *pi_date, date_t *pi_date_end,
                       goom_thread_t *p_this )
{
    int i_samples = 0;
    block_t *p_block;

    while( *pi_data < 512 )
    {
        if( !p_this->i_blocks ) return VLC_EGENERIC;

        p_block = p_this->pp_blocks[0];
        i_samples = __MIN( (unsigned)(512 - *pi_data),
                p_block->i_buffer / sizeof(float) / p_this->i_channels );

        /* Date management */
        if( p_block->i_pts > VLC_TS_INVALID &&
            p_block->i_pts != date_Get( pi_date_end ) )
        {
           date_Set( pi_date_end, p_block->i_pts );
        }
        p_block->i_pts = VLC_TS_INVALID;

        date_Increment( pi_date_end, i_samples );

        while( i_samples > 0 )
        {
            float *p_float = (float *)p_block->p_buffer;

            p_data[*pi_data] = FloatToInt16( p_float[0] );
            if( p_this->i_channels > 1 )
                p_data[512 + *pi_data] = FloatToInt16( p_float[1] );

            (*pi_data)++;
            p_block->p_buffer += (sizeof(float) * p_this->i_channels);
            p_block->i_buffer -= (sizeof(float) * p_this->i_channels);
            i_samples--;
        }

        if( !p_block->i_buffer )
        {
            block_Release( p_block );
            p_this->i_blocks--;
            if( p_this->i_blocks )
                memmove( p_this->pp_blocks, p_this->pp_blocks + 1,
                         p_this->i_blocks * sizeof(block_t *) );
        }
    }

    *pi_date = *pi_date_end;
    *pi_data = 0;
    return VLC_SUCCESS;
}
예제 #16
0
파일: smf.c 프로젝트: CSRedRat/vlc
/*****************************************************************************
 * Demux: read chunks and send them to the synthesizer
 *****************************************************************************
 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
 *****************************************************************************/
static int Demux (demux_t *p_demux)
{
    stream_t *s = p_demux->s;
    demux_sys_t *p_sys = p_demux->p_sys;
    uint64_t     pulse = p_sys->pulse, next_pulse = UINT64_MAX;

    if (pulse == UINT64_MAX)
        return 0; /* all tracks are done */

    es_out_Control (p_demux->out, ES_OUT_SET_PCR, VLC_TS_0 + date_Get (&p_sys->pts));

    for (unsigned i = 0; i < p_sys->trackc; i++)
    {
        mtrk_t *track = p_sys->trackv + i;

        while (track->next == pulse)
        {
            if (HandleMessage (p_demux, track)
             || ReadDeltaTime (s, track))
            {
                msg_Err (p_demux, "fatal parsing error");
                return VLC_EGENERIC;
            }
        }

        if (track->next < next_pulse)
            next_pulse = track->next;
    }

    mtime_t cur_tick = (date_Get (&p_sys->pts) + 9999) / 10000, last_tick;
    if (next_pulse != UINT64_MAX)
        last_tick = date_Increment (&p_sys->pts, next_pulse - pulse) / 10000;
    else
        last_tick = cur_tick + 1;

    /* MIDI Tick emulation (ping the decoder every 10ms) */
    while (cur_tick < last_tick)
    {
        block_t *tick = block_New (p_demux, 1);
        if (tick == NULL)
            break;

        tick->p_buffer[0] = 0xF9;
        tick->i_dts = tick->i_pts = VLC_TS_0 + cur_tick++ * 10000;
        es_out_Send (p_demux->out, p_sys->es, tick);
    }

    p_sys->pulse = next_pulse;

    return 1;
}
예제 #17
0
/*****************************************************************************
 * SendPacket: send an ogg packet to the stream output.
 *****************************************************************************/
static block_t *SendPacket( decoder_t *p_dec, block_t *p_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    /* Date management */
    p_block->i_dts = p_block->i_pts = date_Get( &p_sys->end_date );

    p_block->i_length =
        date_Increment( &p_sys->end_date,
                            p_sys->p_header->frame_size ) -
        p_block->i_pts;

    return p_block;
}
예제 #18
0
파일: a52.c 프로젝트: RicoP/vlcfork
/*****************************************************************************
 * GetSoutBuffer:
 *****************************************************************************/
static block_t *GetSoutBuffer( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    block_t *p_block = block_New( p_dec, p_sys->frame.i_size );
    if( p_block )
    {
        p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date );
        p_block->i_length =
            date_Increment( &p_sys->end_date, p_sys->frame.i_samples ) - p_block->i_pts;
    }

    return p_block;
}
예제 #19
0
파일: araw.c 프로젝트: AsamQi/vlc
/****************************************************************************
 * DecodeBlock: the whole thing
 ****************************************************************************
 * This function must be fed with whole samples (see nBlockAlign).
 ****************************************************************************/
static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    if( pp_block == NULL )
        return NULL;

    block_t *p_block = *pp_block;
    if( p_block == NULL )
        return NULL;
    *pp_block = NULL;

    if( p_block->i_pts > VLC_TS_INVALID &&
        p_block->i_pts != date_Get( &p_sys->end_date ) )
    {
        date_Set( &p_sys->end_date, p_block->i_pts );
    }
    else if( !date_Get( &p_sys->end_date ) )
        /* We've just started the stream, wait for the first PTS. */
        goto skip;

    unsigned samples = (8 * p_block->i_buffer) / p_sys->framebits;
    if( samples == 0 )
        goto skip;

    if( p_sys->decode != NULL )
    {
        block_t *p_out = decoder_NewAudioBuffer( p_dec, samples );
        if( p_out == NULL )
            goto skip;

        p_sys->decode( p_out->p_buffer, p_block->p_buffer,
                       samples * p_dec->fmt_in.audio.i_channels );
        block_Release( p_block );
        p_block = p_out;
    }
    else
    {
        decoder_UpdateAudioFormat( p_dec );
        p_block->i_nb_samples = samples;
        p_block->i_buffer = samples * (p_sys->framebits / 8);
    }

    p_block->i_pts = date_Get( &p_sys->end_date );
    p_block->i_length = date_Increment( &p_sys->end_date, samples )
                      - p_block->i_pts;
    return p_block;
skip:
    block_Release( p_block );
    return NULL;
}
예제 #20
0
파일: a52.c 프로젝트: RicoP/vlcfork
/*****************************************************************************
 * GetAoutBuffer:
 *****************************************************************************/
static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    aout_buffer_t *p_buf = decoder_NewAudioBuffer( p_dec, p_sys->frame.i_samples );
    if( p_buf )
    {
        p_buf->i_pts = date_Get( &p_sys->end_date );
        p_buf->i_length = date_Increment( &p_sys->end_date,
                                          p_sys->frame.i_samples ) - p_buf->i_pts;
    }

    return p_buf;
}
예제 #21
0
파일: dts.c 프로젝트: 9034725985/vlc
/*****************************************************************************
 * GetSoutBuffer:
 *****************************************************************************/
static block_t *GetSoutBuffer( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_block;

    p_block = block_Alloc( p_sys->i_frame_size );
    if( p_block == NULL ) return NULL;

    p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date );

    p_block->i_length = date_Increment( &p_sys->end_date,
        p_sys->i_frame_length ) - p_block->i_pts;

    return p_block;
}
예제 #22
0
파일: dec.c 프로젝트: Jobq/vlc-mdc
/*****************************************************************************
 * aout_DecPlay : filter & mix the decoded buffer
 *****************************************************************************/
int aout_DecPlay (audio_output_t *p_aout, block_t *p_buffer, int i_input_rate)
{
    aout_owner_t *owner = aout_owner (p_aout);
    aout_input_t *input;

    assert( i_input_rate >= INPUT_RATE_DEFAULT / AOUT_MAX_INPUT_RATE &&
            i_input_rate <= INPUT_RATE_DEFAULT * AOUT_MAX_INPUT_RATE );
    assert( p_buffer->i_pts > 0 );

    p_buffer->i_length = (mtime_t)p_buffer->i_nb_samples * 1000000
                                / owner->input_format.i_rate;

    aout_lock( p_aout );
    aout_CheckRestart( p_aout );

    input = owner->input;
    if (unlikely(input == NULL)) /* can happen due to restart */
    {
        aout_unlock( p_aout );
        aout_BufferFree( p_buffer );
        return -1;
    }

    /* Input */
    p_buffer = aout_InputPlay (p_aout, input, p_buffer, i_input_rate,
                               &owner->sync.date);
    if( p_buffer != NULL )
    {
        date_Increment (&owner->sync.date, p_buffer->i_nb_samples);

        /* Mixer */
        if (owner->volume.mixer != NULL)
        {
            float amp = owner->volume.multiplier
                      * vlc_atomic_getf (&owner->gain.multiplier);
            aout_MixerRun (owner->volume.mixer, p_buffer, amp);
        }

        /* Output */
        aout_OutputPlay( p_aout, p_buffer );
    }

    aout_unlock( p_aout );
#ifdef __unix__
    sched_yield();
#endif
    return 0;
}
예제 #23
0
파일: vorbis.c 프로젝트: IAPark/vlc
/*****************************************************************************
 * DecodePacket: decodes a Vorbis packet.
 *****************************************************************************/
static block_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    int           i_samples;

    INTERLEAVE_TYPE **pp_pcm;

    if( p_oggpacket->bytes &&
        vorbis_synthesis( &p_sys->vb, p_oggpacket ) == 0 )
        vorbis_synthesis_blockin( &p_sys->vd, &p_sys->vb );

    /* **pp_pcm is a multichannel float vector. In stereo, for
     * example, pp_pcm[0] is left, and pp_pcm[1] is right. i_samples is
     * the size of each channel. Convert the float values
     * (-1.<=range<=1.) to whatever PCM format and write it out */

    if( ( i_samples = vorbis_synthesis_pcmout( &p_sys->vd, &pp_pcm ) ) > 0 )
    {

        block_t *p_aout_buffer;

        if( decoder_UpdateAudioFormat( p_dec ) ) return NULL;
        p_aout_buffer =
            decoder_NewAudioBuffer( p_dec, i_samples );

        if( p_aout_buffer == NULL ) return NULL;

        /* Interleave the samples */
        Interleave( (INTERLEAVE_TYPE*)p_aout_buffer->p_buffer,
                    (const INTERLEAVE_TYPE**)pp_pcm, p_sys->vi.channels, i_samples,
                    p_sys->pi_chan_table);

        /* Tell libvorbis how many samples we actually consumed */
        vorbis_synthesis_read( &p_sys->vd, i_samples );

        /* Date management */
        p_aout_buffer->i_pts = date_Get( &p_sys->end_date );
        p_aout_buffer->i_length = date_Increment( &p_sys->end_date,
                                           i_samples ) - p_aout_buffer->i_pts;
        return p_aout_buffer;
    }
    else
    {
        return NULL;
    }
}
예제 #24
0
파일: rawaud.c 프로젝트: mstorsjo/vlc
/*****************************************************************************
 * Demux: reads and demuxes data packets
 *****************************************************************************
 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
 *****************************************************************************/
static int Demux( demux_t *p_demux )
{
    demux_sys_t *p_sys  = p_demux->p_sys;
    block_t     *p_block;

    p_block = vlc_stream_Block( p_demux->s, p_sys->i_frame_size );
    if( p_block == NULL )
        return VLC_DEMUXER_EOF;

    p_block->i_dts = p_block->i_pts = date_Get( &p_sys->pts );

    es_out_SetPCR( p_demux->out, p_block->i_pts );
    es_out_Send( p_demux->out, p_sys->p_es, p_block );

    date_Increment( &p_sys->pts, p_sys->i_frame_samples );

    return VLC_DEMUXER_SUCCESS;
}
예제 #25
0
파일: vorbis.c 프로젝트: J861449197/vlc
/*****************************************************************************
 * SendPacket: send an ogg dated packet to the stream output.
 *****************************************************************************/
static block_t *SendPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
                            block_t *p_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    int i_block_size, i_samples;

    i_block_size = vorbis_packet_blocksize( &p_sys->vi, p_oggpacket );
    if( i_block_size < 0 ) i_block_size = 0; /* non audio packet */
    i_samples = ( p_sys->i_last_block_size + i_block_size ) >> 2;
    p_sys->i_last_block_size = i_block_size;

    /* Date management */
    p_block->i_dts = p_block->i_pts = date_Get( &p_sys->end_date );

    p_block->i_length = date_Increment( &p_sys->end_date, i_samples ) - p_block->i_pts;

    return p_block;
}
예제 #26
0
/*****************************************************************************
 * aout_FifoPush : push a packet into the FIFO
 *****************************************************************************/
void aout_FifoPush( aout_fifo_t * p_fifo, aout_buffer_t * p_buffer )
{
    *p_fifo->pp_last = p_buffer;
    p_fifo->pp_last = &p_buffer->p_next;
    *p_fifo->pp_last = NULL;
    /* Enforce the continuity of the stream. */
    if ( date_Get( &p_fifo->end_date ) )
    {
        p_buffer->i_pts = date_Get( &p_fifo->end_date );
        p_buffer->i_length = date_Increment( &p_fifo->end_date,
                                             p_buffer->i_nb_samples );
        p_buffer->i_length -= p_buffer->i_pts;
    }
    else
    {
        date_Set( &p_fifo->end_date, p_buffer->i_pts + p_buffer->i_length );
    }
}
예제 #27
0
파일: image.c 프로젝트: jomanmuk/vlc-2.2
static int Demux(demux_t *demux)
{
    demux_sys_t *sys = demux->p_sys;

    if (!sys->data)
        return 0;

    mtime_t deadline;
    const mtime_t pts_first = sys->pts_origin + date_Get(&sys->pts);
    if (sys->pts_next > VLC_TS_INVALID) {
        deadline = sys->pts_next;
    } else if (sys->is_realtime) {
        deadline = mdate();
        const mtime_t max_wait = CLOCK_FREQ / 50;
        if (deadline + max_wait < pts_first) {
            es_out_Control(demux->out, ES_OUT_SET_PCR, deadline);
            /* That's ugly, but not yet easily fixable */
            mwait(deadline + max_wait);
            return 1;
        }
    } else {
        deadline = 1 + pts_first;
    }

    for (;;) {
        const mtime_t pts = sys->pts_origin + date_Get(&sys->pts);
        if (sys->duration >= 0 && pts >= sys->pts_origin + sys->duration)
            return 0;

        if (pts >= deadline)
            return 1;

        block_t *data = block_Duplicate(sys->data);
        if (!data)
            return -1;

        data->i_dts =
        data->i_pts = VLC_TS_0 + pts;
        es_out_Control(demux->out, ES_OUT_SET_PCR, data->i_pts);
        es_out_Send(demux->out, sys->es, data);

        date_Increment(&sys->pts, 1);
    }
}
예제 #28
0
파일: rawvideo.c 프로젝트: chouquette/vlc
/*****************************************************************************
 * DecodeFrame: decodes a video frame.
 *****************************************************************************/
static int DecodeFrame( decoder_t *p_dec, block_t *p_block )
{
    if( p_block == NULL ) /* No Drain */
        return VLCDEC_SUCCESS;

    p_block = DecodeBlock( p_dec, p_block );
    if( p_block == NULL )
        return VLCDEC_SUCCESS;

    decoder_sys_t *p_sys = p_dec->p_sys;

    /* Get a new picture */
    picture_t *p_pic = NULL;
    if( !decoder_UpdateVideoFormat( p_dec ) )
        p_pic = decoder_NewPicture( p_dec );
    if( p_pic == NULL )
    {
        block_Release( p_block );
        return VLCDEC_SUCCESS;
    }

    FillPicture( p_dec, p_block, p_pic );

    /* Date management: 1 frame per packet */
    p_pic->date = date_Get( &p_dec->p_sys->pts );
    date_Increment( &p_sys->pts, 1 );

    if( p_block->i_flags & BLOCK_FLAG_INTERLACED_MASK )
    {
        p_pic->b_progressive = false;
        p_pic->i_nb_fields = (p_block->i_flags & BLOCK_FLAG_SINGLE_FIELD) ? 1 : 2;
        if( p_block->i_flags & BLOCK_FLAG_TOP_FIELD_FIRST )
            p_pic->b_top_field_first = true;
        else
            p_pic->b_top_field_first = false;
    }
    else
        p_pic->b_progressive = true;

    block_Release( p_block );
    decoder_QueueVideo( p_dec, p_pic );
    return VLCDEC_SUCCESS;
}
예제 #29
0
파일: dts.c 프로젝트: 9034725985/vlc
/*****************************************************************************
 * GetAoutBuffer:
 *****************************************************************************/
static block_t *GetAoutBuffer( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_buf;

    /* Hack for DTS S/PDIF filter which needs to send 3 frames at a time
     * (plus a few header bytes) */
    p_buf = decoder_NewAudioBuffer( p_dec, p_sys->i_frame_length * 4 );
    if( p_buf == NULL ) return NULL;

    p_buf->i_nb_samples = p_sys->i_frame_length;
    p_buf->i_buffer = p_sys->i_frame_size;

    p_buf->i_pts = date_Get( &p_sys->end_date );
    p_buf->i_length = date_Increment( &p_sys->end_date, p_sys->i_frame_length )
                      - p_buf->i_pts;

    return p_buf;
}
예제 #30
0
파일: cdg.c 프로젝트: FLYKingdom/vlc
/*****************************************************************************
 * Demux: read packet and send them to decoders
 *****************************************************************************
 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
 *****************************************************************************/
static int Demux( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    block_t     *p_block;

    p_block = stream_Block( p_demux->s, CDG_FRAME_SIZE );
    if( p_block == NULL )
    {
        msg_Dbg( p_demux, "cannot read data, eof" );
        return 0;
    }

    p_block->i_dts =
    p_block->i_pts = date_Increment( &p_sys->pts, 1 );

    es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );

    es_out_Send( p_demux->out, p_sys->p_es, p_block );
    return 1;
}