eb5a6f54697a98797db62f511c4ddb1f08729eb4
[melted] / mlt++ / test / server.cpp
1 #include <iostream>
2 #include <string>
3 #include <cstring>
4 #include <sstream>
5 using namespace std;
6
7 #include <Mlt.h>
8 using namespace Mlt;
9
10 class Custom : public Miracle
11 {
12 private:
13 Event *event;
14 Profile profile;
15
16 public:
17 Custom( char *name = "Custom", int port = 5290, char *config = NULL ) :
18 Miracle( name, port, config ),
19 event( NULL )
20 {
21 // Ensure that we receive the westley document before it's deserialised
22 set( "push-parser-off", 1 );
23 }
24
25 virtual ~Custom( )
26 {
27 delete event;
28 }
29
30 // Optional step - receive the westley document and do something with it
31 Response *received( char *command, char *document )
32 {
33 cerr << document << endl;
34 Producer producer( profile, "westley-xml", document );
35 return push( command, &producer );
36 }
37
38 // Push handling - clear the playlist, append, seek to beginning and play
39 Response *push( char *command, Service *service )
40 {
41 Playlist playlist( ( mlt_playlist )( unit( 0 )->get_data( "playlist" ) ) );
42 Producer producer( *service );
43 if ( producer.is_valid( ) && playlist.is_valid( ) )
44 {
45 playlist.lock( );
46 playlist.clear( );
47 playlist.append( producer );
48 playlist.seek( 0 );
49 playlist.set_speed( 1 );
50 playlist.unlock( );
51 return new Response( 200, "OK" );
52 }
53 return new Response( 400, "Invalid" );
54 }
55
56 // Custom command execution
57 Response *execute( char *command )
58 {
59 Response *response = NULL;
60
61 if ( !strcmp( command, "debug" ) )
62 {
63 // Example of a custom command
64 response = new Response( 200, "Diagnostics output" );
65 for( int i = 0; unit( i ) != NULL; i ++ )
66 {
67 Properties *properties = unit( i );
68 stringstream output;
69 output << string( "Unit " ) << i << endl;
70 for ( int j = 0; j < properties->count( ); j ++ )
71 output << properties->get_name( j ) << " = " << properties->get( j ) << endl;
72 response->write( output.str( ).c_str( ) );
73 }
74 }
75 else
76 {
77 // Use the default command processing
78 response = Miracle::execute( command );
79 }
80
81 // If no event exists and the first unit has been added...
82 if ( event == NULL && unit( 0 ) != NULL )
83 {
84 // Set up the event handling
85 Consumer consumer( ( mlt_consumer )( unit( 0 )->get_data( "consumer" ) ) );
86 event = consumer.listen( "consumer-frame-render", this, ( mlt_listener )frame_render );
87
88 // In this custom case, we'll loop everything on the unit
89 Playlist playlist( ( mlt_playlist )( unit( 0 )->get_data( "playlist" ) ) );
90 playlist.set( "eof", "loop" );
91 }
92
93 return response;
94 }
95
96 // Callback for frame render notification
97 static void frame_render( mlt_consumer consumer, Custom *self, mlt_frame frame_ptr )
98 {
99 Frame frame( frame_ptr );
100 self->frame_render_event( frame );
101 }
102
103 // Remove all supers and attributes
104 void frame_render_event( Frame &frame )
105 {
106 // Fetch the c double ended queue structure
107 mlt_deque deque = ( mlt_deque )frame.get_data( "data_queue" );
108
109 // While the deque isn't empty
110 while( deque != NULL && mlt_deque_peek_back( deque ) != NULL )
111 {
112 // Fetch the c properties structure
113 mlt_properties cprops = ( mlt_properties )mlt_deque_pop_back( deque );
114
115 // For fun, convert it to c++ and output it :-)
116 Properties properties( cprops );
117 properties.debug( );
118
119 // Wipe it
120 mlt_properties_close( cprops );
121 }
122 }
123 };
124
125 int main( int argc, char **argv )
126 {
127 Custom server( "Server" );
128 server.start( );
129 server.execute( "uadd sdl" );
130 server.execute( "play u0" );
131 server.wait_for_shutdown( );
132 return 0;
133 }
134