]> git.sesse.net Git - vlc/blob - modules/access/vcdx/info.c
Removes trailing spaces. Removes tabs.
[vlc] / modules / access / vcdx / info.c
1 /*****************************************************************************
2  * info.c : CD digital audio input information routines
3  *****************************************************************************
4  * Copyright (C) 2004 the VideoLAN team
5  * $Id$
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
24 #include <vlc/vlc.h>
25 #include <vlc_input.h>
26 #include <vlc_access.h>
27 #include "vcd.h"
28 #include <vlc_playlist.h>
29 #include <vlc_keys.h>
30 #include "info.h"
31
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
39 static inline void
40 MetaInfoAddStr(access_t *p_access, char *psz_cat,
41                char *title, const char *psz)
42 {
43   vcdplayer_t *p_vcdplayer = (vcdplayer_t *) p_access->p_sys;
44   if ( psz ) {
45     dbg_print( INPUT_DBG_META, "cat %s, field: %s: %s", psz_cat, title, psz);
46     input_Control( p_vcdplayer->p_input, INPUT_ADD_INFO, psz_cat, title, "%s",
47            psz);
48   }
49 }
50
51
52 static inline void
53 MetaInfoAddNum(access_t *p_access, char *psz_cat, char *title, int num)
54 {
55   vcdplayer_t *p_vcdplayer = (vcdplayer_t *) p_access->p_sys;
56   dbg_print( INPUT_DBG_META, "cat %s, field %s: %d", psz_cat,  title, num);
57   input_Control( p_vcdplayer->p_input, INPUT_ADD_INFO, psz_cat, title,
58          "%d", num );
59 }
60
61 static inline void
62 MetaInfoAddHex(access_t *p_access, char *psz_cat, char *title, int hex)
63 {
64   vcdplayer_t *p_vcdplayer = (vcdplayer_t *) p_access->p_sys;
65   dbg_print( INPUT_DBG_META, "cat %s, field %s: %d", psz_cat, title, hex);
66   input_Control( p_vcdplayer->p_input, INPUT_ADD_INFO, psz_cat, title,
67          "%x", hex );
68 }
69
70 #define addstr(title, str) \
71   MetaInfoAddStr( p_access, psz_cat, title, str );
72
73 #define addnum(title, num) \
74   MetaInfoAddNum( p_access, psz_cat, title, num );
75
76 #define addhex(title, hex) \
77   MetaInfoAddHex( p_access, psz_cat, title, hex );
78
79 void
80 VCDMetaInfo( access_t *p_access, /*const*/ char *psz_mrl )
81 {
82   vcdplayer_t *p_vcdplayer = (vcdplayer_t *) p_access->p_sys;
83   unsigned int i_entries = vcdinfo_get_num_entries(p_vcdplayer->vcd);
84   unsigned int last_entry = 0;
85   char *psz_cat;
86   track_t i_track;
87
88   psz_cat = _("Disc");
89
90   addstr( _("VCD Format"),  vcdinfo_get_format_version_str(p_vcdplayer->vcd) );
91   addstr( _("Album"),       vcdinfo_get_album_id(p_vcdplayer->vcd));
92   addstr( _("Application"), vcdinfo_get_application_id(p_vcdplayer->vcd) );
93   addstr( _("Preparer"),    vcdinfo_get_preparer_id(p_vcdplayer->vcd) );
94   addnum( _("Vol #"),       vcdinfo_get_volume_num(p_vcdplayer->vcd) );
95   addnum( _("Vol max #"),   vcdinfo_get_volume_count(p_vcdplayer->vcd) );
96   addstr( _("Volume Set"),  vcdinfo_get_volumeset_id(p_vcdplayer->vcd) );
97   addstr( _("Volume"),      vcdinfo_get_volume_id(p_vcdplayer->vcd) );
98   addstr( _("Publisher"),   vcdinfo_get_publisher_id(p_vcdplayer->vcd) );
99   addstr( _("System Id"),   vcdinfo_get_system_id(p_vcdplayer->vcd) );
100   addnum( "LIDs",           vcdinfo_get_num_LIDs(p_vcdplayer->vcd) );
101   addnum( _("Entries"),     vcdinfo_get_num_entries(p_vcdplayer->vcd) );
102   addnum( _("Segments"),    vcdinfo_get_num_segments(p_vcdplayer->vcd) );
103   addnum( _("Tracks"),      vcdinfo_get_num_tracks(p_vcdplayer->vcd) );
104
105   /* Spit out track information. Could also include MSF info.
106      Also build title table.
107    */
108
109 #define TITLE_MAX 30
110   for( i_track = 1 ; i_track < p_vcdplayer->i_tracks ; i_track++ ) {
111     char psz_cat[20];
112     unsigned int audio_type = vcdinfo_get_track_audio_type(p_vcdplayer->vcd,
113                                i_track);
114     uint32_t i_secsize = vcdinfo_get_track_sect_count(p_vcdplayer->vcd, i_track);
115
116     snprintf(psz_cat, sizeof(psz_cat), "Track %d", i_track);
117     if (p_vcdplayer->b_svd) {
118       addnum(_("Audio Channels"),
119          vcdinfo_audio_type_num_channels(p_vcdplayer->vcd, audio_type) );
120     }
121
122     addnum(_("First Entry Point"), last_entry );
123     for ( ; last_entry < i_entries
124         && vcdinfo_get_track(p_vcdplayer->vcd, last_entry) == i_track;
125       last_entry++ ) ;
126     addnum(_("Last Entry Point"), last_entry-1 );
127     addnum(_("Track size (in sectors)"), i_secsize );
128   }
129  
130   {
131     lid_t i_lid;
132     for( i_lid = 1 ; i_lid <= p_vcdplayer->i_lids ; i_lid++ ) {
133       PsdListDescriptor_t pxd;
134       char psz_cat[20];
135       snprintf(psz_cat, sizeof(psz_cat), "LID %d", i_lid);
136       if (vcdinfo_lid_get_pxd(p_vcdplayer->vcd, &pxd, i_lid)) {
137     switch (pxd.descriptor_type) {
138     case PSD_TYPE_END_LIST:
139       addstr(_("type"), _("end"));
140       break;
141     case PSD_TYPE_PLAY_LIST:
142       addstr(_("type"), _("play list"));
143       addnum("items",     vcdinf_pld_get_noi(pxd.pld));
144       addhex("next",      vcdinf_pld_get_next_offset(pxd.pld));
145       addhex("previous",  vcdinf_pld_get_prev_offset(pxd.pld));
146       addhex("return",    vcdinf_pld_get_return_offset(pxd.pld));
147       addnum("wait time", vcdinf_get_wait_time(pxd.pld));
148       break;
149     case PSD_TYPE_SELECTION_LIST:
150     case PSD_TYPE_EXT_SELECTION_LIST:
151       addstr(_("type"),
152          PSD_TYPE_SELECTION_LIST == pxd.descriptor_type
153          ? _("extended selection list")
154          : _("selection list")
155          );
156       addhex("default",          vcdinf_psd_get_default_offset(pxd.psd));
157       addhex("loop count",       vcdinf_get_loop_count(pxd.psd));
158       addhex("next",             vcdinf_psd_get_next_offset(pxd.psd));
159       addhex("previous",         vcdinf_psd_get_prev_offset(pxd.psd));
160       addhex("return",           vcdinf_psd_get_return_offset(pxd.psd));
161       addhex("rejected",         vcdinf_psd_get_lid_rejected(pxd.psd));
162       addhex("time-out offset",  vcdinf_get_timeout_offset(pxd.psd));
163       addnum("time-out time",    vcdinf_get_timeout_time(pxd.psd));
164       break;
165     default:
166       addstr(_("type"), _("unknown type"));
167       break;
168     }
169       }
170     }
171   }
172
173   if ( CDIO_INVALID_TRACK != i_track )
174   {
175     char *psz_name =
176       VCDFormatStr( p_access, p_vcdplayer,
177             config_GetPsz( p_access, MODULE_STRING "-title-format" ),
178             psz_mrl, &(p_vcdplayer->play_item) );
179  
180     input_Control( p_vcdplayer->p_input, INPUT_SET_NAME, psz_name );
181   }
182
183 }
184
185 #define add_format_str_info(val)                   \
186   {                                   \
187     const char *str = strdup(val);                   \
188     unsigned int len;                           \
189     if (val != NULL) {                           \
190       len=strlen(str);                           \
191       if (len != 0) {                           \
192         strncat(tp, str, TEMP_STR_LEN-(tp-temp_str));           \
193         tp += len;                           \
194       }                                                        \
195       saw_control_prefix = VLC_FALSE;                   \
196     }                                   \
197   }
198
199 #define add_format_num_info( val, fmt )                   \
200   {                                   \
201     char num_str[10];                           \
202     unsigned int len;                           \
203     sprintf(num_str, fmt, val);                                \
204     len = strlen(num_str);                       \
205     if( len != 0 )                                             \
206     {                                           \
207       strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str));        \
208       tp += len;                           \
209     }                                   \
210     saw_control_prefix = VLC_FALSE;                                \
211   }
212
213 /*!
214    Take a format string and expand escape sequences, that is sequences that
215    begin with %, with information from the current VCD.
216    The expanded string is returned. Here is a list of escape sequences:
217
218    %A : The album information
219    %C : The VCD volume count - the number of CD's in the collection.
220    %c : The VCD volume num - the number of the CD in the collection.
221    %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD
222    %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, SEGMENT...
223    %L : The playlist ID prefixed with " LID" if it exists
224    %M : MRL
225    %N : The current number of the %I - a decimal number
226    %P : The publisher ID
227    %p : The preparer ID
228    %S : If we are in a segment (menu), the kind of segment
229    %T : The track number
230    %V : The volume set ID
231    %v : The volume ID
232        A number between 1 and the volume count.
233    %% : a %
234 */
235 char *
236 VCDFormatStr(const access_t *p_access, vcdplayer_t *p_vcdplayer,
237              const char format_str[], const char *mrl,
238              const vcdinfo_itemid_t *itemid)
239 {
240 #define TEMP_STR_SIZE 256
241 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
242   static char    temp_str[TEMP_STR_SIZE];
243   size_t         i;
244   char *         tp = temp_str;
245   vlc_bool_t     saw_control_prefix = VLC_FALSE;
246   size_t         format_len = strlen(format_str);
247
248   memset(temp_str, 0, TEMP_STR_SIZE);
249
250   for (i=0; i<format_len; i++) {
251
252     if (!saw_control_prefix && format_str[i] != '%') {
253       *tp++ = format_str[i];
254       saw_control_prefix = VLC_FALSE;
255       continue;
256     }
257
258     switch(format_str[i]) {
259     case '%':
260       if (saw_control_prefix) {
261         *tp++ = '%';
262       }
263       saw_control_prefix = !saw_control_prefix;
264       break;
265     case 'A':
266       add_format_str_info(vcdinfo_strip_trail(vcdinfo_get_album_id(p_vcdplayer->vcd),
267                                               MAX_ALBUM_LEN));
268       break;
269
270     case 'c':
271       add_format_num_info(vcdinfo_get_volume_num(p_vcdplayer->vcd), "%d");
272       break;
273
274     case 'C':
275       add_format_num_info(vcdinfo_get_volume_count(p_vcdplayer->vcd), "%d");
276       break;
277
278     case 'F':
279       add_format_str_info(vcdinfo_get_format_version_str(p_vcdplayer->vcd));
280       break;
281
282     case 'I':
283       {
284         switch (itemid->type) {
285         case VCDINFO_ITEM_TYPE_TRACK:
286           strncat(tp, _("Track"), TEMP_STR_LEN-(tp-temp_str));
287           tp += strlen(_("Track"));
288         break;
289         case VCDINFO_ITEM_TYPE_ENTRY:
290           strncat(tp, _("Entry"), TEMP_STR_LEN-(tp-temp_str));
291           tp += strlen(_("Entry"));
292           break;
293         case VCDINFO_ITEM_TYPE_SEGMENT:
294           strncat(tp, _("Segment"), TEMP_STR_LEN-(tp-temp_str));
295           tp += strlen(_("Segment"));
296           break;
297         case VCDINFO_ITEM_TYPE_LID:
298           strncat(tp, _("List ID"), TEMP_STR_LEN-(tp-temp_str));
299           tp += strlen(_("List ID"));
300           break;
301         case VCDINFO_ITEM_TYPE_SPAREID2:
302           strncat(tp, _("Navigation"), TEMP_STR_LEN-(tp-temp_str));
303           tp += strlen(_("Navigation"));
304           break;
305         default:
306           /* What to do? */
307           ;
308         }
309         saw_control_prefix = VLC_FALSE;
310       }
311       break;
312
313     case 'L':
314       if (vcdplayer_pbc_is_on(p_vcdplayer)) {
315         char num_str[40];
316         sprintf(num_str, "%s %d", _("List ID"), p_vcdplayer->i_lid);
317         strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str));
318         tp += strlen(num_str);
319       }
320       saw_control_prefix = VLC_FALSE;
321       break;
322
323     case 'M':
324       add_format_str_info(mrl);
325       break;
326
327     case 'N':
328       add_format_num_info(itemid->num, "%d");
329       break;
330
331     case 'p':
332       add_format_str_info(vcdinfo_get_preparer_id(p_vcdplayer->vcd));
333       break;
334
335     case 'P':
336       add_format_str_info(vcdinfo_get_publisher_id(p_vcdplayer->vcd));
337       break;
338
339     case 'S':
340       if ( VCDINFO_ITEM_TYPE_SEGMENT==itemid->type ) {
341         char seg_type_str[30];
342
343         sprintf(seg_type_str, " %s",
344                 vcdinfo_video_type2str(p_vcdplayer->vcd, itemid->num));
345         strncat(tp, seg_type_str, TEMP_STR_LEN-(tp-temp_str));
346         tp += strlen(seg_type_str);
347       }
348       saw_control_prefix = VLC_FALSE;
349       break;
350
351     case 'T':
352       add_format_num_info(p_vcdplayer->i_track, "%d");
353       break;
354
355     case 'V':
356       add_format_str_info(vcdinfo_get_volumeset_id(p_vcdplayer->vcd));
357       break;
358
359     case 'v':
360       add_format_str_info(vcdinfo_get_volume_id(p_vcdplayer->vcd));
361       break;
362
363     default:
364       *tp++ = '%';
365       *tp++ = format_str[i];
366       saw_control_prefix = VLC_FALSE;
367     }
368   }
369   return strdup(temp_str);
370 }
371
372 void
373 VCDUpdateTitle( access_t *p_access )
374 {
375
376     vcdplayer_t *p_vcdplayer= (vcdplayer_t *)p_access->p_sys;
377
378     unsigned int psz_mrl_max = strlen(VCD_MRL_PREFIX)
379       + strlen(p_vcdplayer->psz_source) + sizeof("@E999")+3;
380     char *psz_mrl = malloc( psz_mrl_max );
381
382     if( psz_mrl )
383     {
384         char *psz_name;
385     snprintf(psz_mrl, psz_mrl_max, "%s%s",
386          VCD_MRL_PREFIX, p_vcdplayer->psz_source);
387     psz_name = VCDFormatStr( p_access, p_vcdplayer,
388                  config_GetPsz( p_access, MODULE_STRING
389                         "-title-format" ),
390                 psz_mrl, &(p_vcdplayer->play_item) );
391     input_Control( p_vcdplayer->p_input, INPUT_SET_NAME, psz_name );
392     free(psz_mrl);
393     }
394 }
395