Initial revision
[melted] / 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