📄 access.c
字号:
{ lsn_t i_lsn = get_audio_position(p_access); if( CDIO_INVALID_LSN == i_lsn ) { dbg_print( (INPUT_DBG_LSN), "invalid lsn" ); memset( p_buffer, 0, i_len ); return i_len; } p_cdda->i_lsn = i_lsn; p_access->info.i_pos = p_cdda->i_lsn * CDIO_CD_FRAMESIZE_RAW; } dbg_print( (INPUT_DBG_LSN), "updated lsn: %d", p_cdda->i_lsn ); /* Check end of track */ while( p_cdda->i_lsn > cdio_get_track_last_lsn( p_cdda->p_cdio, p_cdda->i_track) ) { if( p_cdda->i_track >= p_cdda->i_first_track + p_cdda->i_titles - 1 ) { dbg_print( (INPUT_DBG_LSN), "EOF"); p_access->info.b_eof = true; return 0; } p_access->info.i_update |= INPUT_UPDATE_TITLE; 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; } } memset( p_buffer, 0, i_len ); return i_len;}/*! Pause CD playing via audio control */static bool cdda_audio_pause( CdIo_t *p_cdio ){ bool b_ok = true;#if LIBCDIO_VERSION_NUM >= 73 cdio_subchannel_t sub; if( DRIVER_OP_SUCCESS == cdio_audio_read_subchannel( p_cdio, &sub ) ) { if( sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY ) { b_ok = DRIVER_OP_SUCCESS == cdio_audio_pause(p_cdio); } } else b_ok = false;#endif return b_ok;}#if LIBCDIO_VERSION_NUM >= 73/*! play CD using audio controls */static driver_return_code_tcdda_audio_play( CdIo_t *p_cdio, lsn_t start_lsn, lsn_t end_lsn ){ msf_t start_msf; msf_t last_msf; cdio_lsn_to_msf( start_lsn, &start_msf ); cdio_lsn_to_msf( end_lsn, &last_msf ); cdda_audio_pause( p_cdio ); return cdio_audio_play_msf( p_cdio, &start_msf, &last_msf );}#endif/**************************************************************************** * CDDASeek - change position for subsequent reads. For example, this * can happen if the user moves a position slider bar in a GUI. ****************************************************************************/static int CDDASeek( access_t * p_access, int64_t i_pos ){ cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys; dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_SEEK), "lsn %lu, offset: %lld", (long unsigned int) p_cdda->i_lsn, i_pos ); p_cdda->i_lsn = (i_pos / CDIO_CD_FRAMESIZE_RAW);#if LIBCDIO_VERSION_NUM >= 72 if( p_cdda->e_paranoia && p_cdda->paranoia ) cdio_paranoia_seek( p_cdda->paranoia, p_cdda->i_lsn, SEEK_SET );#endif#if LIBCDIO_VERSION_NUM >= 73 if( p_cdda->b_audio_ctl ) { track_t i_track = cdio_get_track( p_cdda->p_cdio, p_cdda->i_lsn ); lsn_t i_last_lsn; if( p_cdda->b_nav_mode ) i_last_lsn = p_cdda->last_disc_frame; else i_last_lsn = cdio_get_track_last_lsn( p_cdda->p_cdio, i_track ); cdda_audio_play( p_cdda->p_cdio, p_cdda->i_lsn, i_last_lsn ); }#endif if( ! p_cdda->b_nav_mode ) p_cdda->i_lsn += cdio_get_track_lsn( p_cdda->p_cdio, p_cdda->i_track ); /* Seeked backwards and we are doing disc mode. */ if( p_cdda->b_nav_mode && p_access->info.i_pos > i_pos ) { track_t i_track; char *psz_title; for( i_track = p_cdda->i_track; i_track > 1 && p_cdda->i_lsn < cdio_get_track_lsn( p_cdda->p_cdio, i_track ); i_track--, p_access->info.i_title-- ) ; p_cdda->i_track = i_track; p_access->info.i_update |= INPUT_UPDATE_TITLE | INPUT_UPDATE_META ; psz_title = CDDAFormatTitle( p_access, p_cdda->i_track ); input_Control( p_cdda->p_input, INPUT_SET_NAME, psz_title ); free( psz_title ); } p_access->info.i_pos = i_pos; p_access->info.b_eof = false; return VLC_SUCCESS;}/* Set up internal state so that we play a given track. If we are using audio-ctl mode we also activate CD-ROM to play. */static bool cdda_play_track( access_t *p_access, track_t i_track ){ cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys; dbg_print( (INPUT_DBG_CALL), "called track: %d\n", i_track ); if( i_track > p_cdda->i_tracks ) { msg_Err( p_access, "CD has %d tracks, and you requested track %d", p_cdda->i_tracks, i_track ); return false; } p_cdda->i_track = i_track; /* set up the frame boundaries for this particular track */ p_cdda->first_frame = p_cdda->i_lsn = cdio_get_track_lsn( p_cdda->p_cdio, i_track ); p_cdda->last_frame = cdio_get_track_lsn( p_cdda->p_cdio, i_track+1 ) - 1;#if LIBCDIO_VERSION_NUM >= 73 if( p_cdda->b_audio_ctl ) { lsn_t i_last_lsn; if( p_cdda->b_nav_mode ) i_last_lsn = p_cdda->last_disc_frame; else i_last_lsn = cdio_get_track_last_lsn( p_cdda->p_cdio, i_track ); cdda_audio_play( p_cdda->p_cdio, p_cdda->i_lsn, i_last_lsn ); }#endif return true;}/**************************************************************************** * Public functions ****************************************************************************//***************************************************************************** * Open: open cdda device or image file and initialize structures * for subsequent operations. *****************************************************************************/int CDDAOpen( vlc_object_t *p_this ){ access_t *p_access = (access_t*)p_this; char * psz_source = NULL; cdda_data_t *p_cdda = NULL; CdIo_t *p_cdio; track_t i_track = 1; bool b_single_track = false; int i_rc = VLC_EGENERIC; p_access->p_sys = NULL; /* Set where to log errors messages from libcdio. */ p_cdda_input = p_access; /* parse the options passed in command line : */ if( p_access->psz_path && *p_access->psz_path ) { char *psz_parser = psz_source = strdup( p_access->psz_path ); while( *psz_parser && *psz_parser != '@' ) { psz_parser++; } if( *psz_parser == '@' ) { /* Found options */ *psz_parser = '\0'; ++psz_parser; if ('T' == *psz_parser || 't' == *psz_parser ) ++psz_parser; i_track = (int)strtol( psz_parser, NULL, 10 ); i_track = i_track ? i_track : 1; b_single_track = true; } } if( !psz_source || !*psz_source ) { free( psz_source ); /* No device/track given. Continue only when this plugin was selected */ if( !p_this->b_force ) return VLC_EGENERIC; psz_source = var_CreateGetString( p_this, "cd-audio" ); if( !psz_source || !*psz_source ) { free( psz_source ); /* Scan for a CD-ROM drive with a CD-DA in it. */ char **ppsz_drives = cdio_get_devices_with_cap( NULL, CDIO_FS_AUDIO, false ); if( (NULL == ppsz_drives) || (NULL == ppsz_drives[0]) ) { msg_Err( p_access, "libcdio couldn't find something with a CD-DA in it" ); if( ppsz_drives ) cdio_free_device_list( ppsz_drives ); return VLC_EGENERIC; } psz_source = strdup( ppsz_drives[0] ); cdio_free_device_list( ppsz_drives ); } } cdio_log_set_handler( cdio_log_handler ); /* Open CDDA */ if( !(p_cdio = cdio_open( psz_source, DRIVER_UNKNOWN )) ) { msg_Warn( p_access, "could not open %s", psz_source ); free( psz_source ); return VLC_EGENERIC; } p_cdda = calloc( 1, sizeof(cdda_data_t) ); if( p_cdda == NULL ) { free( psz_source ); return VLC_ENOMEM; }#ifdef HAVE_LIBCDDB cddb_log_set_handler ( cddb_log_handler ); p_cdda->cddb.disc = NULL; p_cdda->b_cddb_enabled = config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );#endif p_cdda->b_cdtext = config_GetInt( p_access, MODULE_STRING "-cdtext-enabled" ); p_cdda->b_cdtext_prefer = config_GetInt( p_access, MODULE_STRING "-cdtext-prefer" );#if LIBCDIO_VERSION_NUM >= 73 p_cdda->b_audio_ctl = config_GetInt( p_access, MODULE_STRING "-analog-output" );#endif p_cdda->psz_source = strdup( psz_source ); p_cdda->b_header = false; p_cdda->p_cdio = p_cdio; p_cdda->i_tracks = 0; p_cdda->i_titles = 0; p_cdda->i_debug = config_GetInt( p_this, MODULE_STRING "-debug" ); p_cdda->b_nav_mode = config_GetInt(p_this, MODULE_STRING "-navigation-mode" ); p_cdda->i_blocks_per_read = config_GetInt( p_this, MODULE_STRING "-blocks-per-read" ); p_cdda->last_disc_frame = cdio_get_track_lsn( p_cdio, CDIO_CDROM_LEADOUT_TRACK ); p_cdda->p_input = vlc_object_find( p_access, VLC_OBJECT_INPUT, FIND_PARENT ); if( 0 == p_cdda->i_blocks_per_read ) p_cdda->i_blocks_per_read = DEFAULT_BLOCKS_PER_READ; if( (p_cdda->i_blocks_per_read < MIN_BLOCKS_PER_READ) || (p_cdda->i_blocks_per_read > MAX_BLOCKS_PER_READ) ) { msg_Warn( p_cdda_input, "number of blocks (%d) has to be between %d and %d. " "Using %d.", p_cdda->i_blocks_per_read, MIN_BLOCKS_PER_READ, MAX_BLOCKS_PER_READ, DEFAULT_BLOCKS_PER_READ ); p_cdda->i_blocks_per_read = DEFAULT_BLOCKS_PER_READ; } dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "%s", psz_source ); /* Set up p_access */ if( p_cdda->b_audio_ctl ) { p_access->pf_read = CDDARead; p_access->pf_block = NULL; } else { p_access->pf_read = NULL; p_access->pf_block = CDDAReadBlocks; } p_access->pf_control = CDDAControl; p_access->pf_seek = CDDASeek; { lsn_t i_last_lsn; if( p_cdda->b_nav_mode ) i_last_lsn = p_cdda->last_disc_frame; else i_last_lsn = cdio_get_track_last_lsn( p_cdio, i_track ); if( CDIO_INVALID_LSN != i_last_lsn ) p_access->info.i_size = i_last_lsn * (uint64_t) CDIO_CD_FRAMESIZE_RAW; else p_access->info.i_size = 0; } p_access->info.i_update = 0; p_access->info.b_eof = false; p_access->info.i_title = 0; p_access->info.i_seekpoint = 0; p_access->p_sys = (access_sys_t *) p_cdda; /* We read the Table Of Content information */ i_rc = CDDAInit( p_access, p_cdda ); if( VLC_SUCCESS != i_rc ) goto error; cdda_play_track( p_access, i_track ); CDDAFixupPlaylist( p_access, p_cdda, b_single_track );#if LIBCDIO_VERSION_NUM >= 72 { char *psz_paranoia = config_GetPsz( p_access, MODULE_STRING "-paranoia" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -