1 /**
2  * MltProducer.cpp - MLT Wrapper
3  * Copyright (C) 2004-2019 Meltytech, LLC
4  *
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.
9  *
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.
14  *
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19 
20 #include "MltProducer.h"
21 #include "MltFilter.h"
22 #include "MltProfile.h"
23 #include "MltEvent.h"
24 #include "MltConsumer.h"
25 using namespace Mlt;
26 
Producer()27 Producer::Producer( ) :
28 	instance( NULL ),
29 	parent_( NULL )
30 {
31 }
32 
Producer(Profile & profile,const char * id,const char * service)33 Producer::Producer( Profile& profile, const char *id, const char *service ) :
34 	Producer( profile.get_profile() , id, service )
35 {
36 }
37 
Producer(mlt_profile profile,const char * id,const char * service)38 Producer::Producer( mlt_profile profile, const char *id, const char *service ) :
39 	instance( NULL ),
40 	parent_( NULL )
41 {
42 	if ( id != NULL && service != NULL )
43 		instance = mlt_factory_producer( profile, id, service );
44 	else
45 		instance = mlt_factory_producer( profile, NULL, id != NULL ? id : service );
46 }
47 
Producer(Service & producer)48 Producer::Producer( Service &producer ) :
49 	instance( NULL ),
50 	parent_( NULL )
51 {
52 	mlt_service_type type = producer.type( );
53 	if ( type == mlt_service_producer_type || type == mlt_service_playlist_type ||
54 		 type == mlt_service_tractor_type || type == mlt_service_multitrack_type ||
55 		 type == mlt_service_chain_type || type == mlt_service_link_type )
56 	{
57 		instance = ( mlt_producer )producer.get_service( );
58 		inc_ref( );
59 	}
60 }
61 
Producer(mlt_producer producer)62 Producer::Producer( mlt_producer producer ) :
63 	instance( producer ),
64 	parent_( NULL )
65 {
66 	inc_ref( );
67 }
68 
Producer(Producer & producer)69 Producer::Producer( Producer &producer ) :
70 	Mlt::Service( producer ),
71 	instance( producer.get_producer( ) ),
72 	parent_( NULL )
73 {
74 	inc_ref( );
75 }
76 
Producer(const Producer & producer)77 Producer::Producer( const Producer &producer ) :
78 	Producer( const_cast<Producer&>(producer) )
79 {
80 }
81 
Producer(Producer * producer)82 Producer::Producer( Producer *producer ) :
83 	instance( producer != NULL ? producer->get_producer( ) : NULL ),
84 	parent_( NULL )
85 {
86 	if ( is_valid( ) )
87 		inc_ref( );
88 }
89 
~Producer()90 Producer::~Producer( )
91 {
92 	delete parent_;
93 	mlt_producer_close( instance );
94 	instance = NULL;
95 }
96 
operator =(const Producer & producer)97 Producer &Producer::operator=(const Producer &producer)
98 {
99 	if (this != &producer)
100 	{
101 		delete parent_;
102 		parent_ = nullptr;
103 		mlt_producer_close( instance );
104 		instance = producer.instance;
105 		inc_ref( );
106 	}
107 	return *this;
108 }
109 
get_producer()110 mlt_producer Producer::get_producer( )
111 {
112 	return instance;
113 }
114 
get_parent()115 mlt_producer Producer::get_parent( )
116 {
117 	return get_producer( ) != NULL && mlt_producer_cut_parent( get_producer( ) ) != NULL ? mlt_producer_cut_parent( get_producer( ) ) : get_producer( );
118 }
119 
parent()120 Producer &Producer::parent( )
121 {
122 	if ( is_cut( ) && parent_ == NULL )
123 		parent_ = new Producer( get_parent( ) );
124 	return parent_ == NULL ? *this : *parent_;
125 }
126 
get_service()127 mlt_service Producer::get_service( )
128 {
129 	return mlt_producer_service( get_producer( ) );
130 }
131 
seek(int position)132 int Producer::seek( int position )
133 {
134 	return mlt_producer_seek( get_producer( ), position );
135 }
136 
seek(const char * time)137 int Producer::seek( const char *time )
138 {
139 	return mlt_producer_seek_time( get_producer( ), time );
140 }
141 
position()142 int Producer::position( )
143 {
144 	return mlt_producer_position( get_producer( ) );
145 }
146 
frame()147 int Producer::frame( )
148 {
149 	return mlt_producer_frame( get_producer( ) );
150 }
151 
frame_time(mlt_time_format format)152 char* Producer::frame_time( mlt_time_format format )
153 {
154 	return mlt_producer_frame_time( get_producer(), format );
155 }
156 
set_speed(double speed)157 int Producer::set_speed( double speed )
158 {
159 	return mlt_producer_set_speed( get_producer( ), speed );
160 }
161 
pause()162 int Producer::pause()
163 {
164 	int result = 0;
165 
166 	if ( get_speed() != 0 )
167 	{
168 		Consumer consumer( ( mlt_consumer ) mlt_service_consumer( get_service( ) ) );
169 		Event *event = consumer.setup_wait_for( "consumer-sdl-paused" );
170 
171 		result = mlt_producer_set_speed( get_producer( ), 0 );
172 		if ( result == 0 && consumer.is_valid() && !consumer.is_stopped() )
173 			consumer.wait_for( event );
174 		delete event;
175 	}
176 
177 	return result;
178 }
179 
get_speed()180 double Producer::get_speed( )
181 {
182 	return mlt_producer_get_speed( get_producer( ) );
183 }
184 
get_fps()185 double Producer::get_fps( )
186 {
187 	return mlt_producer_get_fps( get_producer( ) );
188 }
189 
set_in_and_out(int in,int out)190 int Producer::set_in_and_out( int in, int out )
191 {
192 	return mlt_producer_set_in_and_out( get_producer( ), in, out );
193 }
194 
get_in()195 int Producer::get_in( )
196 {
197 	return mlt_producer_get_in( get_producer( ) );
198 }
199 
get_out()200 int Producer::get_out( )
201 {
202 	return mlt_producer_get_out( get_producer( ) );
203 }
204 
get_length()205 int Producer::get_length( )
206 {
207 	return mlt_producer_get_length( get_producer( ) );
208 }
209 
get_length_time(mlt_time_format format)210 char* Producer::get_length_time( mlt_time_format format )
211 {
212 	return mlt_producer_get_length_time( get_producer( ), format );
213 }
214 
get_playtime()215 int Producer::get_playtime( )
216 {
217 	return mlt_producer_get_playtime( get_producer( ) );
218 }
219 
cut(int in,int out)220 Producer *Producer::cut( int in, int out )
221 {
222 	mlt_producer producer = mlt_producer_cut( get_producer( ), in, out );
223 	Producer *result = new Producer( producer );
224 	mlt_producer_close( producer );
225 	return result;
226 }
227 
is_cut()228 bool Producer::is_cut( )
229 {
230 	return mlt_producer_is_cut( get_producer( ) ) != 0;
231 }
232 
is_blank()233 bool Producer::is_blank( )
234 {
235 	return mlt_producer_is_blank( get_producer( ) ) != 0;
236 }
237 
same_clip(Producer & that)238 bool Producer::same_clip( Producer &that )
239 {
240 	return mlt_producer_cut_parent( get_producer( ) ) == mlt_producer_cut_parent( that.get_producer( ) );
241 }
242 
runs_into(Producer & that)243 bool Producer::runs_into( Producer &that )
244 {
245 	return same_clip( that ) && get_out( ) == ( that.get_in( ) - 1 );
246 }
247 
optimise()248 void Producer::optimise( )
249 {
250 	mlt_producer_optimise( get_producer( ) );
251 }
252 
clear()253 int Producer::clear( )
254 {
255 	return mlt_producer_clear( get_producer( ) );
256 }
257 
get_creation_time()258 int64_t Producer::get_creation_time( )
259 {
260 	return mlt_producer_get_creation_time( get_producer( ) );
261 }
262 
set_creation_time(int64_t creation_time)263 void Producer::set_creation_time( int64_t creation_time )
264 {
265 	mlt_producer_set_creation_time( get_producer( ), creation_time );
266 }
267