double mlt_transition_get_progress_delta( mlt_transition self, mlt_frame frame ) { double progress = 0; mlt_position in = mlt_transition_get_in( self ); mlt_position out = mlt_transition_get_out( self ); if ( out == 0 ) { // If always active, use the frame's producer mlt_producer producer = mlt_frame_get_original_producer( frame ); if ( producer ) { in = mlt_producer_get_in( producer ); out = mlt_producer_get_out( producer ); } } if ( out != 0 ) { mlt_position position = mlt_frame_get_position( frame ); double length = out - in + 1; double x = ( double ) ( position - in ) / length; double y = ( double ) ( position + 1 - in ) / length; progress = ( y - x ) / 2.0; } return progress; }
static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) { // Obtain properties of frame mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); // Obtain the producer for this frame mlt_producer producer = mlt_properties_get_data( properties, "producer_frei0r", NULL ); // Obtain properties of producer mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer ); // Allocate the image int size = *width * ( *height + 1 ) * 2; // Allocate the image *buffer = mlt_pool_alloc( size ); // Update the frame mlt_properties_set_data( properties, "image", *buffer, size, mlt_pool_release, NULL ); mlt_properties_set_int( properties, "width", *width ); mlt_properties_set_int( properties, "height", *height ); *format = mlt_image_yuv422; if ( *buffer != NULL ) { mlt_position in = mlt_producer_get_in( producer ); mlt_position out = mlt_producer_get_out( producer ); mlt_position time = mlt_frame_get_position( frame ); double position = ( double )( time - in ) / ( double )( out - in + 1 ); process_frei0r_item( producer_type , position, producer_props, frame , buffer, format , width , height , writable ); } return 0; }
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; }
double mlt_transition_get_progress( mlt_transition self, mlt_frame frame ) { double progress = 0; mlt_position in = mlt_transition_get_in( self ); mlt_position out = mlt_transition_get_out( self ); if ( out == 0 ) { // If always active, use the frame's producer mlt_producer producer = mlt_frame_get_original_producer( frame ); if ( producer ) { in = mlt_producer_get_in( producer ); out = mlt_producer_get_out( producer ); } } if ( out != 0 ) { mlt_position position = mlt_frame_get_position( frame ); progress = ( double ) ( position - in ) / ( double ) ( out - in + 1 ); } return progress; }
static int producer_get_frame( mlt_service service, mlt_frame_ptr frame, int index ) { int result = 1; mlt_producer self = service != NULL ? service->child : NULL; if ( self != NULL && !mlt_producer_is_cut( self ) ) { // Get the properties of this producer mlt_properties properties = MLT_PRODUCER_PROPERTIES( self ); // Determine eof handling char *eof = mlt_properties_get( MLT_PRODUCER_PROPERTIES( self ), "eof" ); // Get the speed of the producer double speed = mlt_producer_get_speed( self ); // We need to use the clone if it's specified mlt_producer clone = mlt_properties_get_data( properties, "use_clone", NULL ); // If no clone is specified, use self clone = clone == NULL ? self : clone; // A properly instatiated producer will have a get_frame method... if ( self->get_frame == NULL || ( eof && !strcmp( eof, "continue" ) && mlt_producer_position( self ) > mlt_producer_get_out( self ) ) ) { // Generate a test frame *frame = mlt_frame_init( service ); // Set the position result = mlt_frame_set_position( *frame, mlt_producer_position( self ) ); // Mark as a test card mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "test_image", 1 ); mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "test_audio", 1 ); // Calculate the next position mlt_producer_prepare_next( self ); } else { // Get the frame from the implementation result = self->get_frame( clone, frame, index ); } // Copy the fps and speed of the producer onto the frame properties = MLT_FRAME_PROPERTIES( *frame ); mlt_properties_set_double( properties, "_speed", speed ); mlt_properties_set_int( properties, "test_audio", mlt_frame_is_test_audio( *frame ) ); mlt_properties_set_int( properties, "test_image", mlt_frame_is_test_card( *frame ) ); if ( mlt_properties_get_data( properties, "_producer", NULL ) == NULL ) mlt_properties_set_data( properties, "_producer", service, 0, NULL, NULL ); } else if ( self != NULL ) { // Get the speed of the cut double speed = mlt_producer_get_speed( self ); // Get the parent of the cut mlt_producer parent = mlt_producer_cut_parent( self ); // Get the properties of the parent mlt_properties parent_properties = MLT_PRODUCER_PROPERTIES( parent ); // Get the properties of the cut mlt_properties properties = MLT_PRODUCER_PROPERTIES( self ); // Determine the clone index int clone_index = mlt_properties_get_int( properties, "_clone" ); // Determine the clone to use mlt_producer clone = self; if ( clone_index > 0 ) { char key[ 25 ]; sprintf( key, "_clone.%d", clone_index - 1 ); clone = mlt_properties_get_data( MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( self ) ), key, NULL ); if ( clone == NULL ) mlt_log( service, MLT_LOG_ERROR, "requested clone doesn't exist %d\n", clone_index ); clone = clone == NULL ? self : clone; } else { clone = parent; } // We need to seek to the correct position in the clone mlt_producer_seek( clone, mlt_producer_get_in( self ) + mlt_properties_get_int( properties, "_position" ) ); // Assign the clone property to the parent mlt_properties_set_data( parent_properties, "use_clone", clone, 0, NULL, NULL ); // Now get the frame from the parents service result = mlt_service_get_frame( MLT_PRODUCER_SERVICE( parent ), frame, index ); // We're done with the clone now mlt_properties_set_data( parent_properties, "use_clone", NULL, 0, NULL, NULL ); // This is useful and required by always_active transitions to determine in/out points of the cut if ( mlt_properties_get_data( MLT_FRAME_PROPERTIES( *frame ), "_producer", NULL ) == MLT_PRODUCER_SERVICE( parent ) ) mlt_properties_set_data( MLT_FRAME_PROPERTIES( *frame ), "_producer", self, 0, NULL, NULL ); mlt_properties_set_double( MLT_FRAME_PROPERTIES( *frame ), "_speed", speed ); mlt_producer_prepare_next( self ); } else { *frame = mlt_frame_init( service ); result = 0; } // Pass on all meta properties from the producer/cut on to the frame if ( *frame != NULL && self != NULL ) { int i = 0; mlt_properties p_props = MLT_PRODUCER_PROPERTIES( self ); mlt_properties f_props = MLT_FRAME_PROPERTIES( *frame ); mlt_properties_lock( p_props ); int count = mlt_properties_count( p_props ); for ( i = 0; i < count; i ++ ) { char *name = mlt_properties_get_name( p_props, i ); if ( !strncmp( name, "meta.", 5 ) ) mlt_properties_set( f_props, name, mlt_properties_get_value( p_props, i ) ); else if ( !strncmp( name, "set.", 4 ) ) mlt_properties_set( f_props, name + 4, mlt_properties_get_value( p_props, i ) ); } mlt_properties_unlock( p_props ); } return result; }
mlt_position mlt_producer_get_playtime( mlt_producer self ) { return mlt_producer_get_out( self ) - mlt_producer_get_in( self ) + 1; }
mlt_position mlt_multitrack_clip( mlt_multitrack self, mlt_whence whence, int index ) { mlt_position position = 0; int i = 0; int j = 0; mlt_position *map = calloc( 1000, sizeof( mlt_position ) ); int count = 0; for ( i = 0; i < self->count; i ++ ) { // Get the producer for this track mlt_producer producer = self->list[ i ]->producer; // If it's assigned and not a hidden track if ( producer != NULL ) { // Get the properties of this producer mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); // Determine if it's a playlist mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); // Special case consideration of playlists if ( playlist != NULL ) { for ( j = 0; j < mlt_playlist_count( playlist ); j ++ ) count = add_unique( map, count, mlt_playlist_clip( playlist, mlt_whence_relative_start, j ) ); count = add_unique( map, count, mlt_producer_get_out( producer ) + 1 ); } else { count = add_unique( map, count, 0 ); count = add_unique( map, count, mlt_producer_get_out( producer ) + 1 ); } } } // Now sort the map qsort( map, count, sizeof( mlt_position ), position_compare ); // Now locate the requested index switch( whence ) { case mlt_whence_relative_start: if ( index < count ) position = map[ index ]; else position = map[ count - 1 ]; break; case mlt_whence_relative_current: position = mlt_producer_position( MLT_MULTITRACK_PRODUCER( self ) ); for ( i = 0; i < count - 2; i ++ ) if ( position >= map[ i ] && position < map[ i + 1 ] ) break; index += i; if ( index >= 0 && index < count ) position = map[ index ]; else if ( index < 0 ) position = map[ 0 ]; else position = map[ count - 1 ]; break; case mlt_whence_relative_end: if ( index < count ) position = map[ count - index - 1 ]; else position = map[ 0 ]; break; } // Free the map free( map ); return position; }
void AsisScript::pre_judge() throw (Exception) { ScriptProps::Property& service_prop = type_spec_props->get_property("service"); if (!service_prop.Evaluable::finished()) throw_error_v(ErrorScriptFmtError,"asis producer script service should be determinated"); ScriptProps::Property& resource_prop = type_spec_props->get_property("resource"); if (!resource_prop.Evaluable::finished()) throw_error_v(ErrorScriptFmtError,"asis producer script resource should be determinated"); json_t* svc_value = service_prop.compile(); json_t* res_value = resource_prop.compile(); JsonWrap svc_wrap(svc_value,1); JsonWrap res_wrap(res_value,1); if ( !svc_value || !json_is_string(svc_value) || !strlen(json_string_value(svc_value))) throw_error_v(ErrorScriptFmtError,"asis producer script service should be string value"); if ( !res_value || !json_is_string(res_value) || !strlen(json_string_value(res_value))) throw_error_v(ErrorScriptFmtError,"asis producer script resource should be string value"); mlt_profile prof = mlt_profile_clone(MltLoader::global_profile); mlt_producer tmp_prod = mlt_factory_producer(prof, json_string_value(svc_value), json_string_value(res_value)); MltSvcWrap prod_wrap(mlt_producer_service(tmp_prod), 1); if (tmp_prod == NULL) { throw_error_v(ErrorRuntimeLoadFailed, "producer %s load failed", json_string_value(svc_value)); } if ( mlt_props ) { ScriptProps::PropIter it = mlt_props->begin(); for ( ; it!=mlt_props->end(); it++) { if ( it->second->Evaluable::finished() ) { json_t* prop_v = it->second->compile(); JsonWrap prop_wrap(prop_v, 1); switch(prop_v->type) { case JSON_INTEGER: mlt_properties_set_int64(mlt_producer_properties(tmp_prod), it->first.c_str(), json_integer_value(prop_v)); break; case JSON_REAL: mlt_properties_set_double(mlt_producer_properties(tmp_prod), it->first.c_str(), json_real_value(prop_v)); break; case JSON_STRING: mlt_properties_set(mlt_producer_properties(tmp_prod), it->first.c_str(), json_string_value(prop_v)); break; case JSON_TRUE: mlt_properties_set_int(mlt_producer_properties(tmp_prod), it->first.c_str(), 1); break; case JSON_FALSE: mlt_properties_set_int(mlt_producer_properties(tmp_prod), it->first.c_str(), 0); break; default: throw_error_v(ErrorRuntimeLoadFailed, "producer %s load failed. %s prop invalid", json_string_value(svc_value), it->first.c_str()); } } } } int in = mlt_producer_get_in(tmp_prod); int out = mlt_producer_get_out(tmp_prod); set_frame_range(in, out); if ( !mlt_props.get()) { mlt_props.reset(new ScriptProps(*this, NULL)); } json_t* jv = json_integer(in); mlt_props->add_property("in", jv); json_decref(jv); jv = json_integer(out); mlt_props->add_property("out", jv); json_decref(jv); string uuid = Vm::uuid(); type_spec_props->add_property("uuid", JsonWrap(json_string(uuid.c_str()),1).h); prod_wrap.obj = NULL; MltLoader::push_mlt_registry(mlt_producer_service(tmp_prod), uuid.c_str()); }
void loadFromXml( mlt_producer producer, QGraphicsScene *scene, const char *templateXml, const char *templateText ) { scene->clear(); mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer ); QDomDocument doc; QString data = QString::fromUtf8(templateXml); QString replacementText = QString::fromUtf8(templateText); doc.setContent(data); QDomElement title = doc.documentElement(); // Check for invalid title if ( title.isNull() || title.tagName() != "kdenlivetitle" ) return; // Check title locale if ( title.hasAttribute( "LC_NUMERIC" ) ) { QString locale = title.attribute( "LC_NUMERIC" ); QLocale::setDefault( locale ); } int originalWidth; int originalHeight; if ( title.hasAttribute("width") ) { originalWidth = title.attribute("width").toInt(); originalHeight = title.attribute("height").toInt(); scene->setSceneRect(0, 0, originalWidth, originalHeight); } else { originalWidth = scene->sceneRect().width(); originalHeight = scene->sceneRect().height(); } if ( title.hasAttribute( "out" ) ) { mlt_properties_set_position( producer_props, "_animation_out", title.attribute( "out" ).toDouble() ); } else { mlt_properties_set_position( producer_props, "_animation_out", mlt_producer_get_out( producer ) ); } mlt_properties_set_int( producer_props, "_original_width", originalWidth ); mlt_properties_set_int( producer_props, "_original_height", originalHeight ); QDomNode node; QDomNodeList items = title.elementsByTagName("item"); for ( int i = 0; i < items.count(); i++ ) { QGraphicsItem *gitem = NULL; node = items.item( i ); QDomNamedNodeMap nodeAttributes = node.attributes(); int zValue = nodeAttributes.namedItem( "z-index" ).nodeValue().toInt(); if ( zValue > -1000 ) { if ( nodeAttributes.namedItem( "type" ).nodeValue() == "QGraphicsTextItem" ) { QDomNamedNodeMap txtProperties = node.namedItem( "content" ).attributes(); QFont font( txtProperties.namedItem( "font" ).nodeValue() ); QDomNode propsNode = txtProperties.namedItem( "font-bold" ); if ( !propsNode.isNull() ) { // Old: Bold/Not bold. font.setBold( propsNode.nodeValue().toInt() ); } else { // New: Font weight (QFont::) font.setWeight( txtProperties.namedItem( "font-weight" ).nodeValue().toInt() ); } font.setItalic( txtProperties.namedItem( "font-italic" ).nodeValue().toInt() ); font.setUnderline( txtProperties.namedItem( "font-underline" ).nodeValue().toInt() ); // Older Kdenlive version did not store pixel size but point size if ( txtProperties.namedItem( "font-pixel-size" ).isNull() ) { QFont f2; f2.setPointSize( txtProperties.namedItem( "font-size" ).nodeValue().toInt() ); font.setPixelSize( QFontInfo( f2 ).pixelSize() ); } else font.setPixelSize( txtProperties.namedItem( "font-pixel-size" ).nodeValue().toInt() ); QColor col( stringToColor( txtProperties.namedItem( "font-color" ).nodeValue() ) ); QString text = node.namedItem( "content" ).firstChild().nodeValue(); if ( !replacementText.isEmpty() ) { text = text.replace( "%s", replacementText ); } QGraphicsTextItem *txt = scene->addText(text, font); if (txtProperties.namedItem("font-outline").nodeValue().toDouble()>0.0){ QTextDocument *doc = txt->document(); // Make sure some that the text item does not request refresh by itself doc->blockSignals(true); QTextCursor cursor(doc); cursor.select(QTextCursor::Document); QTextCharFormat format; format.setTextOutline( QPen(QColor( stringToColor( txtProperties.namedItem( "font-outline-color" ).nodeValue() ) ), txtProperties.namedItem("font-outline").nodeValue().toDouble(), Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin) ); format.setForeground(QBrush(col)); cursor.mergeCharFormat(format); } else { txt->setDefaultTextColor( col ); } // Effects if (!txtProperties.namedItem( "typewriter" ).isNull()) { // typewriter effect mlt_properties_set_int( producer_props, "_animated", 1 ); QStringList effetData = QStringList() << "typewriter" << text << txtProperties.namedItem( "typewriter" ).nodeValue(); txt->setData(0, effetData); if ( !txtProperties.namedItem( "textwidth" ).isNull() ) txt->setData( 1, txtProperties.namedItem( "textwidth" ).nodeValue() ); } if ( txtProperties.namedItem( "alignment" ).isNull() == false ) { txt->setTextWidth( txt->boundingRect().width() ); QTextOption opt = txt->document()->defaultTextOption (); opt.setAlignment(( Qt::Alignment ) txtProperties.namedItem( "alignment" ).nodeValue().toInt() ); txt->document()->setDefaultTextOption (opt); } if ( !txtProperties.namedItem( "kdenlive-axis-x-inverted" ).isNull() ) { //txt->setData(OriginXLeft, txtProperties.namedItem("kdenlive-axis-x-inverted").nodeValue().toInt()); } if ( !txtProperties.namedItem( "kdenlive-axis-y-inverted" ).isNull() ) { //txt->setData(OriginYTop, txtProperties.namedItem("kdenlive-axis-y-inverted").nodeValue().toInt()); } gitem = txt; } else if ( nodeAttributes.namedItem( "type" ).nodeValue() == "QGraphicsRectItem" ) { QString rect = node.namedItem( "content" ).attributes().namedItem( "rect" ).nodeValue(); QString br_str = node.namedItem( "content" ).attributes().namedItem( "brushcolor" ).nodeValue(); QString pen_str = node.namedItem( "content" ).attributes().namedItem( "pencolor" ).nodeValue(); double penwidth = node.namedItem( "content" ).attributes().namedItem( "penwidth") .nodeValue().toDouble(); QGraphicsRectItem *rec = scene->addRect( stringToRect( rect ), QPen( QBrush( stringToColor( pen_str ) ), penwidth, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin ), QBrush( stringToColor( br_str ) ) ); gitem = rec; } else if ( nodeAttributes.namedItem( "type" ).nodeValue() == "QGraphicsPixmapItem" ) { const QString url = node.namedItem( "content" ).attributes().namedItem( "url" ).nodeValue(); const QString base64 = items.item(i).namedItem("content").attributes().namedItem("base64").nodeValue(); QImage img; if (base64.isEmpty()){ img.load(url); }else{ img.loadFromData(QByteArray::fromBase64(base64.toAscii())); } ImageItem *rec = new ImageItem(img); scene->addItem( rec ); gitem = rec; } else if ( nodeAttributes.namedItem( "type" ).nodeValue() == "QGraphicsSvgItem" ) { QString url = items.item(i).namedItem("content").attributes().namedItem("url").nodeValue(); QString base64 = items.item(i).namedItem("content").attributes().namedItem("base64").nodeValue(); QGraphicsSvgItem *rec = NULL; if (base64.isEmpty()){ rec = new QGraphicsSvgItem(url); }else{ rec = new QGraphicsSvgItem(); QSvgRenderer *renderer= new QSvgRenderer(QByteArray::fromBase64(base64.toAscii()), rec ); rec->setSharedRenderer(renderer); } if (rec){ scene->addItem(rec); gitem = rec; } } } //pos and transform if ( gitem ) { QPointF p( node.namedItem( "position" ).attributes().namedItem( "x" ).nodeValue().toDouble(), node.namedItem( "position" ).attributes().namedItem( "y" ).nodeValue().toDouble() ); gitem->setPos( p ); gitem->setTransform( stringToTransform( node.namedItem( "position" ).firstChild().firstChild().nodeValue() ) ); int zValue = nodeAttributes.namedItem( "z-index" ).nodeValue().toInt(); gitem->setZValue( zValue ); #if QT_VERSION >= 0x040600 // effects QDomNode eff = items.item(i).namedItem("effect"); if (!eff.isNull()) { QDomElement e = eff.toElement(); if (e.attribute("type") == "blur") { QGraphicsBlurEffect *blur = new QGraphicsBlurEffect(); blur->setBlurRadius(e.attribute("blurradius").toInt()); gitem->setGraphicsEffect(blur); } else if (e.attribute("type") == "shadow") { QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(); shadow->setBlurRadius(e.attribute("blurradius").toInt()); shadow->setOffset(e.attribute("xoffset").toInt(), e.attribute("yoffset").toInt()); gitem->setGraphicsEffect(shadow); } } #endif } } QDomNode n = title.firstChildElement("background"); if (!n.isNull()) { QColor color = QColor( stringToColor( n.attributes().namedItem( "color" ).nodeValue() ) ); if (color.alpha() > 0) { QGraphicsRectItem *rec = scene->addRect(0, 0, scene->width(), scene->height() , QPen( Qt::NoPen ), QBrush( color ) ); rec->setZValue(-1100); } } QString startRect; n = title.firstChildElement( "startviewport" ); // Check if node exists, if it has an x attribute, it is an old version title, don't use viewport if (!n.isNull() && !n.toElement().hasAttribute("x")) { startRect = n.attributes().namedItem( "rect" ).nodeValue(); } n = title.firstChildElement( "endviewport" ); // Check if node exists, if it has an x attribute, it is an old version title, don't use viewport if (!n.isNull() && !n.toElement().hasAttribute("x")) { QString rect = n.attributes().namedItem( "rect" ).nodeValue(); if (startRect != rect) mlt_properties_set( producer_props, "_endrect", rect.toUtf8().data() ); } if (!startRect.isEmpty()) { mlt_properties_set( producer_props, "_startrect", startRect.toUtf8().data() ); } return; }