access.c

来自「VLC媒体播放程序」· C语言 代码 · 共 1,611 行 · 第 1/4 页

C
1,611
字号
#ifdef WIN32    /* On Win32 we want the VCD access plugin to be explicitly requested,     * we end up with lots of problems otherwise */    if( !p_input->psz_access || !*p_input->psz_access ) return NULL;#endif    if( !p_input->psz_name )    {        return NULL;    }    psz_parser = psz_source = strdup( p_input->psz_name );    /* Parse input string :     * [device][@[type][title]] */    while( *psz_parser && *psz_parser != '@' )    {        psz_parser++;    }    if( *psz_parser == '@' )    {      /* Found the divide between the source name and the         type+entry number. */      unsigned int num;      *psz_parser = '\0';      ++psz_parser;      if( *psz_parser )        {          switch(*psz_parser) {          case 'E':            p_itemid->type = VCDINFO_ITEM_TYPE_ENTRY;            ++psz_parser;            *play_single_item = true;            break;          case 'P':            p_itemid->type = VCDINFO_ITEM_TYPE_LID;            ++psz_parser;            *play_single_item = false;            break;          case 'S':            p_itemid->type = VCDINFO_ITEM_TYPE_SEGMENT;            ++psz_parser;            *play_single_item = true;            break;          case 'T':            p_itemid->type = VCDINFO_ITEM_TYPE_TRACK;            ++psz_parser;            *play_single_item = true;            break;          default: ;          }        }      num = strtol( psz_parser, &psz_next, 10 );      if ( *psz_parser != '\0' && *psz_next == '\0')        {          p_itemid->num = num;        }    } else {      *play_single_item = ( VCDINFO_ITEM_TYPE_LID == p_itemid->type );    }    if( !*psz_source ) {      /* No source specified, so figure it out. */      if( !p_input->psz_access ) return NULL;      psz_source = config_GetPsz( p_input, "vcd" );      if( !psz_source || 0==strlen(psz_source) ) {        /* Scan for a CD-ROM drive with a VCD in it. */        char **cd_drives = cdio_get_devices_with_cap(NULL,                            (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD                             |CDIO_FS_ANAL_VIDEOCD|CDIO_FS_UNKNOWN),                                                     true);        if (NULL == cd_drives) return NULL;        if (cd_drives[0] == NULL) {          cdio_free_device_list(cd_drives);          return NULL;        }        psz_source = strdup(cd_drives[0]);        cdio_free_device_list(cd_drives);      }    }    dbg_print( (INPUT_DBG_CALL|INPUT_DBG_MRL),               "source=%s entry=%d type=%d",               psz_source, p_itemid->num, p_itemid->type);    return psz_source;}/*   Set's start origin subsequent seeks/reads*/static voidVCDSetOrigin( input_thread_t *p_input, lsn_t origin_lsn,              lsn_t cur_lsn, lsn_t end_lsn, int cur_entry, track_t cur_track ){  thread_vcd_data_t * p_vcd  = (thread_vcd_data_t *) p_input->p_access_data;  p_vcd->origin_lsn = origin_lsn;  p_vcd->cur_lsn    = cur_lsn;  p_vcd->end_lsn    = end_lsn;  p_vcd->cur_track  = cur_track;  p_vcd->play_item.num  = cur_entry;  p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY;  dbg_print( (INPUT_DBG_CALL|INPUT_DBG_LSN),             "origin: %d, cur_lsn: %d, end_lsn: %d, entry: %d, track: %d",             origin_lsn, cur_lsn, end_lsn, cur_entry, cur_track );  p_input->stream.p_selected_area->i_tell =    (off_t) (p_vcd->cur_lsn - p_vcd->origin_lsn) * (off_t)M2F2_SECTOR_SIZE;  VCDUpdateVar( p_input, cur_entry, VLC_VAR_SETVALUE,                "chapter", 		p_vcd->play_item.type == VCDINFO_ITEM_TYPE_ENTRY ?		_("Entry") : _("Segment"), 		"Setting entry/segment");}/***************************************************************************** * vcd_Open: Opens a VCD device or file and returns an opaque handle *****************************************************************************/static vcdinfo_obj_t *vcd_Open( vlc_object_t *p_this, const char *psz_dev ){    vcdinfo_obj_t *p_vcdobj;    char  *actual_dev;    if( !psz_dev ) return NULL;    actual_dev=strdup(psz_dev);    if ( vcdinfo_open(&p_vcdobj, &actual_dev, DRIVER_UNKNOWN, NULL) !=         VCDINFO_OPEN_VCD) {      free(actual_dev);      return NULL;    }    free(actual_dev);    return p_vcdobj;}/**************************************************************************** * VCDReadSector: Read a sector (2324 bytes) ****************************************************************************/static intVCDReadSector( vlc_object_t *p_this, const vcdinfo_obj_t *p_vcd,               lsn_t cur_lsn, byte_t * p_buffer ){  typedef struct {    uint8_t subheader   [8];    uint8_t data        [M2F2_SECTOR_SIZE];    uint8_t spare       [4];  } vcdsector_t;  vcdsector_t vcd_sector;  if (cdio_read_mode2_sector(vcdinfo_get_cd_image(p_vcd),                             &vcd_sector, cur_lsn, true)      != 0)    {      msg_Warn( p_this, "Could not read LSN %d", cur_lsn );      return -1;    }  memcpy (p_buffer, vcd_sector.data, M2F2_SECTOR_SIZE);  return( 0 );}/**************************************************************************** Update the "varname" variable to i_num without triggering a callback.****************************************************************************/static voidVCDUpdateVar( 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 (NULL != p_vcd_input) {    thread_vcd_data_t *p_vcd = (thread_vcd_data_t *)p_vcd_input->p_access_data;    dbg_print( INPUT_DBG_PBC, "%s %d", p_debug_label, 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 );}static inline voidMetaInfoAddStr(input_thread_t *p_input, input_info_category_t *p_cat,               playlist_t *p_playlist, char *title,               const char *str){  thread_vcd_data_t *p_vcd = (thread_vcd_data_t *) p_input->p_access_data;  playlist_item_t *p_item;  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 inline voidMetaInfoAddNum(input_thread_t *p_input, input_info_category_t *p_cat,               playlist_t *p_playlist, char *title, int num){  thread_vcd_data_t *p_vcd = (thread_vcd_data_t *) p_input->p_access_data;  playlist_item_t *p_item;  vlc_mutex_lock( &p_playlist->object_lock );  p_item = playlist_ItemGetByPos( p_playlist, -1 );  vlc_mutex_unlock( &p_playlist->object_lock );  dbg_print( INPUT_DBG_META, "field %s: %d\n", title, num);  input_AddInfo( p_cat, title, "%d", num );  vlc_mutex_lock( &p_item->lock );  playlist_ItemAddInfo( p_item ,  p_cat->psz_name, title, "%d",num );  vlc_mutex_unlock( &p_item->lock );}#define addstr(title, str) \  MetaInfoAddStr( p_input, p_cat, p_playlist, title, str );#define addnum(title, num) \  MetaInfoAddNum( p_input, p_cat, p_playlist, title, num );static void InformationCreate( input_thread_t *p_input  ){  thread_vcd_data_t *p_vcd = (thread_vcd_data_t *) p_input->p_access_data;  unsigned int i_nb = vcdinfo_get_num_entries(p_vcd->vcd);  unsigned int last_entry = 0;  input_info_category_t *p_cat;  track_t i_track;  playlist_t *p_playlist = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,                                                 FIND_PARENT );  p_cat = input_InfoCategory( p_input, "General" );  addstr( _("VCD Format"),  vcdinfo_get_format_version_str(p_vcd->vcd) );  addstr( _("Album"),       vcdinfo_get_album_id(p_vcd->vcd));  addstr( _("Application"), vcdinfo_get_application_id(p_vcd->vcd) );  addstr( _("Preparer"),    vcdinfo_get_preparer_id(p_vcd->vcd) );  addnum( _("Vol #"),       vcdinfo_get_volume_num(p_vcd->vcd) );  addnum( _("Vol max #"),   vcdinfo_get_volume_count(p_vcd->vcd) );  addstr( _("Volume Set"),  vcdinfo_get_volumeset_id(p_vcd->vcd) );  addstr( _("Volume"),      vcdinfo_get_volume_id(p_vcd->vcd) );  addstr( _("Publisher"),   vcdinfo_get_publisher_id(p_vcd->vcd) );  addstr( _("System Id"),   vcdinfo_get_system_id(p_vcd->vcd) );  addnum( "LIDs",           vcdinfo_get_num_LIDs(p_vcd->vcd) );  addnum( _("Entries"),     vcdinfo_get_num_entries(p_vcd->vcd) );  addnum( _("Segments"),    vcdinfo_get_num_segments(p_vcd->vcd) );  addnum( _("Tracks"),      vcdinfo_get_num_tracks(p_vcd->vcd) );  /* Spit out track information. Could also include MSF info.   */#define TITLE_MAX 30  for( i_track = 1 ; i_track < p_vcd->num_tracks ; i_track++ ) {    char track_str[TITLE_MAX];    unsigned int audio_type = vcdinfo_get_track_audio_type(p_vcd->vcd, 							   i_track);    snprintf(track_str, TITLE_MAX, "%s%02d", _("Track"), i_track);    p_cat = input_InfoCategory( p_input, track_str );    if (p_vcd->b_svd) {      addnum(_("Audio Channels"),  	     vcdinfo_audio_type_num_channels(p_vcd->vcd, audio_type) );    }    addnum(_("First Entry Point"), last_entry );    for ( ; last_entry < i_nb 	    && vcdinfo_get_track(p_vcd->vcd, last_entry) == i_track;	  last_entry++ ) ;    addnum(_("Last Entry Point"), last_entry-1 );  }}#define add_format_str_info(val)			       \  {							       \    const char *str = val;				       \    unsigned int len;					       \    if (val != NULL) {					       \      len=strlen(str);					       \      if (len != 0) {					       \        strncat(tp, str, TEMP_STR_LEN-(tp-temp_str));	       \        tp += len;					       \      }                                                        \      saw_control_prefix = false;			       \    }							       \  }#define add_format_num_info(val, fmt)			       \  {							       \    char num_str[10];					       \    unsigned int len;					       \    sprintf(num_str, fmt, val);                                \    len=strlen(num_str);				       \    if (len != 0) {					       \      strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str));        \      tp += len;					       \    }							       \    saw_control_prefix = false;                                \  }/*!   Take a format string and expand escape sequences, that is sequences that   begin with %, with information from the current VCD.   The expanded string is returned. Here is a list of escape sequences:   %A : The album information   %C : The VCD volume count - the number of CD's in the collection.   %c : The VCD volume num - the number of the CD in the collection.   %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD   %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, SEGMENT...   %L : The playlist ID prefixed with " LID" if it exists   %M : MRL   %N : The current number of the %I - a decimal number   %P : The publisher ID   %p : The preparer ID   %S : If we are in a segment (menu), the kind of segment   %T : The track number   %V : The volume set ID   %v : The volume ID       A number between 1 and the volume count.   %% : a %*/static char *VCDFormatStr(const input_thread_t *p_input, thread_vcd_data_t *p_vcd,             const char format_str[], const char *mrl,             const vcdinfo_itemid_t *itemid){#define TEMP_STR_SIZE 256#define TEMP_STR_LEN (TEMP_STR_SIZE-1)  static char    temp_str[TEMP_STR_SIZE];  size_t i;  char * tp = temp_str;  bool saw_control_prefix = false;  size_t format_len = strlen(format_str);  bzero(temp_str, TEMP_STR_SIZE);  for (i=0; i<format_len; i++) {    if (!saw_control_prefix && format_str[i] != '%') {      *tp++ = format_str[i];      saw_control_prefix = false;      continue;    }    switch(format_str[i]) {    case '%':      if (saw_control_prefix) {        *tp++ = '%';      }      saw_control_prefix = !saw_control_prefix;      break;    case 'A':      add_format_str_info(vcdinfo_strip_trail(vcdinfo_get_album_id(p_vcd->vcd),                                              MAX_ALBUM_LEN));      break;    case 'c':      add_format_num_info(vcdinfo_get_volume_num(p_vcd->vcd), "%d");      break;    case 'C':      add_format_num_info(vcdinfo_get_volume_count(p_vcd->vcd), "%d");      break;    case 'F':      add_format_str_info(vcdinfo_get_format_version_str(p_vcd->vcd));      break;    case 'I':      {        switch (itemid->type) {        case VCDINFO_ITEM_TYPE_TRACK:          strncat(tp, _("Track"), TEMP_STR_LEN-(tp-temp_str));          tp += strlen(_("Track"));        break;        case VCDINFO_ITEM_TYPE_ENTRY:          strncat(tp, _("Entry"), TEMP_STR_LEN-(tp-temp_str));

⌨️ 快捷键说明

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