⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jack.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
}/***************************************************************************** * Close: Disconnect from jack server and release associated resources *****************************************************************************/static void Close( vlc_object_t *p_this ){    demux_t    *p_demux = ( demux_t* )p_this;    demux_sys_t    *p_sys = p_demux->p_sys;    msg_Dbg( p_demux,"Module unloaded" );    if( p_sys->p_block_audio ) block_Release( p_sys->p_block_audio );    if( p_sys->p_jack_client ) jack_client_close( p_sys->p_jack_client );    if( p_sys->p_jack_ringbuffer ) jack_ringbuffer_free( p_sys->p_jack_ringbuffer );    free( p_sys->pp_jack_port_input );    free( p_sys->pp_jack_buffer );    free( p_sys->pp_jack_port_table );    free( p_sys );}/***************************************************************************** * Control *****************************************************************************/static int Control( demux_t *p_demux, int i_query, va_list args ){    bool  *pb;    int64_t     *pi64;    demux_sys_t *p_sys = p_demux->p_sys;    switch( i_query )    {    /* Special for access_demux */    case DEMUX_CAN_PAUSE:    case DEMUX_CAN_SEEK:        pb = (bool *)va_arg( args, bool * );        *pb = true;        return VLC_SUCCESS;    case DEMUX_SET_PAUSE_STATE:        return VLC_SUCCESS;    case DEMUX_CAN_CONTROL_PACE:        pb = ( bool* )va_arg( args, bool * );        *pb = var_GetBool( p_demux, "jack-input-use-vlc-pace" );        return VLC_SUCCESS;    case DEMUX_GET_PTS_DELAY:        pi64 = ( int64_t* )va_arg( args, int64_t * );        *pi64 = ( int64_t )var_GetInteger( p_demux, "jack-input-caching" )            * 1000;        return VLC_SUCCESS;    case DEMUX_GET_TIME:        pi64 = ( int64_t* )va_arg( args, int64_t * );        *pi64 =  date_Get(&p_sys->pts);            return VLC_SUCCESS;    /* TODO implement others */    default:        return VLC_EGENERIC;    }    return VLC_EGENERIC;}/***************************************************************************** * Demux *****************************************************************************/static int Demux( demux_t *p_demux ){    demux_sys_t *p_sys;    es_out_id_t  *p_es;    block_t *p_block;    p_sys = p_demux->p_sys;    p_es = p_sys->p_es_audio;    p_block = GrabJack( p_demux );    if( p_block )    {        es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );        es_out_Send( p_demux->out, p_es, p_block );    }    return 1;}/***************************************************************************** * Process Callback : fill ringbuffer with Jack audio data *****************************************************************************/int Process( jack_nframes_t i_frames, void *p_arg ){    demux_t            *p_demux = ( demux_t* )p_arg;    demux_sys_t        *p_sys = p_demux->p_sys;    unsigned int        i, j;    size_t              i_write;     /* Get and interlace buffers */    for ( i = 0; i < p_sys->i_channels ; i++ )    {        p_sys->pp_jack_buffer[i] = jack_port_get_buffer(            p_sys->pp_jack_port_input[i], i_frames );    }    /* fill ring buffer with signal */    for( j = 0; j < i_frames; j++ )    {        for( i = 0; i <p_sys->i_channels; i++ )        {            if( jack_ringbuffer_write_space( p_sys->p_jack_ringbuffer ) <                p_sys->jack_sample_size ) {                msg_Err( p_demux, "buffer overflow");                return 0; // buffer overflow            }            i_write = jack_ringbuffer_write( p_sys->p_jack_ringbuffer,                                             ( char * ) (p_sys->pp_jack_buffer[i]+j),                                             p_sys->jack_sample_size );            if (i_write != p_sys->jack_sample_size ) {                msg_Warn( p_demux, "error writing on ring buffer");            }        }    }    return 1;}/***************************************************************************** * GrabJack: grab audio data in the Jack buffer *****************************************************************************/static block_t *GrabJack( demux_t *p_demux ){    size_t      i_read;    demux_sys_t *p_sys = p_demux->p_sys;    block_t     *p_block;    /* read signal from ring buffer */    i_read = jack_ringbuffer_read_space( p_sys->p_jack_ringbuffer );    if( i_read < 100 ) /* avoid small read */    {   /* vlc has too much free time on its hands? */        msleep(1000);        return NULL;    }    if( p_sys->p_block_audio )    {        p_block = p_sys->p_block_audio;    }    else    {        p_block = block_New( p_demux, i_read );    }    if( !p_block )    {        msg_Warn( p_demux, "cannot get block" );        return 0;    }     //Find the previous power of 2, this algo assumes size_t has the same size on all arch    i_read >>= 1;    i_read--;    i_read |= i_read >> 1;    i_read |= i_read >> 2;    i_read |= i_read >> 4;    i_read |= i_read >> 8;    i_read |= i_read >> 16;    i_read++;     i_read = jack_ringbuffer_read( p_sys->p_jack_ringbuffer, ( char * ) p_block->p_buffer, i_read );     p_block->i_dts = p_block->i_pts =    date_Increment( &p_sys->pts,         i_read/(p_sys->i_channels * p_sys->jack_sample_size) );    p_sys->p_block_audio = p_block;    p_block->i_buffer = i_read;    p_sys->p_block_audio = 0;     return p_block;}/***************************************************************************** * Port_finder: compare ports with the regexp entered *****************************************************************************/static void Port_finder( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    char *psz_expr = p_sys->psz_ports;    char *token = NULL;    char *state = NULL;    char *psz_uri = NULL;    const char **pp_jack_port_output = NULL;    int i_out_ports = 0;    int i_total_out_ports =0;    p_sys->pp_jack_port_table = NULL;    /* parse the ports part of the MRL */    for( token = strtok_r( psz_expr, ",", &state ); token;            token = strtok_r( NULL, ",", &state ) )    {        psz_uri = decode_URI_duplicate( token );        /* get the ports which match the regexp */        pp_jack_port_output = jack_get_ports( p_sys->p_jack_client,           psz_uri, NULL, JackPortIsOutput );        if( pp_jack_port_output == NULL )        {            msg_Err( p_demux, "port(s) asked not found:%s", psz_uri );            free( pp_jack_port_output );        }        else        {            while( pp_jack_port_output && pp_jack_port_output[i_out_ports] )            {                i_out_ports++;            }            /* alloc an array to store all the matched ports */            p_sys->pp_jack_port_table = realloc( p_sys->pp_jack_port_table,                (i_out_ports * sizeof( char * ) + i_total_out_ports * sizeof( char * ) ) );            for(int i=0; i<i_out_ports;i++)            {                p_sys->pp_jack_port_table[i_total_out_ports+i] = ( char * ) pp_jack_port_output[i];            }            i_total_out_ports += i_out_ports;        }    }    free( pp_jack_port_output );    p_sys->i_match_ports = i_total_out_ports;}/***************************************************************************** * Parse: Parse the MRL *****************************************************************************/static void Parse( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    char *psz_dup = strdup( p_demux->psz_path );    char *psz_parser = psz_dup;    if( !strncmp( psz_parser, "channels=", strlen( "channels=" ) ) )    {        p_sys->i_channels = abs( strtol( psz_parser + strlen( "channels=" ),            &psz_parser, 0 ) );    }    else if( !strncmp( psz_parser, "ports=", strlen( "ports=" ) ) )    {        int i_len;        psz_parser += strlen( "ports=" );        if( strchr( psz_parser, ':' ) )        {            i_len = strchr( psz_parser, ':' ) - psz_parser;        }        else        {            i_len = strlen( psz_parser );        }        p_sys->psz_ports = strndup( psz_parser, i_len );        psz_parser += i_len;    }    else    {        msg_Warn( p_demux, "unknown option" );    }    while( *psz_parser && *psz_parser != ':' )    {        psz_parser++;    }    if( *psz_parser == ':' )    {        for( ;; )        {            *psz_parser++ = '\0';            if( !strncmp( psz_parser, "channels=", strlen( "channels=" ) ) )            {                p_sys->i_channels = abs( strtol(                    psz_parser + strlen( "channels=" ), &psz_parser, 0 ) );            }            else if( !strncmp( psz_parser, "ports=", strlen( "ports=" ) ) )            {                int i_len;                psz_parser += strlen( "ports=" );                if( strchr( psz_parser, ':' ) )                {                    i_len = strchr( psz_parser, ':' ) - psz_parser;                }                else                {                    i_len = strlen( psz_parser );                }                p_sys->psz_ports = strndup( psz_parser, i_len );                psz_parser += i_len;            }            else            {                msg_Warn( p_demux, "unknown option" );            }            while( *psz_parser && *psz_parser != ':' )            {                psz_parser++;            }            if( *psz_parser == '\0' )            {                break;            }        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -