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