]> git.sesse.net Git - mlt/commitdiff
Merge commit 'jbm/kdenlivetitle' into kdenlivetitle
authorMarco Gittler <g.marco@freenet.de>
Sat, 1 Aug 2009 19:31:40 +0000 (21:31 +0200)
committerMarco Gittler <g.marco@freenet.de>
Sat, 1 Aug 2009 19:31:40 +0000 (21:31 +0200)
src/modules/qimage/kdenlivetitle_wrapper.cpp
src/modules/qimage/kdenlivetitle_wrapper.h
src/modules/qimage/producer_kdenlivetitle.c

index 9ffa9599e1f5d62c5bc3f93957db040f20e6015f..10478a0132cbf49502e34b5411d6681606d7d682 100644 (file)
 #include <QtGui/QTextCursor>
 #include <QtGui/QStyleOptionGraphicsItem>
 
-static QApplication *app = NULL;
-
-extern "C"
-{
-  
-#include <framework/mlt_producer.h>
-#include <framework/mlt_cache.h>
+#include <QtCore/QString>
 
-       static QMutex g_mutex;
-       void refresh_kdenlivetitle( mlt_producer producer, uint8_t* buffer, int width, int height , double position, int force_refresh )
-       {
-               drawKdenliveTitle( producer, buffer, width, height, position, force_refresh );
-       }
-
-       static void qscene_delete( void *data )
-       {
-               QGraphicsScene *scene = ( QGraphicsScene * )data;
-               delete scene;
-               scene = NULL;
-       }
-}
+#include <QtXml/QDomElement>
+#include <QtCore/QRectF>
+#include <QtGui/QColor>
+#include <QtGui/QWidget>
 
+static QMutex g_mutex;
+static QApplication *app = NULL;
 
 class ImageItem: public QGraphicsRectItem
 {
@@ -60,92 +47,77 @@ public:
     {
        m_img = img;
     }
-    
     QImage m_img;
 
+
 protected:
 virtual void paint( QPainter *painter,
-                       const QStyleOptionGraphicsItem *option,
+                       const QStyleOptionGraphicsItem * /*option*/,
                        QWidget* )
-{
-   //todo: clip rect ?
-   painter->drawImage(QPointF(), m_img);
-   //painter->fillRect(option->exposedRect, QBrush(QColor(0,255,0)));
+{ 
+    painter->setRenderHint(QPainter::SmoothPixmapTransform, true);
+    painter->drawImage(QPoint(), m_img);
 }
-    
-    
 };
 
 
-void drawKdenliveTitle( mlt_producer producer, uint8_t * buffer, int width, int height, double position, int force_refresh )
+QString rectTransform( QString s, QTransform t )
 {
-  
-       // restore QGraphicsScene
-       g_mutex.lock();
-       mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer );
-       QGraphicsScene *scene = static_cast<QGraphicsScene *> (mlt_properties_get_data( producer_props, "qscene", NULL ));
+       QStringList l = s.split( ',' );
+       return QString::number(l.at(0).toDouble() * t.m11()) + ',' + QString::number(l.at(1).toDouble() * t.m22()) + ',' + QString::number(l.at(2).toDouble() * t.m11()) + ',' + QString::number(l.at(3).toDouble() * t.m22());
+}
 
-       if ( force_refresh == 1 && scene )
-       {
-               scene = NULL;
-               mlt_properties_set_data( producer_props, "qscene", NULL, 0, NULL, NULL );
-       }
-       if ( scene == NULL )
-       {
-               int argc = 1;
-               char* argv[1];
-               argv[0] = "xxx";
-               if (qApp) {
-                   app = qApp;
-               }
-               else {
-                   app=new QApplication( argc,argv );
-               }
-               scene = new QGraphicsScene( 0, 0, width, height, app );
-               loadFromXml( producer, scene, mlt_properties_get( producer_props, "xmldata" ), mlt_properties_get( producer_props, "templatetext" ), width, height );
-               mlt_properties_set_data( producer_props, "qscene", scene, 0, ( mlt_destructor )qscene_delete, NULL );
-       }
+QString colorToString( const QColor& c )
+{
+       QString ret = "%1,%2,%3,%4";
+       ret = ret.arg( c.red() ).arg( c.green() ).arg( c.blue() ).arg( c.alpha() );
+       return ret;
+}
 
-       g_mutex.unlock();
-       
-       //must be extracted from kdenlive title
-       QImage img( width, height, QImage::Format_ARGB32 );
-       img.fill( 0 );
-       QPainter p1;
-       p1.begin( &img );
-       p1.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing );
-       //| QPainter::SmoothPixmapTransform );
+QString rectFToString( const QRectF& c )
+{
+       QString ret = "%1,%2,%3,%4";
+       ret = ret.arg( c.top() ).arg( c.left() ).arg( c.width() ).arg( c.height() );
+       return ret;
+}
 
-       const QRectF start = stringToRect( QString( mlt_properties_get( producer_props, "startrect" ) ) );
-       const QRectF end = stringToRect( QString( mlt_properties_get( producer_props, "endrect" ) ) );
-       const QRectF source( 0, 0, width, height );
+QRectF stringToRect( const QString & s )
+{
 
-       if (end.isNull()) {
-               if (start.isNull())
-                       scene->render( &p1, source, source );
-               else
-                       scene->render( &p1, start, source );
-       }
-       else {
-           QPointF topleft = start.topLeft() + ( end.topLeft() - start.topLeft() ) * position;
-           QPointF bottomRight = start.bottomRight() + ( end.bottomRight() - start.bottomRight() ) * position;
-           const QRectF r1( topleft, bottomRight );
-           scene->render( &p1, r1, source );
-       }
-       p1.end();
-       uint8_t *pointer=img.bits();
-       QRgb* src = ( QRgb* ) pointer;
-       for ( int i = 0; i < width * height * 4; i += 4 )
-       {
-               *buffer++=qRed( *src );
-               *buffer++=qGreen( *src );
-               *buffer++=qBlue( *src );
-               *buffer++=qAlpha( *src );
-               src++;
-       }
+       QStringList l = s.split( ',' );
+       if ( l.size() < 4 )
+               return QRectF();
+       return QRectF( l.at( 0 ).toDouble(), l.at( 1 ).toDouble(), l.at( 2 ).toDouble(), l.at( 3 ).toDouble() ).normalized();
+}
+
+QColor stringToColor( const QString & s )
+{
+       QStringList l = s.split( ',' );
+       if ( l.size() < 4 )
+               return QColor();
+       return QColor( l.at( 0 ).toInt(), l.at( 1 ).toInt(), l.at( 2 ).toInt(), l.at( 3 ).toInt() );
+       ;
+}
+QTransform stringToTransform( const QString& s )
+{
+       QStringList l = s.split( ',' );
+       if ( l.size() < 9 )
+               return QTransform();
+       return QTransform(
+                  l.at( 0 ).toDouble(), l.at( 1 ).toDouble(), l.at( 2 ).toDouble(),
+                  l.at( 3 ).toDouble(), l.at( 4 ).toDouble(), l.at( 5 ).toDouble(),
+                  l.at( 6 ).toDouble(), l.at( 7 ).toDouble(), l.at( 8 ).toDouble()
+              );
 }
 
+static void qscene_delete( void *data )
+{
+       QGraphicsScene *scene = ( QGraphicsScene * )data;
+       delete scene;
+       scene = NULL;
+}
+
+
 void loadFromXml( mlt_producer producer, QGraphicsScene *scene, const char *templateXml, const char *templateText, int width, int height  )
 {
        scene->clear();
@@ -207,16 +179,15 @@ void loadFromXml( mlt_producer producer, QGraphicsScene *scene, const char *temp
                                        else
                                                font.setPixelSize( txtProperties.namedItem( "font-pixel-size" ).nodeValue().toInt() );
                                        QColor col( stringToColor( txtProperties.namedItem( "font-color" ).nodeValue() ) );
-                                       QGraphicsTextItem *txt;
+                                       QString text = items.item( i ).namedItem( "content" ).firstChild().nodeValue();
                                        if ( !replacementText.isEmpty() )
                                        {
-                                               QString text = items.item( i ).namedItem( "content" ).firstChild().nodeValue();
                                                text = text.replace( "%s", replacementText );
-                                               txt = scene->addText( text, font );
                                        }
-                                       else txt = scene->addText( items.item( i ).namedItem( "content" ).firstChild().nodeValue(), font );
+                                       QGraphicsTextItem *txt = new QGraphicsTextItem( text );
+                                       txt->setFont(font);
+                                       scene->addItem(txt);
                                        txt->setDefaultTextColor( col );
-                                       txt->setTextInteractionFlags( Qt::NoTextInteraction );
                                        if ( txtProperties.namedItem( "alignment" ).isNull() == false )
                                        {
                                                txt->setTextWidth( txt->boundingRect().width() );
@@ -301,7 +272,7 @@ void loadFromXml( mlt_producer producer, QGraphicsScene *scene, const char *temp
                                if ( transform != QTransform() ) {
                                    rect = rectTransform( rect, transform );
                                }
-                               mlt_properties_set( producer_props, "startrect", rect.toUtf8().data() );
+                               mlt_properties_set( producer_props, "_startrect", rect.toUtf8().data() );
                        }
                        else if ( items.item( i ).nodeName() == "endviewport" )
                        {
@@ -309,60 +280,111 @@ void loadFromXml( mlt_producer producer, QGraphicsScene *scene, const char *temp
                                if ( transform != QTransform() ) {
                                    rect = rectTransform( rect, transform );
                                }
-                               mlt_properties_set( producer_props, "endrect", rect.toUtf8().data() );
+                               mlt_properties_set( producer_props, "_endrect", rect.toUtf8().data() );
                        }
                }
        }
-       if ( mlt_properties_get( producer_props, "startrect") == mlt_properties_get( producer_props, "endrect") )
-               mlt_properties_set( producer_props, "endrect", "" );
+       if ( !strcmp( mlt_properties_get( producer_props, "_startrect" ), mlt_properties_get( producer_props, "_endrect" ) ) )
+               mlt_properties_set( producer_props, "_endrect", "" );
        return;
 }
 
-QString rectTransform( QString s, QTransform t )
-{
-       QStringList l = s.split( ',' );
-       return QString::number(l.at(0).toDouble() * t.m11()) + ',' + QString::number(l.at(1).toDouble() * t.m22()) + ',' + QString::number(l.at(2).toDouble() * t.m11()) + ',' + QString::number(l.at(3).toDouble() * t.m22());
-}
 
-QString colorToString( const QColor& c )
+void drawKdenliveTitle( producer_ktitle self, uint8_t * buffer, int width, int height, double position, int force_refresh )
 {
-       QString ret = "%1,%2,%3,%4";
-       ret = ret.arg( c.red() ).arg( c.green() ).arg( c.blue() ).arg( c.alpha() );
-       return ret;
-}
+  
+       // Obtain the producer 
+       mlt_producer producer = &self->parent;
+       
+       // restore cached image if any
+       mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer );
 
-QString rectFToString( const QRectF& c )
-{
-       QString ret = "%1,%2,%3,%4";
-       ret = ret.arg( c.top() ).arg( c.left() ).arg( c.width() ).arg( c.height() );
-       return ret;
-}
+       /*if ( force_refresh == 0 )
+       {
+               uint8_t * cache = ( uint8_t * )mlt_properties_get_data( producer_props, "image", NULL );
+               if (cache) {
+                   buffer = cache;
+                   return;
+               }
+       }*/
+       
+       // restore QGraphicsScene
+       QGraphicsScene *scene = static_cast<QGraphicsScene *> (mlt_properties_get_data( producer_props, "qscene", NULL ));
 
-QRectF stringToRect( const QString & s )
-{
+       if ( force_refresh == 1 && scene )
+       {
+               scene = NULL;
+               mlt_properties_set_data( producer_props, "qscene", NULL, 0, NULL, NULL );
+       }
+       if ( scene == NULL )
+       {
+               int argc = 1;
+               char* argv[1];
+               argv[0] = "xxx";
+               if (qApp) {
+                   app = qApp;
+               }
+               else {
+                   app=new QApplication( argc,argv ); //, QApplication::Tty );
+               }
+               scene = new QGraphicsScene( 0, 0, width, height, app );
+               loadFromXml( producer, scene, mlt_properties_get( producer_props, "xmldata" ), mlt_properties_get( producer_props, "templatetext" ), width, height );
+               mlt_properties_set_data( producer_props, "qscene", scene, 0, ( mlt_destructor )qscene_delete, NULL );
+       }
 
-       QStringList l = s.split( ',' );
-       if ( l.size() < 4 )
-               return QRectF();
-       return QRectF( l.at( 0 ).toDouble(), l.at( 1 ).toDouble(), l.at( 2 ).toDouble(), l.at( 3 ).toDouble() ).normalized();
-}
 
-QColor stringToColor( const QString & s )
-{
-       QStringList l = s.split( ',' );
-       if ( l.size() < 4 )
-               return QColor();
-       return QColor( l.at( 0 ).toInt(), l.at( 1 ).toInt(), l.at( 2 ).toInt(), l.at( 3 ).toInt() );
-       ;
-}
-QTransform stringToTransform( const QString& s )
-{
-       QStringList l = s.split( ',' );
-       if ( l.size() < 9 )
-               return QTransform();
-       return QTransform(
-                  l.at( 0 ).toDouble(), l.at( 1 ).toDouble(), l.at( 2 ).toDouble(),
-                  l.at( 3 ).toDouble(), l.at( 4 ).toDouble(), l.at( 5 ).toDouble(),
-                  l.at( 6 ).toDouble(), l.at( 7 ).toDouble(), l.at( 8 ).toDouble()
-              );
+       //must be extracted from kdenlive title
+       QImage img( width, height, QImage::Format_ARGB32 );
+       img.fill( 0 );
+       QPainter p1;
+       p1.begin( &img );
+       p1.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing );
+       //| QPainter::SmoothPixmapTransform );
+
+       const QRectF start = stringToRect( QString( mlt_properties_get( producer_props, "_startrect" ) ) );
+       const QRectF end = stringToRect( QString( mlt_properties_get( producer_props, "_endrect" ) ) );
+       const QRectF source( 0, 0, width, height );
+
+       if (end.isNull()) {
+               if (start.isNull())
+                       scene->render( &p1, source, source );
+               else
+                       scene->render( &p1, start, source );
+       }
+       else {
+           QPointF topleft = start.topLeft() + ( end.topLeft() - start.topLeft() ) * position;
+           QPointF bottomRight = start.bottomRight() + ( end.bottomRight() - start.bottomRight() ) * position;
+           const QRectF r1( topleft, bottomRight );
+           scene->render( &p1, r1, source );
+       }
+       p1.end();
+       g_mutex.lock();
+       uint8_t *pointer=img.bits();
+       QRgb* src = ( QRgb* ) pointer;
+       int size = width * height * 4;
+       for ( int i = 0; i < width * height * 4; i += 4 )
+       {
+               *buffer++=qRed( *src );
+               *buffer++=qGreen( *src );
+               *buffer++=qBlue( *src );
+               *buffer++=qAlpha( *src );
+               src++;
+       }
+
+       if ( end.isNull() )
+       {
+           // No animation, cache image for further requests
+           self->current_image = (uint8_t *)mlt_pool_alloc( size );
+           self->current_image = buffer;
+           mlt_properties_set_data( producer_props, "image", self->current_image, width * height * 4, NULL, NULL );
+           
+           // Clear scene, we don't need it anymore
+           mlt_properties_set_data( producer_props, "qscene", NULL, 0, NULL, NULL );
+       }
+       g_mutex.unlock();
 }
+
+
+
+
index 81fad1118af14ab9247aa931c0e4b3fcbb0f9cf5..0660915a78fc10d3abc3c6781a466aadd97ca88b 100644 (file)
 
 #include <framework/mlt.h>
 
-#include <QtCore/QString>
+#ifdef __cplusplus
+extern "C" {
+#endif
+  
+#include <framework/mlt_producer.h>
+#include <framework/mlt_cache.h>
 #include <framework/mlt_frame.h>
-#include <QtXml/QDomElement>
-#include <QtCore/QRectF>
-#include <QtGui/QColor>
-#include <QtGui/QWidget>
-
-class QApplication;
-class QGraphicsScene;
-class QTransform;
-
-void drawKdenliveTitle( mlt_producer producer, uint8_t*, int, int, double, int );
-void loadFromXml( mlt_producer producer, QGraphicsScene *scene, const char *templateXml, const char *templateText,int width, int height );
-
-QString rectTransform( QString s, QTransform t );
-QString colorToString( const QColor& );
-QString rectFToString( const QRectF& );
-QRectF stringToRect( const QString & );
-QColor stringToColor( const QString & );
-QTransform stringToTransform( const QString & );
+
+
+struct producer_ktitle_s
+{
+       struct mlt_producer_s parent;
+       uint8_t *current_image;
+       pthread_mutex_t mutex;
+};
+
+typedef struct producer_ktitle_s *producer_ktitle;
+
+extern void drawKdenliveTitle( producer_ktitle self, uint8_t*, int, int, double, int );
+
+
+#ifdef __cplusplus
+}
+#endif
+
 
 
index e9d2662a19e55600c752e46c315d8d1c5dd975e1..92b7ee178cffe76aae164667c1387e6d5948113a 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include "kdenlivetitle_wrapper.h"
+
 #include <framework/mlt.h>
 #include <stdlib.h>
 #include <string.h>
@@ -52,10 +54,10 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
 
        /* Obtain the producer for this frame */
-       mlt_producer producer = mlt_properties_get_data( properties, "producer_kdenlivetitle", NULL );
-
+       producer_ktitle this = mlt_properties_get_data( properties, "producer_kdenlivetitle", NULL );
+       
        /* Obtain properties of producer */
-       mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer );
+       mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( &this->parent );
        
        *width = mlt_properties_get_int( properties, "width" );
        *height = mlt_properties_get_int( properties, "height" );
@@ -67,27 +69,35 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
 
        mlt_properties_set_int( properties, "width", *width );
        mlt_properties_set_int( properties, "height", *height );
-
-       /* cache later ?? */
-
-       if ( 1 )
+       
+       if ( this->current_image )
+       {
+               // Clone the image
+               uint8_t *image_copy = mlt_pool_alloc( size );
+               memcpy( image_copy, this->current_image, size );
+               // Now update properties so we free the copy after
+               mlt_properties_set_data( properties, "image", image_copy, size, mlt_pool_release, NULL );
+               // We're going to pass the copy on
+               *buffer = image_copy;
+       }
+       else
        {
                /* Allocate the image */
                *format = mlt_image_rgb24a;
-               mlt_position in = mlt_producer_get_in( producer );
-               mlt_position out = mlt_producer_get_out( producer );
-               mlt_position time = mlt_producer_position( producer );
+               mlt_position in = mlt_producer_get_in( &this->parent );
+               mlt_position out = mlt_producer_get_out( &this->parent );
+               mlt_position time = mlt_producer_position( &this->parent );
                double position = ( double )( time - in ) / ( double )( out - in + 1 );
                if ( mlt_properties_get_int( producer_props, "force_reload" ) ) {
                        if (mlt_properties_get_int( producer_props, "force_reload" ) > 1) read_xml(producer_props);
                        mlt_properties_set_int( producer_props, "force_reload", 0 );
-                       refresh_kdenlivetitle( producer, *buffer, *width, *height, position, 1);
+                       drawKdenliveTitle( this, *buffer, *width, *height, position, 1);
                }
-               else refresh_kdenlivetitle( producer, *buffer, *width, *height, position, 0);
+               else drawKdenliveTitle( this, *buffer, *width, *height, position, 0);
                /* Update the frame */
                mlt_properties_set_data( properties, "image", *buffer, size, mlt_pool_release, NULL );
 
-               mlt_log_debug( MLT_PRODUCER_SERVICE( producer ), "width:%d height:%d %s\n", *width, *height, mlt_image_format_name( *format ) );
+               mlt_log_debug( MLT_PRODUCER_SERVICE( &this->parent ), "width:%d height:%d %s\n", *width, *height, mlt_image_format_name( *format ) );
        }
 
        return 0;
@@ -96,6 +106,8 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
 static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
 
 {
+       // Get the real structure for this producer
+       producer_ktitle this = producer->child;
 
        /* Generate a frame */
        *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );
@@ -109,7 +121,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer );
 
                /* Set the producer on the frame properties */
-               mlt_properties_set_data( properties, "producer_kdenlivetitle", producer, 0, NULL, NULL );
+               mlt_properties_set_data( properties, "producer_kdenlivetitle", this, 0, NULL, NULL );
 
                /* Update timecode on the frame we're creating */
                mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
@@ -141,10 +153,12 @@ mlt_producer producer_kdenlivetitle_init( mlt_profile profile, mlt_service_type
 {
        /* fprintf(stderr, ":::::::::::: CREATE TITLE\n"); */
        /* Create a new producer object */
-
-       mlt_producer producer = calloc( 1, sizeof( struct mlt_producer_s ) );
-       if ( producer != NULL && mlt_producer_init( producer, NULL ) == 0 )
+       
+       producer_ktitle this = calloc( sizeof( struct producer_ktitle_s ), 1 );
+       if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 )
        {
+               mlt_producer producer = &this->parent;
+               
                /* Get the properties interface */
                mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
                /* Callback registration */
@@ -155,7 +169,7 @@ mlt_producer producer_kdenlivetitle_init( mlt_profile profile, mlt_service_type
                read_xml(properties);
                return producer;
        }
-       free( producer );
+       free( this );
        return NULL;
 }