]> git.sesse.net Git - mlt/commitdiff
Add fetching previous and next frames in producers.
authorDan Dennedy <dan@dennedy.org>
Wed, 3 Feb 2010 07:20:22 +0000 (23:20 -0800)
committerDan Dennedy <dan@dennedy.org>
Fri, 5 Feb 2010 04:46:53 +0000 (20:46 -0800)
This is only enabled when the property need-previous-next is set true on
the producer. This also adds firing a service-changed event on the
filter when it gets attached so the filter can set this property on the
producer to which it is attached. These frame references are set as
"previous frame" and "next frame" properties on the current frame. It is
also important to note that these frames do not have ANY filters applied
to them, which is important for YADIF and telecide filters, which
process before all other filters.

src/framework/mlt_filter.h
src/framework/mlt_frame.h
src/framework/mlt_service.c
src/framework/mlt_service.h

index 66e2e471c007abe850d4485b923203f52c8fd6a0..5f43e570d9a544d48a1a32e1a66619af7b72f795 100644 (file)
@@ -32,6 +32,8 @@
  *
  * \extends mlt_service_s
  * \properties \em track the index of the track of a multitrack on which the filter is applied
+ * \properties \em service a reference to the service to which this filter is attached.
+ * Currently this is not cleared when the filter is detached.
  */
 
 struct mlt_filter_s
index d190f188fee04dbcf560eee067976527f29f2cec..4977de2361101b2c68e74ba073c068e2cbc80d12 100644 (file)
@@ -53,6 +53,10 @@ typedef int ( *mlt_get_audio )( mlt_frame self, void **buffer, mlt_audio_format
  * \properties \em meta.* holds metadata
  * \properties \em hide set to 1 to hide the video, 2 to mute the audio
  * \properties \em last_track a flag to indicate an end-of-tracks frame
+ * \properties \em previous \em frame a reference to the unfiltered preceding frame
+ * (no speed factor applied, only available when \em need-previous-next is set on the producer)
+ * \properties \em next \em frame a reference to the unfiltered following frame
+ * (no speed factor applied, only available when \em need-previous-next is set on the producer)
  */
 
 struct mlt_frame_s
index 7ccfcd93083c2d38eab78348993b5b4119e6e4a6..19ce5f8dadad313653feb5a710cf344e9afbeb5a 100644 (file)
@@ -27,6 +27,7 @@
 #include "mlt_cache.h"
 #include "mlt_factory.h"
 #include "mlt_log.h"
+#include "mlt_producer.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -451,6 +452,7 @@ int mlt_service_get_frame( mlt_service this, mlt_frame_ptr frame, int index )
                mlt_properties properties = MLT_SERVICE_PROPERTIES( this );
                mlt_position in = mlt_properties_get_position( properties, "in" );
                mlt_position out = mlt_properties_get_position( properties, "out" );
+               mlt_position position = mlt_service_identify( this ) == producer_type ? mlt_producer_position( MLT_PRODUCER( this ) ) : -1;
 
                result = this->get_frame( this, frame, index );
 
@@ -458,6 +460,7 @@ int mlt_service_get_frame( mlt_service this, mlt_frame_ptr frame, int index )
                {
                        mlt_properties_inc_ref( properties );
                        properties = MLT_FRAME_PROPERTIES( *frame );
+                       
                        if ( in >=0 && out > 0 )
                        {
                                mlt_properties_set_position( properties, "in", in );
@@ -465,6 +468,34 @@ int mlt_service_get_frame( mlt_service this, mlt_frame_ptr frame, int index )
                        }
                        mlt_service_apply_filters( this, *frame, 1 );
                        mlt_deque_push_back( MLT_FRAME_SERVICE_STACK( *frame ), this );
+                       
+                       if ( mlt_service_identify( this ) == producer_type &&
+                            mlt_properties_get_int( MLT_SERVICE_PROPERTIES( this ), "need-previous-next" ) )
+                       {
+                               // Save the new position from this->get_frame
+                               mlt_position new_position = mlt_producer_position( MLT_PRODUCER( this ) );
+                               
+                               // Get the preceding frame, unfiltered
+                               mlt_frame previous_frame;
+                               mlt_producer_seek( MLT_PRODUCER(this), position - 1 );
+                               result = this->get_frame( this, &previous_frame, index );
+                               if ( !result )
+                                       mlt_properties_set_data( properties, "previous frame",
+                                               previous_frame, 0, ( mlt_destructor ) mlt_frame_close, NULL );
+
+                               // Get the following frame, unfiltered
+                               mlt_frame next_frame;
+                               mlt_producer_seek( MLT_PRODUCER(this), position + 1 );
+                               result = this->get_frame( this, &next_frame, index );
+                               if ( !result )
+                               {
+                                       mlt_properties_set_data( properties, "next frame",
+                                               next_frame, 0, ( mlt_destructor ) mlt_frame_close, NULL );
+                               }
+                               
+                               // Restore the new position
+                               mlt_producer_seek( MLT_PRODUCER(this), new_position );
+                       }
                }
        }
 
@@ -524,7 +555,9 @@ int mlt_service_attach( mlt_service this, mlt_filter filter )
                                mlt_properties props = MLT_FILTER_PROPERTIES( filter );
                                mlt_properties_inc_ref( MLT_FILTER_PROPERTIES( filter ) );
                                base->filters[ base->filter_count ++ ] = filter;
+                               mlt_properties_set_data( props, "service", this, 0, NULL, NULL );
                                mlt_events_fire( properties, "service-changed", NULL );
+                               mlt_events_fire( props, "service-changed", NULL );
                                mlt_events_listen( props, this, "service-changed", ( mlt_listener )mlt_service_filter_changed );
                                mlt_events_listen( props, this, "property-changed", ( mlt_listener )mlt_service_filter_changed );
                        }
index a1919b9a0eb6e392a67275d1f2f50dae3384b3e9..899ff40e9a73944678af217e97f721070e6e2811 100644 (file)
@@ -52,6 +52,8 @@
  * \properties \em disable Set this on a filter to disable it while keeping it in the object model.
  * \properties \em _profile stores the mlt_profile for a service
  * \properties \em _unique_id is a unique identifier
+ * \properties \em need-previous-next boolean that instructs producers to get
+ * preceding and following frames inside of \p mlt_service_get_frame
  */
 
 struct mlt_service_s