a21ab313b9badab78dff9f5dc10e9e2375143fc0
[melted] / src / melted / melted_unit_commands.c
1 /*
2 * melted_unit_commands.c
3 * Copyright (C) 2002-2009 Ushodaya Enterprises Limited
4 * Author: Dan Dennedy <dan@dennedy.org>
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 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32
33 #include "melted_unit.h"
34 #include "melted_commands.h"
35 #include "melted_log.h"
36
37 int melted_load( command_argument cmd_arg )
38 {
39 melted_unit unit = melted_get_unit(cmd_arg->unit);
40 char *filename = (char*) cmd_arg->argument;
41 char fullname[1024];
42 int flush = 1;
43 char *service;
44
45 if ( filename[0] == '!' )
46 {
47 flush = 0;
48 filename ++;
49 }
50
51 service = strchr( filename, ':' );
52 if ( service != NULL )
53 {
54 service = filename;
55 filename = strchr( service, ':' );
56 *filename ++ = '\0';
57
58 if ( strlen( cmd_arg->root_dir ) && filename[0] == '/' )
59 filename++;
60
61 snprintf( fullname, 1023, "%s:%s%s", service, cmd_arg->root_dir, filename );
62 }
63 else
64 {
65 if ( strlen( cmd_arg->root_dir ) && filename[0] == '/' )
66 filename++;
67
68 snprintf( fullname, 1023, "%s%s", cmd_arg->root_dir, filename );
69 }
70
71 if (unit == NULL)
72 return RESPONSE_INVALID_UNIT;
73 else
74 {
75 int32_t in = -1, out = -1;
76 if ( mvcp_tokeniser_count( cmd_arg->tokeniser ) == 5 )
77 {
78 in = atol( mvcp_tokeniser_get_string( cmd_arg->tokeniser, 3 ) );
79 out = atol( mvcp_tokeniser_get_string( cmd_arg->tokeniser, 4 ) );
80 }
81 if ( melted_unit_load( unit, fullname, in, out, flush ) != mvcp_ok )
82 return RESPONSE_BAD_FILE;
83 }
84 return RESPONSE_SUCCESS;
85 }
86
87 int melted_list( command_argument cmd_arg )
88 {
89 melted_unit unit = melted_get_unit( cmd_arg->unit );
90
91 if ( unit != NULL )
92 {
93 melted_unit_report_list( unit, cmd_arg->response );
94 return RESPONSE_SUCCESS;
95 }
96
97 return RESPONSE_INVALID_UNIT;
98 }
99
100 static int parse_clip( command_argument cmd_arg, int arg )
101 {
102 melted_unit unit = melted_get_unit(cmd_arg->unit);
103 int clip = melted_unit_get_current_clip( unit );
104
105 if ( mvcp_tokeniser_count( cmd_arg->tokeniser ) > arg )
106 {
107 char *token = mvcp_tokeniser_get_string( cmd_arg->tokeniser, arg );
108 if ( token[ 0 ] == '+' )
109 clip += atoi( token + 1 );
110 else if ( token[ 0 ] == '-' )
111 clip -= atoi( token + 1 );
112 else
113 clip = atoi( token );
114 }
115
116 return clip;
117 }
118
119 int melted_insert( command_argument cmd_arg )
120 {
121 melted_unit unit = melted_get_unit(cmd_arg->unit);
122 char *filename = (char*) cmd_arg->argument;
123 char fullname[1024];
124
125 if ( strlen( cmd_arg->root_dir ) && filename[0] == '/' )
126 filename++;
127
128 snprintf( fullname, 1023, "%s%s", cmd_arg->root_dir, filename );
129
130 if (unit == NULL)
131 return RESPONSE_INVALID_UNIT;
132 else
133 {
134 long in = -1, out = -1;
135 int index = parse_clip( cmd_arg, 3 );
136
137 if ( mvcp_tokeniser_count( cmd_arg->tokeniser ) == 6 )
138 {
139 in = atoi( mvcp_tokeniser_get_string( cmd_arg->tokeniser, 4 ) );
140 out = atoi( mvcp_tokeniser_get_string( cmd_arg->tokeniser, 5 ) );
141 }
142
143 switch( melted_unit_insert( unit, fullname, index, in, out ) )
144 {
145 case mvcp_ok:
146 return RESPONSE_SUCCESS;
147 default:
148 return RESPONSE_BAD_FILE;
149 }
150 }
151 return RESPONSE_SUCCESS;
152 }
153
154 int melted_remove( command_argument cmd_arg )
155 {
156 melted_unit unit = melted_get_unit(cmd_arg->unit);
157
158 if (unit == NULL)
159 return RESPONSE_INVALID_UNIT;
160 else
161 {
162 int index = parse_clip( cmd_arg, 2 );
163
164 if ( melted_unit_remove( unit, index ) != mvcp_ok )
165 return RESPONSE_BAD_FILE;
166 }
167 return RESPONSE_SUCCESS;
168 }
169
170 int melted_clean( command_argument cmd_arg )
171 {
172 melted_unit unit = melted_get_unit(cmd_arg->unit);
173
174 if (unit == NULL)
175 return RESPONSE_INVALID_UNIT;
176 else
177 {
178 if ( melted_unit_clean( unit ) != mvcp_ok )
179 return RESPONSE_BAD_FILE;
180 }
181 return RESPONSE_SUCCESS;
182 }
183
184 int melted_wipe( command_argument cmd_arg )
185 {
186 melted_unit unit = melted_get_unit(cmd_arg->unit);
187
188 if (unit == NULL)
189 return RESPONSE_INVALID_UNIT;
190 else
191 {
192 if ( melted_unit_wipe( unit ) != mvcp_ok )
193 return RESPONSE_BAD_FILE;
194 }
195 return RESPONSE_SUCCESS;
196 }
197
198 int melted_clear( command_argument cmd_arg )
199 {
200 melted_unit unit = melted_get_unit(cmd_arg->unit);
201
202 if (unit == NULL)
203 return RESPONSE_INVALID_UNIT;
204 else
205 {
206 if ( melted_unit_clear( unit ) != mvcp_ok )
207 return RESPONSE_BAD_FILE;
208 }
209 return RESPONSE_SUCCESS;
210 }
211
212 int melted_move( command_argument cmd_arg )
213 {
214 melted_unit unit = melted_get_unit(cmd_arg->unit);
215
216 if ( unit != NULL )
217 {
218 if ( mvcp_tokeniser_count( cmd_arg->tokeniser ) > 2 )
219 {
220 int src = parse_clip( cmd_arg, 2 );
221 int dest = parse_clip( cmd_arg, 3 );
222
223 if ( melted_unit_move( unit, src, dest ) != mvcp_ok )
224 return RESPONSE_BAD_FILE;
225 }
226 else
227 {
228 return RESPONSE_MISSING_ARG;
229 }
230 }
231 else
232 {
233 return RESPONSE_INVALID_UNIT;
234 }
235
236 return RESPONSE_SUCCESS;
237 }
238
239 int melted_append( command_argument cmd_arg )
240 {
241 melted_unit unit = melted_get_unit(cmd_arg->unit);
242 char *filename = (char*) cmd_arg->argument;
243 char fullname[1024];
244
245 if ( strlen( cmd_arg->root_dir ) && filename[0] == '/' )
246 filename++;
247
248 snprintf( fullname, 1023, "%s%s", cmd_arg->root_dir, filename );
249
250 if (unit == NULL)
251 return RESPONSE_INVALID_UNIT;
252 else
253 {
254 int32_t in = -1, out = -1;
255 if ( mvcp_tokeniser_count( cmd_arg->tokeniser ) == 5 )
256 {
257 in = atol( mvcp_tokeniser_get_string( cmd_arg->tokeniser, 3 ) );
258 out = atol( mvcp_tokeniser_get_string( cmd_arg->tokeniser, 4 ) );
259 }
260 switch ( melted_unit_append( unit, fullname, in, out ) )
261 {
262 case mvcp_ok:
263 return RESPONSE_SUCCESS;
264 default:
265 return RESPONSE_BAD_FILE;
266 }
267 }
268 return RESPONSE_SUCCESS;
269 }
270
271 int melted_push( command_argument cmd_arg, mlt_service service )
272 {
273 melted_unit unit = melted_get_unit(cmd_arg->unit);
274 if ( !unit )
275 return RESPONSE_INVALID_UNIT;
276 if ( service != NULL )
277 if ( melted_unit_append_service( unit, service ) == mvcp_ok )
278 return RESPONSE_SUCCESS;
279 return RESPONSE_BAD_FILE;
280 }
281
282 int melted_receive( command_argument cmd_arg, char *doc )
283 {
284 melted_unit unit = melted_get_unit(cmd_arg->unit);
285 if ( unit == NULL )
286 return RESPONSE_INVALID_UNIT;
287 else
288 {
289 // Get the consumer's profile
290 mlt_consumer consumer = mlt_properties_get_data( unit->properties, "consumer", NULL );
291 mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( consumer ) );
292 mlt_producer producer = mlt_factory_producer( profile, "xml-string", doc );
293 if ( producer != NULL )
294 {
295 if ( melted_unit_append_service( unit, MLT_PRODUCER_SERVICE( producer ) ) == mvcp_ok )
296 {
297 mlt_producer_close( producer );
298 return RESPONSE_SUCCESS;
299 }
300 mlt_producer_close( producer );
301 }
302 }
303 return RESPONSE_BAD_FILE;
304 }
305
306 int melted_play( command_argument cmd_arg )
307 {
308 melted_unit unit = melted_get_unit(cmd_arg->unit);
309
310 if ( unit == NULL )
311 {
312 return RESPONSE_INVALID_UNIT;
313 }
314 else
315 {
316 int speed = 1000;
317 if ( mvcp_tokeniser_count( cmd_arg->tokeniser ) == 3 )
318 speed = atoi( mvcp_tokeniser_get_string( cmd_arg->tokeniser, 2 ) );
319 melted_unit_play( unit, speed );
320 }
321
322 return RESPONSE_SUCCESS;
323 }
324
325 int melted_stop( command_argument cmd_arg )
326 {
327 melted_unit unit = melted_get_unit(cmd_arg->unit);
328 if ( unit == NULL )
329 return RESPONSE_INVALID_UNIT;
330 else
331 melted_unit_terminate( unit );
332 return RESPONSE_SUCCESS;
333 }
334
335 int melted_pause( command_argument cmd_arg )
336 {
337 melted_unit unit = melted_get_unit(cmd_arg->unit);
338 if ( unit == NULL )
339 return RESPONSE_INVALID_UNIT;
340 else
341 melted_unit_play( unit, 0 );
342 return RESPONSE_SUCCESS;
343 }
344
345 int melted_rewind( command_argument cmd_arg )
346 {
347 melted_unit unit = melted_get_unit(cmd_arg->unit);
348 if ( unit == NULL )
349 return RESPONSE_INVALID_UNIT;
350 else if ( melted_unit_has_terminated( unit ) )
351 melted_unit_change_position( unit, 0, 0 );
352 else
353 melted_unit_play( unit, -2000 );
354 return RESPONSE_SUCCESS;
355 }
356
357 int melted_step( command_argument cmd_arg )
358 {
359 melted_unit unit = melted_get_unit(cmd_arg->unit);
360
361 if (unit == NULL)
362 return RESPONSE_INVALID_UNIT;
363 else
364 {
365 melted_unit_play( unit, 0 );
366 melted_unit_step( unit, *(int*) cmd_arg->argument );
367 }
368 return RESPONSE_SUCCESS;
369 }
370
371 int melted_goto( command_argument cmd_arg )
372 {
373 melted_unit unit = melted_get_unit(cmd_arg->unit);
374 int clip = parse_clip( cmd_arg, 3 );
375
376 if (unit == NULL || melted_unit_is_offline(unit))
377 return RESPONSE_INVALID_UNIT;
378 else
379 melted_unit_change_position( unit, clip, *(int*) cmd_arg->argument );
380 return RESPONSE_SUCCESS;
381 }
382
383 int melted_ff( command_argument cmd_arg )
384 {
385 melted_unit unit = melted_get_unit(cmd_arg->unit);
386 if ( unit == NULL )
387 return RESPONSE_INVALID_UNIT;
388 else if ( melted_unit_has_terminated( unit ) )
389 melted_unit_change_position( unit, 0, 0 );
390 else
391 melted_unit_play( unit, 2000 );
392 return RESPONSE_SUCCESS;
393 }
394
395 int melted_set_in_point( command_argument cmd_arg )
396 {
397 melted_unit unit = melted_get_unit(cmd_arg->unit);
398 int clip = parse_clip( cmd_arg, 3 );
399
400 if ( unit == NULL )
401 return RESPONSE_INVALID_UNIT;
402 else
403 {
404 int position = *(int *) cmd_arg->argument;
405
406 switch( melted_unit_set_clip_in( unit, clip, position ) )
407 {
408 case -1:
409 return RESPONSE_BAD_FILE;
410 case -2:
411 return RESPONSE_OUT_OF_RANGE;
412 }
413 }
414 return RESPONSE_SUCCESS;
415 }
416
417 int melted_set_out_point( command_argument cmd_arg )
418 {
419 melted_unit unit = melted_get_unit(cmd_arg->unit);
420 int clip = parse_clip( cmd_arg, 3 );
421
422 if ( unit == NULL )
423 return RESPONSE_INVALID_UNIT;
424 else
425 {
426 int position = *(int *) cmd_arg->argument;
427
428 switch( melted_unit_set_clip_out( unit, clip, position ) )
429 {
430 case -1:
431 return RESPONSE_BAD_FILE;
432 case -2:
433 return RESPONSE_OUT_OF_RANGE;
434 }
435 }
436
437 return RESPONSE_SUCCESS;
438 }
439
440 int melted_get_unit_status( command_argument cmd_arg )
441 {
442 mvcp_status_t status;
443 int error = melted_unit_get_status( melted_get_unit( cmd_arg->unit ), &status );
444
445 if ( error == -1 )
446 return RESPONSE_INVALID_UNIT;
447 else
448 {
449 char text[ 10240 ];
450 mvcp_response_printf( cmd_arg->response, sizeof( text ), mvcp_status_serialise( &status, text, sizeof( text ) ) );
451 return RESPONSE_SUCCESS_1;
452 }
453 return 0;
454 }
455
456
457 int melted_set_unit_property( command_argument cmd_arg )
458 {
459 melted_unit unit = melted_get_unit(cmd_arg->unit);
460 char *name_value = (char*) cmd_arg->argument;
461 if (unit == NULL)
462 return RESPONSE_INVALID_UNIT;
463 else
464 melted_unit_set( unit, name_value );
465 return RESPONSE_SUCCESS;
466 }
467
468 int melted_get_unit_property( command_argument cmd_arg )
469 {
470 melted_unit unit = melted_get_unit(cmd_arg->unit);
471 char *name = (char*) cmd_arg->argument;
472 if (unit == NULL)
473 {
474 return RESPONSE_INVALID_UNIT;
475 }
476 else
477 {
478 char *value = melted_unit_get( unit, name );
479 if ( value != NULL )
480 mvcp_response_printf( cmd_arg->response, 1024, "%s\n", value );
481 }
482 return RESPONSE_SUCCESS;
483 }
484
485
486 int melted_transfer( command_argument cmd_arg )
487 {
488 melted_unit src_unit = melted_get_unit(cmd_arg->unit);
489 int dest_unit_id = -1;
490 char *string = (char*) cmd_arg->argument;
491 if ( string != NULL && ( string[ 0 ] == 'U' || string[ 0 ] == 'u' ) && strlen( string ) > 1 )
492 dest_unit_id = atoi( string + 1 );
493
494 if ( src_unit != NULL && dest_unit_id != -1 )
495 {
496 melted_unit dest_unit = melted_get_unit( dest_unit_id );
497 if ( dest_unit != NULL && !melted_unit_is_offline(dest_unit) && dest_unit != src_unit )
498 {
499 melted_unit_transfer( dest_unit, src_unit );
500 return RESPONSE_SUCCESS;
501 }
502 }
503 return RESPONSE_INVALID_UNIT;
504 }