]> git.sesse.net Git - mlt/commitdiff
src/framework/mlt_deque.c
authorlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Sun, 26 Jun 2005 21:04:26 +0000 (21:04 +0000)
committerlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Sun, 26 Jun 2005 21:04:26 +0000 (21:04 +0000)
src/framework/mlt_deque.h
+ Added support for doubles

src/framework/mlt_frame.c
+ Switched order of source/dest audio mix extraction (for transition as filter usage)

src/framework/mlt_tractor.c
- Removed warning introduced from previous checkin (missing ctype.h)
+ Temporary work around to allow frames to carry multiple frames (for transition as filter usage)

src/modules/core/Makefile
src/modules/core/configure
src/modules/core/factory.c
+ Support for new transition filter :-)

src/modules/core/transition_composite.c
src/modules/core/transition_composite.h
- Removed frame properties dependence for process/get_image state communication
+ Extended alpha blending modes to 'and' and 'xor' logic (may change property triggering soon)
+ Provided support for transition as filter usage
+ Cleaned up public copy region functionality

git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@742 d19143bc-622f-0410-bfdd-b5b2a6649095

src/framework/mlt_deque.c
src/framework/mlt_deque.h
src/framework/mlt_frame.c
src/framework/mlt_tractor.c
src/modules/core/Makefile
src/modules/core/configure
src/modules/core/factory.c
src/modules/core/transition_composite.c
src/modules/core/transition_composite.h

index d5ec8d807b179a2a7deaece42290b94d37276c70..6deecffaf261fedd0b492d4d8f58dab469055f25 100644 (file)
@@ -29,6 +29,7 @@ typedef union
 {
        void *addr;
        int value;
+       double floating;
 }
 deque_entry;
 
@@ -216,6 +217,75 @@ int mlt_deque_peek_front_int( mlt_deque this )
        return this->count > 0 ? this->list[ 0 ].value : 0;
 }
 
+/** Push an item to the end.
+*/
+
+int mlt_deque_push_back_double( mlt_deque this, double item )
+{
+       int error = mlt_deque_allocate( this );
+
+       if ( error == 0 )
+               this->list[ this->count ++ ].floating = item;
+
+       return error;
+}
+
+/** Pop an item.
+*/
+
+double mlt_deque_pop_back_double( mlt_deque this )
+{
+       return this->count > 0 ? this->list[ -- this->count ].floating : 0;
+}
+
+/** Queue an item at the start.
+*/
+
+int mlt_deque_push_front_double( mlt_deque this, double item )
+{
+       int error = mlt_deque_allocate( this );
+
+       if ( error == 0 )
+       {
+               memmove( &this->list[ 1 ], this->list, ( this->count ++ ) * sizeof( deque_entry ) );
+               this->list[ 0 ].floating = item;
+       }
+
+       return error;
+}
+
+/** Remove an item from the start.
+*/
+
+double mlt_deque_pop_front_double( mlt_deque this )
+{
+       double item = 0;
+
+       if ( this->count > 0 )
+       {
+               item = this->list[ 0 ].floating;
+               memmove( this->list, &this->list[ 1 ], ( -- this->count ) * sizeof( deque_entry ) );
+       }
+
+       return item;
+}
+
+/** Inquire on item at back of deque but don't remove.
+*/
+
+double mlt_deque_peek_back_double( mlt_deque this )
+{
+       return this->count > 0 ? this->list[ this->count - 1 ].floating : 0;
+}
+
+/** Inquire on item at front of deque but don't remove.
+*/
+
+double mlt_deque_peek_front_double( mlt_deque this )
+{
+       return this->count > 0 ? this->list[ 0 ].floating : 0;
+}
+
 /** Close the queue.
 */
 
index f70a3901017742127a75b4641532d339f8c6e247..91e20c0561ea6d0fa01a4c837415e4f398402909 100644 (file)
@@ -39,6 +39,13 @@ extern int mlt_deque_pop_front_int( mlt_deque self );
 extern int mlt_deque_peek_back_int( mlt_deque self );
 extern int mlt_deque_peek_front_int( mlt_deque self );
 
+extern int mlt_deque_push_back_double( mlt_deque self, double item );
+extern double mlt_deque_pop_back_double( mlt_deque self );
+extern int mlt_deque_push_front_double( mlt_deque self, double item );
+extern double mlt_deque_pop_front_double( mlt_deque self );
+extern double mlt_deque_peek_back_double( mlt_deque self );
+extern double mlt_deque_peek_front_double( mlt_deque self );
+
 extern void mlt_deque_close( mlt_deque self );
 
 #endif
index 12a66d6bbb25c839081ec9b25e5a9a25367e0a43..712c8c25a0347dc71727187a4d96ea35ab18a4ed 100644 (file)
@@ -971,8 +971,8 @@ int mlt_frame_mix_audio( mlt_frame this, mlt_frame that, float weight_start, flo
        int i, j;
        double d = 0, s = 0;
 
-       mlt_frame_get_audio( this, &dest, format, &frequency_dest, &channels_dest, &samples_dest );
        mlt_frame_get_audio( that, &src, format, &frequency_src, &channels_src, &samples_src );
+       mlt_frame_get_audio( this, &dest, format, &frequency_dest, &channels_dest, &samples_dest );
 
        int silent = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "silent_audio" );
        mlt_properties_set_int( MLT_FRAME_PROPERTIES( this ), "silent_audio", 0 );
index ce678cfe6664dd3318052c42e56380db1d4400ab..b319a048bce89593214407d8e6ce834f72c9ae19 100644 (file)
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 
 /** Forward references to static methods.
 */
@@ -252,6 +253,8 @@ static void destroy_data_queue( void *arg )
 }
 
 /** Get the next frame.
+
+       TODO: This function needs to be redesigned...
 */
 
 static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int track )
@@ -408,10 +411,24 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra
 
                                // Pick up first video and audio frames
                                if ( !done && !mlt_frame_is_test_audio( temp ) && !( mlt_properties_get_int( temp_properties, "hide" ) & 2 ) )
+                               {
+                                       // Order of frame creation is starting to get problematic
+                                       if ( audio != NULL )
+                                       {
+                                               mlt_deque_push_front( MLT_FRAME_AUDIO_STACK( temp ), producer_get_audio );
+                                               mlt_deque_push_front( MLT_FRAME_AUDIO_STACK( temp ), audio );
+                                       }
                                        audio = temp;
+                               }
                                if ( !done && !mlt_frame_is_test_card( temp ) && !( mlt_properties_get_int( temp_properties, "hide" ) & 1 ) )
+                               {
+                                       if ( video != NULL )
+                                       {
+                                               mlt_deque_push_front( MLT_FRAME_IMAGE_STACK( temp ), producer_get_image );
+                                               mlt_deque_push_front( MLT_FRAME_IMAGE_STACK( temp ), video );
+                                       }
                                        video = temp;
-
+                               }
                        }
        
                        // Now stack callbacks
index af4551cde06a36890c4b949918d38f6abc0d540c..1e4cab1f4e8518ab06ede971a11478ca48248f8a 100644 (file)
@@ -18,6 +18,7 @@ OBJS = factory.o \
           filter_region.o \
           filter_rescale.o \
           filter_resize.o \
+          filter_transition.o \
           filter_watermark.o \
           transition_composite.o \
           transition_luma.o \
index 49ea0d6aad23c2d0a2de968ef34224b18f1899f7..fe80cd07fc1d2acb6ca96a178a3e995f19b3a96c 100755 (executable)
@@ -22,6 +22,7 @@ obscure                       libmltcore$LIBSUF
 region                 libmltcore$LIBSUF
 rescale                        libmltcore$LIBSUF
 resize                 libmltcore$LIBSUF
+transition             libmltcore$LIBSUF
 watermark              libmltcore$LIBSUF
 EOF
 
index 87b8ee42b91aceee0d85d8bc62cd038656c19123..fc76dc87573fc5718014feb1c5eddb4f2728d3dd 100644 (file)
@@ -34,6 +34,7 @@
 #include "filter_rescale.h"
 #include "filter_resize.h"
 #include "filter_region.h"
+#include "filter_transition.h"
 #include "filter_watermark.h"
 #include "transition_composite.h"
 #include "transition_luma.h"
@@ -78,6 +79,8 @@ void *mlt_create_filter( char *id, void *arg )
                return filter_rescale_init( arg );
        if ( !strcmp( id, "resize" ) )
                return filter_resize_init( arg );
+       else if ( !strcmp( id, "transition" ) )
+               return filter_transition_init( arg );
        if ( !strcmp( id, "watermark" ) )
                return filter_watermark_init( arg );
        return NULL;
index 6e20144b9dcd0ee8b5d9b78102bf253f6740cac2..21909e8e026a7d945c930d699dc4e29114dd2308 100644 (file)
@@ -185,17 +185,13 @@ static int position_calculate( mlt_transition this, mlt_position position )
 /** Calculate the field delta for this frame - position between two frames.
 */
 
-static inline double delta_calculate( mlt_transition this, mlt_frame frame )
+static inline double delta_calculate( mlt_transition this, mlt_frame frame, mlt_position position )
 {
        // Get the in and out position
        mlt_position in = mlt_transition_get_in( this );
        mlt_position out = mlt_transition_get_out( this );
        double length = out - in + 1;
 
-       // Get the position of the frame
-       char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( this ), "_unique_id" );
-       mlt_position position = mlt_properties_get_position( MLT_FRAME_PROPERTIES( frame ), name );
-
        // Now do the calcs
        double x = ( double )( position - in ) / length;
        double y = ( double )( position + 1 - in ) / length;
@@ -414,6 +410,46 @@ static void composite_line_yuv_or( uint8_t *dest, uint8_t *src, int width, uint8
        }
 }
 
+static void composite_line_yuv_and( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a,  int weight, uint16_t *luma, int softness )
+{
+       register int j;
+       register int a;
+       register int mix;
+       
+       for ( j = 0; j < width; j ++ )
+       {
+               a = *alpha_b ++ & *alpha_a;
+               mix = ( luma == NULL ) ? weight : smoothstep( luma[ j ], luma[ j ] + softness, weight + softness );
+               mix = ( mix * a ) >> 8;
+               *dest = ( *src++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
+               dest++;
+               *dest = ( *src++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
+               dest++;
+               *alpha_a = mix | *alpha_a;
+               alpha_a ++;
+       }
+}
+
+static void composite_line_yuv_xor( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a,  int weight, uint16_t *luma, int softness )
+{
+       register int j;
+       register int a;
+       register int mix;
+       
+       for ( j = 0; j < width; j ++ )
+       {
+               a = *alpha_b ++ ^ *alpha_a;
+               mix = ( luma == NULL ) ? weight : smoothstep( luma[ j ], luma[ j ] + softness, weight + softness );
+               mix = ( mix * a ) >> 8;
+               *dest = ( *src++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
+               dest++;
+               *dest = ( *src++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
+               dest++;
+               *alpha_a = mix | *alpha_a;
+               alpha_a ++;
+       }
+}
+
 /** Composite function.
 */
 
@@ -853,7 +889,7 @@ mlt_frame composite_copy_region( mlt_transition this, mlt_frame a_frame, mlt_pos
        // Will need to know region to copy
        struct geometry_s result;
 
-       double delta = delta_calculate( this, a_frame );
+       double delta = delta_calculate( this, a_frame, frame_position );
 
        // Calculate the region now
        composite_calculate( this, &result, a_frame, position + delta / 2 );
@@ -938,6 +974,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
        mlt_transition this = mlt_frame_pop_service( a_frame );
 
        // Get in and out
+       double position = mlt_deque_pop_back_double( MLT_FRAME_IMAGE_STACK( a_frame ) );
        int out = mlt_frame_pop_service_int( a_frame );
        int in = mlt_frame_pop_service_int( a_frame );
 
@@ -968,14 +1005,20 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
                struct geometry_s result;
 
                // Calculate the position
-               double position = mlt_properties_get_double( b_props, "relative_position" );
-               double delta = delta_calculate( this, a_frame );
+               double delta = delta_calculate( this, a_frame, position );
 
                // Get the image from the b frame
                uint8_t *image_b = NULL;
                int width_b = *width;
                int height_b = *height;
        
+               // Composites always need scaling... defaulting to lowest
+               char *rescale = mlt_properties_get( a_props, "rescale.interp" );
+               if ( rescale == NULL || !strcmp( rescale, "none" ) )
+                       rescale = "nearest";
+               mlt_properties_set( a_props, "rescale.interp", rescale );
+               mlt_properties_set( b_props, "rescale.interp", rescale );
+
                // Do the calculation
                composite_calculate( this, &result, a_frame, position );
 
@@ -996,6 +1039,9 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
                        return 0;
                }
 
+               if ( a_frame == b_frame )
+                       get_b_frame_image( this, b_frame, &image_b, &width_b, &height_b, &result );
+
                // Get the image from the a frame
                mlt_frame_get_image( a_frame, image, format, width, height, 1 );
 
@@ -1026,7 +1072,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
                        height_b = mlt_properties_get_int( a_props, "dest_height" );
                }
 
-               if ( get_b_frame_image( this, b_frame, &image_b, &width_b, &height_b, &result ) == 0 )
+               if ( image_b != NULL || get_b_frame_image( this, b_frame, &image_b, &width_b, &height_b, &result ) == 0 )
                {
                        uint8_t *dest = *image;
                        uint8_t *src = image_b;
@@ -1043,6 +1089,10 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
 
                        if ( mlt_properties_get_int( properties, "or" ) )
                                line_fn = composite_line_yuv_or;
+                       if ( mlt_properties_get_int( properties, "and" ) )
+                               line_fn = composite_line_yuv_and;
+                       if ( mlt_properties_get_int( properties, "xor" ) )
+                               line_fn = composite_line_yuv_xor;
 
                        if ( mlt_properties_get( properties, "alpha_a" ) )
                                memset( alpha_a, mlt_properties_get_int( properties, "alpha_a" ), *width * *height );
@@ -1089,30 +1139,19 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
 
 static mlt_frame composite_process( mlt_transition this, mlt_frame a_frame, mlt_frame b_frame )
 {
-       // Get a unique name to store the frame position
-       char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( this ), "_unique_id" );
-
        // UGH - this is a TODO - find a more reliable means of obtaining in/out for the always_active case
        if ( mlt_properties_get_int(  MLT_TRANSITION_PROPERTIES( this ), "always_active" ) == 0 )
        {
                mlt_frame_push_service_int( a_frame, mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( this ), "in" ) );
                mlt_frame_push_service_int( a_frame, mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( this ), "out" ) );
-
-               // Assign the current position to the name
-               mlt_properties_set_position( MLT_FRAME_PROPERTIES( a_frame ), name, mlt_frame_get_position( a_frame ) );
-
-               // Propogate the transition properties to the b frame
-               mlt_properties_set_double( MLT_FRAME_PROPERTIES( b_frame ), "relative_position", position_calculate( this, mlt_frame_get_position( a_frame ) ) );
+               mlt_deque_push_back_double( MLT_FRAME_IMAGE_STACK( a_frame ), position_calculate( this, mlt_frame_get_position( a_frame ) ) );
        }
        else
        {
                mlt_properties props = mlt_properties_get_data( MLT_FRAME_PROPERTIES( b_frame ), "_producer", NULL );
                mlt_frame_push_service_int( a_frame, mlt_properties_get_int( props, "in" ) );
                mlt_frame_push_service_int( a_frame, mlt_properties_get_int( props, "out" ) );
-               mlt_properties_set_int( MLT_FRAME_PROPERTIES( b_frame ), "relative_position", mlt_properties_get_int( props, "_frame" ) - mlt_properties_get_int( props, "in" ) );
-
-               // Assign the current position to the name
-               mlt_properties_set_position( MLT_FRAME_PROPERTIES( a_frame ), name, mlt_properties_get_position( MLT_FRAME_PROPERTIES( b_frame ), "relative_position" ) );
+               mlt_deque_push_back_double( MLT_FRAME_IMAGE_STACK( a_frame ), mlt_properties_get_int( props, "_frame" ) - mlt_properties_get_int( props, "in" ) );
        }
        
        mlt_frame_push_service( a_frame, this );
index 28ba6bad36e6ef986d2aef4095fc97ceb7351327..091fdd0a4575e31d0818eab121134160b88102b2 100644 (file)
@@ -26,6 +26,6 @@
 extern mlt_transition transition_composite_init( char *arg );
 
 // Courtesy functionality - allows regionalised filtering
-extern mlt_frame composite_copy_region( mlt_transition this, mlt_frame a_frame, mlt_position position );
+extern mlt_frame composite_copy_region( mlt_transition, mlt_frame, mlt_position );
 
 #endif