1 /*****************************************************************************
2 * qtl.c: QuickTime Media Link Importer
3 *****************************************************************************
4 * Copyright (C) 2006 the VideoLAN team
7 * Authors: Antoine Cellerier <dionoea -@t- videolan -Dot- org>
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.
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.
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 *****************************************************************************/
26 http://developer.apple.com/documentation/QuickTime/QT6WhatsNew/Chap1/chapter_1_section_54.html
28 http://developer.apple.com/documentation/QuickTime/WhatsNewQT5/QT5NewChapt1/chapter_1_section_39.html
31 controller - true/false
32 fullscreen - normal/double/half/current/full
34 kioskmode - true/false
35 loop - true/false/palindrome
38 playeveryframe - true/false
40 quitwhendone - true/false
43 volume - 0 (mute) - 100 (max)
47 /*****************************************************************************
49 *****************************************************************************/
55 #include <vlc_common.h>
56 #include <vlc_demux.h>
61 typedef enum { FULLSCREEN_NORMAL
,
65 FULLSCREEN_FULL
} qtl_fullscreen_t
;
66 const char* ppsz_fullscreen
[] = { "normal", "double", "half", "current", "full" };
67 typedef enum { LOOP_TRUE
,
69 LOOP_PALINDROME
} qtl_loop_t
;
70 const char* ppsz_loop
[] = { "true", "false", "palindrome" };
72 /*****************************************************************************
74 *****************************************************************************/
75 static int Demux( demux_t
*p_demux
);
76 static int Control( demux_t
*p_demux
, int i_query
, va_list args
);
78 /*****************************************************************************
79 * Import_QTL: main import function
80 *****************************************************************************/
81 int Import_QTL( vlc_object_t
*p_this
)
83 demux_t
*p_demux
= (demux_t
*)p_this
;
85 if( !demux_IsPathExtension( p_demux
, ".qtl" ) )
88 p_demux
->pf_demux
= Demux
;
89 p_demux
->pf_control
= Control
;
90 msg_Dbg( p_demux
, "using QuickTime Media Link reader" );
95 /*****************************************************************************
96 * Deactivate: frees unused data
97 *****************************************************************************/
98 void Close_QTL( vlc_object_t
*p_this
)
103 static int Demux( demux_t
*p_demux
)
106 xml_reader_t
*p_xml_reader
= NULL
;
107 char *psz_eltname
= NULL
;
108 input_item_t
*p_input
;
111 /* List of all possible attributes. The only required one is "src" */
112 bool b_autoplay
= false;
113 bool b_controler
= true;
114 qtl_fullscreen_t fullscreen
= false;
115 char *psz_href
= NULL
;
116 bool b_kioskmode
= false;
117 qtl_loop_t loop
= LOOP_FALSE
;
119 char *psz_moviename
= NULL
;
120 bool b_playeveryframe
= false;
121 char *psz_qtnext
= NULL
;
122 bool b_quitwhendone
= false;
123 char *psz_src
= NULL
;
124 char *psz_mimetype
= NULL
;
127 input_item_t
*p_current_input
= GetCurrentItem(p_demux
);
129 p_xml
= xml_Create( p_demux
);
133 p_xml_reader
= xml_ReaderCreate( p_xml
, p_demux
->s
);
137 /* check root node */
138 if( xml_ReaderRead( p_xml_reader
) != 1 )
140 msg_Err( p_demux
, "invalid file (no root node)" );
144 if( xml_ReaderNodeType( p_xml_reader
) != XML_READER_STARTELEM
||
145 ( psz_eltname
= xml_ReaderName( p_xml_reader
) ) == NULL
||
146 strcmp( psz_eltname
, "embed" ) )
148 msg_Err( p_demux
, "invalid root node %i, %s",
149 xml_ReaderNodeType( p_xml_reader
), psz_eltname
);
152 /* second line has <?quicktime tag ... so we try to skip it */
153 msg_Dbg( p_demux
, "trying to read one more node" );
154 xml_ReaderRead( p_xml_reader
);
155 if( xml_ReaderNodeType( p_xml_reader
) != XML_READER_STARTELEM
||
156 ( psz_eltname
= xml_ReaderName( p_xml_reader
) ) == NULL
||
157 strcmp( psz_eltname
, "embed" ) )
159 msg_Err( p_demux
, "invalid root node %i, %s",
160 xml_ReaderNodeType( p_xml_reader
), psz_eltname
);
167 while( xml_ReaderNextAttr( p_xml_reader
) == VLC_SUCCESS
)
169 char *psz_attrname
= xml_ReaderName( p_xml_reader
);
170 char *psz_attrvalue
= xml_ReaderValue( p_xml_reader
);
172 if( !psz_attrname
|| !psz_attrvalue
)
174 free( psz_attrname
);
175 free( psz_attrvalue
);
179 if( !strcmp( psz_attrname
, "autoplay" ) )
181 b_autoplay
= !strcmp( psz_attrvalue
, "true" );
183 else if( !strcmp( psz_attrname
, "controler" ) )
185 b_controler
= !strcmp( psz_attrvalue
, "false" );
187 else if( !strcmp( psz_attrname
, "fullscreen" ) )
189 if( !strcmp( psz_attrvalue
, "double" ) )
191 fullscreen
= FULLSCREEN_DOUBLE
;
193 else if( !strcmp( psz_attrvalue
, "half" ) )
195 fullscreen
= FULLSCREEN_HALF
;
197 else if( !strcmp( psz_attrvalue
, "current" ) )
199 fullscreen
= FULLSCREEN_CURRENT
;
201 else if( !strcmp( psz_attrvalue
, "full" ) )
203 fullscreen
= FULLSCREEN_FULL
;
207 fullscreen
= FULLSCREEN_NORMAL
;
210 else if( !strcmp( psz_attrname
, "href" ) )
212 psz_href
= psz_attrvalue
;
213 psz_attrvalue
= NULL
;
215 else if( !strcmp( psz_attrname
, "kioskmode" ) )
217 b_kioskmode
= !strcmp( psz_attrvalue
, "true" );
219 else if( !strcmp( psz_attrname
, "loop" ) )
221 if( !strcmp( psz_attrvalue
, "true" ) )
225 else if( !strcmp( psz_attrvalue
, "palindrome" ) )
227 loop
= LOOP_PALINDROME
;
234 else if( !strcmp( psz_attrname
, "movieid" ) )
236 i_movieid
= atoi( psz_attrvalue
);
238 else if( !strcmp( psz_attrname
, "moviename" ) )
240 psz_moviename
= psz_attrvalue
;
241 psz_attrvalue
= NULL
;
243 else if( !strcmp( psz_attrname
, "playeveryframe" ) )
245 b_playeveryframe
= !strcmp( psz_attrvalue
, "true" );
247 else if( !strcmp( psz_attrname
, "qtnext" ) )
249 psz_qtnext
= psz_attrvalue
;
250 psz_attrvalue
= NULL
;
252 else if( !strcmp( psz_attrname
, "quitwhendone" ) )
254 b_quitwhendone
= !strcmp( psz_attrvalue
, "true" );
256 else if( !strcmp( psz_attrname
, "src" ) )
258 psz_src
= psz_attrvalue
;
259 psz_attrvalue
= NULL
;
261 else if( !strcmp( psz_attrname
, "mimetype" ) )
263 psz_mimetype
= psz_attrvalue
;
264 psz_attrvalue
= NULL
;
266 else if( !strcmp( psz_attrname
, "volume" ) )
268 i_volume
= atoi( psz_attrvalue
);
272 msg_Dbg( p_demux
, "Attribute %s with value %s isn't valid",
273 psz_attrname
, psz_attrvalue
);
275 free( psz_attrname
);
276 free( psz_attrvalue
);
279 msg_Dbg( p_demux
, "autoplay: %s (unused by VLC)",
280 b_autoplay
? "true": "false" );
281 msg_Dbg( p_demux
, "controler: %s (unused by VLC)",
282 b_controler
? "true": "false" );
283 msg_Dbg( p_demux
, "fullscreen: %s (unused by VLC)",
284 ppsz_fullscreen
[fullscreen
] );
285 msg_Dbg( p_demux
, "href: %s", psz_href
);
286 msg_Dbg( p_demux
, "kioskmode: %s (unused by VLC)",
287 b_kioskmode
? "true":"false" );
288 msg_Dbg( p_demux
, "loop: %s (unused by VLC)", ppsz_loop
[loop
] );
289 msg_Dbg( p_demux
, "movieid: %d (unused by VLC)", i_movieid
);
290 msg_Dbg( p_demux
, "moviename: %s", psz_moviename
);
291 msg_Dbg( p_demux
, "playeverframe: %s (unused by VLC)",
292 b_playeveryframe
? "true":"false" );
293 msg_Dbg( p_demux
, "qtnext: %s", psz_qtnext
);
294 msg_Dbg( p_demux
, "quitwhendone: %s (unused by VLC)",
295 b_quitwhendone
? "true":"false" );
296 msg_Dbg( p_demux
, "src: %s", psz_src
);
297 msg_Dbg( p_demux
, "mimetype: %s", psz_mimetype
);
298 msg_Dbg( p_demux
, "volume: %d (unused by VLC)", i_volume
);
303 msg_Err( p_demux
, "Mandatory attribute 'src' not found" );
307 input_item_node_t
*p_subitems
= input_item_node_Create( p_current_input
);
308 p_input
= input_item_New( p_demux
, psz_src
, psz_moviename
);
309 #define SADD_INFO( type, field ) if( field ) { input_item_AddInfo( \
310 p_input, "QuickTime Media Link", type, "%s", field ) ; }
311 SADD_INFO( "href", psz_href
);
312 SADD_INFO( _("Mime"), psz_mimetype
);
313 input_item_AddSubItem( p_current_input
, p_input
);
314 input_item_node_AppendItem( p_subitems
, p_input
);
315 vlc_gc_decref( p_input
);
318 p_input
= input_item_New( p_demux
, psz_qtnext
, NULL
);
319 input_item_AddSubItem( p_current_input
, p_input
);
320 input_item_node_AppendItem( p_subitems
, p_input
);
321 vlc_gc_decref( p_input
);
323 input_item_AddSubItemTree( p_subitems
);
324 input_item_node_Delete( p_subitems
);
327 i_ret
= 0; /* Needed for correct operation of go back */
331 xml_ReaderDelete( p_xml
, p_xml_reader
);
335 vlc_gc_decref(p_current_input
);
338 free( psz_moviename
);
341 free( psz_mimetype
);
345 static int Control( demux_t
*p_demux
, int i_query
, va_list args
)
347 VLC_UNUSED(p_demux
); VLC_UNUSED(i_query
); VLC_UNUSED(args
);