X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fmodules%2Fwestley%2Fproducer_westley.c;h=75fd54184b6a24ca9203c24c61cd15ef6266d461;hb=6857b65acc5bf6d1dcec03e9d7d3436e5712aa03;hp=f929ca5656294250976587b28e55b9c98e284e37;hpb=421997fe7b5ef0735d706c3976ef90fa5b65bd99;p=melted diff --git a/src/modules/westley/producer_westley.c b/src/modules/westley/producer_westley.c index f929ca5..75fd541 100644 --- a/src/modules/westley/producer_westley.c +++ b/src/modules/westley/producer_westley.c @@ -3,19 +3,19 @@ * Copyright (C) 2003-2004 Ushodaya Enterprises Limited * Author: Dan Dennedy * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // TODO: destroy unreferenced producers (they are currently destroyed @@ -296,6 +296,8 @@ static void on_start_tractor( deserialise_context context, const xmlChar *name, for ( ; atts != NULL && *atts != NULL; atts += 2 ) mlt_properties_set( MLT_SERVICE_PROPERTIES( service ), (char*) atts[0], atts[1] == NULL ? "" : (char*) atts[1] ); + mlt_properties_set_int( MLT_TRACTOR_PROPERTIES( tractor ), "global_feed", 1 ); + if ( mlt_properties_get( properties, "id" ) != NULL ) mlt_properties_set_data( context->producer_map, mlt_properties_get( properties, "id" ), service, 0, NULL, NULL ); @@ -431,6 +433,44 @@ static void on_start_producer( deserialise_context context, const xmlChar *name, mlt_properties_set( properties, (char*) atts[0], atts[1] == NULL ? "" : (char*) atts[1] ); } +// Parse a SMIL clock value (as produced by Kino 0.9.1) and return position in frames +static mlt_position parse_clock_value( char *value, double fps ) +{ + // This implementation expects a fully specified clock value - no optional + // parts (e.g. 1:05) + char *pos, *copy = strdup( value ); + int hh, mm, ss, ms; + mlt_position result = -1; + + value = copy; + pos = strchr( value, ':' ); + if ( !pos ) + return result; + *pos = '\0'; + hh = atoi( value ); + value = pos + 1; + + pos = strchr( value, ':' ); + if ( !pos ) + return result; + *pos = '\0'; + mm = atoi( value ); + value = pos + 1; + + pos = strchr( value, '.' ); + if ( !pos ) + return result; + *pos = '\0'; + ss = atoi( value ); + value = pos + 1; + + ms = atoi( value ); + free( copy ); + result = ( fps * ( ( (hh * 3600) + (mm * 60) + ss ) * 1000 + ms ) / 1000 + 0.5 ); + + return result; +} + static void on_end_producer( deserialise_context context, const xmlChar *name ) { enum service_type type; @@ -471,6 +511,9 @@ static void on_end_producer( deserialise_context context, const xmlChar *name ) if ( producer == NULL ) producer = MLT_SERVICE( mlt_factory_producer( "fezzik", "+INVALID.txt" ) ); + if ( producer == NULL ) + producer = MLT_SERVICE( mlt_factory_producer( "fezzik", "colour:red" ) ); + // Track this producer track_service( context->destructors, producer, (mlt_destructor) mlt_producer_close ); @@ -490,14 +533,29 @@ static void on_end_producer( deserialise_context context, const xmlChar *name ) in = mlt_properties_get_position( properties, "in" ); // Let Kino-SMIL clipBegin be a synonym for in if ( mlt_properties_get( properties, "clipBegin" ) != NULL ) - in = mlt_properties_get_position( properties, "clipBegin" ); + { + if ( strchr( mlt_properties_get( properties, "clipBegin" ), ':' ) ) + // Parse clock value + in = parse_clock_value( mlt_properties_get( properties, "clipBegin" ), + mlt_properties_get_double( mlt_producer_properties( MLT_PRODUCER( producer ) ), "fps" ) ); + else + // Parse frames value + in = mlt_properties_get_position( properties, "clipBegin" ); + } // Get out if ( mlt_properties_get( properties, "out" ) != NULL ) out = mlt_properties_get_position( properties, "out" ); // Let Kino-SMIL clipEnd be a synonym for out if ( mlt_properties_get( properties, "clipEnd" ) != NULL ) - out = mlt_properties_get_position( properties, "clipEnd" ); - + { + if ( strchr( mlt_properties_get( properties, "clipEnd" ), ':' ) ) + // Parse clock value + out = parse_clock_value( mlt_properties_get( properties, "clipEnd" ), + mlt_properties_get_double( mlt_producer_properties( MLT_PRODUCER( producer ) ), "fps" ) ); + else + // Parse frames value + out = mlt_properties_get_position( properties, "clipEnd" ); + } // Remove in and out mlt_properties_set( properties, "in", NULL ); mlt_properties_set( properties, "out", NULL ); @@ -1174,11 +1232,15 @@ static xmlEntityPtr on_get_entity( void *ctx, const xmlChar* name ) // Add our parameters if not already params_to_entities( context ); - e = xmlGetDocEntity( context->entity_doc, name ); + e = xmlGetPredefinedEntity( name ); // Send signal to on_characters that an entity substitutin is pending - if ( e != NULL ) - context->entity_is_replace = 1; + if ( e == NULL ) + { + e = xmlGetDocEntity( context->entity_doc, name ); + if ( e != NULL ) + context->entity_is_replace = 1; + } return e; } @@ -1250,10 +1312,25 @@ static void parse_url( mlt_properties properties, char *url ) mlt_properties_set( properties, name, value ); } +// Quick workaround to avoid unecessary libxml2 warnings +static int file_exists( char *file ) +{ + char *name = strdup( file ); + int exists = 0; + if ( name != NULL && strchr( name, '?' ) ) + *( strchr( name, '?' ) ) = '\0'; + if ( name != NULL ) + { + FILE *f = fopen( name, "r" ); + exists = f != NULL; + if ( exists ) fclose( f ); + } + free( name ); + return exists; +} + mlt_producer producer_westley_init( int info, char *data ) { - if ( data == NULL ) - return NULL; xmlSAXHandler *sax = calloc( 1, sizeof( xmlSAXHandler ) ); struct deserialise_context_s *context = calloc( 1, sizeof( struct deserialise_context_s ) ); mlt_properties properties = NULL; @@ -1262,6 +1339,13 @@ mlt_producer producer_westley_init( int info, char *data ) int well_formed = 0; char *filename = NULL; + if ( data == NULL || !strcmp( data, "" ) || ( info == 0 && !file_exists( data ) ) ) + return NULL; + + context = calloc( 1, sizeof( struct deserialise_context_s ) ); + if ( context == NULL ) + return NULL; + context->producer_map = mlt_properties_new(); context->destructors = mlt_properties_new(); context->params = mlt_properties_new(); @@ -1304,7 +1388,7 @@ mlt_producer producer_westley_init( int info, char *data ) sax->cdataBlock = on_characters; sax->internalSubset = on_internal_subset; sax->entityDecl = on_entity_declaration; - //sax->getEntity = on_get_entity; + sax->getEntity = on_get_entity; // Setup libxml2 SAX parsing xmlInitParser();