]> git.sesse.net Git - vlc/blob - modules/access/vcdx/info.c
Work on getting slider seeking working better.
[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 *p_cat,
41                char *title, const char *str)
42 {
43   vcdplayer_t *p_vcd = (vcdplayer_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   vcdplayer_t *p_vcd = (vcdplayer_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, /*const*/ char *psz_mrl )
67 {
68   vcdplayer_t *p_vcd = (vcdplayer_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 = vcdinfo_get_track_sect_count(p_vcd->vcd, i_track);
100
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   if ( CDIO_INVALID_TRACK != i_track )
115   { 
116     char *psz_name = 
117       VCDFormatStr( p_access, p_vcd,
118                     config_GetPsz( p_access, MODULE_STRING "-title-format" ),
119                     psz_mrl, &(p_vcd->play_item) );
120     
121     input_Control( p_vcd->p_input, INPUT_SET_NAME, psz_name );
122   }
123
124 }
125
126 #define add_format_str_info(val)                               \
127   {                                                            \
128     const char *str = val;                                     \
129     unsigned int len;                                          \
130     if (val != NULL) {                                         \
131       len=strlen(str);                                         \
132       if (len != 0) {                                          \
133         strncat(tp, str, TEMP_STR_LEN-(tp-temp_str));          \
134         tp += len;                                             \
135       }                                                        \
136       saw_control_prefix = VLC_FALSE;                          \
137     }                                                          \
138   }
139
140 #define add_format_num_info( val, fmt )                        \
141   {                                                            \
142     char num_str[10];                                          \
143     unsigned int len;                                          \
144     sprintf(num_str, fmt, val);                                \
145     len = strlen(num_str);                                     \
146     if( len != 0 )                                             \
147     {                                                          \
148       strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str));        \
149       tp += len;                                               \
150     }                                                          \
151     saw_control_prefix = VLC_FALSE;                                \
152   }
153
154 /*!
155    Take a format string and expand escape sequences, that is sequences that
156    begin with %, with information from the current VCD.
157    The expanded string is returned. Here is a list of escape sequences:
158
159    %A : The album information
160    %C : The VCD volume count - the number of CD's in the collection.
161    %c : The VCD volume num - the number of the CD in the collection.
162    %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD
163    %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, SEGMENT...
164    %L : The playlist ID prefixed with " LID" if it exists
165    %M : MRL
166    %N : The current number of the %I - a decimal number
167    %P : The publisher ID
168    %p : The preparer ID
169    %S : If we are in a segment (menu), the kind of segment
170    %T : The track number
171    %V : The volume set ID
172    %v : The volume ID
173        A number between 1 and the volume count.
174    %% : a %
175 */
176 char *
177 VCDFormatStr(const access_t *p_access, vcdplayer_t *p_vcd,
178              const char format_str[], const char *mrl,
179              const vcdinfo_itemid_t *itemid)
180 {
181 #define TEMP_STR_SIZE 256
182 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
183   static char    temp_str[TEMP_STR_SIZE];
184   size_t         i;
185   char *         tp = temp_str;
186   vlc_bool_t     saw_control_prefix = VLC_FALSE;
187   size_t         format_len = strlen(format_str);
188
189   memset(temp_str, 0, TEMP_STR_SIZE);
190
191   for (i=0; i<format_len; i++) {
192
193     if (!saw_control_prefix && format_str[i] != '%') {
194       *tp++ = format_str[i];
195       saw_control_prefix = VLC_FALSE;
196       continue;
197     }
198
199     switch(format_str[i]) {
200     case '%':
201       if (saw_control_prefix) {
202         *tp++ = '%';
203       }
204       saw_control_prefix = !saw_control_prefix;
205       break;
206     case 'A':
207       add_format_str_info(vcdinfo_strip_trail(vcdinfo_get_album_id(p_vcd->vcd),
208                                               MAX_ALBUM_LEN));
209       break;
210
211     case 'c':
212       add_format_num_info(vcdinfo_get_volume_num(p_vcd->vcd), "%d");
213       break;
214
215     case 'C':
216       add_format_num_info(vcdinfo_get_volume_count(p_vcd->vcd), "%d");
217       break;
218
219     case 'F':
220       add_format_str_info(vcdinfo_get_format_version_str(p_vcd->vcd));
221       break;
222
223     case 'I':
224       {
225         switch (itemid->type) {
226         case VCDINFO_ITEM_TYPE_TRACK:
227           strncat(tp, _("Track"), TEMP_STR_LEN-(tp-temp_str));
228           tp += strlen(_("Track"));
229         break;
230         case VCDINFO_ITEM_TYPE_ENTRY:
231           strncat(tp, _("Entry"), TEMP_STR_LEN-(tp-temp_str));
232           tp += strlen(_("Entry"));
233           break;
234         case VCDINFO_ITEM_TYPE_SEGMENT:
235           strncat(tp, _("Segment"), TEMP_STR_LEN-(tp-temp_str));
236           tp += strlen(_("Segment"));
237           break;
238         case VCDINFO_ITEM_TYPE_LID:
239           strncat(tp, _("List ID"), TEMP_STR_LEN-(tp-temp_str));
240           tp += strlen(_("List ID"));
241           break;
242         case VCDINFO_ITEM_TYPE_SPAREID2:
243           strncat(tp, _("Navigation"), TEMP_STR_LEN-(tp-temp_str));
244           tp += strlen(_("Navigation"));
245           break;
246         default:
247           /* What to do? */
248           ;
249         }
250         saw_control_prefix = VLC_FALSE;
251       }
252       break;
253
254     case 'L':
255       if (vcdplayer_pbc_is_on(p_vcd)) {
256         char num_str[40];
257         sprintf(num_str, "%s %d", _("List ID"), p_vcd->i_lid);
258         strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str));
259         tp += strlen(num_str);
260       }
261       saw_control_prefix = VLC_FALSE;
262       break;
263
264     case 'M':
265       add_format_str_info(mrl);
266       break;
267
268     case 'N':
269       add_format_num_info(itemid->num, "%d");
270       break;
271
272     case 'p':
273       add_format_str_info(vcdinfo_get_preparer_id(p_vcd->vcd));
274       break;
275
276     case 'P':
277       add_format_str_info(vcdinfo_get_publisher_id(p_vcd->vcd));
278       break;
279
280     case 'S':
281       if ( VCDINFO_ITEM_TYPE_SEGMENT==itemid->type ) {
282         char seg_type_str[10];
283
284         sprintf(seg_type_str, " %s",
285                 vcdinfo_video_type2str(p_vcd->vcd, itemid->num));
286         strncat(tp, seg_type_str, TEMP_STR_LEN-(tp-temp_str));
287         tp += strlen(seg_type_str);
288       }
289       saw_control_prefix = VLC_FALSE;
290       break;
291
292     case 'T':
293       add_format_num_info(p_vcd->i_track, "%d");
294       break;
295
296     case 'V':
297       add_format_str_info(vcdinfo_get_volumeset_id(p_vcd->vcd));
298       break;
299
300     case 'v':
301       add_format_str_info(vcdinfo_get_volume_id(p_vcd->vcd));
302       break;
303
304     default:
305       *tp++ = '%';
306       *tp++ = format_str[i];
307       saw_control_prefix = VLC_FALSE;
308     }
309   }
310   return strdup(temp_str);
311 }
312
313 static void
314 VCDCreatePlayListItem(const access_t *p_access,
315                       vcdplayer_t *p_vcd,
316                       playlist_t *p_playlist,
317                       const vcdinfo_itemid_t *itemid,
318                       char *psz_mrl, int psz_mrl_max,
319                       const char *psz_source, int playlist_operation,
320                       int i_pos)
321 {
322   char *p_author;
323   char *p_title;
324   char c_type;
325
326   switch(itemid->type) {
327   case VCDINFO_ITEM_TYPE_TRACK:
328     c_type='T';
329     break;
330   case VCDINFO_ITEM_TYPE_SEGMENT:
331     c_type='S';
332     break;
333   case VCDINFO_ITEM_TYPE_LID:
334     c_type='P';
335     break;
336   case VCDINFO_ITEM_TYPE_ENTRY:
337     c_type='E';
338     break;
339   default:
340     c_type='?';
341     break;
342   }
343
344   snprintf(psz_mrl, psz_mrl_max, "%s%s@%c%3u", VCD_MRL_PREFIX, psz_source,
345            c_type, itemid->num);
346
347   p_title =
348     VCDFormatStr( p_access, p_vcd,
349                   config_GetPsz( p_access, MODULE_STRING "-title-format" ),
350                   psz_mrl, itemid );
351   
352   playlist_Add( p_playlist, psz_mrl, p_title, playlist_operation, i_pos );
353
354   p_author =
355     VCDFormatStr( p_access, p_vcd,
356                   config_GetPsz( p_access, MODULE_STRING "-author-format" ),
357                   psz_mrl, itemid );
358
359   if( i_pos == PLAYLIST_END ) i_pos = p_playlist->i_size - 1;
360   playlist_AddInfo(p_playlist, i_pos, _("General"), _("Author"), "%s",
361                    p_author);
362 }
363
364 int
365 VCDFixupPlayList( access_t *p_access, vcdplayer_t *p_vcd,
366                   const char *psz_source, vcdinfo_itemid_t *itemid,
367                   vlc_bool_t b_single_item )
368 {
369   unsigned int i;
370   playlist_t * p_playlist;
371   char       * psz_mrl;
372   unsigned int psz_mrl_max = strlen(VCD_MRL_PREFIX) + strlen(psz_source) +
373     strlen("@T") + strlen("100") + 1;
374
375   psz_mrl = malloc( psz_mrl_max );
376
377   if( psz_mrl == NULL )
378     {
379       msg_Warn( p_access, "out of memory" );
380       return -1;
381     }
382
383   p_playlist = (playlist_t *) vlc_object_find( p_access, VLC_OBJECT_PLAYLIST,
384                                                FIND_ANYWHERE );
385   if( !p_playlist )
386     {
387       msg_Warn( p_access, "can't find playlist" );
388       free(psz_mrl);
389       return -1;
390     }
391
392   {
393     vcdinfo_itemid_t list_itemid;
394     list_itemid.type=VCDINFO_ITEM_TYPE_ENTRY;
395
396     playlist_LockDelete( p_playlist, p_playlist->i_index);
397
398     for( i = 0 ; i < p_vcd->i_entries ; i++ )
399       {
400         list_itemid.num=i;
401         VCDCreatePlayListItem(p_access, p_vcd, p_playlist, &list_itemid,
402                               psz_mrl, psz_mrl_max, psz_source,
403                               PLAYLIST_APPEND, PLAYLIST_END);
404       }
405
406 #if LOOKED_OVER
407     playlist_Command( p_playlist, PLAYLIST_GOTO, 0 );
408 #endif
409
410   }
411
412   vlc_object_release( p_playlist );
413   free(psz_mrl);
414   return 0;
415 }
416
417 void
418 VCDUpdateTitle( access_t *p_access )
419
420
421     vcdplayer_t *p_vcd= (vcdplayer_t *)p_access->p_sys;
422
423     unsigned int psz_mrl_max = strlen(VCD_MRL_PREFIX) 
424       + strlen(p_vcd->psz_source) + sizeof("@E999")+3;
425     char *psz_mrl = malloc( psz_mrl_max );
426
427     if( psz_mrl ) 
428     {
429         char *psz_name;
430         snprintf(psz_mrl, psz_mrl_max, "%s%s", 
431                  VCD_MRL_PREFIX, p_vcd->psz_source);
432         psz_name = VCDFormatStr( p_access, p_vcd,
433                                  config_GetPsz( p_access, MODULE_STRING 
434                                                 "-title-format" ),
435                                 psz_mrl, &(p_vcd->play_item) );
436         input_Control( p_vcd->p_input, INPUT_SET_NAME, psz_name );
437         free(psz_mrl);
438     }
439 }
440