X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fframework%2Fmlt_service.c;h=b5e8f827b350f8cc8719472f27df074b9841d064;hb=93ba5329ea2cadd2ce01b4cceb20f1309fd37bed;hp=5491c13929d0871fc229b8bf1602a126ead32f28;hpb=e5fd66367b6f976e3bcb0ada98408afcb40cb2ce;p=melted diff --git a/src/framework/mlt_service.c b/src/framework/mlt_service.c index 5491c13..b5e8f82 100644 --- a/src/framework/mlt_service.c +++ b/src/framework/mlt_service.c @@ -1,8 +1,9 @@ /** * \file mlt_service.c * \brief interface definition for all service classes + * \see mlt_service_s * - * Copyright (C) 2003-2008 Ushodaya Enterprises Limited + * Copyright (C) 2003-2009 Ushodaya Enterprises Limited * \author Charles Yates * * This library is free software; you can redistribute it and/or @@ -23,11 +24,16 @@ #include "mlt_service.h" #include "mlt_filter.h" #include "mlt_frame.h" +#include "mlt_cache.h" +#include "mlt_factory.h" +#include "mlt_log.h" + #include #include #include #include + /* IMPORTANT NOTES The base service implements a null frame producing service - as such, @@ -60,6 +66,7 @@ static void mlt_service_disconnect( mlt_service this ); static void mlt_service_connect( mlt_service this, mlt_service that ); static int service_get_frame( mlt_service this, mlt_frame_ptr frame, int index ); static void mlt_service_property_changed( mlt_listener, mlt_properties owner, mlt_service this, void **args ); +static void purge_cache( mlt_service self ); /** Initialize a service. * @@ -101,7 +108,9 @@ int mlt_service_init( mlt_service this, void *child ) return error; } -/** The listener for property changes. +/** The transmitter for property changes. + * + * Invokes the listener. * * \private \memberof mlt_service_s * \param listener a function pointer that will be invoked @@ -394,7 +403,6 @@ void mlt_service_apply_filters( mlt_service this, mlt_frame frame, int index ) mlt_service_base *base = this->local; mlt_position position = mlt_frame_get_position( frame ); mlt_position this_in = mlt_properties_get_position( service_properties, "in" ); - /** \properties \em out where to stop playing */ mlt_position this_out = mlt_properties_get_position( service_properties, "out" ); if ( index == 0 || mlt_properties_get_int( service_properties, "_filter_private" ) == 0 ) @@ -627,6 +635,7 @@ void mlt_service_close( mlt_service this ) free( base->in ); pthread_mutex_destroy( &base->mutex ); free( base ); + purge_cache( this ); mlt_properties_close( &this->parent ); } } @@ -635,3 +644,95 @@ void mlt_service_close( mlt_service this ) mlt_service_unlock( this ); } } + +/** Release a service's cache items. + * + * \private \memberof mlt_service_s + * \param self a service + */ + +static void purge_cache( mlt_service self ) +{ + mlt_properties caches = mlt_properties_get_data( mlt_global_properties(), "caches", NULL ); + + if ( caches ) + { + int i = mlt_properties_count( caches ); + while ( i-- ) + { + mlt_cache_purge( mlt_properties_get_data_at( caches, i, NULL ), self ); + mlt_properties_set_data( mlt_global_properties(), mlt_properties_get_name( caches, i ), NULL, 0, NULL, NULL ); + } + } +} + +/** Lookup the cache object for a service. + * + * \private \memberof mlt_service_s + * \param self a service + * \param name a name for the object + * \return a cache + */ + +static mlt_cache get_cache( mlt_service self, const char *name ) +{ + mlt_cache result = NULL; + mlt_properties caches = mlt_properties_get_data( mlt_global_properties(), "caches", NULL ); + + if ( !caches ) + { + caches = mlt_properties_new(); + mlt_properties_set_data( mlt_global_properties(), "caches", caches, 0, ( mlt_destructor )mlt_properties_close, NULL ); + } + if ( caches ) + { + result = mlt_properties_get_data( caches, name, NULL ); + if ( !result ) + { + result = mlt_cache_init(); + mlt_properties_set_data( caches, name, result, 0, ( mlt_destructor )mlt_cache_close, NULL ); + } + } + + return result; +} + +/** Put an object into a service's cache. + * + * \public \memberof mlt_service_s + * \param self a service + * \param name a name for the object that is unique to the service class, but not to the instance + * \param data an opaque pointer to the object to put into the cache + * \param size the number of bytes pointed to by data + * \param destructor a function that releases the data + */ + +void mlt_service_cache_put( mlt_service self, const char *name, void* data, int size, mlt_destructor destructor ) +{ + mlt_log( self, MLT_LOG_DEBUG, "%s: name %s object %p data %p\n", __FUNCTION__, name, self, data ); + mlt_cache cache = get_cache( self, name ); + + if ( cache ) + mlt_cache_put( cache, self, data, size, destructor ); +} + +/** Get an object from a service's cache. + * + * \public \memberof mlt_service_s + * \param self a service + * \param name a name for the object that is unique to the service class, but not to the instance + * \return a cache item or NULL if an object is not found + * \see mlt_cache_item_data + */ + +mlt_cache_item mlt_service_cache_get( mlt_service self, const char *name ) +{ + mlt_log( self, MLT_LOG_DEBUG, "%s: name %s object %p\n", __FUNCTION__, name, self ); + mlt_cache_item result = NULL; + mlt_cache cache = get_cache( self, name ); + + if ( cache ) + result = mlt_cache_get( cache, self ); + + return result; +}