info.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:13k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * info.c : CD digital audio input information routines
  3.  *****************************************************************************
  4.  * Copyright (C) 2004 the VideoLAN team
  5.  * $Id: cf36e53bac448c4295a0b0abb4c38d816377cec6 $
  6.  *
  7.  * Authors: Rocky Bernstein <rocky@panix.com>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. #ifdef HAVE_CONFIG_H
  24. # include "config.h"
  25. #endif
  26. #include <vlc_common.h>
  27. #include <vlc_input.h>
  28. #include <vlc_access.h>
  29. #include "vcd.h"
  30. #include <vlc_keys.h>
  31. #include "info.h"
  32. #include <cdio/cdio.h>
  33. #include <cdio/cd_types.h>
  34. #include <cdio/logging.h>
  35. #include <cdio/util.h>
  36. #include <libvcd/info.h>
  37. #include <libvcd/logging.h>
  38. static inline void
  39. MetaInfoAddStr( access_t *p_access, char *psz_cat,
  40.                 const char *title, const char *psz )
  41. {
  42.   vcdplayer_t *p_vcdplayer = (vcdplayer_t *) p_access->p_sys;
  43.   if ( psz ) {
  44.     dbg_print( INPUT_DBG_META, "cat %s, field: %s: %s", psz_cat, title, psz);
  45.     input_Control( p_vcdplayer->p_input, INPUT_ADD_INFO, psz_cat, title, "%s",
  46.            psz);
  47.   }
  48. }
  49. static inline void
  50. MetaInfoAddNum(access_t *p_access, char *psz_cat, const char *title, int num)
  51. {
  52.   vcdplayer_t *p_vcdplayer = (vcdplayer_t *) p_access->p_sys;
  53.   dbg_print( INPUT_DBG_META, "cat %s, field %s: %d", psz_cat,  title, num);
  54.   input_Control( p_vcdplayer->p_input, INPUT_ADD_INFO, psz_cat, title,
  55.          "%d", num );
  56. }
  57. static inline void
  58. MetaInfoAddHex(access_t *p_access, char *psz_cat, const char *title, int hex)
  59. {
  60.   vcdplayer_t *p_vcdplayer = (vcdplayer_t *) p_access->p_sys;
  61.   dbg_print( INPUT_DBG_META, "cat %s, field %s: %d", psz_cat, title, hex);
  62.   input_Control( p_vcdplayer->p_input, INPUT_ADD_INFO, psz_cat, title,
  63.          "%x", hex );
  64. }
  65. #define addstr(title, str) 
  66.   MetaInfoAddStr( p_access, psz_cat, title, str );
  67. #define addnum(title, num) 
  68.   MetaInfoAddNum( p_access, psz_cat, title, num );
  69. #define addhex(title, hex) 
  70.   MetaInfoAddHex( p_access, psz_cat, title, hex );
  71. void
  72. VCDMetaInfo( access_t *p_access, /*const*/ char *psz_mrl )
  73. {
  74.   vcdplayer_t *p_vcdplayer = (vcdplayer_t *) p_access->p_sys;
  75.   unsigned int i_entries = vcdinfo_get_num_entries(p_vcdplayer->vcd);
  76.   unsigned int last_entry = 0;
  77.   char *psz_cat;
  78.   track_t i_track;
  79.   psz_cat = _("Disc");
  80.   addstr( _("VCD Format"),  vcdinfo_get_format_version_str(p_vcdplayer->vcd) );
  81.   addstr( _("Album"),       vcdinfo_get_album_id(p_vcdplayer->vcd));
  82.   addstr( _("Application"), vcdinfo_get_application_id(p_vcdplayer->vcd) );
  83.   addstr( _("Preparer"),    vcdinfo_get_preparer_id(p_vcdplayer->vcd) );
  84.   addnum( _("Vol #"),       vcdinfo_get_volume_num(p_vcdplayer->vcd) );
  85.   addnum( _("Vol max #"),   vcdinfo_get_volume_count(p_vcdplayer->vcd) );
  86.   addstr( _("Volume Set"),  vcdinfo_get_volumeset_id(p_vcdplayer->vcd) );
  87.   addstr( _("Volume"),      vcdinfo_get_volume_id(p_vcdplayer->vcd) );
  88.   addstr( _("Publisher"),   vcdinfo_get_publisher_id(p_vcdplayer->vcd) );
  89.   addstr( _("System Id"),   vcdinfo_get_system_id(p_vcdplayer->vcd) );
  90.   addnum( "LIDs",           vcdinfo_get_num_LIDs(p_vcdplayer->vcd) );
  91.   addnum( _("Entries"),     vcdinfo_get_num_entries(p_vcdplayer->vcd) );
  92.   addnum( _("Segments"),    vcdinfo_get_num_segments(p_vcdplayer->vcd) );
  93.   addnum( _("Tracks"),      vcdinfo_get_num_tracks(p_vcdplayer->vcd) );
  94.   /* Spit out track information. Could also include MSF info.
  95.      Also build title table.
  96.    */
  97. #define TITLE_MAX 30
  98.   for( i_track = 1 ; i_track < p_vcdplayer->i_tracks ; i_track++ ) {
  99.     char psz_cat[20];
  100.     unsigned int audio_type = vcdinfo_get_track_audio_type(p_vcdplayer->vcd,
  101.                                i_track);
  102.     uint32_t i_secsize = vcdinfo_get_track_sect_count(p_vcdplayer->vcd, i_track);
  103.     snprintf(psz_cat, sizeof(psz_cat), "Track %d", i_track);
  104.     if (p_vcdplayer->b_svd) {
  105.       addnum(_("Audio Channels"),
  106.          vcdinfo_audio_type_num_channels(p_vcdplayer->vcd, audio_type) );
  107.     }
  108.     addnum(_("First Entry Point"), last_entry );
  109.     for ( ; last_entry < i_entries
  110.         && vcdinfo_get_track(p_vcdplayer->vcd, last_entry) == i_track;
  111.       last_entry++ ) ;
  112.     addnum(_("Last Entry Point"), last_entry-1 );
  113.     addnum(_("Track size (in sectors)"), i_secsize );
  114.   }
  115.  
  116.   {
  117.     lid_t i_lid;
  118.     for( i_lid = 1 ; i_lid <= p_vcdplayer->i_lids ; i_lid++ ) {
  119.       PsdListDescriptor_t pxd;
  120.       char psz_cat[20];
  121.       snprintf(psz_cat, sizeof(psz_cat), "LID %d", i_lid);
  122.       if (vcdinfo_lid_get_pxd(p_vcdplayer->vcd, &pxd, i_lid)) {
  123.     switch (pxd.descriptor_type) {
  124.     case PSD_TYPE_END_LIST:
  125.       addstr(_("type"), _("end"));
  126.       break;
  127.     case PSD_TYPE_PLAY_LIST:
  128.       addstr(_("type"), _("play list"));
  129.       addnum("items",     vcdinf_pld_get_noi(pxd.pld));
  130.       addhex("next",      vcdinf_pld_get_next_offset(pxd.pld));
  131.       addhex("previous",  vcdinf_pld_get_prev_offset(pxd.pld));
  132.       addhex("return",    vcdinf_pld_get_return_offset(pxd.pld));
  133.       addnum("wait time", vcdinf_get_wait_time(pxd.pld));
  134.       break;
  135.     case PSD_TYPE_SELECTION_LIST:
  136.     case PSD_TYPE_EXT_SELECTION_LIST:
  137.       addstr(_("type"),
  138.          PSD_TYPE_SELECTION_LIST == pxd.descriptor_type
  139.          ? _("extended selection list")
  140.          : _("selection list")
  141.          );
  142.       addhex("default",          vcdinf_psd_get_default_offset(pxd.psd));
  143.       addhex("loop count",       vcdinf_get_loop_count(pxd.psd));
  144.       addhex("next",             vcdinf_psd_get_next_offset(pxd.psd));
  145.       addhex("previous",         vcdinf_psd_get_prev_offset(pxd.psd));
  146.       addhex("return",           vcdinf_psd_get_return_offset(pxd.psd));
  147.       addhex("rejected",         vcdinf_psd_get_lid_rejected(pxd.psd));
  148.       addhex("time-out offset",  vcdinf_get_timeout_offset(pxd.psd));
  149.       addnum("time-out time",    vcdinf_get_timeout_time(pxd.psd));
  150.       break;
  151.     default:
  152.       addstr(_("type"), _("unknown type"));
  153.       break;
  154.     }
  155.       }
  156.     }
  157.   }
  158.   if ( CDIO_INVALID_TRACK != i_track )
  159.   {
  160.     char* psz_title_format = config_GetPsz( p_access, MODULE_STRING "-title-format" );
  161.     char *psz_name =
  162.       VCDFormatStr( p_access, p_vcdplayer, psz_title_format, psz_mrl,
  163.                     &(p_vcdplayer->play_item) );
  164.     free( psz_title_format );
  165.  
  166.     input_Control( p_vcdplayer->p_input, INPUT_SET_NAME, psz_name );
  167.   }
  168. }
  169. #define add_format_str_info(val)                   
  170.   {                                   
  171.     const char *str = strdup(val);                   
  172.     unsigned int len;                           
  173.     if (val != NULL) {                           
  174.       len=strlen(str);                           
  175.       if (len != 0) {                           
  176.         strncat(tp, str, TEMP_STR_LEN-(tp-temp_str));           
  177.         tp += len;                           
  178.       }                                                        
  179.       saw_control_prefix = false;                   
  180.     }                                   
  181.   }
  182. #define add_format_num_info( val, fmt )                   
  183.   {                                   
  184.     char num_str[10];                           
  185.     unsigned int len;                           
  186.     sprintf(num_str, fmt, val);                                
  187.     len = strlen(num_str);                       
  188.     if( len != 0 )                                             
  189.     {                                           
  190.       strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str));        
  191.       tp += len;                           
  192.     }                                   
  193.     saw_control_prefix = false;                                
  194.   }
  195. /*!
  196.    Take a format string and expand escape sequences, that is sequences that
  197.    begin with %, with information from the current VCD.
  198.    The expanded string is returned. Here is a list of escape sequences:
  199.    %A : The album information
  200.    %C : The VCD volume count - the number of CD's in the collection.
  201.    %c : The VCD volume num - the number of the CD in the collection.
  202.    %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD
  203.    %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, SEGMENT...
  204.    %L : The playlist ID prefixed with " LID" if it exists
  205.    %M : MRL
  206.    %N : The current number of the %I - a decimal number
  207.    %P : The publisher ID
  208.    %p : The preparer ID
  209.    %S : If we are in a segment (menu), the kind of segment
  210.    %T : The track number
  211.    %V : The volume set ID
  212.    %v : The volume ID
  213.        A number between 1 and the volume count.
  214.    %% : a %
  215. */
  216. char *
  217. VCDFormatStr(const access_t *p_access, vcdplayer_t *p_vcdplayer,
  218.              const char format_str[], const char *mrl,
  219.              const vcdinfo_itemid_t *itemid)
  220. {
  221. #define TEMP_STR_SIZE 256
  222. #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
  223.   char           temp_str[TEMP_STR_SIZE];
  224.   size_t         i;
  225.   char *         tp = temp_str;
  226.   bool     saw_control_prefix = false;
  227.   size_t         format_len = strlen(format_str);
  228.   memset(temp_str, 0, TEMP_STR_SIZE);
  229.   for (i=0; i<format_len; i++) {
  230.     if (!saw_control_prefix && format_str[i] != '%') {
  231.       *tp++ = format_str[i];
  232.       saw_control_prefix = false;
  233.       continue;
  234.     }
  235.     switch(format_str[i]) {
  236.     case '%':
  237.       if (saw_control_prefix) {
  238.         *tp++ = '%';
  239.       }
  240.       saw_control_prefix = !saw_control_prefix;
  241.       break;
  242.     case 'A':
  243.       add_format_str_info(vcdinfo_strip_trail(vcdinfo_get_album_id(p_vcdplayer->vcd),
  244.                                               MAX_ALBUM_LEN));
  245.       break;
  246.     case 'c':
  247.       add_format_num_info(vcdinfo_get_volume_num(p_vcdplayer->vcd), "%d");
  248.       break;
  249.     case 'C':
  250.       add_format_num_info(vcdinfo_get_volume_count(p_vcdplayer->vcd), "%d");
  251.       break;
  252.     case 'F':
  253.       add_format_str_info(vcdinfo_get_format_version_str(p_vcdplayer->vcd));
  254.       break;
  255.     case 'I':
  256.       {
  257.         switch (itemid->type) {
  258.         case VCDINFO_ITEM_TYPE_TRACK:
  259.           strncat(tp, _("Track"), TEMP_STR_LEN-(tp-temp_str));
  260.           tp += strlen(_("Track"));
  261.         break;
  262.         case VCDINFO_ITEM_TYPE_ENTRY:
  263.           strncat(tp, _("Entry"), TEMP_STR_LEN-(tp-temp_str));
  264.           tp += strlen(_("Entry"));
  265.           break;
  266.         case VCDINFO_ITEM_TYPE_SEGMENT:
  267.           strncat(tp, _("Segment"), TEMP_STR_LEN-(tp-temp_str));
  268.           tp += strlen(_("Segment"));
  269.           break;
  270.         case VCDINFO_ITEM_TYPE_LID:
  271.           strncat(tp, _("List ID"), TEMP_STR_LEN-(tp-temp_str));
  272.           tp += strlen(_("List ID"));
  273.           break;
  274.         case VCDINFO_ITEM_TYPE_SPAREID2:
  275.           strncat(tp, _("Navigation"), TEMP_STR_LEN-(tp-temp_str));
  276.           tp += strlen(_("Navigation"));
  277.           break;
  278.         default:
  279.           /* What to do? */
  280.           ;
  281.         }
  282.         saw_control_prefix = false;
  283.       }
  284.       break;
  285.     case 'L':
  286.       if (vcdplayer_pbc_is_on(p_vcdplayer)) {
  287.         char num_str[40];
  288.         sprintf(num_str, "%s %d", _("List ID"), p_vcdplayer->i_lid);
  289.         strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str));
  290.         tp += strlen(num_str);
  291.       }
  292.       saw_control_prefix = false;
  293.       break;
  294.     case 'M':
  295.       add_format_str_info(mrl);
  296.       break;
  297.     case 'N':
  298.       add_format_num_info(itemid->num, "%d");
  299.       break;
  300.     case 'p':
  301.       add_format_str_info(vcdinfo_get_preparer_id(p_vcdplayer->vcd));
  302.       break;
  303.     case 'P':
  304.       add_format_str_info(vcdinfo_get_publisher_id(p_vcdplayer->vcd));
  305.       break;
  306.     case 'S':
  307.       if ( VCDINFO_ITEM_TYPE_SEGMENT==itemid->type ) {
  308.         char seg_type_str[30];
  309.         sprintf(seg_type_str, " %s",
  310.                 vcdinfo_video_type2str(p_vcdplayer->vcd, itemid->num));
  311.         strncat(tp, seg_type_str, TEMP_STR_LEN-(tp-temp_str));
  312.         tp += strlen(seg_type_str);
  313.       }
  314.       saw_control_prefix = false;
  315.       break;
  316.     case 'T':
  317.       add_format_num_info(p_vcdplayer->i_track, "%d");
  318.       break;
  319.     case 'V':
  320.       add_format_str_info(vcdinfo_get_volumeset_id(p_vcdplayer->vcd));
  321.       break;
  322.     case 'v':
  323.       add_format_str_info(vcdinfo_get_volume_id(p_vcdplayer->vcd));
  324.       break;
  325.     default:
  326.       *tp++ = '%';
  327.       *tp++ = format_str[i];
  328.       saw_control_prefix = false;
  329.     }
  330.   }
  331.   return strdup(temp_str);
  332. }
  333. void
  334. VCDUpdateTitle( access_t *p_access )
  335. {
  336.     vcdplayer_t *p_vcdplayer= (vcdplayer_t *)p_access->p_sys;
  337.     unsigned int psz_mrl_max = strlen(VCD_MRL_PREFIX)
  338.       + strlen(p_vcdplayer->psz_source) + sizeof("@E999")+3;
  339.     char *psz_mrl = malloc( psz_mrl_max );
  340.     if( psz_mrl )
  341.     {
  342.         char *psz_name;
  343.         char* psz_title_format = config_GetPsz( p_access, MODULE_STRING "-title-format" );
  344.         snprintf( psz_mrl, psz_mrl_max, "%s%s",
  345.                   VCD_MRL_PREFIX, p_vcdplayer->psz_source );
  346.         psz_name = VCDFormatStr( p_access, p_vcdplayer, psz_title_format, psz_mrl,
  347.                                  &(p_vcdplayer->play_item) );
  348.         input_Control( p_vcdplayer->p_input, INPUT_SET_NAME, psz_name );
  349.         free( psz_title_format );
  350.         free(psz_mrl);
  351.     }
  352. }