]> git.sesse.net Git - mlt/commitdiff
Rewrote caching, similar to qimage producer
authorj-b-m <jb@kdenlive.org>
Sat, 1 Aug 2009 14:25:12 +0000 (16:25 +0200)
committerj-b-m <jb@kdenlive.org>
Sat, 1 Aug 2009 14:25:12 +0000 (16:25 +0200)
modified:   kdenlivetitle_wrapper.cpp
modified:   kdenlivetitle_wrapper.h
modified:   producer_kdenlivetitle.c

src/modules/qimage/kdenlivetitle_wrapper.cpp
src/modules/qimage/kdenlivetitle_wrapper.h
src/modules/qimage/producer_kdenlivetitle.c

index d855f4558b15b1ecbae51afdb01e025e92428d3a..10478a0132cbf49502e34b5411d6681606d7d682 100644 (file)
 #include <QtGui/QTextCursor>
 #include <QtGui/QStyleOptionGraphicsItem>
 
-static QApplication *app = NULL;
+#include <QtCore/QString>
 
-extern "C"
-{
-  
-#include <framework/mlt_producer.h>
-#include <framework/mlt_cache.h>
-
-       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
 {
@@ -74,98 +61,63 @@ virtual void paint( QPainter *painter,
 };
 
 
-void drawKdenliveTitle( mlt_producer producer, uint8_t * buffer, int width, int height, double position, int force_refresh )
+QString rectTransform( QString s, QTransform t )
 {
-  
-       // restore cached image if any
-       mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer );
-
-       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 ));
+       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 ); //, 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 );
-       }
+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;
+}
 
+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;
+}
 
-       //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 );
+QRectF stringToRect( const QString & s )
+{
 
-       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 );
+       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();
+}
 
-       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++;
-       }
+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()
+              );
+}
 
-       if ( end.isNull() )
-       {
-           // No animation, cache image for further requests
-           uint8_t *cached_image = (uint8_t *)mlt_pool_alloc( size );
-           cached_image = buffer;
-           mlt_properties_set_data( producer_props, "image", cached_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();
+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();
@@ -337,51 +289,102 @@ void loadFromXml( mlt_producer producer, QGraphicsScene *scene, const char *temp
        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;
 }