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
)
105 xml_reader_t
*p_xml_reader
;
106 char *psz_eltname
= NULL
;
107 input_item_t
*p_input
;
110 /* List of all possible attributes. The only required one is "src" */
111 bool b_autoplay
= false;
112 bool b_controler
= true;
113 qtl_fullscreen_t fullscreen
= false;
114 char *psz_href
= NULL
;
115 bool b_kioskmode
= false;
116 qtl_loop_t loop
= LOOP_FALSE
;
118 char *psz_moviename
= NULL
;
119 bool b_playeveryframe
= false;
120 char *psz_qtnext
= NULL
;
121 bool b_quitwhendone
= false;
122 char *psz_src
= NULL
;
123 char *psz_mimetype
= NULL
;
126 input_item_t
*p_current_input
= GetCurrentItem(p_demux
);
128 p_xml_reader
= xml_ReaderCreate( p_demux
, p_demux
->s
);
132 /* check root node */
133 if( xml_ReaderRead( p_xml_reader
) != 1 )
135 msg_Err( p_demux
, "invalid file (no root node)" );
139 if( xml_ReaderNodeType( p_xml_reader
) != XML_READER_STARTELEM
||
140 ( psz_eltname
= xml_ReaderName( p_xml_reader
) ) == NULL
||
141 strcmp( psz_eltname
, "embed" ) )
143 msg_Err( p_demux
, "invalid root node %i, %s",
144 xml_ReaderNodeType( p_xml_reader
), psz_eltname
);
147 /* second line has <?quicktime tag ... so we try to skip it */
148 msg_Dbg( p_demux
, "trying to read one more node" );
149 xml_ReaderRead( p_xml_reader
);
150 if( xml_ReaderNodeType( p_xml_reader
) != XML_READER_STARTELEM
||
151 ( psz_eltname
= xml_ReaderName( p_xml_reader
) ) == NULL
||
152 strcmp( psz_eltname
, "embed" ) )
154 msg_Err( p_demux
, "invalid root node %i, %s",
155 xml_ReaderNodeType( p_xml_reader
), psz_eltname
);
162 while( xml_ReaderNextAttr( p_xml_reader
) == VLC_SUCCESS
)
164 char *psz_attrname
= xml_ReaderName( p_xml_reader
);
165 char *psz_attrvalue
= xml_ReaderValue( p_xml_reader
);
167 if( !psz_attrname
|| !psz_attrvalue
)
169 free( psz_attrname
);
170 free( psz_attrvalue
);
174 if( !strcmp( psz_attrname
, "autoplay" ) )
176 b_autoplay
= !strcmp( psz_attrvalue
, "true" );
178 else if( !strcmp( psz_attrname
, "controler" ) )
180 b_controler
= !strcmp( psz_attrvalue
, "false" );
182 else if( !strcmp( psz_attrname
, "fullscreen" ) )
184 if( !strcmp( psz_attrvalue
, "double" ) )
186 fullscreen
= FULLSCREEN_DOUBLE
;
188 else if( !strcmp( psz_attrvalue
, "half" ) )
190 fullscreen
= FULLSCREEN_HALF
;
192 else if( !strcmp( psz_attrvalue
, "current" ) )
194 fullscreen
= FULLSCREEN_CURRENT
;
196 else if( !strcmp( psz_attrvalue
, "full" ) )
198 fullscreen
= FULLSCREEN_FULL
;
202 fullscreen
= FULLSCREEN_NORMAL
;
205 else if( !strcmp( psz_attrname
, "href" ) )
207 psz_href
= psz_attrvalue
;
208 psz_attrvalue
= NULL
;
210 else if( !strcmp( psz_attrname
, "kioskmode" ) )
212 b_kioskmode
= !strcmp( psz_attrvalue
, "true" );
214 else if( !strcmp( psz_attrname
, "loop" ) )
216 if( !strcmp( psz_attrvalue
, "true" ) )
220 else if( !strcmp( psz_attrvalue
, "palindrome" ) )
222 loop
= LOOP_PALINDROME
;
229 else if( !strcmp( psz_attrname
, "movieid" ) )
231 i_movieid
= atoi( psz_attrvalue
);
233 else if( !strcmp( psz_attrname
, "moviename" ) )
235 psz_moviename
= psz_attrvalue
;
236 psz_attrvalue
= NULL
;
238 else if( !strcmp( psz_attrname
, "playeveryframe" ) )
240 b_playeveryframe
= !strcmp( psz_attrvalue
, "true" );
242 else if( !strcmp( psz_attrname
, "qtnext" ) )
244 psz_qtnext
= psz_attrvalue
;
245 psz_attrvalue
= NULL
;
247 else if( !strcmp( psz_attrname
, "quitwhendone" ) )
249 b_quitwhendone
= !strcmp( psz_attrvalue
, "true" );
251 else if( !strcmp( psz_attrname
, "src" ) )
253 psz_src
= psz_attrvalue
;
254 psz_attrvalue
= NULL
;
256 else if( !strcmp( psz_attrname
, "mimetype" ) )
258 psz_mimetype
= psz_attrvalue
;
259 psz_attrvalue
= NULL
;
261 else if( !strcmp( psz_attrname
, "volume" ) )
263 i_volume
= atoi( psz_attrvalue
);
267 msg_Dbg( p_demux
, "Attribute %s with value %s isn't valid",
268 psz_attrname
, psz_attrvalue
);
270 free( psz_attrname
);
271 free( psz_attrvalue
);
274 msg_Dbg( p_demux
, "autoplay: %s (unused by VLC)",
275 b_autoplay
? "true": "false" );
276 msg_Dbg( p_demux
, "controler: %s (unused by VLC)",
277 b_controler
? "true": "false" );
278 msg_Dbg( p_demux
, "fullscreen: %s (unused by VLC)",
279 ppsz_fullscreen
[fullscreen
] );
280 msg_Dbg( p_demux
, "href: %s", psz_href
);
281 msg_Dbg( p_demux
, "kioskmode: %s (unused by VLC)",
282 b_kioskmode
? "true":"false" );
283 msg_Dbg( p_demux
, "loop: %s (unused by VLC)", ppsz_loop
[loop
] );
284 msg_Dbg( p_demux
, "movieid: %d (unused by VLC)", i_movieid
);
285 msg_Dbg( p_demux
, "moviename: %s", psz_moviename
);
286 msg_Dbg( p_demux
, "playeverframe: %s (unused by VLC)",
287 b_playeveryframe
? "true":"false" );
288 msg_Dbg( p_demux
, "qtnext: %s", psz_qtnext
);
289 msg_Dbg( p_demux
, "quitwhendone: %s (unused by VLC)",
290 b_quitwhendone
? "true":"false" );
291 msg_Dbg( p_demux
, "src: %s", psz_src
);
292 msg_Dbg( p_demux
, "mimetype: %s", psz_mimetype
);
293 msg_Dbg( p_demux
, "volume: %d (unused by VLC)", i_volume
);
298 msg_Err( p_demux
, "Mandatory attribute 'src' not found" );
302 input_item_node_t
*p_subitems
= input_item_node_Create( p_current_input
);
303 p_input
= input_item_New( p_demux
, psz_src
, psz_moviename
);
304 #define SADD_INFO( type, field ) if( field ) { input_item_AddInfo( \
305 p_input, "QuickTime Media Link", type, "%s", field ) ; }
306 SADD_INFO( "href", psz_href
);
307 SADD_INFO( _("Mime"), psz_mimetype
);
308 input_item_node_AppendItem( p_subitems
, p_input
);
309 vlc_gc_decref( p_input
);
312 p_input
= input_item_New( p_demux
, psz_qtnext
, NULL
);
313 input_item_node_AppendItem( p_subitems
, p_input
);
314 vlc_gc_decref( p_input
);
316 input_item_node_PostAndDelete( p_subitems
);
319 i_ret
= 0; /* Needed for correct operation of go back */
323 xml_ReaderDelete( p_xml_reader
);
325 vlc_gc_decref(p_current_input
);
328 free( psz_moviename
);
331 free( psz_mimetype
);
335 static int Control( demux_t
*p_demux
, int i_query
, va_list args
)
337 VLC_UNUSED(p_demux
); VLC_UNUSED(i_query
); VLC_UNUSED(args
);