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

📄 access.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * access.c : CD digital audio input module for vlc using libcdio ***************************************************************************** * Copyright (C) 2000, 2003, 2004, 2005 VideoLAN * $Id: access.c 10862 2005-05-01 14:48:08Z rocky $ * * 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., 59 Temple Place - Suite 330, Boston, MA  02111, 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 <vlc_playlist.h>  /* Has to come *after* cdda.h */#include "vlc_keys.h"#include <cdio/cdio.h>#include <cdio/logging.h>#include <cdio/cd_types.h>#include <stdio.h>/* #ifdef variables below are defined via config.h via #include vlc above. */#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#ifdef HAVE_STRING_H#include <string.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 int      CDDARead( access_t *, uint8_t *, int );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, message);    break;  case CDIO_LOG_WARN:    msg_Warn( p_cdda_input, message);    break;  case CDIO_LOG_ERROR:  case CDIO_LOG_ASSERT:    msg_Err( p_cdda_input, message);    break;  default:    msg_Warn( p_cdda_input, message,            "The above message had unknown cdio log level",            level);  }  return;}#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);    }}#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);    }    /* gl_default_cdio_log_handler (level, message); */}/* Only used in audio control mode. Gets the current LSN from the    CD-ROM drive. */static int64_tget_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 ) {	    // char *psz = cdio_msf_to_str(&sub.abs_addr);	    // fprintf(stderr, "+++disk mode abs msf %s", psz);	    // free(psz);	    i_offset = cdio_msf_to_lba((&sub.abs_addr));	    // fprintf(stderr, " frame offset %d\n", i_offset);	  } else {	    // char *psz = cdio_msf_to_str(&sub.rel_addr);	    // fprintf(stderr, "+++track abs msf %s", psz);	    // free(psz);	    i_offset = cdio_msf_to_lba((&sub.rel_addr));	    // fprintf(stderr, " frame offset %d\n", i_offset);	  }	} else {	  // fprintf(stderr, "+++Error reading current pos\n");	  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 = VLC_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 = VLC_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 );      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: "" );	      	      if (psz_err) free(psz_err);	      if (psz_mes) 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 intCDDARead( access_t * p_access, uint8_t *p_buffer, int 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 + -