]> git.sesse.net Git - mlt/blobdiff - src/framework/mlt_transition.c
Minor modifications to compositing options and etv fx
[mlt] / src / framework / mlt_transition.c
index b4024fbaa0a6f4132cdae883b571746f3835fb59..435fdb6c62a94b863c53ff1c36623f172838b13f 100644 (file)
@@ -42,9 +42,11 @@ int mlt_transition_init( mlt_transition this, void *child )
        this->child = child;
        if ( mlt_service_init( service, this ) == 0 )
        {
-               mlt_properties properties = mlt_transition_properties( this );
+               mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
 
                service->get_frame = transition_get_frame;
+               service->close = ( mlt_destructor )mlt_transition_close;
+               service->close_object = this;
 
                mlt_properties_set_position( properties, "in", 0 );
                mlt_properties_set_position( properties, "out", 0 );
@@ -56,12 +58,23 @@ int mlt_transition_init( mlt_transition this, void *child )
        return 1;
 }
 
+/** Create a new transition.
+*/
+
+mlt_transition mlt_transition_new( )
+{
+       mlt_transition this = calloc( 1, sizeof( struct mlt_transition_s ) );
+       if ( this != NULL )
+               mlt_transition_init( this, NULL );
+       return this;
+}
+
 /** Get the service associated to the transition.
 */
 
 mlt_service mlt_transition_service( mlt_transition this )
 {
-       return &this->parent;
+       return this != NULL ? &this->parent : NULL;
 }
 
 /** Get the properties interface.
@@ -69,7 +82,7 @@ mlt_service mlt_transition_service( mlt_transition this )
 
 mlt_properties mlt_transition_properties( mlt_transition this )
 {
-       return mlt_service_properties( mlt_transition_service( this ) );
+       return MLT_TRANSITION_PROPERTIES( this );
 }
 
 /** Connect this transition with a producers a and b tracks.
@@ -80,7 +93,7 @@ int mlt_transition_connect( mlt_transition this, mlt_service producer, int a_tra
        int ret = mlt_service_connect_producer( &this->parent, producer, a_track );
        if ( ret == 0 )
        {
-               mlt_properties properties = mlt_transition_properties( this );
+               mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
                this->producer = producer;
                mlt_properties_set_int( properties, "a_track", a_track );
                mlt_properties_set_int( properties, "b_track", b_track );
@@ -93,7 +106,7 @@ int mlt_transition_connect( mlt_transition this, mlt_service producer, int a_tra
 
 void mlt_transition_set_in_and_out( mlt_transition this, mlt_position in, mlt_position out )
 {
-       mlt_properties properties = mlt_transition_properties( this );
+       mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
        mlt_properties_set_position( properties, "in", in );
        mlt_properties_set_position( properties, "out", out );
 }
@@ -103,7 +116,7 @@ void mlt_transition_set_in_and_out( mlt_transition this, mlt_position in, mlt_po
 
 int mlt_transition_get_a_track( mlt_transition this )
 {
-       return mlt_properties_get_int( mlt_transition_properties( this ), "a_track" );
+       return mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( this ), "a_track" );
 }
 
 /** Get the index of the b track.
@@ -111,7 +124,7 @@ int mlt_transition_get_a_track( mlt_transition this )
 
 int mlt_transition_get_b_track( mlt_transition this )
 {
-       return mlt_properties_get_int( mlt_transition_properties( this ), "b_track" );
+       return mlt_properties_get_int( MLT_TRANSITION_PROPERTIES( this ), "b_track" );
 }
 
 /** Get the in point.
@@ -119,7 +132,7 @@ int mlt_transition_get_b_track( mlt_transition this )
 
 mlt_position mlt_transition_get_in( mlt_transition this )
 {
-       return mlt_properties_get_position( mlt_transition_properties( this ), "in" );
+       return mlt_properties_get_position( MLT_TRANSITION_PROPERTIES( this ), "in" );
 }
 
 /** Get the out point.
@@ -127,7 +140,7 @@ mlt_position mlt_transition_get_in( mlt_transition this )
 
 mlt_position mlt_transition_get_out( mlt_transition this )
 {
-       return mlt_properties_get_position( mlt_transition_properties( this ), "out" );
+       return mlt_properties_get_position( MLT_TRANSITION_PROPERTIES( this ), "out" );
 }
 
 /** Process the frame.
@@ -135,7 +148,7 @@ mlt_position mlt_transition_get_out( mlt_transition this )
        If we have no process method (unlikely), we simply return the a_frame unmolested.
 */
 
-static mlt_frame transition_process( mlt_transition this, mlt_frame a_frame, mlt_frame b_frame )
+mlt_frame mlt_transition_process( mlt_transition this, mlt_frame a_frame, mlt_frame b_frame )
 {
        if ( this->process == NULL )
                return a_frame;
@@ -162,14 +175,15 @@ static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int i
 {
        mlt_transition this = service->child;
 
-       mlt_properties properties = mlt_transition_properties( this );
+       mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
 
+       int accepts_blanks = mlt_properties_get_int( properties, "_accepts_blanks" );
        int a_track = mlt_properties_get_int( properties, "a_track" );
        int b_track = mlt_properties_get_int( properties, "b_track" );
        mlt_position in = mlt_properties_get_position( properties, "in" );
        mlt_position out = mlt_properties_get_position( properties, "out" );
+       int always_active = mlt_properties_get_int( properties, "always_active" );
 
-       // Fetch a and b frames together...
        if ( ( index == a_track || index == b_track ) && !( this->a_held || this->b_held ) )
        {
                mlt_service_get_frame( this->producer, &this->a_frame, a_track );
@@ -183,10 +197,29 @@ static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int i
        {
                // Determine if we're in the right time zone
                mlt_position position = mlt_frame_get_position( this->a_frame );
-               if ( position >= in && position <= out )
+               if ( always_active || ( position >= in && position <= out ) )
                {
-                       // Process the transition
-                       *frame = transition_process( this, this->a_frame, this->b_frame );
+                       if ( !accepts_blanks && ( this->b_frame == NULL || ( mlt_frame_is_test_card( this->b_frame ) && mlt_frame_is_test_audio( this->b_frame ) ) ) )
+                       {
+                               *frame = this->a_frame;
+                       }
+                       else if ( !accepts_blanks && ( this->a_frame == NULL || ( mlt_frame_is_test_card( this->a_frame ) && mlt_frame_is_test_audio( this->a_frame ) ) ) )
+                       {
+                               mlt_frame t = this->a_frame;
+                               this->a_frame = this->b_frame;
+                               this->b_frame = t;
+                               *frame = this->a_frame;
+                       }
+                       else
+                       {
+                               int hide = 0;
+                               *frame = mlt_transition_process( this, this->a_frame, this->b_frame );
+                               if ( !mlt_properties_get_int( MLT_FRAME_PROPERTIES( this->a_frame ), "test_image" ) )
+                                       hide = 1;
+                               if ( !mlt_properties_get_int( MLT_FRAME_PROPERTIES( this->a_frame ), "test_audio" ) )
+                                       hide |= 2;
+                               mlt_properties_set_int( MLT_FRAME_PROPERTIES( this->b_frame ), "hide", hide );
+                       }
                        this->a_held = 0;
                }
                else
@@ -216,8 +249,17 @@ static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int i
 
 void mlt_transition_close( mlt_transition this )
 {
-       if ( this->close != NULL )
-               this->close( this );
-       else
-               mlt_service_close( &this->parent );
+       if ( this != NULL && mlt_properties_dec_ref( MLT_TRANSITION_PROPERTIES( this ) ) <= 0 )
+       {
+               this->parent.close = NULL;
+               if ( this->close != NULL )
+               {
+                       this->close( this );
+               }
+               else
+               {
+                       mlt_service_close( &this->parent );
+                       free( this );
+               }
+       }
 }