Cloning optimisations and introduction of the service parser
[melted] / src / framework / mlt_parser.c
1 /*
2 * mlt_parser.c -- service parsing functionality
3 * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
4 * Author: Charles Yates <charles.yates@pandora.be>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 #include "config.h"
22 #include "mlt.h"
23 #include <stdlib.h>
24
25 static int on_invalid( mlt_parser this, mlt_service object )
26 {
27 return 0;
28 }
29
30 static int on_unknown( mlt_parser this, mlt_service object )
31 {
32 return 0;
33 }
34
35 static int on_start_producer( mlt_parser this, mlt_producer object )
36 {
37 if ( !mlt_producer_is_mix( mlt_producer_cut_parent( object ) ) && mlt_producer_is_cut( object ) )
38 mlt_properties_debug( mlt_producer_properties( object ), "cut", stderr );
39 return 0;
40 }
41
42 static int on_end_producer( mlt_parser this, mlt_producer object )
43 {
44 return 0;
45 }
46
47 static int on_start_playlist( mlt_parser this, mlt_playlist object )
48 {
49 return 0;
50 }
51
52 static int on_end_playlist( mlt_parser this, mlt_playlist object )
53 {
54 return 0;
55 }
56
57 static int on_start_tractor( mlt_parser this, mlt_tractor object )
58 {
59 return 0;
60 }
61
62 static int on_end_tractor( mlt_parser this, mlt_tractor object )
63 {
64 return 0;
65 }
66
67 static int on_start_multitrack( mlt_parser this, mlt_multitrack object )
68 {
69 return 0;
70 }
71
72 static int on_end_multitrack( mlt_parser this, mlt_multitrack object )
73 {
74 return 0;
75 }
76
77 static int on_start_track( mlt_parser this )
78 {
79 return 0;
80 }
81
82 static int on_end_track( mlt_parser this )
83 {
84 return 0;
85 }
86
87 static int on_start_filter( mlt_parser this, mlt_filter object )
88 {
89 return 0;
90 }
91
92 static int on_end_filter( mlt_parser this, mlt_filter object )
93 {
94 return 0;
95 }
96
97 static int on_start_transition( mlt_parser this, mlt_transition object )
98 {
99 return 0;
100 }
101
102 static int on_end_transition( mlt_parser this, mlt_transition object )
103 {
104 return 0;
105 }
106
107 mlt_parser mlt_parser_new( )
108 {
109 mlt_parser this = calloc( 1, sizeof( struct mlt_parser_s ) );
110 if ( this != NULL && mlt_properties_init( &this->parent, this ) == 0 )
111 {
112 this->on_invalid = on_invalid;
113 this->on_unknown = on_unknown;
114 this->on_start_producer = on_start_producer;
115 this->on_end_producer = on_end_producer;
116 this->on_start_playlist = on_start_playlist;
117 this->on_end_playlist = on_end_playlist;
118 this->on_start_tractor = on_start_tractor;
119 this->on_end_tractor = on_end_tractor;
120 this->on_start_multitrack = on_start_multitrack;
121 this->on_end_multitrack = on_end_multitrack;
122 this->on_start_track = on_start_track;
123 this->on_end_track = on_end_track;
124 this->on_start_filter = on_start_filter;
125 this->on_end_filter = on_end_filter;
126 this->on_start_transition = on_start_transition;
127 this->on_end_transition = on_end_transition;
128 }
129 return this;
130 }
131
132 mlt_properties mlt_parser_properties( mlt_parser this )
133 {
134 return &this->parent;
135 }
136
137 int mlt_parser_start( mlt_parser this, mlt_service object )
138 {
139 int error = 0;
140 mlt_service_type type = mlt_service_identify( object );
141 switch( type )
142 {
143 case invalid_type:
144 error = this->on_invalid( this, object );
145 break;
146 case unknown_type:
147 error = this->on_unknown( this, object );
148 break;
149 case producer_type:
150 if ( mlt_producer_is_cut( ( mlt_producer )object ) )
151 error = mlt_parser_start( this, ( mlt_service )mlt_producer_cut_parent( ( mlt_producer )object ) );
152 error = this->on_start_producer( this, ( mlt_producer )object );
153 if ( error == 0 )
154 {
155 int i = 0;
156 while ( error == 0 && mlt_producer_filter( ( mlt_producer )object, i ) != NULL )
157 error = mlt_parser_start( this, ( mlt_service )mlt_producer_filter( ( mlt_producer )object, i ++ ) );
158 }
159 error = this->on_end_producer( this, ( mlt_producer )object );
160 break;
161 case playlist_type:
162 error = this->on_start_playlist( this, ( mlt_playlist )object );
163 if ( error == 0 )
164 {
165 int i = 0;
166 while ( error == 0 && i < mlt_playlist_count( ( mlt_playlist )object ) )
167 mlt_parser_start( this, ( mlt_service )mlt_playlist_get_clip( ( mlt_playlist )object, i ++ ) );
168 i = 0;
169 while ( error == 0 && mlt_producer_filter( ( mlt_producer )object, i ) != NULL )
170 error = mlt_parser_start( this, ( mlt_service )mlt_producer_filter( ( mlt_producer )object, i ++ ) );
171 }
172 error = this->on_end_playlist( this, ( mlt_playlist )object );
173 break;
174 case tractor_type:
175 error = this->on_start_tractor( this, ( mlt_tractor )object );
176 if ( error == 0 )
177 {
178 int i = 0;
179 mlt_service next = mlt_service_producer( object );
180 mlt_parser_start( this, ( mlt_service )mlt_tractor_multitrack( ( mlt_tractor )object ) );
181 while ( next != ( mlt_service )mlt_tractor_multitrack( ( mlt_tractor )object ) )
182 {
183 mlt_parser_start( this, next );
184 next = mlt_service_producer( next );
185 }
186 while ( error == 0 && mlt_producer_filter( ( mlt_producer )object, i ) != NULL )
187 error = mlt_parser_start( this, ( mlt_service )mlt_producer_filter( ( mlt_producer )object, i ++ ) );
188 }
189 error = this->on_end_tractor( this, ( mlt_tractor )object );
190 break;
191 case multitrack_type:
192 error = this->on_start_multitrack( this, ( mlt_multitrack )object );
193 if ( error == 0 )
194 {
195 int i = 0;
196 while ( i < mlt_multitrack_count( ( mlt_multitrack )object ) )
197 {
198 this->on_start_track( this );
199 mlt_parser_start( this, ( mlt_service )mlt_multitrack_track( ( mlt_multitrack )object , i ++ ) );
200 this->on_end_track( this );
201 }
202 i = 0;
203 while ( error == 0 && mlt_producer_filter( ( mlt_producer )object, i ) != NULL )
204 error = mlt_parser_start( this, ( mlt_service )mlt_producer_filter( ( mlt_producer )object, i ++ ) );
205 }
206 error = this->on_end_multitrack( this, ( mlt_multitrack )object );
207 break;
208 case filter_type:
209 error = this->on_start_filter( this, ( mlt_filter )object );
210 if ( error == 0 )
211 {
212 int i = 0;
213 while ( error == 0 && mlt_producer_filter( ( mlt_producer )object, i ) != NULL )
214 error = mlt_parser_start( this, ( mlt_service )mlt_producer_filter( ( mlt_producer )object, i ++ ) );
215 }
216 error = this->on_end_filter( this, ( mlt_filter )object );
217 break;
218 case transition_type:
219 error = this->on_start_transition( this, ( mlt_transition )object );
220 if ( error == 0 )
221 {
222 int i = 0;
223 while ( error == 0 && mlt_producer_filter( ( mlt_producer )object, i ) != NULL )
224 error = mlt_parser_start( this, ( mlt_service )mlt_producer_filter( ( mlt_producer )object, i ++ ) );
225 }
226 error = this->on_end_transition( this, ( mlt_transition )object );
227 break;
228 case field_type:
229 break;
230 case consumer_type:
231 break;
232 }
233 return error;
234 }
235
236 void mlt_parser_close( mlt_parser this )
237 {
238 if ( this != NULL )
239 {
240 mlt_properties_close( &this->parent );
241 free( this );
242 }
243 }
244
245