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 ); }
static bool check_qimage( mlt_properties frame_properties ) { mlt_producer producer = static_cast<mlt_producer>( mlt_properties_get_data( frame_properties, "_producer_qtext", NULL ) ); mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); QImage* qImg = static_cast<QImage*>( mlt_properties_get_data( producer_properties, "_qimg", NULL ) ); QSize target_size( mlt_properties_get_int( frame_properties, "rescale_width" ), mlt_properties_get_int( frame_properties, "rescale_height" ) ); QSize native_size( mlt_properties_get_int( frame_properties, "meta.media.width" ), mlt_properties_get_int( frame_properties, "meta.media.height" ) ); // Check if the last image signature is different from the path signature // for this frame. char* last_img_sig = mlt_properties_get( producer_properties, "_img_sig" ); char* path_sig = mlt_properties_get( frame_properties, "_path_sig" ); if( !last_img_sig || strcmp( path_sig, last_img_sig ) ) { mlt_properties_set( producer_properties, "_img_sig", path_sig ); return true; } // Check if the last image size matches the requested image size QSize output_size = target_size; if( output_size.isEmpty() ) { output_size = native_size; } if( output_size != qImg->size() ) { return true; } return false; }
static int producer_get_image( mlt_frame self, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) { uint8_t *data = NULL; int size = 0; mlt_properties properties = MLT_FRAME_PROPERTIES( self ); mlt_frame frame = mlt_frame_pop_service( self ); mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); mlt_properties_set( frame_properties, "rescale.interp", mlt_properties_get( properties, "rescale.interp" ) ); mlt_properties_set_int( frame_properties, "resize_alpha", mlt_properties_get_int( properties, "resize_alpha" ) ); mlt_properties_set_int( frame_properties, "distort", mlt_properties_get_int( properties, "distort" ) ); mlt_properties_set_int( frame_properties, "consumer_deinterlace", mlt_properties_get_int( properties, "consumer_deinterlace" ) ); mlt_properties_set( frame_properties, "deinterlace_method", mlt_properties_get( properties, "deinterlace_method" ) ); mlt_properties_set_int( frame_properties, "consumer_tff", mlt_properties_get_int( properties, "consumer_tff" ) ); mlt_frame_get_image( frame, buffer, format, width, height, writable ); mlt_frame_set_image( self, *buffer, 0, NULL ); mlt_properties_set_int( properties, "width", *width ); mlt_properties_set_int( properties, "height", *height ); mlt_properties_set_int( properties, "format", *format ); mlt_properties_set_double( properties, "aspect_ratio", mlt_frame_get_aspect_ratio( frame ) ); mlt_properties_set_int( properties, "progressive", mlt_properties_get_int( frame_properties, "progressive" ) ); mlt_properties_set_int( properties, "distort", mlt_properties_get_int( frame_properties, "distort" ) ); mlt_properties_set_int( properties, "colorspace", mlt_properties_get_int( frame_properties, "colorspace" ) ); mlt_properties_set_int( properties, "force_full_luma", mlt_properties_get_int( frame_properties, "force_full_luma" ) ); mlt_properties_set_int( properties, "top_field_first", mlt_properties_get_int( frame_properties, "top_field_first" ) ); mlt_properties_set_data( properties, "movit.convert.fence", mlt_properties_get_data( frame_properties, "movit.convert.fence", NULL ), 0, NULL, NULL ); data = mlt_frame_get_alpha_mask( frame ); mlt_properties_get_data( frame_properties, "alpha", &size ); mlt_frame_set_alpha( self, data, size, NULL ); self->convert_image = frame->convert_image; self->convert_audio = frame->convert_audio; return 0; }
static void get_transform_config( VSTransformConfig* conf, mlt_filter filter, mlt_frame frame ) { mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); const char* filterName = mlt_properties_get( properties, "mlt_service" ); *conf = vsTransformGetDefaultConfig( filterName ); conf->smoothing = mlt_properties_get_int( properties, "smoothing" ); conf->maxShift = mlt_properties_get_int( properties, "maxshift" ); conf->maxAngle = mlt_properties_get_double( properties, "maxangle" ); conf->crop = (VSBorderType)mlt_properties_get_int( properties, "crop" ); conf->zoom = mlt_properties_get_int( properties, "zoom" ); conf->optZoom = mlt_properties_get_int( properties, "optzoom" ); conf->zoomSpeed = mlt_properties_get_double( properties, "zoomspeed" ); conf->relative = mlt_properties_get_int( properties, "relative" ); conf->invert = mlt_properties_get_int( properties, "invert" ); if ( mlt_properties_get_int( properties, "tripod" ) != 0 ) { // Virtual tripod mode: relative=False, smoothing=0 conf->relative = 0; conf->smoothing = 0; } // by default a bicubic interpolation is selected const char *interps = mlt_properties_get( MLT_FRAME_PROPERTIES( frame ), "rescale.interp" ); conf->interpolType = VS_BiCubic; if ( strcmp( interps, "nearest" ) == 0 || strcmp( interps, "neighbor" ) == 0 ) conf->interpolType = VS_Zero; else if ( strcmp( interps, "tiles" ) == 0 || strcmp( interps, "fast_bilinear" ) == 0 ) conf->interpolType = VS_Linear; else if ( strcmp( interps, "bilinear" ) == 0 ) conf->interpolType = VS_BiLinear; }
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; }
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); }
static int get_image_b( mlt_frame b_frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) { mlt_transition self = mlt_frame_pop_service( b_frame ); mlt_frame a_frame = mlt_frame_pop_frame( b_frame ); mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame ); mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame ); // Set scaling from A frame if not already provided. if ( !mlt_properties_get( b_props, "rescale.interp" ) ) { const char *rescale = mlt_properties_get( a_props, "rescale.interp" ); if ( !rescale || !strcmp( rescale, "none" ) ) rescale = "nearest"; mlt_properties_set( b_props, "rescale.interp", rescale ); } // Ensure sane aspect ratio if ( mlt_frame_get_aspect_ratio( b_frame ) == 0.0 ) mlt_frame_set_aspect_ratio( b_frame, mlt_profile_sar( mlt_service_profile( MLT_TRANSITION_SERVICE(self) ) ) ); mlt_properties_pass_list( b_props, a_props, "consumer_deinterlace, deinterlace_method, consumer_tff" ); return mlt_frame_get_image( b_frame, image, format, width, height, writable ); }
int consumer_start( mlt_consumer parent ) { consumer_sdl self = parent->child; if ( !self->running ) { consumer_stop( parent ); mlt_properties properties = MLT_CONSUMER_PROPERTIES( parent ); char *audio_driver = mlt_properties_get( properties, "audio_driver" ); char *audio_device = mlt_properties_get( properties, "audio_device" ); if ( audio_driver && strcmp( audio_driver, "" ) ) setenv( "SDL_AUDIODRIVER", audio_driver, 1 ); if ( audio_device && strcmp( audio_device, "" ) ) setenv( "AUDIODEV", audio_device, 1 ); pthread_mutex_lock( &mlt_sdl_mutex ); int ret = SDL_Init( SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE ); pthread_mutex_unlock( &mlt_sdl_mutex ); if ( ret < 0 ) { mlt_log_error( MLT_CONSUMER_SERVICE(parent), "Failed to initialize SDL: %s\n", SDL_GetError() ); return -1; } self->running = 1; self->joined = 0; pthread_create( &self->thread, NULL, consumer_thread, self ); } return 0; }
static void draw_spectrum( mlt_filter filter, mlt_frame frame, QImage* qimg ) { mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter ); mlt_position position = mlt_filter_get_position( filter, frame ); mlt_position length = mlt_filter_get_length2( filter, frame ); mlt_rect rect = mlt_properties_anim_get_rect( filter_properties, "rect", position, length ); if ( strchr( mlt_properties_get( filter_properties, "rect" ), '%' ) ) { rect.x *= qimg->width(); rect.w *= qimg->width(); rect.y *= qimg->height(); rect.h *= qimg->height(); } char* graph_type = mlt_properties_get( filter_properties, "type" ); int mirror = mlt_properties_get_int( filter_properties, "mirror" ); int fill = mlt_properties_get_int( filter_properties, "fill" ); double tension = mlt_properties_get_double( filter_properties, "tension" ); QRectF r( rect.x, rect.y, rect.w, rect.h ); QPainter p( qimg ); if( mirror ) { // Draw two half rectangle instead of one full rectangle. r.setHeight( r.height() / 2.0 ); } setup_graph_painter( p, r, filter_properties ); setup_graph_pen( p, r, filter_properties ); int bands = mlt_properties_get_int( filter_properties, "bands" ); if ( bands == 0 ) { // "0" means match rectangle width bands = r.width(); } float* spectrum = (float*)mlt_pool_alloc( bands * sizeof(float) ); convert_fft_to_spectrum( filter, frame, bands, spectrum ); if( graph_type && graph_type[0] == 'b' ) { paint_bar_graph( p, r, bands, spectrum ); } else { paint_line_graph( p, r, bands, spectrum, tension, fill ); } if( mirror ) { // Second rectangle is mirrored. p.translate( 0, r.y() * 2 + r.height() * 2 ); p.scale( 1, -1 ); if( graph_type && graph_type[0] == 'b' ) { paint_bar_graph( p, r, bands, spectrum ); } else { paint_line_graph( p, r, bands, spectrum, tension, fill ); } } mlt_pool_release( spectrum ); p.end(); }
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; }
static double anim_get_angle(mlt_properties properties, const char* name, mlt_position position, mlt_position length) { double result = 0.0; if (mlt_properties_get(properties, name)) { position = repeat_position(properties, name, position, length); result = mlt_properties_anim_get_double(properties, name, position, length); if (strchr(mlt_properties_get(properties, name), '%')) result *= 360; } return result; }
static void setup_transition( mlt_filter filter, mlt_transition transition ) { mlt_properties my_properties = MLT_FILTER_PROPERTIES( filter ); mlt_properties transition_properties = MLT_TRANSITION_PROPERTIES( transition ); mlt_properties_set( transition_properties, "geometry", mlt_properties_get( my_properties, "geometry" ) ); mlt_properties_set( transition_properties, "halign", mlt_properties_get( my_properties, "halign" ) ); mlt_properties_set( transition_properties, "valign", mlt_properties_get( my_properties, "valign" ) ); mlt_properties_set_int( transition_properties, "out", mlt_properties_get_int( my_properties, "_out" ) ); mlt_properties_set_int( transition_properties, "refresh", 1 ); }
static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) { mlt_filter filter = (mlt_filter) mlt_frame_pop_service( frame ); mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); mlt_position position = mlt_filter_get_position( filter, frame ); mlt_position length = mlt_filter_get_length2( filter, frame ); // Get the image *format = mlt_image_yuv422; int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); // Only process if we have no error and a valid colour space if ( error == 0 ) { double level = 1.0; // Use animated "level" property only if it has been set since init char* level_property = mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "level" ); if ( level_property != NULL ) { level = mlt_properties_anim_get_double( properties, "level", position, length ); } else { // Get level using old "start,"end" mechanics // Get the starting brightness level level = fabs( mlt_properties_get_double( MLT_FILTER_PROPERTIES( filter ), "start" ) ); // If there is an end adjust gain to the range if ( mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "end" ) != NULL ) { // Determine the time position of this frame in the transition duration double end = fabs( mlt_properties_get_double( MLT_FILTER_PROPERTIES( filter ), "end" ) ); level += ( end - level ) * mlt_filter_get_progress( filter, frame ); } } // Only process if level is something other than 1 if ( level != 1.0 ) { int i = *width * *height + 1; uint8_t *p = *image; int32_t m = level * ( 1 << 16 ); int32_t n = 128 * ( ( 1 << 16 ) - m ); while ( --i ) { p[0] = CLAMP( (p[0] * m) >> 16, 16, 235 ); p[1] = CLAMP( (p[1] * m + n) >> 16, 16, 240 ); p += 2; } }
static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) { // Generate a frame *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); if ( *frame != NULL ) { mlt_properties frame_properties = MLT_FRAME_PROPERTIES( *frame ); mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); // Regenerate the QPainterPath if necessary if( check_qpath( producer_properties ) ) { generate_qpath( producer_properties ); } // Give the frame a copy of the painter path QPainterPath* prodPath = static_cast<QPainterPath*>( mlt_properties_get_data( producer_properties, "_qpath", NULL ) ); QPainterPath* framePath = new QPainterPath( *prodPath ); mlt_properties_set_data( frame_properties, "_qpath", static_cast<void*>( framePath ), 0, close_qpath, NULL ); // Pass properties to the frame that will be needed to render the path mlt_properties_set( frame_properties, "_path_sig", mlt_properties_get( producer_properties, "_path_sig" ) ); mlt_properties_set( frame_properties, "_bgcolour", mlt_properties_get( producer_properties, "bgcolour" ) ); mlt_properties_set( frame_properties, "_fgcolour", mlt_properties_get( producer_properties, "fgcolour" ) ); mlt_properties_set( frame_properties, "_olcolour", mlt_properties_get( producer_properties, "olcolour" ) ); mlt_properties_set( frame_properties, "_outline", mlt_properties_get( producer_properties, "outline" ) ); mlt_properties_set_data( frame_properties, "_producer_qtext", static_cast<void*>( producer ), 0, NULL, NULL ); // Set frame properties mlt_properties_set_int( frame_properties, "progressive", 1 ); double force_ratio = mlt_properties_get_double( producer_properties, "force_aspect_ratio" ); if ( force_ratio > 0.0 ) mlt_properties_set_double( frame_properties, "aspect_ratio", force_ratio ); else mlt_properties_set_double( frame_properties, "aspect_ratio", 1.0); // Update time code on the frame mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); // Configure callbacks mlt_frame_push_get_image( *frame, producer_get_image ); } // Calculate the next time code mlt_producer_prepare_next( producer ); return 0; }
int mlt_consumer_stop( mlt_consumer self ) { // Get the properies mlt_properties properties = MLT_CONSUMER_PROPERTIES( self ); // Just in case... mlt_log( MLT_CONSUMER_SERVICE( self ), MLT_LOG_DEBUG, "stopping put waiting\n" ); pthread_mutex_lock( &self->put_mutex ); self->put_active = 0; pthread_cond_broadcast( &self->put_cond ); pthread_mutex_unlock( &self->put_mutex ); // Stop the consumer mlt_log( MLT_CONSUMER_SERVICE( self ), MLT_LOG_DEBUG, "stopping consumer\n" ); // Cancel the read ahead threads self->ahead = 0; if ( self->started ) { // Unblock the consumer calling mlt_consumer_rt_frame pthread_mutex_lock( &self->queue_mutex ); pthread_cond_broadcast( &self->queue_cond ); pthread_mutex_unlock( &self->queue_mutex ); } // Invoke the child callback if ( self->stop != NULL ) self->stop( self ); // Check if the user has requested real time or not and stop if necessary mlt_log( MLT_CONSUMER_SERVICE( self ), MLT_LOG_DEBUG, "stopping read_ahead\n" ); if ( abs( self->real_time ) == 1 ) consumer_read_ahead_stop( self ); else if ( abs( self->real_time ) > 1 ) consumer_work_stop( self ); // Kill the test card mlt_properties_set_data( properties, "test_card_producer", NULL, 0, NULL, NULL ); // Check and run a post command if ( mlt_properties_get( properties, "post" ) ) if (system( mlt_properties_get( properties, "post" ) ) == -1 ) mlt_log( MLT_CONSUMER_SERVICE( self ), MLT_LOG_ERROR, "system(%s) failed!\n", mlt_properties_get( properties, "post" ) ); mlt_log( MLT_CONSUMER_SERVICE( self ), MLT_LOG_DEBUG, "stopped\n" ); return 0; }
static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ){ if (*format!=mlt_image_yuv422 ){ return -1; } mlt_frame b_frame = mlt_frame_pop_frame( a_frame ); mlt_transition transition = mlt_frame_pop_service( a_frame ); mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition ); mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame ); mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame ); int invert = mlt_properties_get_int( properties, "invert" ); if ( mlt_properties_get( a_props, "rescale.interp" ) == NULL || !strcmp( mlt_properties_get( a_props, "rescale.interp" ), "none" ) ) mlt_properties_set( a_props, "rescale.interp", "nearest" ); // set consumer_aspect_ratio for a and b frame if ( mlt_properties_get_double( a_props, "aspect_ratio" ) == 0.0 ) mlt_properties_set_double( a_props, "aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); if ( mlt_properties_get_double( b_props, "aspect_ratio" ) == 0.0 ) mlt_properties_set_double( b_props, "aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); if ( mlt_properties_get( b_props, "rescale.interp" ) == NULL || !strcmp( mlt_properties_get( b_props, "rescale.interp" ), "none" ) ) mlt_properties_set( b_props, "rescale.interp", "nearest" ); uint8_t *images[]={NULL,NULL,NULL}; mlt_frame_get_image( a_frame, &images[0], format, width, height, 1 ); mlt_frame_get_image( b_frame, &images[1], format, width, height, 1 ); mlt_position in = mlt_transition_get_in( transition ); mlt_position out = mlt_transition_get_out( transition ); // Get the position of the frame char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( transition ), "_unique_id" ); mlt_position position = mlt_properties_get_position( MLT_FRAME_PROPERTIES( a_frame ), name ); float pos=( float )( position - in ) / ( float )( out - in + 1 ); process_frei0r_item( transition_type , pos , properties, !invert ? a_frame : b_frame , images , format, width,height, writable ); *width = mlt_properties_get_int( !invert ? a_props : b_props, "width" ); *height = mlt_properties_get_int( !invert ? a_props : b_props, "height" ); *image = mlt_properties_get_data( !invert ? a_props : b_props , "image", NULL ); return 0; }
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); }
int mlt_producer_seek( mlt_producer self, mlt_position position ) { // Determine eof handling mlt_properties properties = MLT_PRODUCER_PROPERTIES( self ); char *eof = mlt_properties_get( properties, "eof" ); int use_points = 1 - mlt_properties_get_int( properties, "ignore_points" ); // Recursive behaviour for cuts - repositions parent and then repositions cut // hence no return on this condition if ( mlt_producer_is_cut( self ) ) mlt_producer_seek( mlt_producer_cut_parent( self ), position + mlt_producer_get_in( self ) ); // Check bounds if ( position < 0 || mlt_producer_get_playtime( self ) == 0 ) { position = 0; } else if ( use_points && ( eof == NULL || !strcmp( eof, "pause" ) ) && position >= mlt_producer_get_playtime( self ) ) { mlt_producer_set_speed( self, 0 ); position = mlt_producer_get_playtime( self ) - 1; } else if ( use_points && eof && !strcmp( eof, "loop" ) && position >= mlt_producer_get_playtime( self ) ) { position = (int)position % (int)mlt_producer_get_playtime( self ); } // Set the position mlt_properties_set_position( MLT_PRODUCER_PROPERTIES( self ), "_position", position ); // Calculate the absolute frame mlt_properties_set_position( MLT_PRODUCER_PROPERTIES( self ), "_frame", use_points * mlt_producer_get_in( self ) + position ); return 0; }
mlt_frame mlt_filter_process( mlt_filter self, mlt_frame frame ) { mlt_properties properties = MLT_FILTER_PROPERTIES( self ); int disable = mlt_properties_get_int( properties, "disable" ); const char *unique_id = mlt_properties_get( properties, "_unique_id" ); mlt_position position = mlt_frame_get_position( frame ); char name[30]; // Make the properties key from unique id snprintf( name, sizeof(name), "pos.%s", unique_id ); name[sizeof(name) -1] = '\0'; // Save the position on the frame mlt_properties_set_position( MLT_FRAME_PROPERTIES( frame ), name, position ); if ( disable || self->process == NULL ) { return frame; } else { // Add a reference to this filter on the frame mlt_properties_inc_ref( MLT_FILTER_PROPERTIES(self) ); snprintf( name, sizeof(name), "filter.%s", unique_id ); name[sizeof(name) -1] = '\0'; mlt_properties_set_data( MLT_FRAME_PROPERTIES(frame), name, self, 0, (mlt_destructor) mlt_filter_close, NULL ); return self->process( self, frame ); } }
static StabData* init_detect(mlt_properties properties, mlt_image_format *format, int *width, int *height) { StabData *data = new StabData; memset(data, 0, sizeof(StabData)); data->animation = mlt_animation_new(); VSPixelFormat pf = convertImageFormat(*format); VSFrameInfo fi; vsFrameInfoInit(&fi, *width, *height, pf); const char* filterName = mlt_properties_get(properties, "mlt_service"); VSMotionDetectConfig conf = vsMotionDetectGetDefaultConfig(filterName); conf.shakiness = mlt_properties_get_int(properties, "shakiness"); conf.accuracy = mlt_properties_get_int(properties, "accuracy"); conf.stepSize = mlt_properties_get_int(properties, "stepsize"); conf.algo = mlt_properties_get_int(properties, "algo"); conf.contrastThreshold = mlt_properties_get_double(properties, "mincontrast"); conf.show = mlt_properties_get_int(properties, "show"); conf.virtualTripod = mlt_properties_get_int(properties, "tripod"); vsMotionDetectInit(&data->md, &conf, &fi); // add vectors to properties mlt_properties_set_data(properties, "vectors", data->animation, 1, (mlt_destructor) mlt_animation_close, (mlt_serialiser) vectors_serializer); return data; }
static void consumer_read_ahead_start( mlt_consumer self ) { // We're running now self->ahead = 1; // Create the frame queue self->queue = mlt_deque_init( ); // Create the queue mutex pthread_mutex_init( &self->queue_mutex, NULL ); // Create the condition pthread_cond_init( &self->queue_cond, NULL ); // Create the read ahead if ( mlt_properties_get( MLT_CONSUMER_PROPERTIES( self ), "priority" ) ) { struct sched_param priority; priority.sched_priority = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( self ), "priority" ); pthread_attr_t thread_attributes; pthread_attr_init( &thread_attributes ); pthread_attr_setschedpolicy( &thread_attributes, SCHED_OTHER ); pthread_attr_setschedparam( &thread_attributes, &priority ); pthread_attr_setinheritsched( &thread_attributes, PTHREAD_EXPLICIT_SCHED ); pthread_attr_setscope( &thread_attributes, PTHREAD_SCOPE_SYSTEM ); if ( pthread_create( &self->ahead_thread, &thread_attributes, consumer_read_ahead_thread, self ) < 0 ) pthread_create( &self->ahead_thread, NULL, consumer_read_ahead_thread, self ); pthread_attr_destroy( &thread_attributes ); } else { pthread_create( &self->ahead_thread, NULL, consumer_read_ahead_thread, self ); } self->started = 1; }
static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) { context cx = mlt_frame_pop_service( frame ); mlt_frame nested_frame = mlt_frame_pop_service( frame ); *width = cx->profile->width; *height = cx->profile->height; int result = mlt_frame_get_image( nested_frame, image, format, width, height, writable ); // Allocate the image int size = mlt_image_format_size( *format, *width, *height, NULL ); uint8_t *new_image = mlt_pool_alloc( size ); // Update the frame mlt_properties properties = mlt_frame_properties( frame ); mlt_frame_set_image( frame, new_image, size, mlt_pool_release ); memcpy( new_image, *image, size ); mlt_properties_set( properties, "progressive", mlt_properties_get( MLT_FRAME_PROPERTIES(nested_frame), "progressive" ) ); *image = new_image; // Copy the alpha channel uint8_t *alpha = mlt_properties_get_data( MLT_FRAME_PROPERTIES( nested_frame ), "alpha", &size ); if ( alpha && size > 0 ) { new_image = mlt_pool_alloc( size ); memcpy( new_image, alpha, size ); mlt_frame_set_alpha( frame, new_image, size, mlt_pool_release ); } return result; }
int mlt_frame_set_position( mlt_frame self, mlt_position value ) { // Only set the original_position the first time. if ( ! mlt_properties_get( MLT_FRAME_PROPERTIES( self ), "original_position" ) ) mlt_properties_set_position( MLT_FRAME_PROPERTIES( self ), "original_position", value ); return mlt_properties_set_position( MLT_FRAME_PROPERTIES( self ), "_position", value ); }
static int attach_boundry_to_frame( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) { // Get the filter object mlt_filter filter = mlt_frame_pop_service( frame ); // Get the filter's property object mlt_properties filter_properties = MLT_FILTER_PROPERTIES(filter); // Get the frame properties mlt_properties frame_properties = MLT_FRAME_PROPERTIES(frame); // Get the frame position mlt_position position = mlt_filter_get_position( filter, frame ); mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); // Get the geometry object mlt_geometry geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL); if (geometry == NULL) { mlt_geometry geom = mlt_geometry_init(); char *arg = mlt_properties_get(filter_properties, "geometry"); // Initialize with the supplied geometry struct mlt_geometry_item_s item; mlt_geometry_parse_item( geom, &item, arg ); item.frame = 0; item.key = 1; item.mix = 100; mlt_geometry_insert( geom, &item ); mlt_geometry_interpolate( geom ); mlt_properties_set_data( filter_properties, "filter_geometry", geom, 0, (mlt_destructor)mlt_geometry_close, (mlt_serialiser)mlt_geometry_serialise ); geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL); } mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); // Get the current geometry item mlt_geometry_item geometry_item = mlt_pool_alloc( sizeof( struct mlt_geometry_item_s ) ); mlt_geometry_fetch(geometry, geometry_item, position); // Cleanse the geometry item geometry_item->w = geometry_item->x < 0 ? geometry_item->w + geometry_item->x : geometry_item->w; geometry_item->h = geometry_item->y < 0 ? geometry_item->h + geometry_item->y : geometry_item->h; geometry_item->x = geometry_item->x < 0 ? 0 : geometry_item->x; geometry_item->y = geometry_item->y < 0 ? 0 : geometry_item->y; geometry_item->w = geometry_item->w < 0 ? 0 : geometry_item->w; geometry_item->h = geometry_item->h < 0 ? 0 : geometry_item->h; mlt_properties_set_data( frame_properties, "bounds", geometry_item, sizeof( struct mlt_geometry_item_s ), mlt_pool_release, NULL ); // Get the new image int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); if( error != 0 ) mlt_properties_debug( frame_properties, "error after mlt_frame_get_image() in autotrack_rectangle attach_boundry_to_frame", stderr ); return error; }
static void add_clock_to_frame( mlt_producer producer, mlt_frame frame, time_info* info ) { mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) ); mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); uint8_t* image = NULL; mlt_image_format format = mlt_image_rgb24a; int size = 0; int width = profile->width; int height = profile->height; int line_width = LINE_WIDTH_RATIO * (width > height ? height : width) / 100; int radius = (width > height ? height : width) / 2; char* direction = mlt_properties_get( producer_properties, "direction" ); int clock_angle = 0; mlt_frame_get_image( frame, &image, &format, &width, &height, 1 ); // Calculate the angle for the clock. int frames = info->frames; if( !strcmp( direction, "down" ) ) { frames = info->fps - info->frames - 1; } clock_angle = (frames + 1) * 360 / info->fps; draw_clock( image, profile, clock_angle, line_width ); draw_cross( image, profile, line_width ); draw_ring( image, profile, ( radius * OUTER_RING_RATIO ) / 100, line_width ); draw_ring( image, profile, ( radius * INNER_RING_RATIO ) / 100, line_width ); size = mlt_image_format_size( format, width, height, NULL ); mlt_frame_set_image( frame, image, size, mlt_pool_release ); }
static void get_time_info( mlt_producer producer, mlt_frame frame, time_info* info ) { mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); mlt_position position = mlt_frame_original_position( frame ); info->fps = ceil( mlt_producer_get_fps( producer ) ); char* direction = mlt_properties_get( producer_properties, "direction" ); if( !strcmp( direction, "down" ) ) { mlt_position length = mlt_properties_get_int( producer_properties, "length" ); info->position = length - 1 - position; } else { info->position = position; } char* tc_str = NULL; if( mlt_properties_get_int( producer_properties, "drop" ) ) { tc_str = mlt_properties_frames_to_time( producer_properties, info->position, mlt_time_smpte_df ); } else { tc_str = mlt_properties_frames_to_time( producer_properties, info->position, mlt_time_smpte_ndf ); } sscanf( tc_str, "%02d:%02d:%02d%c%d", &info->hours, &info->minutes, &info->seconds, &info->sep, &info->frames ); }
char *mlt_environment( const char *name ) { if ( global_properties ) return mlt_properties_get( global_properties, name ); else return NULL; }
static int iconv_from_utf8( mlt_properties properties, const char *prop_name, const char *prop_name_out, const char* encoding ) { const char *text = mlt_properties_get( properties, prop_name ); int result = -1; iconv_t cd = iconv_open( encoding, "UTF-8" ); if ( text && ( cd != ( iconv_t )-1 ) ) { size_t inbuf_n = strlen( text ); size_t outbuf_n = inbuf_n * 6; char *outbuf = mlt_pool_alloc( outbuf_n ); char *outbuf_p = outbuf; memset( outbuf, 0, outbuf_n ); if ( text != NULL && strcmp( text, "" ) && iconv( cd, &text, &inbuf_n, &outbuf_p, &outbuf_n ) != -1 ) mlt_properties_set( properties, prop_name_out, outbuf ); else mlt_properties_set( properties, prop_name_out, "" ); mlt_pool_release( outbuf ); result = 0; } iconv_close( cd ); return result; }
int mlt_properties_from_utf8( mlt_properties properties, const char *prop_name, const char *prop_name_out ) { int result = -1; // Get the locale name. const char *locale = setlocale( LC_CTYPE, NULL ); if ( locale && strchr( locale, '.' ) ) { // Check for a code page in locale format = language_country.codepage. locale = strchr( locale, '.' ) + 1; if ( isdigit( locale[0] ) ) { // numeric code page char codepage[10]; snprintf( codepage, sizeof(codepage), "CP%s", locale ); result = iconv_from_utf8( properties, prop_name, prop_name_out, codepage ); } else { // non-numeric code page possible on Windows? // TODO: some code pages may require conversion from numeric to iconv // compatible name. For example, maybe Shift-JIS or KOI8-R. result = iconv_from_utf8( properties, prop_name, prop_name_out, locale ); } } if ( result < 0 ) { result = mlt_properties_set( properties, prop_name_out, mlt_properties_get( properties, prop_name ) ); } return result; }
static void property_changed( mlt_properties owner, mlt_consumer self, char *name ) { mlt_properties properties = MLT_PRODUCER_PROPERTIES(self); context cx = mlt_properties_get_data( properties, "context", NULL ); if ( !cx ) return; if ( name == strstr( name, CONSUMER_PROPERTIES_PREFIX ) ) mlt_properties_set(MLT_CONSUMER_PROPERTIES( cx->consumer ), name + strlen( CONSUMER_PROPERTIES_PREFIX ), mlt_properties_get( properties, name )); if ( name == strstr( name, PRODUCER_PROPERTIES_PREFIX ) ) mlt_properties_set(MLT_PRODUCER_PROPERTIES( cx->producer ), name + strlen( PRODUCER_PROPERTIES_PREFIX ), mlt_properties_get( properties, name )); }