1 /*****************************************************************************
2 * info.c : CD digital audio input information routines
3 *****************************************************************************
4 * Copyright (C) 2004 VideoLAN
5 * $Id: info.c 8845 2004-09-29 09:00:41Z rocky $
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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
25 #include <vlc/input.h>
28 #include <vlc_playlist.h>
29 #include "vcdplayer.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>
39 static char *VCDFormatStr(const access_t *p_access, access_vcd_data_t *p_vcd,
40 const char format_str[], const char *mrl,
41 const vcdinfo_itemid_t *itemid);
44 MetaInfoAddStr(access_t *p_access, char *p_cat,
45 char *title, const char *str)
47 access_vcd_data_t *p_vcd = (access_vcd_data_t *) p_access->p_sys;
49 dbg_print( INPUT_DBG_META, "field: %s: %s", title, str);
50 input_Control( p_vcd->p_input, INPUT_ADD_INFO, p_cat, title, "%s", str);
56 MetaInfoAddNum(access_t *p_access, char *psz_cat, char *title, int num)
58 access_vcd_data_t *p_vcd = (access_vcd_data_t *) p_access->p_sys;
59 dbg_print( INPUT_DBG_META, "field %s: %d", title, num);
60 input_Control( p_vcd->p_input, INPUT_ADD_INFO, psz_cat, title, "%d", num );
63 #define addstr(title, str) \
64 MetaInfoAddStr( p_access, psz_cat, title, str );
66 #define addnum(title, num) \
67 MetaInfoAddNum( p_access, psz_cat, title, num );
70 VCDMetaInfo( access_t *p_access, /*const*/ char *psz_mrl )
72 access_vcd_data_t *p_vcd = (access_vcd_data_t *) p_access->p_sys;
73 unsigned int i_entries = vcdinfo_get_num_entries(p_vcd->vcd);
74 unsigned int last_entry = 0;
78 psz_cat = _("General");
80 addstr( _("VCD Format"), vcdinfo_get_format_version_str(p_vcd->vcd) );
81 addstr( _("Album"), vcdinfo_get_album_id(p_vcd->vcd));
82 addstr( _("Application"), vcdinfo_get_application_id(p_vcd->vcd) );
83 addstr( _("Preparer"), vcdinfo_get_preparer_id(p_vcd->vcd) );
84 addnum( _("Vol #"), vcdinfo_get_volume_num(p_vcd->vcd) );
85 addnum( _("Vol max #"), vcdinfo_get_volume_count(p_vcd->vcd) );
86 addstr( _("Volume Set"), vcdinfo_get_volumeset_id(p_vcd->vcd) );
87 addstr( _("Volume"), vcdinfo_get_volume_id(p_vcd->vcd) );
88 addstr( _("Publisher"), vcdinfo_get_publisher_id(p_vcd->vcd) );
89 addstr( _("System Id"), vcdinfo_get_system_id(p_vcd->vcd) );
90 addnum( "LIDs", vcdinfo_get_num_LIDs(p_vcd->vcd) );
91 addnum( _("Entries"), vcdinfo_get_num_entries(p_vcd->vcd) );
92 addnum( _("Segments"), vcdinfo_get_num_segments(p_vcd->vcd) );
93 addnum( _("Tracks"), vcdinfo_get_num_tracks(p_vcd->vcd) );
95 /* Spit out track information. Could also include MSF info.
96 Also build title table.
100 for( i_track = 1 ; i_track < p_vcd->i_tracks ; i_track++ ) {
101 unsigned int audio_type = vcdinfo_get_track_audio_type(p_vcd->vcd,
103 uint32_t i_secsize = vcdinfo_get_track_sect_count(p_vcd->vcd, i_track);
106 addnum(_("Audio Channels"),
107 vcdinfo_audio_type_num_channels(p_vcd->vcd, audio_type) );
110 addnum(_("First Entry Point"), last_entry );
111 for ( ; last_entry < i_entries
112 && vcdinfo_get_track(p_vcd->vcd, last_entry) == i_track;
114 addnum(_("Last Entry Point"), last_entry-1 );
115 addnum(_("Track size (in sectors)"), i_secsize );
118 if ( CDIO_INVALID_TRACK != i_track )
121 VCDFormatStr( p_access, p_vcd,
122 config_GetPsz( p_access, MODULE_STRING "-title-format" ),
123 psz_mrl, &(p_vcd->play_item) );
125 input_Control( p_vcd->p_input, INPUT_SET_NAME, psz_name );
130 #define add_format_str_info(val) \
132 const char *str = val; \
137 strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \
140 saw_control_prefix = VLC_FALSE; \
144 #define add_format_num_info( val, fmt ) \
148 sprintf(num_str, fmt, val); \
149 len = strlen(num_str); \
152 strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \
155 saw_control_prefix = VLC_FALSE; \
159 Take a format string and expand escape sequences, that is sequences that
160 begin with %, with information from the current VCD.
161 The expanded string is returned. Here is a list of escape sequences:
163 %A : The album information
164 %C : The VCD volume count - the number of CD's in the collection.
165 %c : The VCD volume num - the number of the CD in the collection.
166 %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD
167 %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, SEGMENT...
168 %L : The playlist ID prefixed with " LID" if it exists
170 %N : The current number of the %I - a decimal number
171 %P : The publisher ID
173 %S : If we are in a segment (menu), the kind of segment
174 %T : The track number
175 %V : The volume set ID
177 A number between 1 and the volume count.
181 VCDFormatStr(const access_t *p_access, access_vcd_data_t *p_vcd,
182 const char format_str[], const char *mrl,
183 const vcdinfo_itemid_t *itemid)
185 #define TEMP_STR_SIZE 256
186 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
187 static char temp_str[TEMP_STR_SIZE];
189 char * tp = temp_str;
190 vlc_bool_t saw_control_prefix = VLC_FALSE;
191 size_t format_len = strlen(format_str);
193 memset(temp_str, 0, TEMP_STR_SIZE);
195 for (i=0; i<format_len; i++) {
197 if (!saw_control_prefix && format_str[i] != '%') {
198 *tp++ = format_str[i];
199 saw_control_prefix = VLC_FALSE;
203 switch(format_str[i]) {
205 if (saw_control_prefix) {
208 saw_control_prefix = !saw_control_prefix;
211 add_format_str_info(vcdinfo_strip_trail(vcdinfo_get_album_id(p_vcd->vcd),
216 add_format_num_info(vcdinfo_get_volume_num(p_vcd->vcd), "%d");
220 add_format_num_info(vcdinfo_get_volume_count(p_vcd->vcd), "%d");
224 add_format_str_info(vcdinfo_get_format_version_str(p_vcd->vcd));
229 switch (itemid->type) {
230 case VCDINFO_ITEM_TYPE_TRACK:
231 strncat(tp, _("Track"), TEMP_STR_LEN-(tp-temp_str));
232 tp += strlen(_("Track"));
234 case VCDINFO_ITEM_TYPE_ENTRY:
235 strncat(tp, _("Entry"), TEMP_STR_LEN-(tp-temp_str));
236 tp += strlen(_("Entry"));
238 case VCDINFO_ITEM_TYPE_SEGMENT:
239 strncat(tp, _("Segment"), TEMP_STR_LEN-(tp-temp_str));
240 tp += strlen(_("Segment"));
242 case VCDINFO_ITEM_TYPE_LID:
243 strncat(tp, _("List ID"), TEMP_STR_LEN-(tp-temp_str));
244 tp += strlen(_("List ID"));
246 case VCDINFO_ITEM_TYPE_SPAREID2:
247 strncat(tp, _("Navigation"), TEMP_STR_LEN-(tp-temp_str));
248 tp += strlen(_("Navigation"));
254 saw_control_prefix = VLC_FALSE;
259 if (vcdplayer_pbc_is_on(p_vcd)) {
261 sprintf(num_str, "%s %d", _("List ID"), p_vcd->i_lid);
262 strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str));
263 tp += strlen(num_str);
265 saw_control_prefix = VLC_FALSE;
269 add_format_str_info(mrl);
273 add_format_num_info(itemid->num, "%d");
277 add_format_str_info(vcdinfo_get_preparer_id(p_vcd->vcd));
281 add_format_str_info(vcdinfo_get_publisher_id(p_vcd->vcd));
285 if ( VCDINFO_ITEM_TYPE_SEGMENT==itemid->type ) {
286 char seg_type_str[10];
288 sprintf(seg_type_str, " %s",
289 vcdinfo_video_type2str(p_vcd->vcd, itemid->num));
290 strncat(tp, seg_type_str, TEMP_STR_LEN-(tp-temp_str));
291 tp += strlen(seg_type_str);
293 saw_control_prefix = VLC_FALSE;
297 add_format_num_info(p_vcd->i_track, "%d");
301 add_format_str_info(vcdinfo_get_volumeset_id(p_vcd->vcd));
305 add_format_str_info(vcdinfo_get_volume_id(p_vcd->vcd));
310 *tp++ = format_str[i];
311 saw_control_prefix = VLC_FALSE;
314 return strdup(temp_str);
318 VCDCreatePlayListItem(const access_t *p_access,
319 access_vcd_data_t *p_vcd,
320 playlist_t *p_playlist,
321 const vcdinfo_itemid_t *itemid,
322 char *psz_mrl, int psz_mrl_max,
323 const char *psz_source, int playlist_operation,
330 switch(itemid->type) {
331 case VCDINFO_ITEM_TYPE_TRACK:
334 case VCDINFO_ITEM_TYPE_SEGMENT:
337 case VCDINFO_ITEM_TYPE_LID:
340 case VCDINFO_ITEM_TYPE_ENTRY:
348 snprintf(psz_mrl, psz_mrl_max, "%s%s@%c%u", VCD_MRL_PREFIX, psz_source,
349 c_type, itemid->num);
352 VCDFormatStr( p_access, p_vcd,
353 config_GetPsz( p_access, MODULE_STRING "-title-format" ),
356 playlist_Add( p_playlist, psz_mrl, p_title, playlist_operation, i_pos );
359 VCDFormatStr( p_access, p_vcd,
360 config_GetPsz( p_access, MODULE_STRING "-author-format" ),
363 if( i_pos == PLAYLIST_END ) i_pos = p_playlist->i_size - 1;
364 playlist_AddInfo(p_playlist, i_pos, _("General"), _("Author"), "%s",
369 VCDFixupPlayList( access_t *p_access, access_vcd_data_t *p_vcd,
370 const char *psz_source, vcdinfo_itemid_t *itemid,
371 vlc_bool_t b_single_item )
374 playlist_t * p_playlist;
376 unsigned int psz_mrl_max = strlen(VCD_MRL_PREFIX) + strlen(psz_source) +
377 strlen("@T") + strlen("100") + 1;
379 psz_mrl = malloc( psz_mrl_max );
381 if( psz_mrl == NULL )
383 msg_Warn( p_access, "out of memory" );
387 p_playlist = (playlist_t *) vlc_object_find( p_access, VLC_OBJECT_PLAYLIST,
391 msg_Warn( p_access, "can't find playlist" );
397 vcdinfo_itemid_t list_itemid;
398 list_itemid.type=VCDINFO_ITEM_TYPE_ENTRY;
400 playlist_LockDelete( p_playlist, p_playlist->i_index);
402 for( i = 0 ; i < p_vcd->i_entries ; i++ )
405 VCDCreatePlayListItem(p_access, p_vcd, p_playlist, &list_itemid,
406 psz_mrl, psz_mrl_max, psz_source,
407 PLAYLIST_APPEND, PLAYLIST_END);
411 playlist_Command( p_playlist, PLAYLIST_GOTO, 0 );
416 vlc_object_release( p_playlist );