+// This function will add remaing services in the context service stack marked
+// with a "xml_retain" property to a property named "xml_retain" on the returned
+// service. The property is a mlt_properties data property.
+
+static void retain_services( struct deserialise_context_s *context, mlt_service service )
+{
+ mlt_properties retain_list = mlt_properties_new();
+ enum service_type type;
+ mlt_service retain_service = context_pop_service( context, &type );
+
+ while ( retain_service )
+ {
+ mlt_properties retain_properties = MLT_SERVICE_PROPERTIES( retain_service );
+
+ if ( mlt_properties_get_int( retain_properties, "xml_retain" ) )
+ {
+ // Remove the retained service from the destructors list.
+ int i;
+ for ( i = mlt_properties_count( context->destructors ) - 1; i >= 1; i -- )
+ {
+ const char *name = mlt_properties_get_name( context->destructors, i );
+ if ( mlt_properties_get_data_at( context->destructors, i, NULL ) == retain_service )
+ {
+ mlt_properties_set_data( context->destructors, name, retain_service, 0, NULL, NULL );
+ break;
+ }
+ }
+ const char *name = mlt_properties_get( retain_properties, "id" );
+ if ( name )
+ mlt_properties_set_data( retain_list, name, retain_service, 0,
+ (mlt_destructor) mlt_service_close, NULL );
+ }
+ retain_service = context_pop_service( context, &type );
+ }
+ if ( mlt_properties_count( retain_list ) > 0 )
+ {
+ mlt_properties_set_data( MLT_SERVICE_PROPERTIES(service), "xml_retain", retain_list, 0,
+ (mlt_destructor) mlt_properties_close, NULL );
+ }
+}
+