Ejemplo n.º 1
0
/**
 * Common initialization for decoder and packetizer
 */
static int OpenCommon( decoder_t *p_dec, bool b_packetizer )
{
    const vlc_chroma_description_t *dsc =
        vlc_fourcc_GetChromaDescription( p_dec->fmt_in.i_codec );
    if( dsc == NULL || dsc->plane_count == 0 )
        return VLC_EGENERIC;

    if( p_dec->fmt_in.video.i_width <= 0 || p_dec->fmt_in.video.i_height == 0 )
    {
        msg_Err( p_dec, "invalid display size %dx%d",
                 p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height );
        return VLC_EGENERIC;
    }

    /* Allocate the memory needed to store the decoder's structure */
    decoder_sys_t *p_sys = calloc(1, sizeof(*p_sys));
    if( unlikely(p_sys == NULL) )
        return VLC_ENOMEM;

    if( !p_dec->fmt_in.video.i_visible_width )
        p_dec->fmt_in.video.i_visible_width = p_dec->fmt_in.video.i_width;
    if( !p_dec->fmt_in.video.i_visible_height )
        p_dec->fmt_in.video.i_visible_height = p_dec->fmt_in.video.i_height;

    if ( !b_packetizer )
        es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );

    date_Init( &p_sys->pts, p_dec->fmt_out.video.i_frame_rate,
               p_dec->fmt_out.video.i_frame_rate_base );
    if( p_dec->fmt_out.video.i_frame_rate == 0 ||
        p_dec->fmt_out.video.i_frame_rate_base == 0)
    {
        msg_Warn( p_dec, "invalid frame rate %d/%d, using 25 fps instead",
                  p_dec->fmt_out.video.i_frame_rate,
                  p_dec->fmt_out.video.i_frame_rate_base);
        date_Init( &p_sys->pts, 25, 1 );
    }

    for( unsigned i = 0; i < dsc->plane_count; i++ )
    {
        unsigned pitch = p_dec->fmt_in.video.i_width * dsc->pixel_size
                         * dsc->p[i].w.num / dsc->p[i].w.den;
        unsigned lines = p_dec->fmt_in.video.i_height
                         * dsc->p[i].h.num / dsc->p[i].h.den;

        p_sys->pitches[i] = pitch;
        p_sys->lines[i] = lines;
        p_sys->size += pitch * lines;
    }

    p_dec->p_sys           = p_sys;
    return VLC_SUCCESS;
}
Ejemplo n.º 2
0
/*****************************************************************************
 * InitAudioDec: initialize audio decoder
 *****************************************************************************
 * The avcodec codec will be opened, some memory allocated.
 *****************************************************************************/
int InitAudioDec( decoder_t *p_dec, AVCodecContext *p_context,
                      AVCodec *p_codec, int i_codec_id, const char *psz_namecodec )
{
    decoder_sys_t *p_sys;

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
    {
        return VLC_ENOMEM;
    }

    p_codec->type = AVMEDIA_TYPE_AUDIO;
    p_context->codec_type = AVMEDIA_TYPE_AUDIO;
    p_context->codec_id = i_codec_id;
    p_context->get_buffer = GetAudioBuf;
    p_sys->p_context = p_context;
    p_sys->p_codec = p_codec;
    p_sys->i_codec_id = i_codec_id;
    p_sys->psz_namecodec = psz_namecodec;
    p_sys->b_delayed_open = true;

    // Initialize decoder extradata
    InitDecoderConfig( p_dec, p_context);

    /* ***** Open the codec ***** */
    if( ffmpeg_OpenCodec( p_dec ) < 0 )
    {
        msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
        free( p_sys->p_context->extradata );
        free( p_sys );
        return VLC_EGENERIC;
    }

    p_sys->i_reject_count = 0;
    p_sys->b_extract = false;
    p_sys->i_previous_channels = 0;
    p_sys->i_previous_layout = 0;

    /* */
    p_dec->fmt_out.i_cat = AUDIO_ES;
    /* Try to set as much information as possible but do not trust it */
    SetupOutputFormat( p_dec, false );

    date_Set( &p_sys->end_date, 0 );
    if( p_dec->fmt_out.audio.i_rate )
        date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
    else if( p_dec->fmt_in.audio.i_rate )
        date_Init( &p_sys->end_date, p_dec->fmt_in.audio.i_rate, 1 );

    return VLC_SUCCESS;
}
Ejemplo n.º 3
0
static int SeekSet0 (demux_t *demux)
{
    stream_t *stream = demux->s;
    demux_sys_t *sys = demux->p_sys;

    /* Default SMF tempo is 120BPM, i.e. half a second per quarter note */
    date_Init (&sys->pts, sys->ppqn * 2, 1);
    date_Set (&sys->pts, VLC_TS_0);
    sys->pulse = 0;
    sys->tick = VLC_TS_0;

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

        tr->offset = 0;
        tr->next = 0;
        /* Why 0xF6 (Tuning Calibration)?
         * Because it has zero bytes of data, so the parser will detect the
         * error if the first event uses running status. */
        tr->running_event = 0xF6;

        if (stream_Seek (stream, tr->start)
         || ReadDeltaTime (stream, tr))
        {
            msg_Err (demux, "fatal parsing error");
            return -1;
        }
    }

    return 0;
}
Ejemplo n.º 4
0
Archivo: cdg.c Proyecto: FLYKingdom/vlc
/*****************************************************************************
 * Open: check file and initializes structures
 *****************************************************************************/
static int Open( vlc_object_t * p_this )
{
    demux_t     *p_demux = (demux_t*)p_this;
    demux_sys_t *p_sys;

    /* Identify cdg file by extension, as there is no simple way to
     * detect it */
    if( !demux_IsPathExtension( p_demux, ".cdg" ) && !demux_IsForced( p_demux, "cdg" ) )
        return VLC_EGENERIC;

    /* CDG file size has to be multiple of CDG_FRAME_SIZE (it works even
     * if size is unknown ie 0) */
//    if( (stream_Size( p_demux->s ) % CDG_FRAME_SIZE) != 0 )
//    {
//        msg_Err( p_demux, "Reject CDG file based on its size" );
//        return VLC_EGENERIC;
//    }

    p_demux->pf_demux   = Demux;
    p_demux->pf_control = Control;
    p_demux->p_sys      = p_sys = malloc( sizeof( demux_sys_t ) );

    /* */
    es_format_Init( &p_sys->fmt, VIDEO_ES, VLC_CODEC_CDG );
    p_sys->fmt.video.i_width  = 300-2*6;
    p_sys->fmt.video.i_height = 216-2*12 ;

    p_sys->p_es = es_out_Add( p_demux->out, &p_sys->fmt );

    /* There is CDG_FRAME_RATE frames per second */
    date_Init( &p_sys->pts, CDG_FRAME_RATE, 1 );
    date_Set( &p_sys->pts, 1 );

    return VLC_SUCCESS;
}
Ejemplo n.º 5
0
static int Open (vlc_object_t *obj)
{
    demux_t *demux = (demux_t *)obj;
    demux_sys_t *sys = vlc_malloc(obj, sizeof (*sys));

    if (unlikely(sys == NULL))
        return VLC_ENOMEM;

    es_format_t fmt;
    es_format_Init (&fmt, SPU_ES, VLC_CODEC_ITU_T140);
    sys->es = es_out_Add (demux->out, &fmt);

    unsigned num, den;
    if (var_InheritURational (demux, &num, &den, "timecode-fps")
     || !num || !den)
    {
        msg_Err (demux, "invalid frame rate");
        return VLC_EGENERIC;
    }

    date_Init (&sys->date, num, den);
    date_Set (&sys->date, VLC_TS_0);
    sys->next_time = VLC_TS_INVALID;

    demux->p_sys = sys;
    demux->pf_demux   = Demux;
    demux->pf_control = Control;
    return VLC_SUCCESS;
}
Ejemplo n.º 6
0
/**
 * Initializes the members of a FIFO.
 */
static void aout_FifoInit( aout_fifo_t *p_fifo, uint32_t i_rate )
{
    assert( i_rate != 0);
    p_fifo->p_first = NULL;
    p_fifo->pp_last = &p_fifo->p_first;
    date_Init( &p_fifo->end_date, i_rate, 1 );
    date_Set( &p_fifo->end_date, VLC_TS_INVALID );
}
Ejemplo n.º 7
0
/*****************************************************************************
 * InitAudioDec: initialize audio decoder
 *****************************************************************************
 * The avcodec codec will be opened, some memory allocated.
 *****************************************************************************/
int InitAudioDec( decoder_t *p_dec, AVCodecContext *p_context,
                  const AVCodec *p_codec )
{
    decoder_sys_t *p_sys;

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
    {
        return VLC_ENOMEM;
    }

    p_context->refcounted_frames = true;
    p_sys->p_context = p_context;
    p_sys->p_codec = p_codec;
    p_sys->b_delayed_open = true;

    // Initialize decoder extradata
    InitDecoderConfig( p_dec, p_context);

    /* ***** Open the codec ***** */
    if( OpenAudioCodec( p_dec ) < 0 )
    {
        free( p_sys );
        return VLC_EGENERIC;
    }

    p_sys->i_reject_count = 0;
    p_sys->b_extract = false;
    p_sys->i_previous_channels = 0;
    p_sys->i_previous_layout = 0;

    /* */
    p_dec->fmt_out.i_cat = AUDIO_ES;
    /* Try to set as much information as possible but do not trust it */
    SetupOutputFormat( p_dec, false );

    date_Set( &p_sys->end_date, VLC_TS_INVALID );
    if( p_dec->fmt_out.audio.i_rate )
        date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
    else if( p_dec->fmt_in.audio.i_rate )
        date_Init( &p_sys->end_date, p_dec->fmt_in.audio.i_rate, 1 );

    p_dec->pf_decode_audio = DecodeAudio;
    p_dec->pf_flush        = Flush;
    return VLC_SUCCESS;
}
Ejemplo n.º 8
0
static int Open (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_MIDI)
        return VLC_EGENERIC;

    char *font_path = var_CreateGetNonEmptyString (p_this, "soundfont");
    if (font_path == NULL)
    {
        msg_Err (p_this, "sound fonts file required for synthesis");
        return VLC_EGENERIC;
    }

    p_dec->pf_decode_audio = DecodeBlock;
    p_sys = p_dec->p_sys = malloc (sizeof (*p_sys));
    if (p_sys == NULL)
    {
        free (font_path);
        return VLC_ENOMEM;
    }

    p_sys->settings = new_fluid_settings ();
    p_sys->synth = new_fluid_synth (p_sys->settings);
    /* FIXME: I bet this is not thread-safe */
    p_sys->soundfont = fluid_synth_sfload (p_sys->synth, font_path, 1);
    free (font_path);
    if (p_sys->soundfont == -1)
    {
        msg_Err (p_this, "cannot load sound fonts file");
        Close (p_this);
        return VLC_EGENERIC;
    }

    p_dec->fmt_out.i_cat = AUDIO_ES;
    p_dec->fmt_out.audio.i_rate = 44100;
    p_dec->fmt_out.audio.i_channels = 2;
    p_dec->fmt_out.audio.i_original_channels =
    p_dec->fmt_out.audio.i_physical_channels =
        AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
    if (HAVE_FPU)
    {
        p_dec->fmt_out.i_codec = VLC_CODEC_FL32;
        p_dec->fmt_out.audio.i_bitspersample = 32;
        p_sys->fixed = false;
    }
    else
    {
        p_dec->fmt_out.i_codec = VLC_CODEC_S16N;
        p_dec->fmt_out.audio.i_bitspersample = 16;
        p_sys->fixed = true;
    }
    date_Init (&p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1);
    date_Set (&p_sys->end_date, 0);

    return VLC_SUCCESS;
}
Ejemplo n.º 9
0
bool transcode_audio_add( sout_stream_t *p_stream, es_format_t *p_fmt, 
            sout_stream_id_t *id )
{
    sout_stream_sys_t *p_sys = p_stream->p_sys;

    msg_Dbg( p_stream,
             "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
             (char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec );

    /* Complete destination format */
    id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
    id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
        p_sys->i_sample_rate : p_fmt->audio.i_rate;
    id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;
    id->p_encoder->fmt_out.audio.i_bitspersample =
        p_fmt->audio.i_bitspersample;
    id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?
        p_sys->i_channels : p_fmt->audio.i_channels;
    /* Sanity check for audio channels */
    id->p_encoder->fmt_out.audio.i_channels =
        __MIN( id->p_encoder->fmt_out.audio.i_channels,
               id->p_decoder->fmt_in.audio.i_channels );
    id->p_encoder->fmt_out.audio.i_original_channels =
        id->p_decoder->fmt_in.audio.i_physical_channels;
    if( id->p_decoder->fmt_in.audio.i_channels ==
        id->p_encoder->fmt_out.audio.i_channels )
    {
        id->p_encoder->fmt_out.audio.i_physical_channels =
            id->p_decoder->fmt_in.audio.i_physical_channels;
    }
    else
    {
        id->p_encoder->fmt_out.audio.i_physical_channels =
            pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];
    }

    /* Build decoder -> filter -> encoder chain */
    if( transcode_audio_new( p_stream, id ) )
    {
        msg_Err( p_stream, "cannot create audio chain" );
        return false;
    }

    /* Open output stream */
    id->id = sout_StreamIdAdd( p_stream->p_next, &id->p_encoder->fmt_out );
    id->b_transcode = true;

    if( !id->id )
    {
        transcode_audio_close( id );
        return false;
    }

    date_Init( &id->interpolated_pts, p_fmt->audio.i_rate, 1 );

    return true;
}
Ejemplo n.º 10
0
/*****************************************************************************
 * aout_FifoInit : initialize the members of a FIFO
 *****************************************************************************/
void aout_FifoInit( vlc_object_t *obj, aout_fifo_t * p_fifo, uint32_t i_rate )
{
    if( unlikely(i_rate == 0) )
        msg_Err( obj, "initialising fifo with zero divider" );

    p_fifo->p_first = NULL;
    p_fifo->pp_last = &p_fifo->p_first;
    date_Init( &p_fifo->end_date, i_rate, 1 );
}
Ejemplo n.º 11
0
/*****************************************************************************
 * aout_FifoInit : initialize the members of a FIFO
 *****************************************************************************/
void aout_FifoInit( aout_instance_t * p_aout, aout_fifo_t * p_fifo,
                    uint32_t i_rate )
{
    AOUT_ASSERT_FIFO_LOCKED;

    if( i_rate == 0 )
    {
        msg_Err( p_aout, "initialising fifo with zero divider" );
    }

    p_fifo->p_first = NULL;
    p_fifo->pp_last = &p_fifo->p_first;
    date_Init( &p_fifo->end_date, i_rate, 1 );
}
Ejemplo n.º 12
0
Archivo: mjpeg.c Proyecto: mstorsjo/vlc
/*****************************************************************************
 * Open:
 *****************************************************************************/
static int Open( 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_MJPG )
        return VLC_EGENERIC;

    p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
    if( !p_dec->p_sys )
        return VLC_ENOMEM;

    p_sys->i_next_block_flags = 0;

    if( p_dec->fmt_in.video.i_frame_rate &&
        p_dec->fmt_in.video.i_frame_rate_base )
    {
        date_Init( &p_sys->date, p_dec->fmt_in.video.i_frame_rate,
                   p_dec->fmt_in.video.i_frame_rate_base );
    }
    else
        date_Init( &p_sys->date, 30000, 1001 );

    es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );

    /* Misc init */
    packetizer_Init( &p_sys->packetizer,
                     p_mjpg_startcode, sizeof(p_mjpg_startcode), startcode_Find,
                     NULL, 0, 295,
                     PacketizeReset, PacketizeParse, PacketizeValidate, p_dec );

    p_dec->pf_packetize = Packetize;
    p_dec->pf_flush = PacketizeFlush;
    p_dec->pf_get_cc = NULL;

    return VLC_SUCCESS;
}
Ejemplo n.º 13
0
static int UpdateAudioFormat( decoder_t *p_dec )
{
    int i_err;
    decoder_sys_t *p_sys = p_dec->p_sys;
    struct mpg123_frameinfo frame_info;

    /* Get details about the stream */
    i_err = mpg123_info( p_sys->p_handle, &frame_info );
    if( i_err != MPG123_OK )
    {
        msg_Err( p_dec, "mpg123_info failed: %s",
                 mpg123_plain_strerror( i_err ) );
        return VLC_EGENERIC;
    }

    p_dec->fmt_out.i_bitrate = frame_info.bitrate * 1000;

    switch( frame_info.mode )
    {
        case MPG123_M_DUAL:
            p_dec->fmt_out.audio.i_chan_mode = AOUT_CHANMODE_DUALMONO;
            /* fall through */
        case MPG123_M_STEREO:
        case MPG123_M_JOINT:
            p_dec->fmt_out.audio.i_physical_channels =
                AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
            break;
        case MPG123_M_MONO:
            p_dec->fmt_out.audio.i_physical_channels = AOUT_CHAN_CENTER;
            break;
        default:
            return VLC_EGENERIC;
    }

    aout_FormatPrepare( &p_dec->fmt_out.audio );

    /* Date management */
    if( p_dec->fmt_out.audio.i_rate != frame_info.rate )
    {
        p_dec->fmt_out.audio.i_rate = frame_info.rate;
        date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
        date_Set( &p_sys->end_date, 0 );
    }

    return decoder_UpdateAudioFormat( p_dec );
}
Ejemplo n.º 14
0
Archivo: dts.c Proyecto: 9034725985/vlc
/*****************************************************************************
 * GetOutBuffer:
 *****************************************************************************/
static uint8_t *GetOutBuffer( decoder_t *p_dec, block_t **pp_out_buffer )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    uint8_t *p_buf;

    if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
    {
        msg_Info( p_dec, "DTS channels:%d samplerate:%d bitrate:%d",
                  p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );

        date_Init( &p_sys->end_date, p_sys->i_rate, 1 );
        date_Set( &p_sys->end_date, p_sys->i_pts );
    }

    p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
    p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
    /* Hack for DTS S/PDIF filter which needs to pad the DTS frames */
    p_dec->fmt_out.audio.i_bytes_per_frame =
        __MAX( p_sys->i_frame_size, p_sys->i_frame_length * 4 );
    p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;

    p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
    p_dec->fmt_out.audio.i_physical_channels =
        p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;

    p_dec->fmt_out.i_bitrate = p_sys->i_bit_rate;

    if( p_sys->b_packetizer )
    {
        block_t *p_sout_buffer = GetSoutBuffer( p_dec );
        p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
        *pp_out_buffer = p_sout_buffer;
    }
    else
    {
        block_t *p_aout_buffer = GetAoutBuffer( p_dec );
        p_buf = p_aout_buffer ? p_aout_buffer->p_buffer : NULL;
        *pp_out_buffer = p_aout_buffer;
    }

    return p_buf;
}
Ejemplo n.º 15
0
Archivo: a52.c Proyecto: RicoP/vlcfork
/*****************************************************************************
 * GetOutBuffer:
 *****************************************************************************/
static uint8_t *GetOutBuffer( decoder_t *p_dec, block_t **pp_out_buffer )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    uint8_t *p_buf;

    if( p_dec->fmt_out.audio.i_rate != p_sys->frame.i_rate )
    {
        msg_Dbg( p_dec, "A/52 channels:%d samplerate:%d bitrate:%d",
                 p_sys->frame.i_channels, p_sys->frame.i_rate, p_sys->frame.i_bitrate );

        date_Init( &p_sys->end_date, p_sys->frame.i_rate, 1 );
        date_Set( &p_sys->end_date, p_sys->i_pts );
    }

    p_dec->fmt_out.audio.i_rate     = p_sys->frame.i_rate;
    p_dec->fmt_out.audio.i_channels = p_sys->frame.i_channels;
    if( p_dec->fmt_out.audio.i_bytes_per_frame < p_sys->frame.i_size )
        p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->frame.i_size;
    p_dec->fmt_out.audio.i_frame_length = p_sys->frame.i_samples;

    p_dec->fmt_out.audio.i_original_channels = p_sys->frame.i_channels_conf;
    p_dec->fmt_out.audio.i_physical_channels =
        p_sys->frame.i_channels_conf & AOUT_CHAN_PHYSMASK;

    p_dec->fmt_out.i_bitrate = p_sys->frame.i_bitrate;

    if( p_sys->b_packetizer )
    {
        block_t *p_sout_buffer = GetSoutBuffer( p_dec );
        p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
        *pp_out_buffer = p_sout_buffer;
    }
    else
    {
        aout_buffer_t *p_aout_buffer = GetAoutBuffer( p_dec );
        p_buf = p_aout_buffer ? p_aout_buffer->p_buffer : NULL;
        *pp_out_buffer = p_aout_buffer;
    }

    return p_buf;
}
Ejemplo n.º 16
0
Archivo: dts.c Proyecto: etix/vlc
static block_t *GetOutBuffer( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    if( !p_sys->b_date_set
     || p_dec->fmt_out.audio.i_rate != p_sys->dts.i_rate )
    {
        msg_Dbg( p_dec, "DTS samplerate:%d bitrate:%d",
                 p_sys->dts.i_rate, p_sys->dts.i_bitrate );

        date_Init( &p_sys->end_date, p_sys->dts.i_rate, 1 );
        date_Set( &p_sys->end_date, p_sys->i_pts );
        p_sys->b_date_set = true;
    }

    p_dec->fmt_out.audio.i_rate     = p_sys->dts.i_rate;
    if( p_dec->fmt_out.audio.i_bytes_per_frame < p_sys->dts.i_frame_size )
        p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->dts.i_frame_size;
    p_dec->fmt_out.audio.i_frame_length = p_sys->dts.i_frame_length;

    p_dec->fmt_out.audio.i_original_channels = p_sys->dts.i_original_channels;
    p_dec->fmt_out.audio.i_physical_channels = 
        p_sys->dts.i_original_channels & AOUT_CHAN_PHYSMASK;
    p_dec->fmt_out.audio.i_channels =
        popcount( p_dec->fmt_out.audio.i_physical_channels );

    p_dec->fmt_out.i_bitrate = p_sys->dts.i_bitrate;

    block_t *p_block = block_Alloc( p_sys->i_input_size );
    if( p_block == NULL )
        return NULL;

    p_block->i_nb_samples = p_sys->dts.i_frame_length;
    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_block->i_nb_samples ) - p_block->i_pts;
    return p_block;
}
Ejemplo n.º 17
0
Archivo: a52.c Proyecto: IAPark/vlc
static block_t *GetOutBuffer( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    if( !p_sys->b_date_set
     || p_dec->fmt_out.audio.i_rate != p_sys->frame.i_rate )
    {
        msg_Dbg( p_dec, "A/52 channels:%d samplerate:%d bitrate:%d",
                 p_sys->frame.i_channels, p_sys->frame.i_rate, p_sys->frame.i_bitrate );

        date_Init( &p_sys->end_date, p_sys->frame.i_rate, 1 );
        date_Set( &p_sys->end_date, p_sys->i_pts );
        p_sys->b_date_set = true;
    }

    p_dec->fmt_out.audio.i_rate     = p_sys->frame.i_rate;
    p_dec->fmt_out.audio.i_channels = p_sys->frame.i_channels;
    if( p_dec->fmt_out.audio.i_bytes_per_frame < p_sys->frame.i_size )
        p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->frame.i_size;
    p_dec->fmt_out.audio.i_frame_length = p_sys->frame.i_samples;

    p_dec->fmt_out.audio.i_chan_mode = p_sys->frame.i_chan_mode;
    p_dec->fmt_out.audio.i_physical_channels = p_sys->frame.i_channels_conf;

    p_dec->fmt_out.i_bitrate = p_sys->frame.i_bitrate;

    block_t *p_block = block_Alloc( p_sys->frame.i_size );
    if( p_block == NULL )
        return NULL;

    p_block->i_nb_samples = p_sys->frame.i_samples;
    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_block->i_nb_samples ) - p_block->i_pts;
    return p_block;
}
Ejemplo n.º 18
0
static int Open(vlc_object_t *object)
{
    demux_t *demux = (demux_t*)object;

    /* Detect the image type */
    const image_format_t *img;

    const uint8_t *peek;
    int peek_size = 0;
    for (int i = 0; ; i++) {
        img = &formats[i];
        if (!img->codec)
            return VLC_EGENERIC;

        if (img->detect) {
            if (img->detect(demux->s))
                break;
        } else {
            if (peek_size < img->marker_size)
                peek_size = stream_Peek(demux->s, &peek, img->marker_size);
            if (peek_size >= img->marker_size &&
                !memcmp(peek, img->marker, img->marker_size))
                break;
        }
    }
    msg_Dbg(demux, "Detected image: %s",
            vlc_fourcc_GetDescription(VIDEO_ES, img->codec));

    if( img->codec == VLC_CODEC_MXPEG )
    {
        return VLC_EGENERIC; //let avformat demux this file
    }

    /* Load and if selected decode */
    es_format_t fmt;
    es_format_Init(&fmt, VIDEO_ES, img->codec);
    fmt.video.i_chroma = fmt.i_codec;

    block_t *data = Load(demux);
    if (data && var_InheritBool(demux, "image-decode")) {
        char *string = var_InheritString(demux, "image-chroma");
        vlc_fourcc_t chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, string);
        free(string);

        data = Decode(demux, &fmt.video, chroma, data);
        fmt.i_codec = fmt.video.i_chroma;
    }
    fmt.i_id    = var_InheritInteger(demux, "image-id");
    fmt.i_group = var_InheritInteger(demux, "image-group");
    if (var_InheritURational(demux,
                             &fmt.video.i_frame_rate,
                             &fmt.video.i_frame_rate_base,
                             "image-fps") ||
        fmt.video.i_frame_rate <= 0 || fmt.video.i_frame_rate_base <= 0) {
        msg_Err(demux, "Invalid frame rate, using 10/1 instead");
        fmt.video.i_frame_rate      = 10;
        fmt.video.i_frame_rate_base = 1;
    }

    /* If loadind failed, we still continue to avoid mis-detection
     * by other demuxers. */
    if (!data)
        msg_Err(demux, "Failed to load the image");

    /* */
    demux_sys_t *sys = malloc(sizeof(*sys));
    if (!sys) {
        if (data)
            block_Release(data);
        es_format_Clean(&fmt);
        return VLC_ENOMEM;
    }

    sys->data        = data;
    sys->es          = es_out_Add(demux->out, &fmt);
    sys->duration    = CLOCK_FREQ * var_InheritFloat(demux, "image-duration");
    sys->is_realtime = var_InheritBool(demux, "image-realtime");
    sys->pts_origin  = sys->is_realtime ? mdate() : 0;
    sys->pts_next    = VLC_TS_INVALID;
    date_Init(&sys->pts, fmt.video.i_frame_rate, fmt.video.i_frame_rate_base);
    date_Set(&sys->pts, 0);

    es_format_Clean(&fmt);

    demux->pf_demux   = Demux;
    demux->pf_control = Control;
    demux->p_sys      = sys;
    return VLC_SUCCESS;
}
Ejemplo n.º 19
0
Archivo: opus.c Proyecto: MSalmo/vlc
/*****************************************************************************
 * ProcessInitialHeader: processes the inital Opus header packet.
 *****************************************************************************/
static int ProcessInitialHeader( decoder_t *p_dec, ogg_packet *p_oggpacket )
{
    int err;
    unsigned char new_stream_map[8];
    decoder_sys_t *p_sys = p_dec->p_sys;

    OpusHeader *p_header = &p_sys->header;

    if( !opus_header_parse((unsigned char *)p_oggpacket->packet,p_oggpacket->bytes,p_header) )
    {
        msg_Err( p_dec, "cannot read Opus header" );
        return VLC_EGENERIC;
    }
    msg_Dbg( p_dec, "Opus audio with %d channels", p_header->channels);

    if((p_header->channels>2 && p_header->channel_mapping==0) ||
       (p_header->channels>8 && p_header->channel_mapping==1) ||
        p_header->channel_mapping>1)
    {
        msg_Err( p_dec, "Unsupported channel mapping" );
        return VLC_EGENERIC;
    }

    /* Setup the format */
    p_dec->fmt_out.audio.i_physical_channels =
        p_dec->fmt_out.audio.i_original_channels =
            pi_channels_maps[p_header->channels];
    p_dec->fmt_out.audio.i_channels = p_header->channels;
    p_dec->fmt_out.audio.i_rate = 48000;

    if( p_header->channels>2 && p_header->channels<9 )
    {
        static const uint32_t *pi_ch[6] = { pi_3channels_in, pi_4channels_in,
                                            pi_5channels_in, pi_6channels_in,
                                            pi_7channels_in, pi_8channels_in };
        uint8_t pi_chan_table[AOUT_CHAN_MAX];

        aout_CheckChannelReorder( pi_ch[p_header->channels-3], NULL,
                                  p_dec->fmt_out.audio.i_physical_channels,
                                  pi_chan_table );
        for(int i=0;i<p_header->channels;i++)
            new_stream_map[pi_chan_table[i]]=p_header->stream_map[i];
    }
    /* Opus decoder init */
    p_sys->p_st = opus_multistream_decoder_create( 48000, p_header->channels,
                    p_header->nb_streams, p_header->nb_coupled,
                    p_header->channels>2?new_stream_map:p_header->stream_map,
                    &err );
    if( !p_sys->p_st || err!=OPUS_OK )
    {
        msg_Err( p_dec, "decoder initialization failed" );
        return VLC_EGENERIC;
    }

#ifdef OPUS_SET_GAIN
    if( opus_multistream_decoder_ctl( p_sys->p_st,OPUS_SET_GAIN(p_header->gain) ) != OPUS_OK )
    {
        msg_Err( p_dec, "OPUS_SET_GAIN failed" );
        opus_multistream_decoder_destroy( p_sys->p_st );
        return VLC_EGENERIC;
    }
#endif

    date_Init( &p_sys->end_date, 48000, 1 );

    return VLC_SUCCESS;
}
Ejemplo n.º 20
0
/*****************************************************************************
 * DecodeFrame: decodes an lpcm frame.
 ****************************************************************************
 * Beware, this function must be fed with complete frames (PES packet).
 *****************************************************************************/
static void *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t       *p_block;
    unsigned int  i_rate = 0, i_original_channels = 0, i_channels = 0, i_bits = 0;
    int           i_frame_length;

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

    p_block = *pp_block;
    *pp_block = NULL; /* So the packet doesn't get re-sent */

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

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

    if( p_block->i_buffer <= p_sys->i_header_size )
    {
        msg_Err(p_dec, "frame is too short");
        block_Release( p_block );
        return NULL;
    }

    int i_ret;
    unsigned i_padding = 0;
    aob_group_t p_aob_group[2];
    switch( p_sys->i_type )
    {
    case LPCM_VOB:
        i_ret = VobHeader( &i_rate, &i_channels, &i_original_channels, &i_bits,
                           p_block->p_buffer );
        break;
    case LPCM_AOB:
        i_ret = AobHeader( &i_rate, &i_channels, &i_original_channels, &i_bits, &i_padding,
                           p_aob_group,
                           p_block->p_buffer );
        break;
    case LPCM_BD:
        i_ret = BdHeader( &i_rate, &i_channels, &i_original_channels, &i_bits,
                          p_block->p_buffer );
        break;
    default:
        assert(0);
    }

    if( i_ret || p_block->i_buffer <= p_sys->i_header_size + i_padding )
    {
        msg_Warn( p_dec, "no frame sync or too small frame" );
        block_Release( p_block );
        return NULL;
    }

    /* Set output properties */
    if( p_dec->fmt_out.audio.i_rate != i_rate )
    {
        date_Init( &p_sys->end_date, i_rate, 1 );
        date_Set( &p_sys->end_date, p_block->i_pts );
    }
    p_dec->fmt_out.audio.i_rate = i_rate;
    p_dec->fmt_out.audio.i_channels = i_channels;
    p_dec->fmt_out.audio.i_original_channels = i_original_channels;
    p_dec->fmt_out.audio.i_physical_channels = i_original_channels & AOUT_CHAN_PHYSMASK;

    i_frame_length = (p_block->i_buffer - p_sys->i_header_size - i_padding) / i_channels * 8 / i_bits;

    if( p_sys->b_packetizer )
    {
        p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date );
        p_block->i_length =
            date_Increment( &p_sys->end_date, i_frame_length ) -
            p_block->i_pts;

        /* Just pass on the incoming frame */
        return p_block;
    }
    else
    {
        /* */
        if( i_bits == 16 )
        {
            p_dec->fmt_out.i_codec = VLC_CODEC_S16B;
            p_dec->fmt_out.audio.i_bitspersample = 16;
        }
        else
        {
            p_dec->fmt_out.i_codec = VLC_CODEC_S24B;
            p_dec->fmt_out.audio.i_bitspersample = 24;
        }

        /* */
        aout_buffer_t *p_aout_buffer;
        p_aout_buffer = decoder_NewAudioBuffer( p_dec, i_frame_length );
        if( !p_aout_buffer )
            return NULL;

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

        p_block->p_buffer += p_sys->i_header_size + i_padding;
        p_block->i_buffer -= p_sys->i_header_size + i_padding;

        switch( p_sys->i_type )
        {
        case LPCM_VOB:
            VobExtract( p_aout_buffer, p_block, i_bits );
            break;
        case LPCM_AOB:
            AobExtract( p_aout_buffer, p_block, i_bits, p_aob_group );
            break;
        default:
            assert(0);
        case LPCM_BD:
            BdExtract( p_aout_buffer, p_block );
            break;
        }

        block_Release( p_block );
        return p_aout_buffer;
    }
}
Ejemplo n.º 21
0
/*****************************************************************************
 * OpenDecoder: probe the decoder and return score
 *****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t*)p_this;
    decoder_sys_t *p_sys;

    switch( p_dec->fmt_in.i_codec )
    {
        case VLC_FOURCC('i','m','a', '4'): /* IMA ADPCM */
        case VLC_FOURCC('m','s',0x00,0x02): /* MS ADPCM */
        case VLC_FOURCC('m','s',0x00,0x11): /* IMA ADPCM */
        case VLC_CODEC_ADPCM_DK3:
        case VLC_CODEC_ADPCM_DK4:
        case VLC_FOURCC('X','A','J', 0): /* EA ADPCM */
            break;
        default:
            return VLC_EGENERIC;
    }

    if( p_dec->fmt_in.audio.i_channels <= 0 ||
        p_dec->fmt_in.audio.i_channels > 5 )
    {
        msg_Err( p_dec, "invalid number of channel (not between 1 and 5): %i",
                 p_dec->fmt_in.audio.i_channels );
        return VLC_EGENERIC;
    }

    if( p_dec->fmt_in.audio.i_rate <= 0 )
    {
        msg_Err( p_dec, "bad samplerate" );
        return VLC_EGENERIC;
    }

    /* Allocate the memory needed to store the decoder's structure */
    p_sys = malloc(sizeof(*p_sys));
    if( unlikely(p_sys == NULL) )
        return VLC_ENOMEM;

    p_sys->prev = NULL;

    switch( p_dec->fmt_in.i_codec )
    {
        case VLC_FOURCC('i','m','a', '4'): /* IMA ADPCM */
            p_sys->codec = ADPCM_IMA_QT;
            break;
        case VLC_CODEC_ADPCM_IMA_WAV: /* IMA ADPCM */
            p_sys->codec = ADPCM_IMA_WAV;
            break;
        case VLC_CODEC_ADPCM_MS: /* MS ADPCM */
            p_sys->codec = ADPCM_MS;
            break;
        case VLC_CODEC_ADPCM_DK4: /* Duck DK4 ADPCM */
            p_sys->codec = ADPCM_DK4;
            break;
        case VLC_CODEC_ADPCM_DK3: /* Duck DK3 ADPCM */
            p_sys->codec = ADPCM_DK3;
            break;
        case VLC_FOURCC('X','A','J', 0): /* EA ADPCM */
            p_sys->codec = ADPCM_EA;
            p_sys->prev = calloc( 2 * p_dec->fmt_in.audio.i_channels,
                                  sizeof( int16_t ) );
            if( unlikely(p_sys->prev == NULL) )
            {
                free( p_sys );
                return VLC_ENOMEM;
            }
            break;
    }

    if( p_dec->fmt_in.audio.i_blockalign <= 0 )
    {
        p_sys->i_block = (p_sys->codec == ADPCM_IMA_QT) ?
            34 * p_dec->fmt_in.audio.i_channels : 1024;
        msg_Warn( p_dec, "block size undefined, using %zu", p_sys->i_block );
    }
    else
    {
        p_sys->i_block = p_dec->fmt_in.audio.i_blockalign;
    }

    /* calculate samples per block */
    switch( p_sys->codec )
    {
    case ADPCM_IMA_QT:
        p_sys->i_samplesperblock = 64;
        break;
    case ADPCM_IMA_WAV:
        p_sys->i_samplesperblock =
            2 * ( p_sys->i_block - 4 * p_dec->fmt_in.audio.i_channels ) /
            p_dec->fmt_in.audio.i_channels;
        break;
    case ADPCM_MS:
        p_sys->i_samplesperblock =
            2 * (p_sys->i_block - 7 * p_dec->fmt_in.audio.i_channels) /
            p_dec->fmt_in.audio.i_channels + 2;
        break;
    case ADPCM_DK4:
        p_sys->i_samplesperblock =
            2 * (p_sys->i_block - 4 * p_dec->fmt_in.audio.i_channels) /
            p_dec->fmt_in.audio.i_channels + 1;
        break;
    case ADPCM_DK3:
        p_dec->fmt_in.audio.i_channels = 2;
        p_sys->i_samplesperblock = ( 4 * ( p_sys->i_block - 16 ) + 2 )/ 3;
        break;
    case ADPCM_EA:
        p_sys->i_samplesperblock =
            2 * (p_sys->i_block - p_dec->fmt_in.audio.i_channels) /
            p_dec->fmt_in.audio.i_channels;
    }

    msg_Dbg( p_dec, "format: samplerate:%d Hz channels:%d bits/sample:%d "
             "blockalign:%zu samplesperblock:%zu",
             p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
             p_dec->fmt_in.audio.i_bitspersample, p_sys->i_block,
             p_sys->i_samplesperblock );

    p_dec->p_sys = p_sys;
    p_dec->fmt_out.i_cat = AUDIO_ES;
    p_dec->fmt_out.i_codec = VLC_CODEC_S16N;
    p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
    p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
    p_dec->fmt_out.audio.i_physical_channels =
        p_dec->fmt_out.audio.i_original_channels =
            pi_channels_maps[p_dec->fmt_in.audio.i_channels];

    date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
    date_Set( &p_sys->end_date, 0 );

    p_dec->pf_decode_audio = DecodeBlock;

    return VLC_SUCCESS;
}
Ejemplo n.º 22
0
Archivo: dirac.c Proyecto: CSRedRat/vlc
/****************************************************************************
 * Encode: the whole thing
 ****************************************************************************
 * This function spits out encapsulation units.
 ****************************************************************************/
static block_t *Encode( encoder_t *p_enc, picture_t *p_pic )
{
    encoder_sys_t *p_sys = p_enc->p_sys;
    block_t *p_block, *p_output_chain = NULL;
    int i_plane, i_line, i_width, i_src_stride;
    uint8_t *p_dst;

    if( !p_pic ) return NULL;
    /* we only know if the sequence is interlaced when the first
     * picture arrives, so final setup is done here */
    /* XXX todo, detect change of interlace */
    p_sys->ctx.src_params.topfieldfirst = p_pic->b_top_field_first;
    p_sys->ctx.src_params.source_sampling = !p_pic->b_progressive;

    if( p_sys->b_auto_field_coding )
        p_sys->ctx.enc_params.picture_coding_mode = !p_pic->b_progressive;

    if( !p_sys->p_dirac )
    {
        date_t date;
        /* Initialise the encoder with the encoder context */
        p_sys->p_dirac = dirac_encoder_init( &p_sys->ctx, 0 );
        if( !p_sys->p_dirac )
        {
            msg_Err( p_enc, "Failed to initialize dirac encoder" );
            return NULL;
        }
        date_Init( &date, p_enc->fmt_in.video.i_frame_rate, p_enc->fmt_in.video.i_frame_rate_base );
#if DIRAC_RESEARCH_VERSION_ATLEAST(1,0,2)
        int i_delayinpics = dirac_encoder_pts_offset( p_sys->p_dirac );
        i_delayinpics /= p_sys->ctx.enc_params.picture_coding_mode + 1;
        date_Increment( &date, i_delayinpics );
#else
        date_Increment( &date, 1 );
#endif
        p_sys->i_pts_offset = date_Get( &date );

        /* picture_coding_mode = 1 == FIELD_CODING, two pictures are produced
         * for each frame input. Calculate time between fields for offsetting
         * the second field later. */
        if( 1 == p_sys->ctx.enc_params.picture_coding_mode )
        {
            date_Set( &date, 0 );
            date_Increment( &date, 1 );
            p_sys->i_field_time = date_Get( &date ) / 2;
        }
    }

    /* Copy input picture into encoder input buffer (stride by stride) */
    /* Would be lovely to just pass the picture in, but there is noway for the
     * library to free it */
    p_dst = p_sys->p_buffer_in;
    for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
    {
        uint8_t *p_src = p_pic->p[i_plane].p_pixels;
        i_width = p_pic->p[i_plane].i_visible_pitch;
        i_src_stride = p_pic->p[i_plane].i_pitch;

        for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines; i_line++ )
        {
            vlc_memcpy( p_dst, p_src, i_width );
            p_dst += i_width;
            p_src += i_src_stride;
        }
    }

    /* Load one frame of data into encoder */
    if( dirac_encoder_load( p_sys->p_dirac, p_sys->p_buffer_in,
                            p_sys->i_buffer_in ) < 0 )
    {
        msg_Dbg( p_enc, "dirac_encoder_load() error" );
        return NULL;
    }

    /* store pts in a lookaside buffer, so that the same pts may
     * be used for the picture in coded order */
    StorePicturePTS( p_enc, p_sys->i_input_picnum, p_pic->date );
    p_sys->i_input_picnum++;

    /* store dts in a queue, so that they appear in order in
     * coded order */
    p_block = block_New( p_enc, 1 );
    if( !p_block )
        return NULL;
    p_block->i_dts = p_pic->date - p_sys->i_pts_offset;
    block_FifoPut( p_sys->p_dts_fifo, p_block );
    p_block = NULL;

    /* for field coding mode, insert an extra value into both the
     * pts lookaside buffer and dts queue, offset to correspond
     * to a one field delay. */
    if( 1 == p_sys->ctx.enc_params.picture_coding_mode )
    {
        StorePicturePTS( p_enc, p_sys->i_input_picnum, p_pic->date + p_sys->i_field_time );
        p_sys->i_input_picnum++;

        p_block = block_New( p_enc, 1 );
        if( !p_block )
            return NULL;
        p_block->i_dts = p_pic->date - p_sys->i_pts_offset + p_sys->i_field_time;
        block_FifoPut( p_sys->p_dts_fifo, p_block );
        p_block = NULL;
    }

    dirac_encoder_state_t state;
    /* Retrieve encoded frames from encoder */
    do
    {
        p_sys->p_dirac->enc_buf.buffer = p_sys->p_buffer_out;
        p_sys->p_dirac->enc_buf.size = p_sys->i_buffer_out;
        state = dirac_encoder_output( p_sys->p_dirac );
        switch( state )
        {
        case ENC_STATE_AVAIL: {
            uint32_t pic_num;

            /* extract data from encoder temporary buffer. */
            p_block = block_New( p_enc, p_sys->p_dirac->enc_buf.size );
            if( !p_block )
                return NULL;
            memcpy( p_block->p_buffer, p_sys->p_dirac->enc_buf.buffer,
                    p_sys->p_dirac->enc_buf.size );

            /* if some flags were set for a previous block, prevent
             * them from getting lost */
            if( p_sys->p_chain )
                p_block->i_flags |= p_sys->p_chain->i_flags;

            /* store all extracted blocks in a chain and gather up when an
             * entire encapsulation unit is avaliable (ends with a picture) */
            block_ChainAppend( &p_sys->p_chain, p_block );

            /* Presence of a Sequence header indicates a seek point */
            if( 0 == p_block->p_buffer[4] )
            {
                p_block->i_flags |= BLOCK_FLAG_TYPE_I;

                if( !p_enc->fmt_out.p_extra ) {
                    const uint8_t eos[] = { 'B','B','C','D',0x10,0,0,0,13,0,0,0,0 };
                    uint32_t len = GetDWBE( p_block->p_buffer + 5 );
                    /* if it hasn't been done so far, stash a copy of the
                     * sequence header for muxers such as ogg */
                    /* The OggDirac spec advises that a Dirac EOS DataUnit
                     * is appended to the sequence header to allow guard
                     * against poor streaming servers */
                    /* XXX, should this be done using the packetizer ? */
                    p_enc->fmt_out.p_extra = malloc( len + sizeof(eos) );
                    if( !p_enc->fmt_out.p_extra )
                        return NULL;
                    memcpy( p_enc->fmt_out.p_extra, p_block->p_buffer, len);
                    memcpy( (uint8_t*)p_enc->fmt_out.p_extra + len, eos, sizeof(eos) );
                    SetDWBE( (uint8_t*)p_enc->fmt_out.p_extra + len + 10, len );
                    p_enc->fmt_out.i_extra = len + sizeof(eos);
                }
            }

            if( ReadDiracPictureNumber( &pic_num, p_block ) )
            {
                /* Finding a picture terminates an ecapsulation unit, gather
                 * all data and output; use the next dts value queued up
                 * and find correct pts in the tlb */
                p_block = block_FifoGet( p_sys->p_dts_fifo );
                p_sys->p_chain->i_dts = p_block->i_dts;
                p_sys->p_chain->i_pts = GetPicturePTS( p_enc, pic_num );
                block_Release( p_block );
                block_ChainAppend( &p_output_chain, block_ChainGather( p_sys->p_chain ) );
                p_sys->p_chain = NULL;
            } else {
                p_block = NULL;
            }
            break;
            }

        case ENC_STATE_BUFFER:
            break;
        case ENC_STATE_INVALID:
        default:
            break;
        }
    } while( state == ENC_STATE_AVAIL );

    return p_output_chain;
}
Ejemplo n.º 23
0
/*****************************************************************************
 * OpenDecoder: probe the decoder and return score
 *****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t*)p_this;
    decoder_sys_t *p_sys;

    switch( p_dec->fmt_in.i_codec )
    {
        /* Planar YUV */
        case VLC_CODEC_I444:
        case VLC_CODEC_J444:
        case VLC_CODEC_I440:
        case VLC_CODEC_J440:
        case VLC_CODEC_I422:
        case VLC_CODEC_J422:
        case VLC_CODEC_I420:
        case VLC_CODEC_J420:
        case VLC_CODEC_YV12:
        case VLC_CODEC_YV9:
        case VLC_CODEC_I411:
        case VLC_CODEC_I410:
        case VLC_CODEC_GREY:
        case VLC_CODEC_YUVP:
        case VLC_CODEC_NV12:
        case VLC_CODEC_NV21:
        case VLC_CODEC_I422_10L:
        case VLC_CODEC_I422_10B:

        /* Packed YUV */
        case VLC_CODEC_YUYV:
        case VLC_CODEC_YVYU:
        case VLC_CODEC_UYVY:
        case VLC_CODEC_VYUY:

        /* RGB */
        case VLC_CODEC_RGB32:
        case VLC_CODEC_RGB24:
        case VLC_CODEC_RGB16:
        case VLC_CODEC_RGB15:
        case VLC_CODEC_RGB8:
        case VLC_CODEC_RGBP:
        case VLC_CODEC_RGBA:
            break;

        default:
            return VLC_EGENERIC;
    }

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys =
          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
        return VLC_ENOMEM;
    /* Misc init */
    p_dec->p_sys->b_packetizer = false;
    p_sys->b_invert = false;

    if( (int)p_dec->fmt_in.video.i_height < 0 )
    {
        /* Frames are coded from bottom to top */
        p_dec->fmt_in.video.i_height =
            (unsigned int)(-(int)p_dec->fmt_in.video.i_height);
        p_sys->b_invert = true;
    }
    if( !p_dec->fmt_in.video.i_visible_width )
        p_dec->fmt_in.video.i_visible_width = p_dec->fmt_in.video.i_width;
    if( !p_dec->fmt_in.video.i_visible_height )
        p_dec->fmt_in.video.i_visible_height = p_dec->fmt_in.video.i_height;

    if( p_dec->fmt_in.video.i_visible_width <= 0
     || p_dec->fmt_in.video.i_visible_height <= 0 )
    {
        msg_Err( p_dec, "invalid display size %dx%d",
                 p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height );
        return VLC_EGENERIC;
    }

    es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );

    date_Init( &p_sys->pts, p_dec->fmt_out.video.i_frame_rate,
               p_dec->fmt_out.video.i_frame_rate_base );
    if( p_dec->fmt_out.video.i_frame_rate == 0 ||
        p_dec->fmt_out.video.i_frame_rate_base == 0)
    {
        msg_Warn( p_dec, "invalid frame rate %d/%d, using 25 fps instead",
                  p_dec->fmt_out.video.i_frame_rate,
                  p_dec->fmt_out.video.i_frame_rate_base);
        date_Init( &p_sys->pts, 25, 1 );
    }

    /* Find out p_vdec->i_raw_size */
    video_format_Setup( &p_dec->fmt_out.video, p_dec->fmt_in.i_codec,
                        p_dec->fmt_in.video.i_visible_width,
                        p_dec->fmt_in.video.i_visible_height,
                        p_dec->fmt_in.video.i_sar_num,
                        p_dec->fmt_in.video.i_sar_den );
    picture_t picture;
    picture_Setup( &picture, p_dec->fmt_out.i_codec,
                   p_dec->fmt_in.video.i_width,
                   p_dec->fmt_in.video.i_height, 0, 1 );
    p_sys->i_raw_size = 0;
    for( int i = 0; i < picture.i_planes; i++ )
    {
        p_sys->i_raw_size += picture.p[i].i_visible_pitch *
                             picture.p[i].i_visible_lines;
        p_sys->planes[i] = picture.p[i];
    }

    if( !p_dec->fmt_in.video.i_sar_num || !p_dec->fmt_in.video.i_sar_den )
    {
        p_dec->fmt_out.video.i_sar_num = 1;
        p_dec->fmt_out.video.i_sar_den = 1;
    }

    /* Set callbacks */
    p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
        DecodeBlock;
    p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
        DecodeBlock;

    return VLC_SUCCESS;
}
Ejemplo n.º 24
0
/*****************************************************************************
 * OpenAudio:
 *****************************************************************************/
static int OpenAudio( decoder_t *p_dec )
{
    decoder_sys_t *p_sys;

    int             i_error;
    char            fcc[4];
    unsigned long   WantedBufferSize;
    unsigned long   InputBufferSize = 0;
    unsigned long   OutputBufferSize = 0;

    /* get lock, avoid segfault */
    vlc_mutex_lock( &qt_mutex );

    p_sys = calloc( 1, sizeof( decoder_sys_t ) );
    p_dec->p_sys = p_sys;
    p_dec->pf_decode_audio = DecodeAudio;

    if( p_dec->fmt_in.i_original_fourcc )
        memcpy( fcc, &p_dec->fmt_in.i_original_fourcc, 4 );
    else
        memcpy( fcc, &p_dec->fmt_in.i_codec, 4 );

#ifdef __APPLE__
    EnterMovies();
#endif

    if( QTAudioInit( p_dec ) )
    {
        msg_Err( p_dec, "cannot initialize QT");
        goto exit_error;
    }

#ifndef __APPLE__
    if( ( i_error = p_sys->InitializeQTML( 6 + 16 ) ) )
    {
        msg_Dbg( p_dec, "error on InitializeQTML = %d", i_error );
        goto exit_error;
    }
#endif

    /* input format settings */
    p_sys->InputFormatInfo.flags       = 0;
    p_sys->InputFormatInfo.sampleCount = 0;
    p_sys->InputFormatInfo.buffer      = NULL;
    p_sys->InputFormatInfo.reserved    = 0;
    p_sys->InputFormatInfo.numChannels = p_dec->fmt_in.audio.i_channels;
    p_sys->InputFormatInfo.sampleSize  = p_dec->fmt_in.audio.i_bitspersample;
    p_sys->InputFormatInfo.sampleRate  = p_dec->fmt_in.audio.i_rate;
    p_sys->InputFormatInfo.format      = FCC( fcc[0], fcc[1], fcc[2], fcc[3] );

    /* output format settings */
    p_sys->OutputFormatInfo.flags       = 0;
    p_sys->OutputFormatInfo.sampleCount = 0;
    p_sys->OutputFormatInfo.buffer      = NULL;
    p_sys->OutputFormatInfo.reserved    = 0;
    p_sys->OutputFormatInfo.numChannels = p_dec->fmt_in.audio.i_channels;
    p_sys->OutputFormatInfo.sampleSize  = 16;
    p_sys->OutputFormatInfo.sampleRate  = p_dec->fmt_in.audio.i_rate;
    p_sys->OutputFormatInfo.format      = FCC( 'N', 'O', 'N', 'E' );


    i_error = p_sys->SoundConverterOpen( &p_sys->InputFormatInfo,
                                         &p_sys->OutputFormatInfo,
                                         &p_sys->myConverter );
    if( i_error )
    {
        msg_Err( p_dec, "error on SoundConverterOpen = %d", i_error );
        goto exit_error;
    }

#if 0
    /* tell the sound converter we accept VBR formats */
    i_error = SoundConverterSetInfo( p_dec->myConverter, siClientAcceptsVBR,
                                     (void *)true );
#endif

    if( p_dec->fmt_in.i_extra > 36 + 8 )
    {
        i_error = p_sys->SoundConverterSetInfo( p_sys->myConverter,
                                                FCC( 'w', 'a', 'v', 'e' ),
                                                ((uint8_t*)p_dec->fmt_in.p_extra) + 36 + 8 );

        msg_Dbg( p_dec, "error on SoundConverterSetInfo = %d", i_error );
    }

    WantedBufferSize = p_sys->OutputFormatInfo.numChannels *
                       p_sys->OutputFormatInfo.sampleRate * 2;
    p_sys->FramesToGet = 0;

    i_error = p_sys->SoundConverterGetBufferSizes( p_sys->myConverter,
                                                   WantedBufferSize,
                                                   &p_sys->FramesToGet,
                                                   &InputBufferSize,
                                                   &OutputBufferSize );

    msg_Dbg( p_dec, "WantedBufferSize=%li InputBufferSize=%li "
             "OutputBufferSize=%li FramesToGet=%li",
             WantedBufferSize, InputBufferSize, OutputBufferSize,
             p_sys->FramesToGet );

    p_sys->InFrameSize  = (InputBufferSize + p_sys->FramesToGet - 1 ) /
                            p_sys->FramesToGet;
    p_sys->OutFrameSize = OutputBufferSize / p_sys->FramesToGet;

    msg_Dbg( p_dec, "frame size %d -> %d",
             p_sys->InFrameSize, p_sys->OutFrameSize );

    if( (i_error = p_sys->SoundConverterBeginConversion(p_sys->myConverter)) )
    {
        msg_Err( p_dec,
                 "error on SoundConverterBeginConversion = %d", i_error );
        goto exit_error;
    }


    es_format_Init( &p_dec->fmt_out, AUDIO_ES, VLC_CODEC_S16N );
    p_dec->fmt_out.audio.i_rate = p_sys->OutputFormatInfo.sampleRate;
    p_dec->fmt_out.audio.i_channels = p_sys->OutputFormatInfo.numChannels;
    p_dec->fmt_out.audio.i_physical_channels =
    p_dec->fmt_out.audio.i_original_channels =
        pi_channels_maps[p_sys->OutputFormatInfo.numChannels];

    date_Init( &p_sys->date, p_dec->fmt_out.audio.i_rate, 1 );

    p_sys->i_buffer      = 0;
    p_sys->i_buffer_size = 100*1000;
    p_sys->p_buffer      = malloc( p_sys->i_buffer_size );
    if( !p_sys->p_buffer )
        goto exit_error;

    p_sys->i_out = 0;
    p_sys->i_out_frames = 0;

    vlc_mutex_unlock( &qt_mutex );
    return VLC_SUCCESS;

exit_error:

#ifdef LOADER
    Restore_LDT_Keeper( p_sys->ldt_fs );
#endif
    vlc_mutex_unlock( &qt_mutex );

    free( p_sys );
    return VLC_EGENERIC;
}
Ejemplo n.º 25
0
/*****************************************************************************
 * DecodeAudio: Called to decode one frame
 *****************************************************************************/
aout_buffer_t * DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    int i_used, i_output;
    aout_buffer_t *p_buffer;
    block_t *p_block;
    AVPacket pkt;

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

    p_block = *pp_block;

    if( !p_sys->p_context->extradata_size && p_dec->fmt_in.i_extra &&
            p_sys->b_delayed_open)
    {
        InitDecoderConfig( p_dec, p_sys->p_context);
        if( ffmpeg_OpenCodec( p_dec ) )
            msg_Err( p_dec, "Cannot open decoder %s", p_sys->psz_namecodec );
    }
    if( p_sys->b_delayed_open )
    {
        block_Release( p_block );
        return NULL;
    }

    if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
    {
        block_Release( p_block );
        avcodec_flush_buffers( p_sys->p_context );
        p_sys->i_samples = 0;
        date_Set( &p_sys->end_date, 0 );

        if( p_sys->i_codec_id == CODEC_ID_MP2 || p_sys->i_codec_id == CODEC_ID_MP3 )
            p_sys->i_reject_count = 3;
        return NULL;
    }

    if( p_sys->i_samples > 0 )
    {
        /* More data */
        p_buffer = SplitBuffer( p_dec );
        if( !p_buffer ) block_Release( p_block );
        return p_buffer;
    }

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

    if( p_block->i_buffer <= 0 )
    {
        block_Release( p_block );
        return NULL;
    }

    if( (p_block->i_flags & BLOCK_FLAG_PRIVATE_REALLOCATED) == 0 )
    {
        *pp_block = p_block = block_Realloc( p_block, 0, p_block->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE );
        if( !p_block )
            return NULL;
        p_block->i_buffer -= FF_INPUT_BUFFER_PADDING_SIZE;
        memset( &p_block->p_buffer[p_block->i_buffer], 0, FF_INPUT_BUFFER_PADDING_SIZE );

        p_block->i_flags |= BLOCK_FLAG_PRIVATE_REALLOCATED;
    }

    do
    {
        i_output = __MAX( p_block->i_buffer, p_sys->i_output_max );
        if( i_output > p_sys->i_output_max )
        {
            /* Grow output buffer if necessary (eg. for PCM data) */
            p_sys->p_output = av_realloc( p_sys->p_output, i_output );
        }

        av_init_packet( &pkt );
        pkt.data = p_block->p_buffer;
        pkt.size = p_block->i_buffer;
        i_used = avcodec_decode_audio3( p_sys->p_context,
                                        (int16_t*)p_sys->p_output, &i_output,
                                        &pkt );

        if( i_used < 0 || i_output < 0 )
        {
            if( i_used < 0 )
                msg_Warn( p_dec, "cannot decode one frame (%zu bytes)",
                          p_block->i_buffer );

            block_Release( p_block );
            return NULL;
        }
        else if( (size_t)i_used > p_block->i_buffer )
        {
            i_used = p_block->i_buffer;
        }

        p_block->i_buffer -= i_used;
        p_block->p_buffer += i_used;

    } while( p_block->i_buffer > 0 && i_output <= 0 );

    if( p_sys->p_context->channels <= 0 || p_sys->p_context->channels > 8 ||
            p_sys->p_context->sample_rate <= 0 )
    {
        msg_Warn( p_dec, "invalid audio properties channels count %d, sample rate %d",
                  p_sys->p_context->channels, p_sys->p_context->sample_rate );
        block_Release( p_block );
        return NULL;
    }

    if( p_dec->fmt_out.audio.i_rate != (unsigned int)p_sys->p_context->sample_rate )
    {
        date_Init( &p_sys->end_date, p_sys->p_context->sample_rate, 1 );
        date_Set( &p_sys->end_date, p_block->i_pts );
    }

    /* **** Set audio output parameters **** */
    SetupOutputFormat( p_dec, true );

    if( p_block->i_pts != 0 &&
            p_block->i_pts != date_Get( &p_sys->end_date ) )
    {
        date_Set( &p_sys->end_date, p_block->i_pts );
    }
    p_block->i_pts = 0;

    /* **** Now we can output these samples **** */
    p_sys->i_samples = i_output / (p_dec->fmt_out.audio.i_bitspersample / 8) / p_sys->p_context->channels;
    p_sys->p_samples = p_sys->p_output;

    /* Silent unwanted samples */
    if( p_sys->i_reject_count > 0 )
    {
        memset( p_sys->p_output, 0, i_output );
        p_sys->i_reject_count--;
    }

    p_buffer = SplitBuffer( p_dec );
    if( !p_buffer ) block_Release( p_block );
    return p_buffer;
}
Ejemplo n.º 26
0
/*****************************************************************************
 * InitAudioDec: initialize audio decoder
 *****************************************************************************
 * The ffmpeg codec will be opened, some memory allocated.
 *****************************************************************************/
int InitAudioDec( decoder_t *p_dec, AVCodecContext *p_context,
                  AVCodec *p_codec, int i_codec_id, const char *psz_namecodec )
{
    decoder_sys_t *p_sys;

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
    {
        return VLC_ENOMEM;
    }

    p_codec->type = AVMEDIA_TYPE_AUDIO;
    p_context->codec_type = AVMEDIA_TYPE_AUDIO;
    p_context->codec_id = i_codec_id;
    p_sys->p_context = p_context;
    p_sys->p_codec = p_codec;
    p_sys->i_codec_id = i_codec_id;
    p_sys->psz_namecodec = psz_namecodec;
    p_sys->b_delayed_open = true;

    // Initialize decoder extradata
    InitDecoderConfig( p_dec, p_context);

    /* ***** Open the codec ***** */
    if( ffmpeg_OpenCodec( p_dec ) < 0 )
    {
        msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
        free( p_sys->p_context->extradata );
        free( p_sys );
        return VLC_EGENERIC;
    }

    switch( i_codec_id )
    {
    case CODEC_ID_WAVPACK:
        p_sys->i_output_max = 8 * sizeof(int32_t) * 131072;
        break;
    case CODEC_ID_TTA:
        p_sys->i_output_max = p_sys->p_context->channels * sizeof(int32_t) * p_sys->p_context->sample_rate * 2;
        break;
    case CODEC_ID_FLAC:
        p_sys->i_output_max = 8 * sizeof(int32_t) * 65535;
        break;
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 52, 35, 0 )
    case CODEC_ID_WMAPRO:
        p_sys->i_output_max = 8 * sizeof(float) * 6144; /* (1 << 12) * 3/2 */
        break;
#endif
    default:
        p_sys->i_output_max = 0;
        break;
    }
    if( p_sys->i_output_max < AVCODEC_MAX_AUDIO_FRAME_SIZE )
        p_sys->i_output_max = AVCODEC_MAX_AUDIO_FRAME_SIZE;
    msg_Dbg( p_dec, "Using %d bytes output buffer", p_sys->i_output_max );
    p_sys->p_output = av_malloc( p_sys->i_output_max );

    p_sys->p_samples = NULL;
    p_sys->i_samples = 0;
    p_sys->i_reject_count = 0;
    p_sys->b_extract = false;
    p_sys->i_previous_channels = 0;
    p_sys->i_previous_layout = 0;

    /* */
    p_dec->fmt_out.i_cat = AUDIO_ES;
    /* Try to set as much information as possible but do not trust it */
    SetupOutputFormat( p_dec, false );

    date_Set( &p_sys->end_date, 0 );
    if( p_dec->fmt_out.audio.i_rate )
        date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
    else if( p_dec->fmt_in.audio.i_rate )
        date_Init( &p_sys->end_date, p_dec->fmt_in.audio.i_rate, 1 );

    return VLC_SUCCESS;
}
Ejemplo n.º 27
0
Archivo: speex.c Proyecto: 0xheart0/vlc
static block_t *DecodeRtpSpeexPacket( decoder_t *p_dec, block_t **pp_block )
{
    block_t *p_speex_bit_block = *pp_block;
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_aout_buffer;
    int i_decode_ret;
    unsigned int i_speex_frame_size;

    if ( !p_speex_bit_block || p_speex_bit_block->i_pts <= VLC_TS_INVALID )
        return NULL;

    /*
      If the SpeexBits buffer size is 0 (a default value),
      we know that a proper initialization has not yet been done.
    */
    if ( p_sys->bits.buf_size==0 )
    {
        p_sys->p_header = malloc(sizeof(SpeexHeader));
        if ( !p_sys->p_header )
        {
            msg_Err( p_dec, "Could not allocate a Speex header.");
            return NULL;
        }

        const SpeexMode *mode = speex_lib_get_mode((p_sys->rtp_rate / 8000) >> 1);

        speex_init_header( p_sys->p_header,p_sys->rtp_rate, 1, mode );
        speex_bits_init( &p_sys->bits );
        p_sys->p_state = speex_decoder_init( mode );
        if ( !p_sys->p_state )
        {
            msg_Err( p_dec, "Could not allocate a Speex decoder." );
            free( p_sys->p_header );
            return NULL;
        }

        /*
          Assume that variable bit rate is enabled. Also assume
          that there is only one frame per packet.
        */
        p_sys->p_header->vbr = 1;
        p_sys->p_header->frames_per_packet = 1;

        p_dec->fmt_out.audio.i_channels = p_sys->p_header->nb_channels;
        p_dec->fmt_out.audio.i_physical_channels =
        p_dec->fmt_out.audio.i_original_channels =
            pi_channels_maps[p_sys->p_header->nb_channels];
        p_dec->fmt_out.audio.i_rate = p_sys->p_header->rate;

        if ( speex_mode_query( &speex_nb_mode,
                               SPEEX_MODE_FRAME_SIZE,
                               &i_speex_frame_size ) )
        {
            msg_Err( p_dec, "Could not determine the frame size." );
            speex_decoder_destroy( p_sys->p_state );
            free( p_sys->p_header );
            return NULL;
        }
        p_dec->fmt_out.audio.i_bytes_per_frame = i_speex_frame_size;

        date_Init(&p_sys->end_date, p_sys->p_header->rate, 1);
    }
Ejemplo n.º 28
0
Archivo: speex.c Proyecto: 0xheart0/vlc
/*****************************************************************************
 * ProcessInitialHeader: processes the inital Speex header packet.
 *****************************************************************************/
static int ProcessInitialHeader( decoder_t *p_dec, ogg_packet *p_oggpacket )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    void *p_state;
    SpeexHeader *p_header;
    const SpeexMode *p_mode;
    SpeexCallback callback;

    p_sys->p_header = p_header =
        speex_packet_to_header( (char *)p_oggpacket->packet,
                                p_oggpacket->bytes );
    if( !p_header )
    {
        msg_Err( p_dec, "cannot read Speex header" );
        return VLC_EGENERIC;
    }
    if( p_header->mode >= SPEEX_NB_MODES || p_header->mode < 0 )
    {
        msg_Err( p_dec, "mode number %d does not (yet/any longer) exist in "
                 "this version of libspeex.", p_header->mode );
        return VLC_EGENERIC;
    }

    p_mode = speex_mode_list[p_header->mode];
    if( p_mode == NULL )
        return VLC_EGENERIC;

    if( p_header->speex_version_id > 1 )
    {
        msg_Err( p_dec, "this file was encoded with Speex bit-stream "
                 "version %d which is not supported by this decoder.",
                 p_header->speex_version_id );
        return VLC_EGENERIC;
    }

    if( p_mode->bitstream_version < p_header->mode_bitstream_version )
    {
        msg_Err( p_dec, "file encoded with a newer version of Speex." );
        return VLC_EGENERIC;
    }
    if( p_mode->bitstream_version > p_header->mode_bitstream_version )
    {
        msg_Err( p_dec, "file encoded with an older version of Speex." );
        return VLC_EGENERIC;
    }

    msg_Dbg( p_dec, "Speex %d Hz audio using %s mode %s%s",
             p_header->rate, p_mode->modeName,
             ( p_header->nb_channels == 1 ) ? " (mono" : " (stereo",
             p_header->vbr ? ", VBR)" : ")" );

    /* Take care of speex decoder init */
    speex_bits_init( &p_sys->bits );
    p_sys->p_state = p_state = speex_decoder_init( p_mode );
    if( !p_state )
    {
        msg_Err( p_dec, "decoder initialization failed" );
        return VLC_EGENERIC;
    }

    if( p_header->nb_channels == 2 )
    {
        SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT;
        p_sys->stereo = stereo;
        callback.callback_id = SPEEX_INBAND_STEREO;
        callback.func = speex_std_stereo_request_handler;
        callback.data = &p_sys->stereo;
        speex_decoder_ctl( p_state, SPEEX_SET_HANDLER, &callback );
    }
    if( p_header->nb_channels <= 0 ||
        p_header->nb_channels > 5 )
    {
        msg_Err( p_dec, "invalid number of channels (not between 1 and 5): %i",
                 p_header->nb_channels );
        return VLC_EGENERIC;
    }

    /* Setup the format */
    p_dec->fmt_out.audio.i_physical_channels =
        p_dec->fmt_out.audio.i_original_channels =
            pi_channels_maps[p_header->nb_channels];
    p_dec->fmt_out.audio.i_channels = p_header->nb_channels;
    p_dec->fmt_out.audio.i_rate = p_header->rate;

    date_Init( &p_sys->end_date, p_header->rate, 1 );

    return VLC_SUCCESS;
}
Ejemplo n.º 29
0
static int Open (vlc_object_t *p_this)
{
    decoder_t *p_dec = (decoder_t *)p_this;

    if (p_dec->fmt_in.i_codec != VLC_CODEC_MIDI)
        return VLC_EGENERIC;

    decoder_sys_t *p_sys = (decoder_sys_t *)malloc (sizeof (*p_sys));			// sunqueen modify
    if (unlikely(p_sys == NULL))
        return VLC_ENOMEM;

    p_sys->settings = new_fluid_settings ();
    p_sys->synth = new_fluid_synth (p_sys->settings);
    p_sys->soundfont = -1;

    char *font_path = var_InheritString (p_this, "soundfont");
    if (font_path != NULL)
    {
        msg_Dbg (p_this, "loading sound fonts file %s", font_path);
        p_sys->soundfont = fluid_synth_sfload (p_sys->synth, font_path, 1);
        if (p_sys->soundfont == -1)
            msg_Err (p_this, "cannot load sound fonts file %s", font_path);
        free (font_path);
    }
#ifdef _POSIX_VERSION
    else
    {
        glob_t gl;

        glob ("/usr/share/sounds/sf2/*.sf2", GLOB_NOESCAPE, NULL, &gl);
        for (size_t i = 0; i < gl.gl_pathc; i++)
        {
            const char *path = gl.gl_pathv[i];

            msg_Dbg (p_this, "loading sound fonts file %s", path);
            p_sys->soundfont = fluid_synth_sfload (p_sys->synth, path, 1);
            if (p_sys->soundfont != -1)
                break; /* it worked! */
            msg_Err (p_this, "cannot load sound fonts file %s", path);
        }
        globfree (&gl);
    }
#endif

    if (p_sys->soundfont == -1)
    {
        msg_Err (p_this, "sound font file required for synthesis");
        dialog_Fatal (p_this, _("MIDI synthesis not set up"),
            _("A sound font file (.SF2) is required for MIDI synthesis.\n"
              "Please install a sound font and configure it "
              "from the VLC preferences "
              "(Input / Codecs > Audio codecs > FluidSynth).\n"));
        delete_fluid_synth (p_sys->synth);
        delete_fluid_settings (p_sys->settings);
        free (p_sys);
        return VLC_EGENERIC;
    }

    fluid_synth_set_chorus_on (p_sys->synth,
                               var_InheritBool (p_this, "synth-chorus"));
    fluid_synth_set_gain (p_sys->synth,
                          var_InheritFloat (p_this, "synth-gain"));
    fluid_synth_set_polyphony (p_sys->synth,
                               var_InheritInteger (p_this, "synth-polyphony"));
    fluid_synth_set_reverb_on (p_sys->synth,
                               var_InheritBool (p_this, "synth-reverb"));

    p_dec->fmt_out.i_cat = AUDIO_ES;
    p_dec->fmt_out.audio.i_rate =
        var_InheritInteger (p_this, "synth-sample-rate");;
    fluid_synth_set_sample_rate (p_sys->synth, p_dec->fmt_out.audio.i_rate);
    p_dec->fmt_out.audio.i_channels = 2;
    p_dec->fmt_out.audio.i_original_channels =
    p_dec->fmt_out.audio.i_physical_channels =
        AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
    p_dec->fmt_out.i_codec = VLC_CODEC_FL32;
    p_dec->fmt_out.audio.i_bitspersample = 32;
    date_Init (&p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1);
    date_Set (&p_sys->end_date, 0);

    p_dec->p_sys = p_sys;
    p_dec->pf_decode_audio = DecodeBlock;
    return VLC_SUCCESS;
}
Ejemplo n.º 30
0
/*****************************************************************************
 * ProcessHeaders: process Vorbis headers.
 *****************************************************************************/
static int ProcessHeaders( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    ogg_packet oggpacket;

    unsigned pi_size[XIPH_MAX_HEADER_COUNT];
    void *pp_data[XIPH_MAX_HEADER_COUNT];
    unsigned i_count;
    if( xiph_SplitHeaders( pi_size, pp_data, &i_count,
                           p_dec->fmt_in.i_extra, p_dec->fmt_in.p_extra) )
        return VLC_EGENERIC;
    if( i_count < 3 )
        return VLC_EGENERIC;

    oggpacket.granulepos = -1;
    oggpacket.e_o_s = 0;
    oggpacket.packetno = 0;

    /* Take care of the initial Vorbis header */
    oggpacket.b_o_s  = 1; /* yes this actually is a b_o_s packet :) */
    oggpacket.bytes  = pi_size[0];
    oggpacket.packet = pp_data[0];
    if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, &oggpacket ) < 0 )
    {
        msg_Err( p_dec, "this bitstream does not contain Vorbis audio data");
        return VLC_EGENERIC;
    }

    /* Setup the format */
    p_dec->fmt_out.audio.i_rate     = p_sys->vi.rate;
    p_dec->fmt_out.audio.i_channels = p_sys->vi.channels;

    if( p_dec->fmt_out.audio.i_channels >= ARRAY_SIZE(pi_channels_maps) )
    {
        msg_Err( p_dec, "invalid number of channels (1-%zu): %i",
                 ARRAY_SIZE(pi_channels_maps),
                 p_dec->fmt_out.audio.i_channels );
        return VLC_EGENERIC;
    }

    p_dec->fmt_out.audio.i_physical_channels =
        p_dec->fmt_out.audio.i_original_channels =
            pi_channels_maps[p_sys->vi.channels];
    p_dec->fmt_out.i_bitrate = __MAX( 0, (int32_t) p_sys->vi.bitrate_nominal );

    date_Init( &p_sys->end_date, p_sys->vi.rate, 1 );

    msg_Dbg( p_dec, "channels:%d samplerate:%ld bitrate:%ud",
             p_sys->vi.channels, p_sys->vi.rate, p_dec->fmt_out.i_bitrate );

    /* The next packet in order is the comments header */
    oggpacket.b_o_s  = 0;
    oggpacket.bytes  = pi_size[1];
    oggpacket.packet = pp_data[1];
    if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, &oggpacket ) < 0 )
    {
        msg_Err( p_dec, "2nd Vorbis header is corrupted" );
        return VLC_EGENERIC;
    }
    ParseVorbisComments( p_dec );

    /* The next packet in order is the codebooks header
     * We need to watch out that this packet is not missing as a
     * missing or corrupted header is fatal. */
    oggpacket.b_o_s  = 0;
    oggpacket.bytes  = pi_size[2];
    oggpacket.packet = pp_data[2];
    if( vorbis_synthesis_headerin( &p_sys->vi, &p_sys->vc, &oggpacket ) < 0 )
    {
        msg_Err( p_dec, "3rd Vorbis header is corrupted" );
        return VLC_EGENERIC;
    }

    if( !p_sys->b_packetizer )
    {
        /* Initialize the Vorbis packet->PCM decoder */
        vorbis_synthesis_init( &p_sys->vd, &p_sys->vi );
        vorbis_block_init( &p_sys->vd, &p_sys->vb );
    }
    else
    {
        p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
        p_dec->fmt_out.p_extra = xrealloc( p_dec->fmt_out.p_extra,
                                           p_dec->fmt_out.i_extra );
        memcpy( p_dec->fmt_out.p_extra,
                p_dec->fmt_in.p_extra, p_dec->fmt_out.i_extra );
    }

    ConfigureChannelOrder(p_sys->pi_chan_table, p_sys->vi.channels,
                          p_dec->fmt_out.audio.i_physical_channels, true);

    return VLC_SUCCESS;
}