+ return mlt_multitrack_track( mlt_tractor_multitrack( self ), index );
+}
+
+static int producer_get_image( mlt_frame self, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
+{
+ uint8_t *data = NULL;
+ int size = 0;
+ mlt_properties properties = MLT_FRAME_PROPERTIES( self );
+ mlt_frame frame = mlt_frame_pop_service( self );
+ mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame );
+ mlt_properties_set( frame_properties, "rescale.interp", mlt_properties_get( properties, "rescale.interp" ) );
+ mlt_properties_set_int( frame_properties, "resize_alpha", mlt_properties_get_int( properties, "resize_alpha" ) );
+ mlt_properties_set_int( frame_properties, "distort", mlt_properties_get_int( properties, "distort" ) );
+ mlt_properties_set_int( frame_properties, "consumer_deinterlace", mlt_properties_get_int( properties, "consumer_deinterlace" ) );
+ mlt_properties_set( frame_properties, "deinterlace_method", mlt_properties_get( properties, "deinterlace_method" ) );
+ mlt_properties_set_int( frame_properties, "consumer_tff", mlt_properties_get_int( properties, "consumer_tff" ) );
+ mlt_frame_get_image( frame, buffer, format, width, height, writable );
+ mlt_frame_set_image( self, *buffer, 0, NULL );
+ mlt_properties_set_int( properties, "width", *width );
+ mlt_properties_set_int( properties, "height", *height );
+ mlt_properties_set_int( properties, "format", *format );
+ mlt_properties_set_double( properties, "aspect_ratio", mlt_frame_get_aspect_ratio( frame ) );
+ mlt_properties_set_int( properties, "progressive", mlt_properties_get_int( frame_properties, "progressive" ) );
+ mlt_properties_set_int( properties, "distort", mlt_properties_get_int( frame_properties, "distort" ) );
+ mlt_properties_set_int( properties, "colorspace", mlt_properties_get_int( frame_properties, "colorspace" ) );
+ mlt_properties_set_int( properties, "force_full_luma", mlt_properties_get_int( frame_properties, "force_full_luma" ) );
+ mlt_properties_set_int( properties, "top_field_first", mlt_properties_get_int( frame_properties, "top_field_first" ) );
+ data = mlt_frame_get_alpha_mask( frame );
+ mlt_properties_get_data( frame_properties, "alpha", &size );
+ mlt_frame_set_alpha( self, data, size, NULL );
+ self->convert_image = frame->convert_image;
+ self->convert_audio = frame->convert_audio;
+ return 0;
+}
+
+static int producer_get_audio( mlt_frame self, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
+{
+ mlt_properties properties = MLT_FRAME_PROPERTIES( self );
+ mlt_frame frame = mlt_frame_pop_audio( self );
+ mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
+ mlt_frame_set_audio( self, *buffer, *format, mlt_audio_format_size( *format, *samples, *channels ), NULL );
+ mlt_properties_set_int( properties, "audio_frequency", *frequency );
+ mlt_properties_set_int( properties, "audio_channels", *channels );
+ mlt_properties_set_int( properties, "audio_samples", *samples );
+ return 0;
+}
+
+static void destroy_data_queue( void *arg )
+{
+ if ( arg != NULL )
+ {
+ // Assign the correct type
+ mlt_deque queue = arg;
+
+ // Iterate through each item and destroy them
+ while ( mlt_deque_peek_front( queue ) != NULL )
+ mlt_properties_close( mlt_deque_pop_back( queue ) );
+
+ // Close the deque
+ mlt_deque_close( queue );
+ }
+}
+
+/** Get the next frame.
+ *
+ * \private \memberof mlt_tractor_s
+ * \param parent the producer interface to the tractor
+ * \param[out] frame a frame by reference
+ * \param track the 0-based track index
+ * \return true on error
+ */
+
+static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int track )
+{
+ mlt_tractor self = parent->child;