]> git.sesse.net Git - vlc/blob - modules/access/vcdx/info.c
Make Zorglub less unhappy
[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: info.c 8845 2004-09-29 09:00:41Z rocky $
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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #include <vlc/vlc.h>
25 #include <vlc/input.h>
26
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     unsigned int audio_type = vcdinfo_get_track_audio_type(p_vcdplayer->vcd, 
112                                                            i_track);
113     uint32_t i_secsize = vcdinfo_get_track_sect_count(p_vcdplayer->vcd, i_track);
114
115     if (p_vcdplayer->b_svd) {
116       addnum(_("Audio Channels"),  
117              vcdinfo_audio_type_num_channels(p_vcdplayer->vcd, audio_type) );
118     }
119
120     addnum(_("First Entry Point"), last_entry );
121     for ( ; last_entry < i_entries 
122             && vcdinfo_get_track(p_vcdplayer->vcd, last_entry) == i_track;
123           last_entry++ ) ;
124     addnum(_("Last Entry Point"), last_entry-1 );
125     addnum(_("Track size (in sectors)"), i_secsize );
126   }
127   
128   {
129     lid_t i_lid;
130     for( i_lid = 1 ; i_lid <= p_vcdplayer->i_lids ; i_lid++ ) {
131       PsdListDescriptor_t pxd;
132       char psz_cat[20];
133       snprintf(psz_cat, sizeof(psz_cat), "LID %d", i_lid);
134       if (vcdinfo_lid_get_pxd(p_vcdplayer->vcd, &pxd, i_lid)) {
135         switch (pxd.descriptor_type) {
136         case PSD_TYPE_END_LIST:
137           addstr(_("type"), _("end"));
138           break;
139         case PSD_TYPE_PLAY_LIST:
140           addstr(_("type"), _("play list"));
141           addnum("items",     vcdinf_pld_get_noi(pxd.pld));
142           addhex("next",      vcdinf_pld_get_next_offset(pxd.pld));
143           addhex("previous",  vcdinf_pld_get_prev_offset(pxd.pld));
144           addhex("return",    vcdinf_pld_get_return_offset(pxd.pld));
145           addnum("wait time", vcdinf_get_wait_time(pxd.pld));
146           break;
147         case PSD_TYPE_SELECTION_LIST:
148         case PSD_TYPE_EXT_SELECTION_LIST:
149           addstr(_("type"), 
150                  PSD_TYPE_SELECTION_LIST == pxd.descriptor_type 
151                  ? _("extended selection list")
152                  : _("selection list")
153                  );
154           addhex("default",          vcdinf_psd_get_default_offset(pxd.psd));
155           addhex("loop count",       vcdinf_get_loop_count(pxd.psd));
156           addhex("next",             vcdinf_psd_get_next_offset(pxd.psd));
157           addhex("previous",         vcdinf_psd_get_prev_offset(pxd.psd));
158           addhex("return",           vcdinf_psd_get_return_offset(pxd.psd));
159           addhex("rejected",         vcdinf_psd_get_lid_rejected(pxd.psd));
160           addhex("time-out offset",  vcdinf_get_timeout_offset(pxd.psd));
161           addnum("time-out time",    vcdinf_get_timeout_time(pxd.psd));
162           break;
163         default: 
164           addstr(_("type"), _("unknown type"));
165           break;
166         }
167       }
168     }
169   }
170
171   if ( CDIO_INVALID_TRACK != i_track )
172   { 
173     char *psz_name = 
174       VCDFormatStr( p_access, p_vcdplayer,
175                     config_GetPsz( p_access, MODULE_STRING "-title-format" ),
176                     psz_mrl, &(p_vcdplayer->play_item) );
177     
178     input_Control( p_vcdplayer->p_input, INPUT_SET_NAME, psz_name );
179   }
180
181 }
182
183 #define add_format_str_info(val)                               \
184   {                                                            \
185     const char *str = strdup(val);                             \
186     unsigned int len;                                          \
187     if (val != NULL) {                                         \
188       len=strlen(str);                                         \
189       if (len != 0) {                                          \
190         strncat(tp, str, TEMP_STR_LEN-(tp-temp_str));          \
191         tp += len;                                             \
192       }                                                        \
193       saw_control_prefix = VLC_FALSE;                          \
194     }                                                          \
195   }
196
197 #define add_format_num_info( val, fmt )                        \
198   {                                                            \
199     char num_str[10];                                          \
200     unsigned int len;                                          \
201     sprintf(num_str, fmt, val);                                \
202     len = strlen(num_str);                                     \
203     if( len != 0 )                                             \
204     {                                                          \
205       strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str));        \
206       tp += len;                                               \
207     }                                                          \
208     saw_control_prefix = VLC_FALSE;                                \
209   }
210
211 /*!
212    Take a format string and expand escape sequences, that is sequences that
213    begin with %, with information from the current VCD.
214    The expanded string is returned. Here is a list of escape sequences:
215
216    %A : The album information
217    %C : The VCD volume count - the number of CD's in the collection.
218    %c : The VCD volume num - the number of the CD in the collection.
219    %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD
220    %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, SEGMENT...
221    %L : The playlist ID prefixed with " LID" if it exists
222    %M : MRL
223    %N : The current number of the %I - a decimal number
224    %P : The publisher ID
225    %p : The preparer ID
226    %S : If we are in a segment (menu), the kind of segment
227    %T : The track number
228    %V : The volume set ID
229    %v : The volume ID
230        A number between 1 and the volume count.
231    %% : a %
232 */
233 char *
234 VCDFormatStr(const access_t *p_access, vcdplayer_t *p_vcdplayer,
235              const char format_str[], const char *mrl,
236              const vcdinfo_itemid_t *itemid)
237 {
238 #define TEMP_STR_SIZE 256
239 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
240   static char    temp_str[TEMP_STR_SIZE];
241   size_t         i;
242   char *         tp = temp_str;
243   vlc_bool_t     saw_control_prefix = VLC_FALSE;
244   size_t         format_len = strlen(format_str);
245
246   memset(temp_str, 0, TEMP_STR_SIZE);
247
248   for (i=0; i<format_len; i++) {
249
250     if (!saw_control_prefix && format_str[i] != '%') {
251       *tp++ = format_str[i];
252       saw_control_prefix = VLC_FALSE;
253       continue;
254     }
255
256     switch(format_str[i]) {
257     case '%':
258       if (saw_control_prefix) {
259         *tp++ = '%';
260       }
261       saw_control_prefix = !saw_control_prefix;
262       break;
263     case 'A':
264       add_format_str_info(vcdinfo_strip_trail(vcdinfo_get_album_id(p_vcdplayer->vcd),
265                                               MAX_ALBUM_LEN));
266       break;
267
268     case 'c':
269       add_format_num_info(vcdinfo_get_volume_num(p_vcdplayer->vcd), "%d");
270       break;
271
272     case 'C':
273       add_format_num_info(vcdinfo_get_volume_count(p_vcdplayer->vcd), "%d");
274       break;
275
276     case 'F':
277       add_format_str_info(vcdinfo_get_format_version_str(p_vcdplayer->vcd));
278       break;
279
280     case 'I':
281       {
282         switch (itemid->type) {
283         case VCDINFO_ITEM_TYPE_TRACK:
284           strncat(tp, _("Track"), TEMP_STR_LEN-(tp-temp_str));
285           tp += strlen(_("Track"));
286         break;
287         case VCDINFO_ITEM_TYPE_ENTRY:
288           strncat(tp, _("Entry"), TEMP_STR_LEN-(tp-temp_str));
289           tp += strlen(_("Entry"));
290           break;
291         case VCDINFO_ITEM_TYPE_SEGMENT:
292           strncat(tp, _("Segment"), TEMP_STR_LEN-(tp-temp_str));
293           tp += strlen(_("Segment"));
294           break;
295         case VCDINFO_ITEM_TYPE_LID:
296           strncat(tp, _("List ID"), TEMP_STR_LEN-(tp-temp_str));
297           tp += strlen(_("List ID"));
298           break;
299         case VCDINFO_ITEM_TYPE_SPAREID2:
300           strncat(tp, _("Navigation"), TEMP_STR_LEN-(tp-temp_str));
301           tp += strlen(_("Navigation"));
302           break;
303         default:
304           /* What to do? */
305           ;
306         }
307         saw_control_prefix = VLC_FALSE;
308       }
309       break;
310
311     case 'L':
312       if (vcdplayer_pbc_is_on(p_vcdplayer)) {
313         char num_str[40];
314         sprintf(num_str, "%s %d", _("List ID"), p_vcdplayer->i_lid);
315         strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str));
316         tp += strlen(num_str);
317       }
318       saw_control_prefix = VLC_FALSE;
319       break;
320
321     case 'M':
322       add_format_str_info(mrl);
323       break;
324
325     case 'N':
326       add_format_num_info(itemid->num, "%d");
327       break;
328
329     case 'p':
330       add_format_str_info(vcdinfo_get_preparer_id(p_vcdplayer->vcd));
331       break;
332
333     case 'P':
334       add_format_str_info(vcdinfo_get_publisher_id(p_vcdplayer->vcd));
335       break;
336
337     case 'S':
338       if ( VCDINFO_ITEM_TYPE_SEGMENT==itemid->type ) {
339         char seg_type_str[30];
340
341         sprintf(seg_type_str, " %s",
342                 vcdinfo_video_type2str(p_vcdplayer->vcd, itemid->num));
343         strncat(tp, seg_type_str, TEMP_STR_LEN-(tp-temp_str));
344         tp += strlen(seg_type_str);
345       }
346       saw_control_prefix = VLC_FALSE;
347       break;
348
349     case 'T':
350       add_format_num_info(p_vcdplayer->i_track, "%d");
351       break;
352
353     case 'V':
354       add_format_str_info(vcdinfo_get_volumeset_id(p_vcdplayer->vcd));
355       break;
356
357     case 'v':
358       add_format_str_info(vcdinfo_get_volume_id(p_vcdplayer->vcd));
359       break;
360
361     default:
362       *tp++ = '%';
363       *tp++ = format_str[i];
364       saw_control_prefix = VLC_FALSE;
365     }
366   }
367   return strdup(temp_str);
368 }
369
370 void
371 VCDUpdateTitle( access_t *p_access )
372
373
374     vcdplayer_t *p_vcdplayer= (vcdplayer_t *)p_access->p_sys;
375
376     unsigned int psz_mrl_max = strlen(VCD_MRL_PREFIX) 
377       + strlen(p_vcdplayer->psz_source) + sizeof("@E999")+3;
378     char *psz_mrl = malloc( psz_mrl_max );
379
380     if( psz_mrl ) 
381     {
382         char *psz_name;
383         snprintf(psz_mrl, psz_mrl_max, "%s%s", 
384                  VCD_MRL_PREFIX, p_vcdplayer->psz_source);
385         psz_name = VCDFormatStr( p_access, p_vcdplayer,
386                                  config_GetPsz( p_access, MODULE_STRING 
387                                                 "-title-format" ),
388                                 psz_mrl, &(p_vcdplayer->play_item) );
389         input_Control( p_vcdplayer->p_input, INPUT_SET_NAME, psz_name );
390         free(psz_mrl);
391     }
392 }
393