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

📄 access.c

📁 vlc源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * access.c : CD digital audio input module for vlc using libcdio ***************************************************************************** * Copyright (C) 2000, 2003, 2004, 2005 the VideoLAN team * $Id$ * * Authors: Rocky Bernstein <rocky@panix.com> *          Laurent Aimar <fenrir@via.ecp.fr> *          Gildas Bazin <gbazin@netcourrier.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include "callback.h"      /* FIXME - reorganize callback.h, cdda.h better */#include "cdda.h"          /* private structures. Also #includes vlc things */#include "info.h"          /* headers for meta info retrieval */#include "access.h"#include "vlc_keys.h"#include <vlc_interface.h>#include <cdio/cdio.h>#include <cdio/logging.h>#include <cdio/cd_types.h>/* #ifdef variables below are defined via config.h via #include vlc above. */#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#ifdef HAVE_UNISTD_H#   include <unistd.h>#endif/* FIXME: This variable is a hack. Would be nice to eliminate. */access_t *p_cdda_input = NULL;/***************************************************************************** * Local prototypes *****************************************************************************/static ssize_t  CDDARead( access_t *, uint8_t *, size_t );static block_t *CDDAReadBlocks( access_t * p_access );static int      CDDASeek( access_t * p_access, int64_t i_pos );static int      CDDAControl( access_t *p_access, int i_query,                             va_list args );static int      CDDAInit( access_t *p_access, cdda_data_t *p_cdda ) ;/**************************************************************************** * Private functions ****************************************************************************//* process messages that originate from libcdio.   called by CDDAOpen*/static voidcdio_log_handler( cdio_log_level_t level, const char message[] ){    cdda_data_t *p_cdda = (cdda_data_t *)p_cdda_input->p_sys;    if( p_cdda == NULL )        return;    switch( level )    {        case CDIO_LOG_DEBUG:        case CDIO_LOG_INFO:            if (p_cdda->i_debug & INPUT_DBG_CDIO)            msg_Dbg( p_cdda_input, "%s", message);            break;        case CDIO_LOG_WARN:            msg_Warn( p_cdda_input, "%s", message);            break;        case CDIO_LOG_ERROR:        case CDIO_LOG_ASSERT:            msg_Err( p_cdda_input, "%s", message);            break;        default:            msg_Warn( p_cdda_input, "%s\n%s %d", message,                    "the above message had unknown cdio log level",                    level);            break;    }}#ifdef HAVE_LIBCDDB/*! This routine is called by libcddb routines on error.   called by CDDAOpen*/static voidcddb_log_handler( cddb_log_level_t level, const char message[] ){    cdda_data_t *p_cdda = (cdda_data_t *)p_cdda_input->p_sys;    switch( level )    {        case CDDB_LOG_DEBUG:        case CDDB_LOG_INFO:            if( !(p_cdda->i_debug & INPUT_DBG_CDDB) )                return;        /* Fall through if to warn case */        default:            cdio_log_handler( level, message );            break;    }}#endif /*HAVE_LIBCDDB*//*! This routine is when vlc is not fully set up (before full initialization)  or is not around (before finalization).*/static voiduninit_log_handler( cdio_log_level_t level, const char message[] ){    cdda_data_t *p_cdda = NULL;    if( p_cdda_input )        p_cdda = (cdda_data_t *)p_cdda_input->p_sys;     switch( level )     {        case CDIO_LOG_DEBUG:        case CDIO_LOG_INFO:            if( !p_cdda || !(p_cdda->i_debug & (INPUT_DBG_CDIO|INPUT_DBG_CDDB)) )                return;        /* Fall through if to warn case */        case CDIO_LOG_WARN:            fprintf( stderr, "WARN: %s\n", message );            break;        case CDIO_LOG_ERROR:            fprintf( stderr, "ERROR: %s\n", message );            break;        case CDIO_LOG_ASSERT:            fprintf( stderr, "ASSERT ERROR: %s\n", message );            break;        default:            fprintf( stderr, "UNKNOWN ERROR: %s\n%s %d\n", message,                            "The above message had unknown cdio log level",                            level );        break;    }    /* gl_default_cdio_log_handler (level, message); */}/* Only used in audio control mode. Gets the current LSN from the   CD-ROM drive. */static int64_t get_audio_position ( access_t *p_access ){    cdda_data_t *p_cdda   = (cdda_data_t *) p_access->p_sys;    lsn_t i_offset;#if LIBCDIO_VERSION_NUM >= 73    if( p_cdda->b_audio_ctl )    {        cdio_subchannel_t sub;        CdIo_t *p_cdio = p_cdda->p_cdio;        if( DRIVER_OP_SUCCESS == cdio_audio_read_subchannel(p_cdio, &sub) )        {            if( (sub.audio_status != CDIO_MMC_READ_SUB_ST_PAUSED) &&                (sub.audio_status != CDIO_MMC_READ_SUB_ST_PLAY) )                return CDIO_INVALID_LSN;            if( ! p_cdda->b_nav_mode )            {                i_offset = cdio_msf_to_lba( (&sub.abs_addr) );            }            else            {                i_offset = cdio_msf_to_lba( (&sub.rel_addr) );            }        }        else        {            i_offset = p_cdda->i_lsn;        }    }    else    {        i_offset = p_cdda->i_lsn;    }#else        i_offset = p_cdda->i_lsn;#endif    return i_offset;}/***************************************************************************** * CDDAReadBlocks: reads a group of blocks from the CD-DA and returns * an allocated pointer to the data. NULL is returned if no data * read. It is also possible if we haven't read a RIFF header in which * case one that we creaded during Open/Initialization is returned. *****************************************************************************/static block_t * CDDAReadBlocks( access_t * p_access ){    block_t     *p_block;    cdda_data_t *p_cdda   = (cdda_data_t *) p_access->p_sys;    int          i_blocks = p_cdda->i_blocks_per_read;    dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_LSN),                "called i_lsn: %d i_pos: %lld, size: %lld",                p_cdda->i_lsn, p_access->info.i_pos, p_access->info.i_size );    /* Check end of file */    if( p_access->info.b_eof )        return NULL;    if( !p_cdda->b_header )      {        /* Return only the dummy RIFF header we created in Open/Init */        p_block = block_New( p_access, sizeof( WAVEHEADER ) );        memcpy( p_block->p_buffer, &p_cdda->waveheader, sizeof(WAVEHEADER) );        p_cdda->b_header = true;        return p_block;    }    /* Check end of track */    while( p_cdda->i_lsn > cdio_get_track_last_lsn(p_cdda->p_cdio,           p_cdda->i_track) )    {        bool go_on;        if( p_cdda->b_nav_mode )            go_on = p_cdda->i_lsn > p_cdda->last_disc_frame;        else            go_on = p_cdda->i_track >= p_cdda->i_first_track+p_cdda->i_titles-1 ;        if( go_on )        {            dbg_print( (INPUT_DBG_LSN), "EOF");                        p_access->info.b_eof = true;            return NULL;        }        p_access->info.i_update |= INPUT_UPDATE_TITLE | INPUT_UPDATE_META;        p_access->info.i_title++;        p_cdda->i_track++;        if( p_cdda-> b_nav_mode )        {            char *psz_title = CDDAFormatTitle( p_access, p_cdda->i_track );            input_Control( p_cdda->p_input, INPUT_SET_NAME, psz_title );            free(psz_title);        }        else        {            p_access->info.i_size =                    p_cdda->p_title[p_access->info.i_title]->i_size;            p_access->info.i_pos = 0;            p_access->info.i_update |= INPUT_UPDATE_SIZE;        }    }    /* Possibly adjust i_blocks so we don't read past the end of a track. */    if( p_cdda->i_lsn + i_blocks >=        cdio_get_track_lsn(p_cdda->p_cdio, p_cdda->i_track+1) )    {        i_blocks = cdio_get_track_lsn( p_cdda->p_cdio, p_cdda->i_track+1 )                    - p_cdda->i_lsn;    }    /* Do the actual reading */    p_block = block_New( p_access, i_blocks * CDIO_CD_FRAMESIZE_RAW );    if( !p_block)    {        msg_Err( p_access, "cannot get a new block of size: %i",                i_blocks * CDIO_CD_FRAMESIZE_RAW );        intf_UserFatal( p_access, false, _("CD reading failed"),                        _("VLC could not get a new block of size: %i."),                        i_blocks * CDIO_CD_FRAMESIZE_RAW );        return NULL;    }    {#if LIBCDIO_VERSION_NUM >= 72        driver_return_code_t rc = DRIVER_OP_SUCCESS;        if( p_cdda->e_paranoia && p_cdda->paranoia )        {            int i;            for( i = 0; i < i_blocks; i++ )            {                int16_t *p_readbuf = cdio_paranoia_read( p_cdda->paranoia, NULL );                char *psz_err = cdio_cddap_errors( p_cdda->paranoia_cd );                char *psz_mes = cdio_cddap_messages( p_cdda->paranoia_cd );                if( psz_mes || psz_err )                    msg_Err( p_access, "%s%s\n", psz_mes ? psz_mes: "",                             psz_err ? psz_err: "" );                free( psz_err );                free( psz_mes );                if( !p_readbuf )                {                    msg_Err( p_access, "paranoia read error on frame %i\n",                    p_cdda->i_lsn+i );                }                else                    memcpy( p_block->p_buffer + i * CDIO_CD_FRAMESIZE_RAW,                            p_readbuf, CDIO_CD_FRAMESIZE_RAW );            }        }        else        {            rc = cdio_read_audio_sectors( p_cdda->p_cdio, p_block->p_buffer,                                          p_cdda->i_lsn, i_blocks );#else#define DRIVER_OP_SUCCESS 0            int rc;            rc = cdio_read_audio_sectors( p_cdda->p_cdio, p_block->p_buffer,                                          p_cdda->i_lsn, i_blocks);#endif        }        if( rc != DRIVER_OP_SUCCESS )        {            msg_Err( p_access, "could not read %d sectors starting from %lu",                     i_blocks, (long unsigned int) p_cdda->i_lsn );            block_Release( p_block );            /* If we had problems above, assume the problem is with                the first sector of the read and set to skip it.  In                the future libcdio may have cdparanoia support.            */            p_cdda->i_lsn++;            p_access->info.i_pos += CDIO_CD_FRAMESIZE_RAW;            return NULL;        }    }    p_cdda->i_lsn        += i_blocks;    p_access->info.i_pos += i_blocks * CDIO_CD_FRAMESIZE_RAW;    return p_block;}/***************************************************************************** * CDDARead: Handler for audio control reads the CD-DA. *****************************************************************************/static ssize_tCDDARead( access_t * p_access, uint8_t *p_buffer, size_t i_len ){    cdda_data_t *p_cdda   = (cdda_data_t *) p_access->p_sys;    dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_LSN),               "called lsn: %d pos: %lld, size: %lld",                p_cdda->i_lsn, p_access->info.i_pos, p_access->info.i_size);    /* Check end of file */    if( p_access->info.b_eof )        return 0;

⌨️ 快捷键说明

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