]> git.sesse.net Git - mlt/blob - src/framework/mlt_tractor.c
Initial revision
[mlt] / src / framework / mlt_tractor.c
1 /*
2  * mlt_tractor.c -- tractor service class
3  * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
4  * Author: Charles Yates <charles.yates@pandora.be>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22
23 #include "mlt_tractor.h"
24 #include "mlt_frame.h"
25
26 #include <stdio.h>
27 #include <stdlib.h>
28
29 /** Private structure.
30 */
31
32 struct mlt_tractor_s
33 {
34         struct mlt_service_s parent;
35         mlt_service producer;
36 };
37
38 /** Forward references to static methods.
39 */
40
41 static int service_get_frame( mlt_service this, mlt_frame_ptr frame, int track );
42
43 /** Constructor for the tractor.
44
45         TODO: thread this service...
46 */
47
48 mlt_tractor mlt_tractor_init( )
49 {
50         mlt_tractor this = calloc( sizeof( struct mlt_tractor_s ), 1 );
51         if ( this != NULL )
52         {
53                 mlt_service service = &this->parent;
54                 if ( mlt_service_init( service, this ) == 0 )
55                 {
56                         service->get_frame = service_get_frame;
57                 }
58                 else
59                 {
60                         free( this );
61                         this = NULL;
62                 }
63         }
64         return this;
65 }
66
67 /** Get the service object associated to the tractor.
68 */
69
70 mlt_service mlt_tractor_service( mlt_tractor this )
71 {
72         return &this->parent;
73 }
74
75 /** Connect the tractor.
76 */
77
78 int mlt_tractor_connect( mlt_tractor this, mlt_service producer )
79 {
80         int ret = mlt_service_connect_producer( &this->parent, producer, 0 );
81
82         if ( ret == 0 )
83         {
84                 // This is the producer we're going to connect to
85                 this->producer = producer;
86         }
87
88         return ret;
89 }
90
91 /** Get the next frame.
92
93         TODO: This should be reading a pump being populated by the thread...
94 */
95
96 static int service_get_frame( mlt_service parent, mlt_frame_ptr frame, int track )
97 {
98         mlt_tractor this = parent->child;
99
100         // We only respond to the first track requests
101         if ( track == 0 && this->producer != NULL )
102         {
103                 int i = 0;
104                 int looking = 1;
105                 int done = 0;
106                 mlt_frame temp;
107
108                 // Loop through each of the tracks we're harvesting
109                 for ( i = 0; !done; i ++ )
110                 {
111                         // Get a frame from the producer
112                         mlt_service_get_frame( this->producer, &temp, i );
113
114                         // Check for last track
115                         done = mlt_properties_get_int( mlt_frame_properties( temp ), "last_track" );
116
117                         // Handle the frame
118                         if ( done && looking )
119                         {
120                                 // Use this as output if we don't have one already
121                                 *frame = temp;
122                         }
123                         else if ( !mlt_frame_is_test_card( temp ) && looking )
124                         {
125                                 // This is the one we want and we can stop looking
126                                 *frame = temp;
127                                 looking = 0;
128                         }
129                         else
130                         {
131                                 // We discard all other frames
132                                 mlt_frame_close( temp );
133                         }
134                 }
135
136                 // Indicate our found status
137                 return 0;
138         }
139         else
140         {
141                 // Generate a test card
142                 *frame = mlt_frame_init( );
143                 return 0;
144         }
145 }
146
147 /** Close the tractor.
148 */
149
150 void mlt_tractor_close( mlt_tractor this )
151 {
152         mlt_service_close( &this->parent );
153         free( this );
154 }
155