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

📄 access.c

📁 VLC媒体播放程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * cddax.c : CD digital audio input module for vlc using libcdio ***************************************************************************** * Copyright (C) 2000, 2003, 2004 VideoLAN * $Id: access.c,v 1.28 2004/02/23 00:10:50 rocky Exp $ * * 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 <stdio.h>#include <stdlib.h>#include <vlc/vlc.h>#include <vlc/intf.h>#include <sys/types.h>#include <cdio/cdio.h>#include <cdio/cd_types.h>#include "codecs.h"#include "vlc_keys.h"#ifdef HAVE_UNISTD_H#   include <unistd.h>#endif#ifdef HAVE_ERRNO_H#   include <errno.h>#endif#include <string.h>#include "cdda.h"/* how many blocks Open will read in each loop */#define CDDA_BLOCKS_ONCE 20#define CDDA_DATA_ONCE   (CDDA_BLOCKS_ONCE * CDIO_CD_FRAMESIZE_RAW)#define CDDA_MRL_PREFIX "cddax://"/* FIXME: This variable is a hack. Would be nice to eliminate. */static input_thread_t *p_cdda_input = NULL;/***************************************************************************** * Local prototypes *****************************************************************************/static int  CDDARead         ( input_thread_t *, byte_t *, size_t );static void CDDASeek         ( input_thread_t *, off_t );static int  CDDASetArea      ( input_thread_t *, input_area_t * );static int  CDDASetProgram   ( input_thread_t *, pgrm_descriptor_t * );static int  CDDAFixupPlayList( input_thread_t *p_input,                              cdda_data_t *p_cdda, const char *psz_source,                              bool play_single_track);static void CDDAUpdateVar( input_thread_t *p_input, int i_entry, int i_action,			   const char *p_varname, char *p_label,			   const char *p_debug_label );/**************************************************************************** * Private functions ****************************************************************************//* process messages that originate from libcdio. */static voidcdio_log_handler (cdio_log_level_t level, const char message[]){  cdda_data_t *p_cdda = (cdda_data_t *)p_cdda_input->p_access_data;  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 vcdimager log level"),            level);  }  return;}#ifdef HAVE_LIBCDDB/*! This routine is called by libcddb routines on error.   Setup is done by init_input_plugin.*/static voidcddb_log_handler (cddb_log_level_t level, const char message[]){  cdda_data_t *p_cdda = (cdda_data_t *)p_cdda_input->p_access_data;  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 xine 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 = (cdda_data_t *)p_cdda_input->p_access_data;  switch (level) {  case CDIO_LOG_DEBUG:  case CDIO_LOG_INFO:    if (!(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); */}/***************************************************************************** * CDDAPlay: Arrange things so we play the specified track. * VLC_TRUE is returned if there was no error. *****************************************************************************/vlc_bool_tCDDAPlay( input_thread_t *p_input, int i_track ){  cdda_data_t *p_cdda = (cdda_data_t *) p_input->p_access_data;  if( i_track > p_cdda->i_nb_tracks || i_track < 1 )    return VLC_FALSE;  CDDASetArea( p_input, p_input->stream.pp_areas[i_track] );  return VLC_TRUE;}/***************************************************************************** * CDDARead: reads from the CDDA into PES packets. ***************************************************************************** * Returns -1 in case of error, 0 in case of EOF, otherwise the number of * bytes. *****************************************************************************/static int CDDARead( input_thread_t * p_input, byte_t * p_buffer,                     size_t i_len ){    cdda_data_t *           p_cdda;    int                     i_blocks;    int                     i_index;    int                     i_read;    p_cdda = (cdda_data_t *)p_input->p_access_data;    /* Compute the number of blocks we have to read */    i_blocks = i_len / CDIO_CD_FRAMESIZE_RAW;    i_read = 0;    if( !p_cdda->i_header_pos )    {        p_cdda->i_header_pos = sizeof(WAVEHEADER);        i_blocks = (i_len - sizeof(WAVEHEADER)) / CDIO_CD_FRAMESIZE_RAW;        memcpy( p_buffer, &p_cdda->waveheader, sizeof(WAVEHEADER) );        p_buffer += sizeof(WAVEHEADER);        i_read += sizeof(WAVEHEADER);    }    for( i_index = 0; i_index < i_blocks; i_index++ )    {        if( cdio_read_audio_sector( p_cdda->p_cddev->cdio, p_buffer,                                    p_cdda->i_sector) != 0 )        {            msg_Err( p_input, "could not read sector %d", p_cdda->i_sector );            return -1;        }        p_cdda->i_sector ++;        if( p_cdda->i_sector == p_cdda->p_sectors[p_cdda->i_track + 1] )        {            input_area_t *p_area;            dbg_print( (INPUT_DBG_LSN|INPUT_DBG_CALL),                       "end of track, cur: %u", p_cdda->i_sector );            /*???? if ( p_cdda->i_track >= p_cdda->i_nb_tracks - 1 )*/                return 0; /* EOF */            vlc_mutex_lock( &p_input->stream.stream_lock );            p_area = p_input->stream.pp_areas[                    p_input->stream.p_selected_area->i_id + 1 ];            p_area->i_part = 1;            CDDASetArea( p_input, p_area );            vlc_mutex_unlock( &p_input->stream.stream_lock );        }        i_read += CDIO_CD_FRAMESIZE_RAW;        p_buffer += CDIO_CD_FRAMESIZE_RAW;    }    if ( i_len % CDIO_CD_FRAMESIZE_RAW ) /* this should not happen */    {        msg_Err( p_input, "must read full sectors" );    }    return i_read;}/***************************************************************************** * CDDASetProgram: Does nothing since a CDDA is mono_program *****************************************************************************/static int CDDASetProgram( input_thread_t * p_input,                           pgrm_descriptor_t * p_program){    cdda_data_t * p_cdda= (cdda_data_t *) p_input->p_access_data;    dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "" );    return 0;}/***************************************************************************** * CDDASetArea: initialize input data for title x. * It should be called for each user navigation request. ****************************************************************************/static int CDDASetArea( input_thread_t * p_input, input_area_t * p_area ){    cdda_data_t *p_cdda = (cdda_data_t*) p_input->p_access_data;    vlc_value_t val;    vlc_value_t text;    dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "");    text.psz_string = _("Track");    var_Change( p_input, "title", VLC_VAR_SETTEXT, &text, NULL );    /* we can't use the interface slider until initilization is complete */    p_input->stream.b_seekable = 0;    if( p_area != p_input->stream.p_selected_area )    {        /* Change the default area */        p_input->stream.p_selected_area = p_area;        /* Change the current track */        p_cdda->i_track = p_area->i_id - 1;        p_cdda->i_sector = p_cdda->p_sectors[p_cdda->i_track];        /* Update the navigation variables without triggering a callback */        val.i_int = p_area->i_id;        var_Change( p_input, "title", VLC_VAR_SETVALUE, &val, NULL );    }    p_cdda->i_sector = p_cdda->p_sectors[p_cdda->i_track];    p_input->stream.p_selected_area->i_tell =        (off_t)p_cdda->i_sector * (off_t)CDIO_CD_FRAMESIZE_RAW         - p_input->stream.p_selected_area->i_start;    /* warn interface that something has changed */    p_input->stream.b_seekable = 1;    p_input->stream.b_changed = 1;    return 0;}/**************************************************************************** * CDDASeek ****************************************************************************/static void CDDASeek( input_thread_t * p_input, off_t i_off ){    cdda_data_t * p_cdda;    p_cdda = (cdda_data_t *) p_input->p_access_data;    p_cdda->i_sector = p_cdda->p_sectors[p_cdda->i_track]                       + i_off / (off_t)CDIO_CD_FRAMESIZE_RAW;    vlc_mutex_lock( &p_input->stream.stream_lock );    p_input->stream.p_selected_area->i_tell =        (off_t)p_cdda->i_sector * (off_t)CDIO_CD_FRAMESIZE_RAW         - p_input->stream.p_selected_area->i_start;    vlc_mutex_unlock( &p_input->stream.stream_lock );    dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_SEEK),    "sector %ud, offset: %lld, i_tell: %lld",  p_cdda->i_sector, i_off,               p_input->stream.p_selected_area->i_tell );}/**************************************************************************** Update the "varname" variable to i_num without triggering a callback.****************************************************************************/static voidCDDAUpdateVar( input_thread_t *p_input, int i_num, int i_action,              const char *p_varname, char *p_label, 	      const char *p_debug_label){  vlc_value_t val;  val.i_int = i_num;  if (p_label) {    vlc_value_t text;    text.psz_string = p_label;    var_Change( p_input, p_varname, VLC_VAR_SETTEXT, &text, NULL );  }  var_Change( p_input, p_varname, i_action, &val, NULL );}#define meta_info_add_str(title, str)                          \  if ( str ) {                                                 \    dbg_print( INPUT_DBG_META, "field %s: %s\n", title, str);  \    input_AddInfo( p_cat, _(title), "%s", str );               \    vlc_mutex_lock( &p_playlist->object_lock );                \    p_item = playlist_ItemGetByPos( p_playlist, -1 );          \    vlc_mutex_unlock( &p_playlist->object_lock );              \    vlc_mutex_lock( &p_item->lock );                           \    playlist_ItemAddInfo( p_item, p_cat->psz_name,             \                      _(title), "%s" , str );                  \    vlc_mutex_unlock( &p_item->lock );                         \  }static void InformationCreate( input_thread_t *p_input  ){  cdda_data_t *p_cdda = (cdda_data_t *) p_input->p_access_data;  playlist_t *p_playlist = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,                                            FIND_PARENT );  input_info_category_t *p_cat;  playlist_item_t *p_item;  p_cat = input_InfoCategory( p_input, "General" );#ifdef HAVE_LIBCDDB  if (p_cdda->i_cddb_enabled) {    meta_info_add_str( "Title", p_cdda->cddb.disc->title );    meta_info_add_str( "Artist", p_cdda->cddb.disc->artist );

⌨️ 快捷键说明

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