1 /*****************************************************************************
2 * info.c : CD digital audio input information routines
3 *****************************************************************************
4 * Copyright (C) 2004 the VideoLAN team
7 * Authors: Rocky Bernstein <rocky@panix.com>
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.
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.
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 *****************************************************************************/
28 #include <vlc_common.h>
29 #include <vlc_input.h>
30 #include <vlc_access.h>
35 #include <cdio/cdio.h>
36 #include <cdio/cd_types.h>
37 #include <cdio/logging.h>
38 #include <cdio/util.h>
39 #include <libvcd/info.h>
40 #include <libvcd/logging.h>
43 MetaInfoAddStr(access_t *p_access, char *psz_cat,
44 char *title, const char *psz)
46 vcdplayer_t *p_vcdplayer = (vcdplayer_t *) p_access->p_sys;
48 dbg_print( INPUT_DBG_META, "cat %s, field: %s: %s", psz_cat, title, psz);
49 input_Control( p_vcdplayer->p_input, INPUT_ADD_INFO, psz_cat, title, "%s",
56 MetaInfoAddNum(access_t *p_access, char *psz_cat, char *title, int num)
58 vcdplayer_t *p_vcdplayer = (vcdplayer_t *) p_access->p_sys;
59 dbg_print( INPUT_DBG_META, "cat %s, field %s: %d", psz_cat, title, num);
60 input_Control( p_vcdplayer->p_input, INPUT_ADD_INFO, psz_cat, title,
65 MetaInfoAddHex(access_t *p_access, char *psz_cat, char *title, int hex)
67 vcdplayer_t *p_vcdplayer = (vcdplayer_t *) p_access->p_sys;
68 dbg_print( INPUT_DBG_META, "cat %s, field %s: %d", psz_cat, title, hex);
69 input_Control( p_vcdplayer->p_input, INPUT_ADD_INFO, psz_cat, title,
73 #define addstr(title, str) \
74 MetaInfoAddStr( p_access, psz_cat, title, str );
76 #define addnum(title, num) \
77 MetaInfoAddNum( p_access, psz_cat, title, num );
79 #define addhex(title, hex) \
80 MetaInfoAddHex( p_access, psz_cat, title, hex );
83 VCDMetaInfo( access_t *p_access, /*const*/ char *psz_mrl )
85 vcdplayer_t *p_vcdplayer = (vcdplayer_t *) p_access->p_sys;
86 unsigned int i_entries = vcdinfo_get_num_entries(p_vcdplayer->vcd);
87 unsigned int last_entry = 0;
93 addstr( _("VCD Format"), vcdinfo_get_format_version_str(p_vcdplayer->vcd) );
94 addstr( _("Album"), vcdinfo_get_album_id(p_vcdplayer->vcd));
95 addstr( _("Application"), vcdinfo_get_application_id(p_vcdplayer->vcd) );
96 addstr( _("Preparer"), vcdinfo_get_preparer_id(p_vcdplayer->vcd) );
97 addnum( _("Vol #"), vcdinfo_get_volume_num(p_vcdplayer->vcd) );
98 addnum( _("Vol max #"), vcdinfo_get_volume_count(p_vcdplayer->vcd) );
99 addstr( _("Volume Set"), vcdinfo_get_volumeset_id(p_vcdplayer->vcd) );
100 addstr( _("Volume"), vcdinfo_get_volume_id(p_vcdplayer->vcd) );
101 addstr( _("Publisher"), vcdinfo_get_publisher_id(p_vcdplayer->vcd) );
102 addstr( _("System Id"), vcdinfo_get_system_id(p_vcdplayer->vcd) );
103 addnum( "LIDs", vcdinfo_get_num_LIDs(p_vcdplayer->vcd) );
104 addnum( _("Entries"), vcdinfo_get_num_entries(p_vcdplayer->vcd) );
105 addnum( _("Segments"), vcdinfo_get_num_segments(p_vcdplayer->vcd) );
106 addnum( _("Tracks"), vcdinfo_get_num_tracks(p_vcdplayer->vcd) );
108 /* Spit out track information. Could also include MSF info.
109 Also build title table.
113 for( i_track = 1 ; i_track < p_vcdplayer->i_tracks ; i_track++ ) {
115 unsigned int audio_type = vcdinfo_get_track_audio_type(p_vcdplayer->vcd,
117 uint32_t i_secsize = vcdinfo_get_track_sect_count(p_vcdplayer->vcd, i_track);
119 snprintf(psz_cat, sizeof(psz_cat), "Track %d", i_track);
120 if (p_vcdplayer->b_svd) {
121 addnum(_("Audio Channels"),
122 vcdinfo_audio_type_num_channels(p_vcdplayer->vcd, audio_type) );
125 addnum(_("First Entry Point"), last_entry );
126 for ( ; last_entry < i_entries
127 && vcdinfo_get_track(p_vcdplayer->vcd, last_entry) == i_track;
129 addnum(_("Last Entry Point"), last_entry-1 );
130 addnum(_("Track size (in sectors)"), i_secsize );
135 for( i_lid = 1 ; i_lid <= p_vcdplayer->i_lids ; i_lid++ ) {
136 PsdListDescriptor_t pxd;
138 snprintf(psz_cat, sizeof(psz_cat), "LID %d", i_lid);
139 if (vcdinfo_lid_get_pxd(p_vcdplayer->vcd, &pxd, i_lid)) {
140 switch (pxd.descriptor_type) {
141 case PSD_TYPE_END_LIST:
142 addstr(_("type"), _("end"));
144 case PSD_TYPE_PLAY_LIST:
145 addstr(_("type"), _("play list"));
146 addnum("items", vcdinf_pld_get_noi(pxd.pld));
147 addhex("next", vcdinf_pld_get_next_offset(pxd.pld));
148 addhex("previous", vcdinf_pld_get_prev_offset(pxd.pld));
149 addhex("return", vcdinf_pld_get_return_offset(pxd.pld));
150 addnum("wait time", vcdinf_get_wait_time(pxd.pld));
152 case PSD_TYPE_SELECTION_LIST:
153 case PSD_TYPE_EXT_SELECTION_LIST:
155 PSD_TYPE_SELECTION_LIST == pxd.descriptor_type
156 ? _("extended selection list")
157 : _("selection list")
159 addhex("default", vcdinf_psd_get_default_offset(pxd.psd));
160 addhex("loop count", vcdinf_get_loop_count(pxd.psd));
161 addhex("next", vcdinf_psd_get_next_offset(pxd.psd));
162 addhex("previous", vcdinf_psd_get_prev_offset(pxd.psd));
163 addhex("return", vcdinf_psd_get_return_offset(pxd.psd));
164 addhex("rejected", vcdinf_psd_get_lid_rejected(pxd.psd));
165 addhex("time-out offset", vcdinf_get_timeout_offset(pxd.psd));
166 addnum("time-out time", vcdinf_get_timeout_time(pxd.psd));
169 addstr(_("type"), _("unknown type"));
176 if ( CDIO_INVALID_TRACK != i_track )
178 char* psz_title_format = config_GetPsz( p_access, MODULE_STRING "-title-format" );
180 VCDFormatStr( p_access, p_vcdplayer, psz_title_format, psz_mrl,
181 &(p_vcdplayer->play_item) );
182 free( psz_title_format );
184 input_Control( p_vcdplayer->p_input, INPUT_SET_NAME, psz_name );
189 #define add_format_str_info(val) \
191 const char *str = strdup(val); \
196 strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \
199 saw_control_prefix = false; \
203 #define add_format_num_info( val, fmt ) \
207 sprintf(num_str, fmt, val); \
208 len = strlen(num_str); \
211 strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \
214 saw_control_prefix = false; \
218 Take a format string and expand escape sequences, that is sequences that
219 begin with %, with information from the current VCD.
220 The expanded string is returned. Here is a list of escape sequences:
222 %A : The album information
223 %C : The VCD volume count - the number of CD's in the collection.
224 %c : The VCD volume num - the number of the CD in the collection.
225 %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD
226 %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, SEGMENT...
227 %L : The playlist ID prefixed with " LID" if it exists
229 %N : The current number of the %I - a decimal number
230 %P : The publisher ID
232 %S : If we are in a segment (menu), the kind of segment
233 %T : The track number
234 %V : The volume set ID
236 A number between 1 and the volume count.
240 VCDFormatStr(const access_t *p_access, vcdplayer_t *p_vcdplayer,
241 const char format_str[], const char *mrl,
242 const vcdinfo_itemid_t *itemid)
244 #define TEMP_STR_SIZE 256
245 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
246 char temp_str[TEMP_STR_SIZE];
248 char * tp = temp_str;
249 bool saw_control_prefix = false;
250 size_t format_len = strlen(format_str);
252 memset(temp_str, 0, TEMP_STR_SIZE);
254 for (i=0; i<format_len; i++) {
256 if (!saw_control_prefix && format_str[i] != '%') {
257 *tp++ = format_str[i];
258 saw_control_prefix = false;
262 switch(format_str[i]) {
264 if (saw_control_prefix) {
267 saw_control_prefix = !saw_control_prefix;
270 add_format_str_info(vcdinfo_strip_trail(vcdinfo_get_album_id(p_vcdplayer->vcd),
275 add_format_num_info(vcdinfo_get_volume_num(p_vcdplayer->vcd), "%d");
279 add_format_num_info(vcdinfo_get_volume_count(p_vcdplayer->vcd), "%d");
283 add_format_str_info(vcdinfo_get_format_version_str(p_vcdplayer->vcd));
288 switch (itemid->type) {
289 case VCDINFO_ITEM_TYPE_TRACK:
290 strncat(tp, _("Track"), TEMP_STR_LEN-(tp-temp_str));
291 tp += strlen(_("Track"));
293 case VCDINFO_ITEM_TYPE_ENTRY:
294 strncat(tp, _("Entry"), TEMP_STR_LEN-(tp-temp_str));
295 tp += strlen(_("Entry"));
297 case VCDINFO_ITEM_TYPE_SEGMENT:
298 strncat(tp, _("Segment"), TEMP_STR_LEN-(tp-temp_str));
299 tp += strlen(_("Segment"));
301 case VCDINFO_ITEM_TYPE_LID:
302 strncat(tp, _("List ID"), TEMP_STR_LEN-(tp-temp_str));
303 tp += strlen(_("List ID"));
305 case VCDINFO_ITEM_TYPE_SPAREID2:
306 strncat(tp, _("Navigation"), TEMP_STR_LEN-(tp-temp_str));
307 tp += strlen(_("Navigation"));
313 saw_control_prefix = false;
318 if (vcdplayer_pbc_is_on(p_vcdplayer)) {
320 sprintf(num_str, "%s %d", _("List ID"), p_vcdplayer->i_lid);
321 strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str));
322 tp += strlen(num_str);
324 saw_control_prefix = false;
328 add_format_str_info(mrl);
332 add_format_num_info(itemid->num, "%d");
336 add_format_str_info(vcdinfo_get_preparer_id(p_vcdplayer->vcd));
340 add_format_str_info(vcdinfo_get_publisher_id(p_vcdplayer->vcd));
344 if ( VCDINFO_ITEM_TYPE_SEGMENT==itemid->type ) {
345 char seg_type_str[30];
347 sprintf(seg_type_str, " %s",
348 vcdinfo_video_type2str(p_vcdplayer->vcd, itemid->num));
349 strncat(tp, seg_type_str, TEMP_STR_LEN-(tp-temp_str));
350 tp += strlen(seg_type_str);
352 saw_control_prefix = false;
356 add_format_num_info(p_vcdplayer->i_track, "%d");
360 add_format_str_info(vcdinfo_get_volumeset_id(p_vcdplayer->vcd));
364 add_format_str_info(vcdinfo_get_volume_id(p_vcdplayer->vcd));
369 *tp++ = format_str[i];
370 saw_control_prefix = false;
373 return strdup(temp_str);
377 VCDUpdateTitle( access_t *p_access )
380 vcdplayer_t *p_vcdplayer= (vcdplayer_t *)p_access->p_sys;
382 unsigned int psz_mrl_max = strlen(VCD_MRL_PREFIX)
383 + strlen(p_vcdplayer->psz_source) + sizeof("@E999")+3;
384 char *psz_mrl = malloc( psz_mrl_max );
389 char* psz_title_format = config_GetPsz( p_access, MODULE_STRING "-title-format" );
390 snprintf( psz_mrl, psz_mrl_max, "%s%s",
391 VCD_MRL_PREFIX, p_vcdplayer->psz_source );
392 psz_name = VCDFormatStr( p_access, p_vcdplayer, psz_title_format, psz_mrl,
393 &(p_vcdplayer->play_item) );
394 input_Control( p_vcdplayer->p_input, INPUT_SET_NAME, psz_name );
395 free( psz_title_format );