Merge mlt++/CUSTOMISING into docs/melted++.
[melted] / mlt++ / test / server.cpp
index 21a6ce3..b82087f 100644 (file)
@@ -1,9 +1,130 @@
-#include <MltMiracle.h>
+#include <iostream>
+#include <string>
+#include <cstring>
+#include <sstream>
+using namespace std;
+
+#include <Mlt.h>
 using namespace Mlt;
 
-int main( int argc, char **argv )
+class Custom : public Miracle
+{
+       private:
+               Event *event;
+               Profile profile;
+
+       public:
+               Custom( char *name = "Custom", int port = 5290, char *config = NULL ) :
+                       Miracle( name, port, config ),
+                       event( NULL )
+               {
+                       // Ensure that we receive the westley document before it's deserialised
+                       set( "push-parser-off", 1 );
+               }
+
+               virtual ~Custom( )
+               {
+                       delete event;
+               }
+
+               // Optional step - receive the westley document and do something with it
+               Response *received( char *command, char *document )
+               {
+                       cerr << document << endl;
+                       Producer producer( profile, "westley-xml", document );
+                       return push( command, &producer );
+               }
+
+               // Push handling - clear the playlist, append, seek to beginning and play
+               Response *push( char*, Service *service )
+               {
+                       Playlist playlist( ( mlt_playlist )( unit( 0 )->get_data( "playlist" ) ) );
+                       Producer producer( *service );
+                       if ( producer.is_valid( ) && playlist.is_valid( ) )
+                       {
+                               playlist.lock( );
+                               playlist.clear( );
+                               playlist.append( producer );
+                               playlist.seek( 0 );
+                               playlist.set_speed( 1 );
+                               playlist.unlock( );
+                               return new Response( 200, "OK" );
+                       }
+                       return new Response( 400, "Invalid" );
+               }
+
+               // Custom command execution
+               Response *execute( char *command )
+               {
+                       Response *response = NULL;
+
+                       if ( !strcmp( command, "debug" ) )
+                       {
+                               // Example of a custom command 
+                               response = new Response( 200, "Diagnostics output" );
+                               for( int i = 0; unit( i ) != NULL; i ++ )
+                               {
+                                       Properties *properties = unit( i );
+                                       stringstream output;
+                                       output << string( "Unit " ) << i << endl;
+                                       for ( int j = 0; j < properties->count( ); j ++ )
+                                               output << properties->get_name( j ) << " = " << properties->get( j ) << endl;
+                                       response->write( output.str( ).c_str( ) );
+                               }
+                       }
+                       else
+                       {
+                               // Use the default command processing
+                               response = Miracle::execute( command );
+                       }
+
+                       // If no event exists and the first unit has been added...
+                       if ( event == NULL && unit( 0 ) != NULL )
+                       {
+                               // Set up the event handling
+                               Consumer consumer( ( mlt_consumer )( unit( 0 )->get_data( "consumer" ) ) );
+                               event = consumer.listen( "consumer-frame-render", this, ( mlt_listener )frame_render );
+
+                               // In this custom case, we'll loop everything on the unit
+                               Playlist playlist( ( mlt_playlist )( unit( 0 )->get_data( "playlist" ) ) );
+                               playlist.set( "eof", "loop" );
+                       }
+
+                       return response;
+               }
+
+               // Callback for frame render notification
+               static void frame_render( mlt_consumer, Custom *self, mlt_frame frame_ptr )
+               {
+                       Frame frame( frame_ptr );
+                       self->frame_render_event( frame );
+               }
+
+               // Remove all supers and attributes
+               void frame_render_event( Frame &frame )
+               {
+                       // Fetch the c double ended queue structure
+                       mlt_deque deque = ( mlt_deque )frame.get_data( "data_queue" );
+
+                       // While the deque isn't empty
+                       while( deque != NULL && mlt_deque_peek_back( deque ) != NULL )
+                       {
+                               // Fetch the c properties structure
+                               mlt_properties cprops = ( mlt_properties )mlt_deque_pop_back( deque );
+
+                               // For fun, convert it to c++ and output it :-)
+                               Properties properties( cprops );
+                               properties.debug( );
+
+                               // Wipe it
+                               mlt_properties_close( cprops );
+                       }
+               }
+};
+       
+int main( int, char** )
 {
-       Miracle server( "miracle++" );
+       Custom server( "Server" );
        server.start( );
        server.execute( "uadd sdl" );
        server.execute( "play u0" );