]> git.sesse.net Git - vlc/blob - modules/demux/playlist/qtl.c
Remove E_()
[vlc] / modules / demux / playlist / qtl.c
1 /*****************************************************************************
2  * qtl.c: QuickTime Media Link Importer
3  *****************************************************************************
4  * Copyright (C) 2006 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Antoine Cellerier <dionoea -@t- videolan -Dot- org>
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 /*
25 See
26 http://developer.apple.com/documentation/QuickTime/QT6WhatsNew/Chap1/chapter_1_section_54.html
27 and
28 http://developer.apple.com/documentation/QuickTime/WhatsNewQT5/QT5NewChapt1/chapter_1_section_39.html
29
30 autoplay - true/false
31 controller - true/false
32 fullscreen - normal/double/half/current/full
33 href - url
34 kioskmode - true/false
35 loop - true/false/palindrome
36 movieid - integer
37 moviename - string
38 playeveryframe - true/false
39 qtnext - url
40 quitwhendone - true/false
41 src - url (required)
42 type - mime type
43 volume - 0 (mute) - 100 (max)
44
45 */
46
47 /*****************************************************************************
48  * Preamble
49  *****************************************************************************/
50
51 #ifdef HAVE_CONFIG_H
52 # include "config.h"
53 #endif
54
55 #include <vlc/vlc.h>
56 #include <vlc_demux.h>
57
58 #include "playlist.h"
59 #include "vlc_xml.h"
60
61 struct demux_sys_t
62 {
63     playlist_t *p_playlist;
64     input_item_t *p_current_input;
65
66     xml_t *p_xml;
67     xml_reader_t *p_xml_reader;
68 };
69
70 typedef enum { FULLSCREEN_NORMAL,
71                FULLSCREEN_DOUBLE,
72                FULLSCREEN_HALF,
73                FULLSCREEN_CURRENT,
74                FULLSCREEN_FULL } qtl_fullscreen_t;
75 const char* ppsz_fullscreen[] = { "normal", "double", "half", "current", "full" };
76 typedef enum { LOOP_TRUE,
77                LOOP_FALSE,
78                LOOP_PALINDROME } qtl_loop_t;
79 const char* ppsz_loop[] = { "true", "false", "palindrome" };
80
81 /*****************************************************************************
82  * Local prototypes
83  *****************************************************************************/
84 static int Demux( demux_t *p_demux);
85 static int Control( demux_t *p_demux, int i_query, va_list args );
86
87 /*****************************************************************************
88  * Import_QTL: main import function
89  *****************************************************************************/
90 int Import_QTL( vlc_object_t *p_this )
91 {
92     DEMUX_BY_EXTENSION_MSG( ".qtl", "using QuickTime Media Link reader" );
93     p_demux->p_sys->p_playlist = NULL;
94     p_demux->p_sys->p_xml = NULL;
95     p_demux->p_sys->p_xml_reader = NULL;
96     return VLC_SUCCESS;
97 }
98
99 /*****************************************************************************
100  * Deactivate: frees unused data
101  *****************************************************************************/
102 void Close_QTL( vlc_object_t *p_this )
103 {
104     demux_t *p_demux = (demux_t *)p_this;
105     demux_sys_t *p_sys = p_demux->p_sys;
106
107     if( p_sys->p_playlist )
108         vlc_object_release( p_sys->p_playlist );
109     if( p_sys->p_xml_reader )
110         xml_ReaderDelete( p_sys->p_xml, p_sys->p_xml_reader );
111     if( p_sys->p_xml )
112         xml_Delete( p_sys->p_xml );
113     free( p_sys );
114 }
115
116 static int Demux( demux_t *p_demux )
117 {
118     demux_sys_t *p_sys = p_demux->p_sys;
119     xml_t *p_xml;
120     xml_reader_t *p_xml_reader;
121     char *psz_eltname = NULL;
122     input_item_t *p_input;
123
124     /* List of all possible attributes. The only required one is "src" */
125     bool b_autoplay = false;
126     bool b_controler = true;
127     qtl_fullscreen_t fullscreen = false;
128     char *psz_href = NULL;
129     bool b_kioskmode = false;
130     qtl_loop_t loop = LOOP_FALSE;
131     int i_movieid = -1;
132     char *psz_moviename = NULL;
133     bool b_playeveryframe = false;
134     char *psz_qtnext = NULL;
135     bool b_quitwhendone = false;
136     char *psz_src = NULL;
137     char *psz_mimetype = NULL;
138     int i_volume = 100;
139
140     INIT_PLAYLIST_STUFF;
141
142     p_sys->p_playlist = p_playlist;
143     p_sys->p_current_input = p_current_input;
144
145     p_xml = p_sys->p_xml = xml_Create( p_demux );
146     if( !p_xml ) return -1;
147
148     p_xml_reader = xml_ReaderCreate( p_xml, p_demux->s );
149     if( !p_xml_reader ) return -1;
150     p_sys->p_xml_reader = p_xml_reader;
151
152     /* check root node */
153     if( xml_ReaderRead( p_xml_reader ) != 1 )
154     {
155         msg_Err( p_demux, "invalid file (no root node)" );
156         return -1;
157     }
158
159     if( xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM ||
160         ( psz_eltname = xml_ReaderName( p_xml_reader ) ) == NULL ||
161         strcmp( psz_eltname, "embed" ) )
162     {
163         msg_Err( p_demux, "invalid root node %i, %s",
164                  xml_ReaderNodeType( p_xml_reader ), psz_eltname );
165         free( psz_eltname );
166
167         /* second line has <?quicktime tag ... so we try to skip it */
168         msg_Dbg( p_demux, "trying to read one more node" );
169         xml_ReaderRead( p_xml_reader );
170         if( xml_ReaderNodeType( p_xml_reader ) != XML_READER_STARTELEM ||
171             ( psz_eltname = xml_ReaderName( p_xml_reader ) ) == NULL ||
172             strcmp( psz_eltname, "embed" ) )
173         {
174             msg_Err( p_demux, "invalid root node %i, %s",
175                      xml_ReaderNodeType( p_xml_reader ), psz_eltname );
176             free( psz_eltname );
177             return -1;
178         }
179     }
180     free( psz_eltname );
181
182     while( xml_ReaderNextAttr( p_sys->p_xml_reader ) == VLC_SUCCESS )
183     {
184         char *psz_attrname = xml_ReaderName( p_sys->p_xml_reader );
185         char *psz_attrvalue = xml_ReaderValue( p_sys->p_xml_reader );
186
187         if( !psz_attrname || !psz_attrvalue )
188         {
189             free( psz_attrname );
190             free( psz_attrvalue );
191             return -1;
192         }
193
194         if( !strcmp( psz_attrname, "autoplay" ) )
195         {
196             if( !strcmp( psz_attrvalue, "true" ) )
197             {
198                 b_autoplay = true;
199             }
200             else
201             {
202                 b_autoplay = false;
203             }
204         }
205         else if( !strcmp( psz_attrname, "controler" ) )
206         {
207             if( !strcmp( psz_attrvalue, "false" ) )
208             {
209                 b_controler = false;
210             }
211             else
212             {
213                 b_controler = true;
214             }
215         }
216         else if( !strcmp( psz_attrname, "fullscreen" ) )
217         {
218             if( !strcmp( psz_attrvalue, "double" ) )
219             {
220                 fullscreen = FULLSCREEN_DOUBLE;
221             }
222             else if( !strcmp( psz_attrvalue, "half" ) )
223             {
224                 fullscreen = FULLSCREEN_HALF;
225             }
226             else if( !strcmp( psz_attrvalue, "current" ) )
227             {
228                 fullscreen = FULLSCREEN_CURRENT;
229             }
230             else if( !strcmp( psz_attrvalue, "full" ) )
231             {
232                 fullscreen = FULLSCREEN_FULL;
233             }
234             else
235             {
236                 fullscreen = FULLSCREEN_NORMAL;
237             }
238         }
239         else if( !strcmp( psz_attrname, "href" ) )
240         {
241             psz_href = psz_attrvalue;
242             psz_attrvalue = NULL;
243         }
244         else if( !strcmp( psz_attrname, "kioskmode" ) )
245         {
246             if( !strcmp( psz_attrvalue, "true" ) )
247             {
248                 b_kioskmode = true;
249             }
250             else
251             {
252                 b_kioskmode = false;
253             }
254         }
255         else if( !strcmp( psz_attrname, "loop" ) )
256         {
257             if( !strcmp( psz_attrvalue, "true" ) )
258             {
259                 loop = LOOP_TRUE;
260             }
261             else if( !strcmp( psz_attrvalue, "palindrome" ) )
262             {
263                 loop = LOOP_PALINDROME;
264             }
265             else
266             {
267                 loop = LOOP_FALSE;
268             }
269         }
270         else if( !strcmp( psz_attrname, "movieid" ) )
271         {
272             i_movieid = atoi( psz_attrvalue );
273         }
274         else if( !strcmp( psz_attrname, "moviename" ) )
275         {
276             psz_moviename = psz_attrvalue;
277             psz_attrvalue = NULL;
278         }
279         else if( !strcmp( psz_attrname, "playeveryframe" ) )
280         {
281             if( !strcmp( psz_attrvalue, "true" ) )
282             {
283                 b_playeveryframe = true;
284             }
285             else
286             {
287                 b_playeveryframe = false;
288             }
289         }
290         else if( !strcmp( psz_attrname, "qtnext" ) )
291         {
292             psz_qtnext = psz_attrvalue;
293             psz_attrvalue = NULL;
294         }
295         else if( !strcmp( psz_attrname, "quitwhendone" ) )
296         {
297             if( !strcmp( psz_attrvalue, "true" ) )
298             {
299                 b_quitwhendone = true;
300             }
301             else
302             {
303                 b_quitwhendone = false;
304             }
305         }
306         else if( !strcmp( psz_attrname, "src" ) )
307         {
308             psz_src = psz_attrvalue;
309             psz_attrvalue = NULL;
310         }
311         else if( !strcmp( psz_attrname, "mimetype" ) )
312         {
313             psz_mimetype = psz_attrvalue;
314             psz_attrvalue = NULL;
315         }
316         else if( !strcmp( psz_attrname, "volume" ) )
317         {
318             i_volume = atoi( psz_attrvalue );
319         }
320         else
321         {
322             msg_Dbg( p_demux, "Attribute %s with value %s isn't valid",
323                      psz_attrname, psz_attrvalue );
324         }
325         free( psz_attrname );
326         free( psz_attrvalue );
327     }
328
329     msg_Dbg( p_demux, "autoplay: %s (unused by VLC)",
330              b_autoplay==true ? "true": "false" );
331     msg_Dbg( p_demux, "controler: %s (unused by VLC)",
332              b_controler==true?"true": "false" );
333     msg_Dbg( p_demux, "fullscreen: %s (unused by VLC)",
334              ppsz_fullscreen[fullscreen] );
335     msg_Dbg( p_demux, "href: %s", psz_href );
336     msg_Dbg( p_demux, "kioskmode: %s (unused by VLC)",
337              b_kioskmode==true?"true":"false" );
338     msg_Dbg( p_demux, "loop: %s (unused by VLC)", ppsz_loop[loop] );
339     msg_Dbg( p_demux, "movieid: %d (unused by VLC)", i_movieid );
340     msg_Dbg( p_demux, "moviename: %s", psz_moviename );
341     msg_Dbg( p_demux, "playeverframe: %s (unused by VLC)",
342              b_playeveryframe==true?"true":"false" );
343     msg_Dbg( p_demux, "qtnext: %s", psz_qtnext );
344     msg_Dbg( p_demux, "quitwhendone: %s (unused by VLC)",
345              b_quitwhendone==true?"true":"false" );
346     msg_Dbg( p_demux, "src: %s", psz_src );
347     msg_Dbg( p_demux, "mimetype: %s", psz_mimetype );
348     msg_Dbg( p_demux, "volume: %d (unused by VLC)", i_volume );
349
350
351     if( !psz_src )
352     {
353         msg_Err( p_demux, "Mandatory attribute 'src' not found" );
354     }
355     else
356     {
357         p_input = input_ItemNewExt( p_sys->p_playlist,
358                                 psz_src, psz_moviename, 0, NULL, -1 );
359 #define SADD_INFO( type, field ) if( field ) { input_ItemAddInfo( \
360                     p_input, "QuickTime Media Link", _(type), "%s", field ) ; }
361         SADD_INFO( "href", psz_href );
362         SADD_INFO( "mime type", psz_mimetype );
363         input_ItemAddSubItem( p_current_input, p_input );
364         vlc_gc_decref( p_input );
365         if( psz_qtnext )
366         {
367             p_input = input_ItemNewExt( p_sys->p_playlist,
368                                         psz_qtnext, NULL, 0, NULL, -1 );
369             input_ItemAddSubItem( p_current_input, p_input );
370             vlc_gc_decref( p_input );
371         }
372     }
373
374     HANDLE_PLAY_AND_RELEASE;
375
376     p_sys->p_playlist = NULL;
377
378     free( psz_href );
379     free( psz_moviename );
380     free( psz_qtnext );
381     free( psz_src );
382     free( psz_mimetype );
383
384     return 0; /* Needed for correct operation of go back */
385 }
386
387 static int Control( demux_t *p_demux, int i_query, va_list args )
388 {
389     VLC_UNUSED(p_demux); VLC_UNUSED(i_query); VLC_UNUSED(args);
390     return VLC_EGENERIC;
391 }