]> git.sesse.net Git - mlt/commitdiff
add rendering to vqm and yaml service metadata
authorDan Dennedy <dan@dennedy.org>
Thu, 9 Feb 2012 05:04:55 +0000 (21:04 -0800)
committerDan Dennedy <dan@dennedy.org>
Thu, 9 Feb 2012 05:05:07 +0000 (21:05 -0800)
src/modules/qimage/factory.c
src/modules/qimage/transition_vqm.cpp
src/modules/qimage/transition_vqm.yml [new file with mode: 0644]

index 1c1e6366cbe3a1c1458da4c20b14360917c4ae46..46ca30b5c728fd56b25ac5e22aad723abf24e0ac 100644 (file)
@@ -40,4 +40,5 @@ MLT_REPOSITORY
        MLT_REGISTER( transition_type, "vqm", transition_vqm_init );
        MLT_REGISTER_METADATA( producer_type, "qimage", metadata, "producer_qimage.yml" );
        MLT_REGISTER_METADATA( producer_type, "kdenlivetitle", metadata, "producer_kdenlivetitle.yml" );
+       MLT_REGISTER_METADATA( transition_type, "vqm", metadata, "transition_vqm.yml" );
 }
index a75a60abe9c4fdc491218da3638b606974ae1dda..4d45d8a6c73985f0177ba401d6fa47a4f9f8c720 100644 (file)
@@ -22,6 +22,9 @@
 #include <string.h>
 #include <math.h>
 #include <stdio.h>
+#include <QtGui>
+
+static QApplication *app = 0;
 
 static double calc_psnr( const uint8_t *a, const uint8_t *b, int size, int bpp )
 {
@@ -117,9 +120,98 @@ static int get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *form
                        mlt_frame_get_position( a_frame ), psnr[0], psnr[1], psnr[2],
                        ssim[0], ssim[1], ssim[2] );
 
+       // copy the B frame to the bottom of the A frame for comparison
        window_size = mlt_image_format_size( *format, *width, *height, NULL ) / 2;
        memcpy( *image + window_size, b_image + window_size, window_size );
 
+       if ( !mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( transition ), "render" ) )
+               return 0;
+
+       // get RGBA image for Qt drawing
+       *format = mlt_image_rgb24a;
+       mlt_frame_get_image( a_frame, image, format, width, height, 1 );
+
+       // convert mlt image to qimage
+       QImage img( *width, *height, QImage::Format_ARGB32 );
+       int y = *height + 1;
+       uint8_t *src = *image;
+       while ( --y )
+       {
+               QRgb *dst = (QRgb*) img.scanLine( *height - y );
+               int x = *width + 1;
+               while ( --x )
+               {
+                       *dst++ = qRgba( src[0], src[1], src[2], 255 );
+                       src += 4;
+               }
+       }
+
+       // create QApplication, if needed
+       if ( !app )
+       {
+               if ( qApp )
+               {
+                       app = qApp;
+               }
+               else
+               {
+                       int argc = 1;
+                       char* argv[] = { strdup( "unknown" ) };
+
+                       app = new QApplication( argc, argv );
+                       const char *localename = mlt_properties_get_lcnumeric( MLT_TRANSITION_PROPERTIES(transition) );
+                       QLocale::setDefault( QLocale( localename ) );
+                       free( argv[0] );
+               }
+       }
+
+       // setup Qt drawing
+       QPainter painter;
+       painter.begin( &img );
+       painter.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing );
+
+       // draw some stuff with Qt
+       QPalette palette;
+       QFont font;
+       QString s;
+       font.setBold( true );
+       font.setPointSize( 30 );
+       painter.setPen( QColor("black") );
+       painter.drawLine( 0, *height/2 + 1, *width, *height/2 );
+       painter.setPen( QColor("white") );
+       painter.drawLine( 0, *height/2 - 1, *width, *height/2 );
+       painter.setFont( font );
+       s.sprintf( "Frame: %05d\nPSNR:   %05.2f (Y) %05.2f (Cb) %05.2f (Cr)\nSSIM:    %5.3f (Y) %5.3f (Cb) %5.3f (Cr)",
+                         mlt_frame_get_position( a_frame ), psnr[0], psnr[1], psnr[2],
+                         ssim[0], ssim[1], ssim[2] );
+       painter.setPen( QColor("black") );
+       painter.drawText( 52, *height - 300 * font.pointSize() / 72 + 2, *width, *height, NULL, s );
+       painter.setPen( QColor("white") );
+       painter.drawText( 50, *height - 300 * font.pointSize() / 72, *width, *height, NULL, s );
+
+       // finish Qt drawing
+       painter.end();
+       window_size = mlt_image_format_size( *format, *width, *height, NULL );
+       uint8_t *dst = (uint8_t *) mlt_pool_alloc( window_size );
+       mlt_properties_set_data( MLT_FRAME_PROPERTIES(a_frame), "image", dst, window_size, mlt_pool_release, NULL );
+       *image = dst;
+
+       // convert qimage to mlt
+       y = *height + 1;
+       while ( --y )
+       {
+               QRgb *src = (QRgb*) img.scanLine( *height - y );
+               int x = *width + 1;
+               while ( --x )
+               {
+                       *dst++ = qRed( *src );
+                       *dst++ = qGreen( *src );
+                       *dst++ = qBlue( *src );
+                       *dst++ = qAlpha( *src );
+                       src++;
+               }
+       }
+
        return 0;
 }
 
diff --git a/src/modules/qimage/transition_vqm.yml b/src/modules/qimage/transition_vqm.yml
new file mode 100644 (file)
index 0000000..836cb72
--- /dev/null
@@ -0,0 +1,28 @@
+schema_version: 0.1
+type: transition
+identifier: vqm
+title: Video Quality Measurement
+version: 1
+copyright: Dan Dennedy
+creator: Dan Dennedy
+license: GPLv3
+language: en
+description: >
+  This performs the PSNR and SSIM video quality measurements by comparing the
+  B frames to the reference frame A.
+  It outputs the numbers to stdout in space-delimited format for easy
+  by another tool.
+  The bottom half of the B frame is placed below the top half of the A frame
+  for visual comparison.
+tags:
+  - Video
+parameters:
+  - identifier: render
+    title: Render
+    description: >
+      Render a line between top and bottom halves and the values atop the video.
+    type: integer
+    default: 0
+    minimum: 0
+    maximum: 1
+    widget: checkbox