[vlc-devel] [vlc-commits] commit: Added C64 sid demux module (Alan Fischer )

Laurent Aimar fenrir at elivagar.org
Sat Dec 11 10:32:49 CET 2010


Hi,

On Sat, Dec 11, 2010 at 02:13:41AM +0100, git at videolan.org wrote:
> +static int Open (vlc_object_t *obj)
> +{
> +    demux_t *demux = (demux_t *)obj;
> +    demux_sys_t *sys = NULL;
> +    es_format_t fmt;
> +    bool result = false;
 Useless initialization.
> +    SidTune *tune = NULL;
> +    sidplay2 *player = NULL;
> +    ReSIDBuilder *builder = NULL;
> +
> +    int64_t size = stream_Size (demux->s);
> +    if (size < 4 || size > LONG_MAX) /* We need to load the whole file for sidplay */
> +        return VLC_EGENERIC;
 Why LONG_MAX? Shouldn't it be SIZE_MAX to avoid overflow in malloc?
(Anyway, both LONG_MAX/SIZE_MAX seem a bit large for valid files).

> +    const uint8_t *peek;
> +    if (stream_Peek (demux->s, &peek, 4) < 4)
> +        return VLC_EGENERIC;
> +
> +    /* sidplay2 can read PSID and the newer RSID formats */
> +    if(memcmp(peek,"PSID",4)!=0 && memcmp(peek,"RSID",4)!=0)
> +        return VLC_EGENERIC;
> +
> +    uint8_t *data = (uint8_t*) malloc(size);
> +    if (unlikely (data==NULL))
> +        goto error;
> +
> +    if (stream_Read (demux->s,data,size) < size) {
> +        free (data);
> +        goto error;
> +    }
> +
> +    tune = new SidTune(0);
> +    if (unlikely (tune==NULL)) {
> +        free (data);
> +        goto error;
> +    }
> +
> +    result = tune->read (data, size);
> +    free (data);
> +    if (result==false)
> +        goto error;
> +
> +    player = new sidplay2();
> +    if (unlikely(player==NULL))
> +        goto error;
> +
> +    sys = (demux_sys_t*) calloc (1, sizeof(demux_sys_t));
> +    if (unlikely(sys==NULL))
> +        goto error;
> +
> +    sys->player = player;
> +    sys->tune = tune;
> +
> +    tune->getInfo (sys->tuneInfo);
> +
> +    sys->info = player->info();
> +    sys->config = player->config();
> +
> +    builder = new ReSIDBuilder ("ReSID");
> +    if (unlikely(builder==NULL))
> +        goto error;
> +
> +    builder->create (sys->info.maxsids);
> +    builder->sampling (sys->config.frequency);
> +
> +    sys->config.sidEmulation = builder;
> +    sys->config.precision    = 16;
> +    sys->config.playback     = (sys->info.channels == 2 ? sid2_stereo : sid2_mono);
> +
> +    player->config (sys->config);
> +
> +    sys->bytes_per_frame = sys->info.channels * sys->config.precision / 8;
> +    sys->block_size = sys->config.frequency / 10 * sys->bytes_per_frame;
> +
> +    es_format_Init (&fmt, AUDIO_ES, VLC_CODEC_S16N);
> +
> +    fmt.audio.i_channels        = sys->info.channels;
> +    fmt.audio.i_bitspersample   = sys->config.precision;
> +    fmt.audio.i_rate            = sys->config.frequency;
> +    fmt.audio.i_bytes_per_frame = sys->bytes_per_frame;
> +    fmt.audio.i_frame_length    = fmt.audio.i_bytes_per_frame;
> +    fmt.audio.i_blockalign      = fmt.audio.i_bytes_per_frame;
> +
> +    fmt.i_bitrate = fmt.audio.i_rate * fmt.audio.i_bytes_per_frame;
> +
> +    sys->es = es_out_Add (demux->out, &fmt);
> +
> +    date_Init (&sys->pts, fmt.audio.i_rate, 1);
> +    date_Set (&sys->pts, 0);
> +
> +    sys->tune->selectSong (0);
> +    result = (sys->player->load (sys->tune) >=0 );
> +    sys->player->fastForward (100);
> +    if (result==false)
> +        goto error;
> +
> +    /* Callbacks */
> +    demux->pf_demux = Demux;
> +    demux->pf_control = Control;
> +    demux->p_sys = sys;
> +
> +    return VLC_SUCCESS;
> +
> +error:
> +    msg_Err (demux, "An error occured during sid demuxing" );
> +    delete player;
> +    delete builder;
> +    delete tune;
> +    free (sys);
> +    return VLC_EGENERIC;
> +}
> +
> +
> +static void Close (vlc_object_t *obj)
> +{
> +    demux_t *demux = (demux_t *)obj;
> +    demux_sys_t *sys = demux->p_sys;
> +
> +    delete sys->player;
> +    delete sys->config.sidEmulation;
> +    delete sys->tune;
> +    free (sys);
> +}
> +
> +static int Demux (demux_t *demux)
> +{
> +    demux_sys_t *sys = demux->p_sys;
> +
> +    block_t *block = block_New( p_demux, sys->block_size);
> +    if (unlikely(block==NULL))
> +        return 0;
> +
> +    if (sys->tune->getStatus() == false) {
> +        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;
> +}
> +
> +
> +static int Control (demux_t *demux, int query, va_list args)
> +{
> +    demux_sys_t *sys = demux->p_sys;
> +
> +    switch (query)
> +    {
> +        case DEMUX_GET_TIME : {
> +            int64_t *v = va_arg (args, int64_t*);
> +            *v = sys->player->time() * sys->player->timebase() * (CLOCK_FREQ / 100);
> +            return VLC_SUCCESS;
> +        }
> +
> +        case DEMUX_GET_META : {
> +            vlc_meta_t *p_meta = (vlc_meta_t *) va_arg (args, vlc_meta_t*);
> +
> +            /* These are specified in the sid tune class as 0 = Title, 1 = Artist, 2 = Copyright/Publisher */
> +            vlc_meta_SetTitle( p_meta, sys->tuneInfo.infoString[0] );
> +            vlc_meta_SetArtist( p_meta, sys->tuneInfo.infoString[1] );
> +            vlc_meta_SetCopyright( p_meta, sys->tuneInfo.infoString[2] );
> +
> +            return VLC_SUCCESS;
> +        }
> +
> +        case DEMUX_GET_TITLE_INFO :
> +            if ( sys->tuneInfo.songs > 1 ) {
> +                input_title_t ***ppp_title = (input_title_t***) va_arg (args, input_title_t***);
> +                int *pi_int    = (int*)va_arg( args, int* );
> +
> +                *pi_int = sys->tuneInfo.songs;
> +                *ppp_title = (input_title_t**) malloc( sizeof (input_title_t**) * sys->tuneInfo.songs);
> +
> +                for( int i = 0; i < sys->tuneInfo.songs; i++ ) {
> +                    (*ppp_title)[i] = vlc_input_title_New();
> +                }
> +
> +                return VLC_SUCCESS;
> +            }
> +            return VLC_EGENERIC;
> +
> +        case DEMUX_SET_TITLE : {
> +            int i_idx = (int) va_arg (args, int);
> +            sys->tune->selectSong (i_idx+1);
> +            bool result = (sys->player->load (sys->tune) >=0 );
> +            if (result == false)
> +                return  VLC_EGENERIC;
> +
> +            demux->info.i_title = i_idx;
> +            demux->info.i_update = INPUT_UPDATE_TITLE;
> +            msg_Dbg( demux, "set song %i", i_idx);
> +
> +            return VLC_SUCCESS;
> +        }
> +    }
 Not supporting GET_POSITION and GET_LENGTH will make this demuxer badly behaves
from a user point of view.

> +
> +    return VLC_EGENERIC;
> +}

-- 
fenrir




More information about the vlc-devel mailing list