2 * Copyright (C) 2011 Ushodaya Enterprises Limited
3 * Author: Dan Dennedy <dan@dennedy.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <framework/mlt.h>
27 static int start( mlt_consumer consumer );
28 static int stop( mlt_consumer consumer );
29 static int is_stopped( mlt_consumer consumer );
30 static void *consumer_thread( void *arg );
31 static void consumer_close( mlt_consumer consumer );
33 /** Initialise the consumer.
36 mlt_consumer consumer_multi_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
38 mlt_consumer consumer = mlt_consumer_new( profile );
43 consumer->close = consumer_close;
44 consumer->start = start;
45 consumer->stop = stop;
46 consumer->is_stopped = is_stopped;
52 /** Start the consumer.
55 static int start( mlt_consumer consumer )
57 // Check that we're not already running
58 if ( is_stopped( consumer ) )
60 mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
61 pthread_t *thread = calloc( 1, sizeof( pthread_t ) );
63 // Assign the thread to properties with automatic dealloc
64 mlt_properties_set_data( properties, "thread", thread, sizeof( pthread_t ), free, NULL );
66 // Set the running state
67 mlt_properties_set_int( properties, "running", 1 );
70 pthread_create( thread, NULL, consumer_thread, consumer );
75 /** Stop the consumer.
78 static int stop( mlt_consumer consumer )
80 // Check that we're running
81 if ( !is_stopped( consumer ) )
83 mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
84 pthread_t *thread = mlt_properties_get_data( properties, "thread", NULL );
87 mlt_properties_set_int( properties, "running", 0 );
89 // Wait for termination
91 pthread_join( *thread, NULL );
97 /** Determine if the consumer is stopped.
100 static int is_stopped( mlt_consumer consumer )
102 return !mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( consumer ), "running" );
105 /** The main thread - the argument is simply the consumer.
108 static void *consumer_thread( void *arg )
110 mlt_consumer consumer = arg;
111 mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
112 mlt_frame frame = NULL;
114 // Determine whether to stop at end-of-media
115 int terminate_on_pause = mlt_properties_get_int( properties, "terminate_on_pause" );
118 // Loop while running
119 while ( !terminated && mlt_properties_get_int( properties, "running" ) )
121 // Get the next frame
122 frame = mlt_consumer_rt_frame( consumer );
124 // Check for termination
125 if ( terminate_on_pause && frame )
126 terminated = mlt_properties_get_double( MLT_FRAME_PROPERTIES( frame ), "_speed" ) == 0.0;
128 // Check that we have a frame to work with
132 mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
133 mlt_frame_close( frame );
137 // Indicate that the consumer is stopped
138 mlt_properties_set_int( properties, "running", 0 );
139 mlt_consumer_stopped( consumer );
144 /** Close the consumer.
147 static void consumer_close( mlt_consumer consumer )
149 mlt_consumer_stop( consumer );
151 mlt_consumer_close( consumer );