void mlt_service_close( mlt_service self ) { if ( self != NULL && mlt_properties_dec_ref( MLT_SERVICE_PROPERTIES( self ) ) <= 0 ) { if ( self->close != NULL ) { self->close( self->close_object ); } else { mlt_service_base *base = self->local; int i = 0; int count = base->filter_count; mlt_events_block( MLT_SERVICE_PROPERTIES( self ), self ); while( count -- ) mlt_service_detach( self, base->filters[ 0 ] ); free( base->filters ); for ( i = 0; i < base->count; i ++ ) if ( base->in[ i ] != NULL ) mlt_service_close( base->in[ i ] ); self->parent.close = NULL; free( base->in ); pthread_mutex_destroy( &base->mutex ); free( base ); mlt_properties_close( &self->parent ); } } }
int ServiceManager::render(WebVfx::Image* outputImage, mlt_position position, mlt_position length, bool hasAlpha) { double time = length > 0 ? position / (double)length : 0; parameters->setPositionAndLength(position, length); if (mlt_properties_get_int(MLT_SERVICE_PROPERTIES(service), "_reload")) { mlt_properties_set_int(MLT_SERVICE_PROPERTIES(service), "_reload", 0); effects->reload(); } // Produce any extra images if (imageProducers) { for (std::vector<ImageProducer*>::iterator it = imageProducers->begin(); it != imageProducers->end(); it++) { ImageProducer* imageProducer = *it; if (imageProducer && imageProducer->isPositionValid(position)) { WebVfx::Image extraImage = imageProducer->produceImage(position, outputImage->width(), outputImage->height(), hasAlpha); if (extraImage.isNull()) { mlt_log(service, MLT_LOG_ERROR, "WebVfx failed to produce image for name %s\n", imageProducer->getName().toLatin1().constData()); return 1; } effects->setImage(imageProducer->getName(), &extraImage); } } } return !effects->render(time, outputImage); }
void TransitionHandler::deleteTransition(QString tag, int /*a_track*/, int b_track, GenTime in, GenTime out, QDomElement /*xml*/, bool /*do_refresh*/) { QScopedPointer<Mlt::Field> field(m_tractor->field()); field->lock(); mlt_service nextservice = mlt_service_get_producer(field->get_service()); mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice); QString mlt_type = mlt_properties_get(properties, "mlt_type"); QString resource = mlt_properties_get(properties, "mlt_service"); const int old_pos = (int)((in + out).frames(m_fps) / 2); ////qDebug() << " del trans pos: " << in.frames(25) << '-' << out.frames(25); while (mlt_type == QLatin1String("transition")) { mlt_transition tr = (mlt_transition) nextservice; int currentTrack = mlt_transition_get_b_track(tr); int currentIn = (int) mlt_transition_get_in(tr); int currentOut = (int) mlt_transition_get_out(tr); ////qDebug() << "// FOUND EXISTING TRANS, IN: " << currentIn << ", OUT: " << currentOut << ", TRACK: " << currentTrack; if (resource == tag && b_track == currentTrack && currentIn <= old_pos && currentOut >= old_pos) { mlt_field_disconnect_service(field->get_field(), nextservice); break; } nextservice = mlt_service_producer(nextservice); if (nextservice == NULL) break; properties = MLT_SERVICE_PROPERTIES(nextservice); mlt_type = mlt_properties_get(properties, "mlt_type"); resource = mlt_properties_get(properties, "mlt_service"); } field->unlock(); //askForRefresh(); //if (m_isBlocked == 0) m_mltConsumer->set("refresh", 1); }
bool TransitionHandler::moveTransition(QString type, int startTrack, int newTrack, int newTransitionTrack, GenTime oldIn, GenTime oldOut, GenTime newIn, GenTime newOut) { double fps = m_tractor->get_fps(); int new_in = (int)newIn.frames(fps); int new_out = (int)newOut.frames(fps) - 1; if (new_in >= new_out) return false; int old_in = (int)oldIn.frames(fps); int old_out = (int)oldOut.frames(fps) - 1; bool doRefresh = true; // Check if clip is visible in monitor int position = mlt_producer_position(m_tractor->get_producer()); int diff = old_out - position; if (diff < 0 || diff > old_out - old_in) doRefresh = false; if (doRefresh) { diff = new_out - position; if (diff < 0 || diff > new_out - new_in) doRefresh = false; } QScopedPointer<Mlt::Field> field(m_tractor->field()); field->lock(); mlt_service nextservice = mlt_service_get_producer(field->get_service()); mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice); QString resource = mlt_properties_get(properties, "mlt_service"); int old_pos = (int)(old_in + old_out) / 2; bool found = false; mlt_service_type mlt_type = mlt_service_identify( nextservice ); while (mlt_type == transition_type) { Mlt::Transition transition((mlt_transition) nextservice); nextservice = mlt_service_producer(nextservice); int currentTrack = transition.get_b_track(); int currentIn = (int) transition.get_in(); int currentOut = (int) transition.get_out(); if (resource == type && startTrack == currentTrack && currentIn <= old_pos && currentOut >= old_pos) { found = true; if (newTrack - startTrack != 0) { Mlt::Properties trans_props(transition.get_properties()); Mlt::Transition new_transition(*m_tractor->profile(), transition.get("mlt_service")); Mlt::Properties new_trans_props(new_transition.get_properties()); // We cannot use MLT's property inherit because it also clones internal values like _unique_id which messes up the playlist cloneProperties(new_trans_props, trans_props); new_transition.set_in_and_out(new_in, new_out); field->disconnect_service(transition); plantTransition(field.data(), new_transition, newTransitionTrack, newTrack); } else transition.set_in_and_out(new_in, new_out); break; } if (nextservice == NULL) break; properties = MLT_SERVICE_PROPERTIES(nextservice); mlt_type = mlt_service_identify( nextservice ); resource = mlt_properties_get(properties, "mlt_service"); } field->unlock(); if (doRefresh) refresh(); //if (m_isBlocked == 0) m_mltConsumer->set("refresh", 1); return found; }
mlt_service_type mlt_service_identify( mlt_service self ) { mlt_service_type type = invalid_type; if ( self != NULL ) { mlt_properties properties = MLT_SERVICE_PROPERTIES( self ); char *mlt_type = mlt_properties_get( properties, "mlt_type" ); char *resource = mlt_properties_get( properties, "resource" ); if ( mlt_type == NULL ) type = unknown_type; else if (resource != NULL && !strcmp( resource, "<playlist>" ) ) type = playlist_type; else if (resource != NULL && !strcmp( resource, "<tractor>" ) ) type = tractor_type; else if (resource != NULL && !strcmp( resource, "<multitrack>" ) ) type = multitrack_type; else if ( !strcmp( mlt_type, "producer" ) ) type = producer_type; else if ( !strcmp( mlt_type, "filter" ) ) type = filter_type; else if ( !strcmp( mlt_type, "transition" ) ) type = transition_type; else if ( !strcmp( mlt_type, "consumer" ) ) type = consumer_type; else type = unknown_type; } return type; }
int mlt_service_move_filter( mlt_service self, int from, int to ) { int error = -1; if ( self ) { mlt_service_base *base = self->local; if ( from < 0 ) from = 0; if ( from >= base->filter_count ) from = base->filter_count - 1; if ( to < 0 ) to = 0; if ( to >= base->filter_count ) to = base->filter_count - 1; if ( from != to && base->filter_count > 1 ) { mlt_filter filter = base->filters[from]; int i; if ( from > to ) { for ( i = from; i > to; i-- ) base->filters[i] = base->filters[i - 1]; } else { for ( i = from; i < to; i++ ) base->filters[i] = base->filters[i + 1]; } base->filters[to] = filter; mlt_events_fire( MLT_SERVICE_PROPERTIES(self), "service-changed", NULL ); error = 0; } } return error; }
int mlt_consumer_init( mlt_consumer self, void *child, mlt_profile profile ) { int error = 0; memset( self, 0, sizeof( struct mlt_consumer_s ) ); self->child = child; error = mlt_service_init( &self->parent, self ); if ( error == 0 ) { // Get the properties from the service mlt_properties properties = MLT_SERVICE_PROPERTIES( &self->parent ); // Apply profile to properties if ( profile == NULL ) { // Normally the application creates the profile and controls its lifetime // This is the fallback exception handling profile = mlt_profile_init( NULL ); mlt_properties properties = MLT_CONSUMER_PROPERTIES( self ); mlt_properties_set_data( properties, "_profile", profile, 0, (mlt_destructor)mlt_profile_close, NULL ); } apply_profile_properties( self, profile, properties ); // Default rescaler for all consumers mlt_properties_set( properties, "rescale", "bilinear" ); // Default read ahead buffer size mlt_properties_set_int( properties, "buffer", 25 ); mlt_properties_set_int( properties, "drop_max", 5 ); // Default audio frequency and channels mlt_properties_set_int( properties, "frequency", 48000 ); mlt_properties_set_int( properties, "channels", 2 ); // Default of all consumers is real time mlt_properties_set_int( properties, "real_time", 1 ); // Default to environment test card mlt_properties_set( properties, "test_card", mlt_environment( "MLT_TEST_CARD" ) ); // Hmm - default all consumers to yuv422 :-/ self->format = mlt_image_yuv422; mlt_properties_set( properties, "mlt_image_format", mlt_image_format_name( self->format ) ); mlt_properties_set( properties, "mlt_audio_format", mlt_audio_format_name( mlt_audio_s16 ) ); mlt_events_register( properties, "consumer-frame-show", ( mlt_transmitter )mlt_consumer_frame_show ); mlt_events_register( properties, "consumer-frame-render", ( mlt_transmitter )mlt_consumer_frame_render ); mlt_events_register( properties, "consumer-stopped", NULL ); mlt_events_listen( properties, self, "consumer-frame-show", ( mlt_listener )on_consumer_frame_show ); // Register a property-changed listener to handle the profile property - // subsequent properties can override the profile self->event_listener = mlt_events_listen( properties, self, "property-changed", ( mlt_listener )mlt_consumer_property_changed ); // Create the push mutex and condition pthread_mutex_init( &self->put_mutex, NULL ); pthread_cond_init( &self->put_cond, NULL ); } return error; }
void default_callback( void* ptr, int level, const char* fmt, va_list vl ) { static int print_prefix = 1; mlt_properties properties = ptr ? MLT_SERVICE_PROPERTIES( ( mlt_service )ptr ) : NULL; if ( level > log_level ) return; if ( print_prefix && properties ) { char *mlt_type = mlt_properties_get( properties, "mlt_type" ); char *mlt_service = mlt_properties_get( properties, "mlt_service" ); char *resource = mlt_properties_get( properties, "resource" ); if ( !( resource && *resource && resource[0] == '<' && resource[ strlen(resource) - 1 ] == '>' ) ) mlt_type = mlt_properties_get( properties, "mlt_type" ); if ( mlt_service ) fprintf( stderr, "[%s %s] ", mlt_type, mlt_service ); else fprintf( stderr, "[%s %p] ", mlt_type, ptr ); if ( resource ) fprintf( stderr, "%s\n ", resource ); } print_prefix = strstr( fmt, "\n" ) != NULL; vfprintf( stderr, fmt, vl ); }
int mlt_filter_init( mlt_filter self, void *child ) { mlt_service service = &self->parent; memset( self, 0, sizeof( struct mlt_filter_s ) ); self->child = child; if ( mlt_service_init( service, self ) == 0 ) { mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); // Override the get_frame method service->get_frame = filter_get_frame; // Define the destructor service->close = ( mlt_destructor )mlt_filter_close; service->close_object = self; // Default in, out, track properties mlt_properties_set_position( properties, "in", 0 ); mlt_properties_set_position( properties, "out", 0 ); mlt_properties_set_int( properties, "track", 0 ); return 0; } return 1; }
void mlt_service_apply_filters( mlt_service self, mlt_frame frame, int index ) { int i; mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); mlt_properties service_properties = MLT_SERVICE_PROPERTIES( self ); mlt_service_base *base = self->local; mlt_position position = mlt_frame_get_position( frame ); mlt_position self_in = mlt_properties_get_position( service_properties, "in" ); mlt_position self_out = mlt_properties_get_position( service_properties, "out" ); if ( index == 0 || mlt_properties_get_int( service_properties, "_filter_private" ) == 0 ) { // Process the frame with the attached filters for ( i = 0; i < base->filter_count; i ++ ) { if ( base->filters[ i ] != NULL ) { mlt_position in = mlt_filter_get_in( base->filters[ i ] ); mlt_position out = mlt_filter_get_out( base->filters[ i ] ); int disable = mlt_properties_get_int( MLT_FILTER_PROPERTIES( base->filters[ i ] ), "disable" ); if ( !disable && ( ( in == 0 && out == 0 ) || ( position >= in && ( position <= out || out == 0 ) ) ) ) { mlt_properties_set_position( frame_properties, "in", in == 0 ? self_in : in ); mlt_properties_set_position( frame_properties, "out", out == 0 ? self_out : out ); mlt_filter_process( base->filters[ i ], frame ); mlt_service_apply_filters( MLT_FILTER_SERVICE( base->filters[ i ] ), frame, index + 1 ); } } } } }
mlt_position mlt_filter_get_length( mlt_filter self ) { mlt_properties properties = MLT_SERVICE_PROPERTIES( &self->parent ); mlt_position in = mlt_properties_get_position( properties, "in" ); mlt_position out = mlt_properties_get_position( properties, "out" ); return ( out > 0 ) ? ( out - in + 1 ) : 0; }
int mlt_service_detach( mlt_service self, mlt_filter filter ) { int error = self == NULL || filter == NULL; if ( error == 0 ) { int i = 0; mlt_service_base *base = self->local; mlt_properties properties = MLT_SERVICE_PROPERTIES( self ); for ( i = 0; i < base->filter_count; i ++ ) if ( base->filters[ i ] == filter ) break; if ( i < base->filter_count ) { base->filters[ i ] = NULL; for ( i ++ ; i < base->filter_count; i ++ ) base->filters[ i - 1 ] = base->filters[ i ]; base->filter_count --; mlt_events_disconnect( MLT_FILTER_PROPERTIES( filter ), self ); mlt_filter_close( filter ); mlt_events_fire( properties, "service-changed", NULL ); } } return error; }
ServiceManager::ServiceManager(mlt_service service) : service(service) , event(0) , effects(0) , imageProducers(0) { mlt_properties_set(MLT_SERVICE_PROPERTIES(service), "factory", mlt_environment("MLT_PRODUCER")); }
int mlt_producer_init( mlt_producer self, void *child ) { // Check that we haven't received NULL int error = self == NULL; // Continue if no error if ( error == 0 ) { #ifdef _MLT_PRODUCER_CHECKS_ producers_created ++; #endif // Initialise the producer memset( self, 0, sizeof( struct mlt_producer_s ) ); // Associate with the child self->child = child; // Initialise the service if ( mlt_service_init( &self->parent, self ) == 0 ) { // The parent is the service mlt_service parent = &self->parent; // Define the parent close parent->close = ( mlt_destructor )mlt_producer_close; parent->close_object = self; // For convenience, we'll assume the close_object is self self->close_object = self; // Get the properties of the parent mlt_properties properties = MLT_SERVICE_PROPERTIES( parent ); // Set the default properties mlt_properties_set( properties, "mlt_type", "mlt_producer" ); mlt_properties_set_position( properties, "_position", 0.0 ); mlt_properties_set_double( properties, "_frame", 0 ); mlt_properties_set_double( properties, "_speed", 1.0 ); mlt_properties_set_position( properties, "in", 0 ); char *e = getenv( "MLT_DEFAULT_PRODUCER_LENGTH" ); int p = e ? atoi( e ) : 15000; mlt_properties_set_position( properties, "out", p - 1 ); mlt_properties_set_position( properties, "length", p ); mlt_properties_set( properties, "eof", "pause" ); mlt_properties_set( properties, "resource", "<producer>" ); // Override service get_frame parent->get_frame = producer_get_frame; mlt_events_listen( properties, self, "service-changed", ( mlt_listener )mlt_producer_service_changed ); mlt_events_listen( properties, self, "property-changed", ( mlt_listener )mlt_producer_property_changed ); mlt_events_register( properties, "producer-changed", NULL ); } } return error; }
int mlt_service_attach( mlt_service self, mlt_filter filter ) { int error = self == NULL || filter == NULL; if ( error == 0 ) { int i = 0; mlt_properties properties = MLT_SERVICE_PROPERTIES( self ); mlt_service_base *base = self->local; for ( i = 0; error == 0 && i < base->filter_count; i ++ ) if ( base->filters[ i ] == filter ) error = 1; if ( error == 0 ) { if ( base->filter_count == base->filter_size ) { base->filter_size += 10; base->filters = realloc( base->filters, base->filter_size * sizeof( mlt_filter ) ); } if ( base->filters != NULL ) { mlt_properties props = MLT_FILTER_PROPERTIES( filter ); mlt_properties_inc_ref( MLT_FILTER_PROPERTIES( filter ) ); base->filters[ base->filter_count ++ ] = filter; mlt_properties_set_data( props, "service", self, 0, NULL, NULL ); mlt_events_fire( properties, "service-changed", NULL ); mlt_events_fire( props, "service-changed", NULL ); mlt_service cp = mlt_properties_get_data( properties, "_cut_parent", NULL ); if ( cp ) mlt_events_fire( MLT_SERVICE_PROPERTIES(cp), "service-changed", NULL ); mlt_events_listen( props, self, "service-changed", ( mlt_listener )mlt_service_filter_changed ); mlt_events_listen( props, self, "property-changed", ( mlt_listener )mlt_service_filter_property_changed ); } else { error = 2; } } } return error; }
// adds the transition by keeping the instance order from topmost track down to background void TransitionHandler::plantTransition(Mlt::Field *field, Mlt::Transition &tr, int a_track, int b_track) { mlt_service nextservice = mlt_service_get_producer(field->get_service()); mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice); QString mlt_type = mlt_properties_get(properties, "mlt_type"); QString resource = mlt_properties_get(properties, "mlt_service"); QList <Mlt::Transition *> trList; mlt_properties insertproperties = tr.get_properties(); QString insertresource = mlt_properties_get(insertproperties, "mlt_service"); bool isMixTransition = insertresource == QLatin1String("mix"); while (mlt_type == QLatin1String("transition")) { Mlt::Transition transition((mlt_transition) nextservice); nextservice = mlt_service_producer(nextservice); int aTrack = transition.get_a_track(); int bTrack = transition.get_b_track(); int internal = transition.get_int("internal_added"); if ((isMixTransition || resource != QLatin1String("mix")) && (internal > 0 || aTrack < a_track || (aTrack == a_track && bTrack > b_track))) { Mlt::Properties trans_props(transition.get_properties()); Mlt::Transition *cp = new Mlt::Transition(*m_tractor->profile(), transition.get("mlt_service")); Mlt::Properties new_trans_props(cp->get_properties()); //new_trans_props.inherit(trans_props); cloneProperties(new_trans_props, trans_props); trList.append(cp); field->disconnect_service(transition); } //else qDebug() << "// FOUND TRANS OK, "<<resource<< ", A_: " << aTrack << ", B_ "<<bTrack; if (nextservice == NULL) break; properties = MLT_SERVICE_PROPERTIES(nextservice); mlt_type = mlt_properties_get(properties, "mlt_type"); resource = mlt_properties_get(properties, "mlt_service"); } field->plant_transition(tr, a_track, b_track); // re-add upper transitions for (int i = trList.count() - 1; i >= 0; --i) { ////qDebug()<< "REPLANT ON TK: "<<trList.at(i)->get_a_track()<<", "<<trList.at(i)->get_b_track(); field->plant_transition(*trList.at(i), trList.at(i)->get_a_track(), trList.at(i)->get_b_track()); } qDeleteAll(trList); }
void GlslManager::render_fbo( mlt_service service, void* chain, GLuint fbo, int width, int height ) { EffectChain* effect_chain = (EffectChain*) chain; mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); if ( !mlt_properties_get_int( properties, "_movit finalized" ) ) { mlt_properties_set_int( properties, "_movit finalized", 1 ); effect_chain->add_effect( new Mlt::VerticalFlip() ); effect_chain->finalize(); } effect_chain->render_to_fbo( fbo, width, height ); }
mlt_properties mlt_frame_unique_properties( mlt_frame self, mlt_service service ) { mlt_properties frame_props = MLT_FRAME_PROPERTIES( self ); mlt_properties service_props = MLT_SERVICE_PROPERTIES( service ); char *unique = mlt_properties_get( service_props, "_unique_id" ); mlt_properties instance_props = mlt_properties_get_data( frame_props, unique, NULL ); if ( !instance_props ) { instance_props = mlt_properties_new(); mlt_properties_set_data( frame_props, unique, instance_props, 0, (mlt_destructor) mlt_properties_close, NULL ); } return instance_props; }
int mlt_filter_connect( mlt_filter self, mlt_service producer, int index ) { int ret = mlt_service_connect_producer( &self->parent, producer, index ); // If the connection was successful, grab the producer, track and reset in/out if ( ret == 0 ) { mlt_properties properties = MLT_SERVICE_PROPERTIES( &self->parent ); mlt_properties_set_position( properties, "in", 0 ); mlt_properties_set_position( properties, "out", 0 ); mlt_properties_set_int( properties, "track", index ); } return ret; }
static void mlt_log_handler(void *service, int mlt_level, const char *format, va_list args) { if (mlt_level > mlt_log_get_level()) return; enum Logger::LogLevel cuteLoggerLevel = Logger::Fatal; switch (mlt_level) { case MLT_LOG_DEBUG: cuteLoggerLevel = Logger::Trace; break; case MLT_LOG_ERROR: case MLT_LOG_FATAL: case MLT_LOG_PANIC: cuteLoggerLevel = Logger::Error; break; case MLT_LOG_INFO: cuteLoggerLevel = Logger::Info; break; case MLT_LOG_VERBOSE: cuteLoggerLevel = Logger::Debug; break; case MLT_LOG_WARNING: cuteLoggerLevel = Logger::Warning; break; } QString message; mlt_properties properties = service? MLT_SERVICE_PROPERTIES((mlt_service) service) : NULL; if (properties) { char *mlt_type = mlt_properties_get(properties, "mlt_type"); char *service_name = mlt_properties_get(properties, "mlt_service"); char *resource = mlt_properties_get(properties, "resource"); if (!resource || resource[0] != '<' || resource[strlen(resource) - 1] != '>') mlt_type = mlt_properties_get(properties, "mlt_type" ); if (service_name) message = QString("[%1 %2] ").arg(mlt_type).arg(service_name); else message = QString().sprintf("[%s %p] ", mlt_type, service); if (resource) message.append(QString("\"%1\" ").arg(resource)); message.append(QString().vsprintf(format, args)); message.replace('\n', ""); } else { message = QString().vsprintf(format, args); message.replace('\n', ""); } cuteLogger->write(cuteLoggerLevel, __FILE__, __LINE__, "MLT", cuteLogger->defaultCategory().toLatin1().constData(), message); }
mlt_position mlt_filter_get_length2( mlt_filter self, mlt_frame frame ) { mlt_properties properties = MLT_SERVICE_PROPERTIES( &self->parent ); mlt_position in = mlt_properties_get_position( properties, "in" ); mlt_position out = mlt_properties_get_position( properties, "out" ); if ( out == 0 && frame ) { // If always active, use the frame's producer mlt_producer producer = mlt_frame_get_original_producer( frame ); if ( producer ) { producer = mlt_producer_cut_parent( producer ); in = mlt_producer_get_in( producer ); out = mlt_producer_get_out( producer ); } } return ( out > 0 ) ? ( out - in + 1 ) : 0; }
static void create_filter( mlt_profile profile, mlt_service service, char *effect, int *created ) { char *id = strdup( effect ); char *arg = strchr( id, ':' ); if ( arg != NULL ) *arg ++ = '\0'; // The swscale and avcolor_space filters require resolution as arg to test compatibility if ( strncmp( effect, "swscale", 7 ) == 0 || strncmp( effect, "avcolo", 6 ) == 0 ) arg = (char*) mlt_properties_get_int( MLT_SERVICE_PROPERTIES( service ), "meta.media.width" ); mlt_filter filter = mlt_factory_filter( profile, id, arg ); if ( filter != NULL ) { mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "_loader", 1 ); mlt_service_attach( service, filter ); mlt_filter_close( filter ); *created = 1; } free( id ); }
static void MltLogCallback( void* ptr, int level, const char* fmt, va_list vl ) { int print_prefix = 1; mlt_properties properties = ptr ? MLT_SERVICE_PROPERTIES( ( mlt_service )ptr ) : NULL; char prefixbuf[512] = ""; char logbuf[1024] = ""; static const char* prefix_fmt1= "[%s %s] %s\n"; static const char* prefix_fmt2= "[%s %p] %s\n"; if ( level > mltLogLevel ) { return; } if ( print_prefix && properties ) { char *mlt_type = mlt_properties_get( properties, "mlt_type" ); char *mlt_service = mlt_properties_get( properties, "mlt_service" ); char *resource = mlt_properties_get( properties, "resource" ); if ( !( resource && *resource && resource[0] == '<' && resource[ strlen(resource) - 1 ] == '>' ) ) mlt_type = mlt_properties_get( properties, "mlt_type" ); if (mlt_service) { snprintf(prefixbuf, sizeof(prefixbuf), prefix_fmt1, mlt_type, mlt_service, resource); } else { snprintf(prefixbuf, sizeof(prefixbuf), prefix_fmt2, mlt_type, ptr, resource); } } print_prefix = strstr( fmt, "\n" ) != NULL; vsnprintf( logbuf,sizeof(logbuf), fmt, vl ); if (print_prefix) { __android_log_print(ANDROID_LOG_ERROR, mltLogTag, "%s%s", prefixbuf, logbuf); } else { __android_log_print(ANDROID_LOG_ERROR, mltLogTag, "%s", logbuf); } }
bool createQApplicationIfNeeded(mlt_service service) { if (!qApp) { #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) XInitThreads(); if (getenv("DISPLAY") == 0) { mlt_log_error(service, "The MLT Qt module requires a X11 environment.\n" "Please either run melt from an X session or use a fake X server like xvfb:\n" "xvfb-run -a melt (...)\n" ); return false; } #endif if (!mlt_properties_get(mlt_global_properties(), "qt_argv")) mlt_properties_set(mlt_global_properties(), "qt_argv", "MLT"); static int argc = 1; static char* argv[] = { mlt_properties_get(mlt_global_properties(), "Qt argv") }; new QApplication(argc, argv); const char *localename = mlt_properties_get_lcnumeric(MLT_SERVICE_PROPERTIES(service)); QLocale::setDefault(QLocale(localename)); } return true; }
int mlt_tractor_remove_track( mlt_tractor self, int index ) { int error = mlt_multitrack_disconnect( mlt_tractor_multitrack( self ), index ); if ( !error ) { // Update the track indices of transitions and track filters. mlt_service service = mlt_service_producer( MLT_TRACTOR_SERVICE( self ) ); while ( service ) { mlt_service_type type = mlt_service_identify( service ); mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); if ( type == transition_type ) { mlt_transition transition = MLT_TRANSITION( service ); int a_track = mlt_transition_get_a_track( transition ); int b_track = mlt_transition_get_b_track( transition ); if ( a_track >= index || b_track >= index ) { a_track = MAX( a_track >= index ? a_track - 1 : a_track, 0 ); b_track = MAX( b_track >= index ? b_track - 1 : b_track, 0 ); mlt_transition_set_tracks( transition, a_track, b_track ); } } else if ( type == filter_type ) { int current_track = mlt_properties_get_int( properties, "track" ); if ( current_track >= index ) mlt_properties_set_int( properties, "track", MAX( current_track - 1, 0 ) ); } service = mlt_service_producer( service ); } } return error; }
mlt_consumer consumer_sdl2_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) { // Create the consumer object consumer_sdl self = calloc( 1, sizeof( struct consumer_sdl_s ) ); // If no malloc'd and consumer init ok if ( self != NULL && mlt_consumer_init( &self->parent, self, profile ) == 0 ) { // Create the queue self->queue = mlt_deque_init( ); // Get the parent consumer object mlt_consumer parent = &self->parent; // We have stuff to clean up, so override the close method parent->close = consumer_close; // get a handle on properties mlt_service service = MLT_CONSUMER_SERVICE( parent ); self->properties = MLT_SERVICE_PROPERTIES( service ); // Set the default volume mlt_properties_set_double( self->properties, "volume", 1.0 ); // This is the initialisation of the consumer pthread_mutex_init( &self->audio_mutex, NULL ); pthread_cond_init( &self->audio_cond, NULL); pthread_mutex_init( &self->video_mutex, NULL ); pthread_cond_init( &self->video_cond, NULL); // Default scaler (for now we'll use nearest) mlt_properties_set( self->properties, "rescale", "nearest" ); mlt_properties_set( self->properties, "deinterlace_method", "onefield" ); mlt_properties_set_int( self->properties, "top_field_first", -1 ); // Default buffer for low latency mlt_properties_set_int( self->properties, "buffer", 1 ); // Default audio buffer mlt_properties_set_int( self->properties, "audio_buffer", 2048 ); #if defined(_WIN32) && SDL_MAJOR_VERSION == 2 mlt_properties_set( self->properties, "audio_driver", "DirectSound" ); #endif // Ensure we don't join on a non-running object self->joined = 1; // process actual param if ( arg && sscanf( arg, "%dx%d", &self->width, &self->height ) ) { mlt_properties_set_int( self->properties, "resolution", 1 ); } else { self->width = mlt_properties_get_int( self->properties, "width" ); self->height = mlt_properties_get_int( self->properties, "height" ); } // Allow thread to be started/stopped parent->start = consumer_start; parent->stop = consumer_stop; parent->is_stopped = consumer_is_stopped; parent->purge = consumer_purge; // Register specific events mlt_events_register( self->properties, "consumer-sdl-event", ( mlt_transmitter )consumer_sdl_event ); // Return the consumer produced return parent; } // malloc or consumer init failed free( self ); // Indicate failure return NULL; }
int refresh_qimage( producer_qimage self, mlt_frame frame ) { // Obtain properties of frame and producer mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); mlt_producer producer = &self->parent; mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer ); // Check if user wants us to reload the image if ( mlt_properties_get_int( producer_props, "force_reload" ) ) { self->qimage = NULL; self->current_image = NULL; mlt_properties_set_int( producer_props, "force_reload", 0 ); } // Get the time to live for each frame double ttl = mlt_properties_get_int( producer_props, "ttl" ); // Get the original position of this frame mlt_position position = mlt_frame_original_position( frame ); position += mlt_producer_get_in( producer ); // Image index int image_idx = ( int )floor( ( double )position / ttl ) % self->count; // Key for the cache char image_key[ 10 ]; sprintf( image_key, "%d", image_idx ); int disable_exif = mlt_properties_get_int( producer_props, "disable_exif" ); if ( app == NULL ) { if ( qApp ) { app = qApp; } else { #ifdef linux if ( getenv("DISPLAY") == 0 ) { mlt_log_panic( MLT_PRODUCER_SERVICE( producer ), "Error, cannot render titles without an X11 environment.\nPlease either run melt from an X session or use a fake X server like xvfb:\nxvfb-run -a melt (...)\n" ); return -1; } #endif int argc = 1; char* argv[1]; argv[0] = (char*) "xxx"; app = new QApplication( argc, argv ); const char *localename = mlt_properties_get_lcnumeric( MLT_SERVICE_PROPERTIES( MLT_PRODUCER_SERVICE( producer ) ) ); QLocale::setDefault( QLocale( localename ) ); } } if ( image_idx != self->qimage_idx ) self->qimage = NULL; if ( !self->qimage || mlt_properties_get_int( producer_props, "_disable_exif" ) != disable_exif ) { self->current_image = NULL; QImage *qimage = new QImage( QString::fromUtf8( mlt_properties_get_value( self->filenames, image_idx ) ) ); self->qimage = qimage; if ( !qimage->isNull( ) ) { // Read the exif value for this file if ( !disable_exif ) qimage = reorient_with_exif( self, image_idx, qimage ); // Register qimage for destruction and reuse mlt_cache_item_close( self->qimage_cache ); mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "qimage.qimage", qimage, 0, ( mlt_destructor )qimage_delete ); self->qimage_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.qimage" ); self->qimage_idx = image_idx; // Store the width/height of the qimage self->current_width = qimage->width( ); self->current_height = qimage->height( ); mlt_events_block( producer_props, NULL ); mlt_properties_set_int( producer_props, "meta.media.width", self->current_width ); mlt_properties_set_int( producer_props, "meta.media.height", self->current_height ); mlt_properties_set_int( producer_props, "_disable_exif", disable_exif ); mlt_events_unblock( producer_props, NULL ); } else { delete qimage; self->qimage = NULL; } } // Set width/height of frame mlt_properties_set_int( properties, "width", self->current_width ); mlt_properties_set_int( properties, "height", self->current_height ); return image_idx; }
mlt_properties mlt_producer_properties( mlt_producer self ) { return MLT_SERVICE_PROPERTIES( &self->parent ); }
MltInput *GlslManager::get_input( mlt_service service ) { return (MltInput*) mlt_properties_get_data( MLT_SERVICE_PROPERTIES(service), "movit input", NULL ); }
void GlslManager::reset_finalized( mlt_service service ) { mlt_properties_set_int( MLT_SERVICE_PROPERTIES(service), "_movit finalized", 0 ); }