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