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