1 /*****************************************************************************
2 * qtl.c: QuickTime Media Link Importer
3 *****************************************************************************
4 * Copyright (C) 2006 VLC authors and VideoLAN
7 * Authors: Antoine Cellerier <dionoea -@t- videolan -Dot- org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * 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_access.h>
60 #include <vlc_strings.h>
62 typedef enum { FULLSCREEN_NORMAL
,
66 FULLSCREEN_FULL
} qtl_fullscreen_t
;
67 const char* ppsz_fullscreen
[] = { "normal", "double", "half", "current", "full" };
68 typedef enum { LOOP_TRUE
,
70 LOOP_PALINDROME
} qtl_loop_t
;
71 const char* ppsz_loop
[] = { "true", "false", "palindrome" };
73 #define ROOT_NODE_MAX_DEPTH 2
75 /*****************************************************************************
77 *****************************************************************************/
78 static int ReadDir( stream_t
*, input_item_node_t
* );
80 /*****************************************************************************
81 * Import_QTL: main import function
82 *****************************************************************************/
83 int Import_QTL( vlc_object_t
*p_this
)
85 stream_t
*p_demux
= (stream_t
*)p_this
;
88 if( !stream_HasExtension( p_demux
, ".qtl" ) )
91 p_demux
->pf_readdir
= ReadDir
;
92 p_demux
->pf_control
= access_vaDirectoryControlHelper
;
93 msg_Dbg( p_demux
, "using QuickTime Media Link reader" );
98 static int ReadDir( stream_t
*p_demux
, input_item_node_t
*p_subitems
)
100 xml_reader_t
*p_xml_reader
;
101 input_item_t
*p_input
;
104 /* List of all possible attributes. The only required one is "src" */
105 bool b_autoplay
= false;
106 bool b_controller
= true;
107 qtl_fullscreen_t fullscreen
= false;
108 char *psz_href
= NULL
;
109 bool b_kioskmode
= false;
110 qtl_loop_t loop
= LOOP_FALSE
;
112 char *psz_moviename
= NULL
;
113 bool b_playeveryframe
= false;
114 char *psz_qtnext
= NULL
;
115 bool b_quitwhendone
= false;
116 char *psz_src
= NULL
;
117 char *psz_mimetype
= NULL
;
120 p_xml_reader
= xml_ReaderCreate( p_demux
, p_demux
->p_source
);
124 for( int i
= 0;; ++i
) /* locate root node */
127 if( i
== ROOT_NODE_MAX_DEPTH
||
128 xml_ReaderNextNode( p_xml_reader
, &node
) != XML_READER_STARTELEM
)
130 msg_Err( p_demux
, "unable to locate root-node" );
134 if( strcmp( node
, "embed" ) == 0 )
135 break; /* found it */
137 msg_Dbg( p_demux
, "invalid root node <%s>, trying next (%d / %d)",
138 node
, i
+ 1, ROOT_NODE_MAX_DEPTH
);
141 const char *attrname
, *value
;
142 while( (attrname
= xml_ReaderNextAttr( p_xml_reader
, &value
)) != NULL
)
144 if( !strcmp( attrname
, "autoplay" ) )
145 b_autoplay
= !strcmp( value
, "true" );
146 else if( !strcmp( attrname
, "controller" ) )
147 b_controller
= !strcmp( attrname
, "false" );
148 else if( !strcmp( attrname
, "fullscreen" ) )
150 if( !strcmp( value
, "double" ) )
151 fullscreen
= FULLSCREEN_DOUBLE
;
152 else if( !strcmp( value
, "half" ) )
153 fullscreen
= FULLSCREEN_HALF
;
154 else if( !strcmp( value
, "current" ) )
155 fullscreen
= FULLSCREEN_CURRENT
;
156 else if( !strcmp( value
, "full" ) )
157 fullscreen
= FULLSCREEN_FULL
;
159 fullscreen
= FULLSCREEN_NORMAL
;
161 else if( !strcmp( attrname
, "href" ) )
164 psz_href
= strdup( value
);
166 else if( !strcmp( attrname
, "kioskmode" ) )
167 b_kioskmode
= !strcmp( value
, "true" );
168 else if( !strcmp( attrname
, "loop" ) )
170 if( !strcmp( value
, "true" ) )
172 else if( !strcmp( value
, "palindrome" ) )
173 loop
= LOOP_PALINDROME
;
177 else if( !strcmp( attrname
, "movieid" ) )
178 i_movieid
= atoi( value
);
179 else if( !strcmp( attrname
, "moviename" ) )
181 free( psz_moviename
);
182 psz_moviename
= strdup( value
);
184 else if( !strcmp( attrname
, "playeveryframe" ) )
185 b_playeveryframe
= !strcmp( value
, "true" );
186 else if( !strcmp( attrname
, "qtnext" ) )
189 psz_qtnext
= strdup( value
);
191 else if( !strcmp( attrname
, "quitwhendone" ) )
192 b_quitwhendone
= !strcmp( value
, "true" );
193 else if( !strcmp( attrname
, "src" ) )
196 psz_src
= strdup( value
);
198 else if( !strcmp( attrname
, "mimetype" ) )
200 free( psz_mimetype
);
201 psz_mimetype
= strdup( value
);
203 else if( !strcmp( attrname
, "volume" ) )
204 i_volume
= atoi( value
);
206 msg_Dbg( p_demux
, "Attribute %s with value %s isn't valid",
210 msg_Dbg( p_demux
, "autoplay: %s (unused by VLC)",
211 b_autoplay
? "true": "false" );
212 msg_Dbg( p_demux
, "controller: %s (unused by VLC)",
213 b_controller
? "true": "false" );
214 msg_Dbg( p_demux
, "fullscreen: %s (unused by VLC)",
215 ppsz_fullscreen
[fullscreen
] );
216 msg_Dbg( p_demux
, "href: %s", psz_href
);
217 msg_Dbg( p_demux
, "kioskmode: %s (unused by VLC)",
218 b_kioskmode
? "true":"false" );
219 msg_Dbg( p_demux
, "loop: %s (unused by VLC)", ppsz_loop
[loop
] );
220 msg_Dbg( p_demux
, "movieid: %d (unused by VLC)", i_movieid
);
221 msg_Dbg( p_demux
, "moviename: %s", psz_moviename
);
222 msg_Dbg( p_demux
, "playeverframe: %s (unused by VLC)",
223 b_playeveryframe
? "true":"false" );
224 msg_Dbg( p_demux
, "qtnext: %s", psz_qtnext
);
225 msg_Dbg( p_demux
, "quitwhendone: %s (unused by VLC)",
226 b_quitwhendone
? "true":"false" );
227 msg_Dbg( p_demux
, "src: %s", psz_src
);
228 msg_Dbg( p_demux
, "mimetype: %s", psz_mimetype
);
229 msg_Dbg( p_demux
, "volume: %d (unused by VLC)", i_volume
);
234 msg_Err( p_demux
, "Mandatory attribute 'src' not found" );
238 p_input
= input_item_New( psz_src
, psz_moviename
);
239 #define SADD_INFO( type, field ) if( field ) { input_item_AddInfo( \
240 p_input, "QuickTime Media Link", type, "%s", field ) ; }
241 SADD_INFO( "href", psz_href
);
242 SADD_INFO( _("Mime"), psz_mimetype
);
243 input_item_node_AppendItem( p_subitems
, p_input
);
244 input_item_Release( p_input
);
247 vlc_xml_decode( psz_qtnext
);
248 p_input
= input_item_New( psz_qtnext
, NULL
);
249 input_item_node_AppendItem( p_subitems
, p_input
);
250 input_item_Release( p_input
);
254 i_ret
= 0; /* Needed for correct operation of go back */
258 xml_ReaderDelete( p_xml_reader
);
261 free( psz_moviename
);
264 free( psz_mimetype
);