Exemple #1
0
static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
{
	// Get the real structure for this producer
	producer_qimage self = producer->child;

	// Fetch the producers properties
	mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );

	if ( self->filenames == NULL && mlt_properties_get( producer_properties, "resource" ) != NULL )
		load_filenames( self, producer_properties );

	// Generate a frame
	*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );

	if ( *frame != NULL && self->count > 0 )
	{
		// Obtain properties of frame and producer
		mlt_properties properties = MLT_FRAME_PROPERTIES( *frame );

		// Set the producer on the frame properties
		mlt_properties_set_data( properties, "producer_qimage", self, 0, NULL, NULL );

		// Update timecode on the frame we're creating
		mlt_frame_set_position( *frame, mlt_producer_position( producer ) );

		// Ensure that we have a way to obtain the position in the get_image
		mlt_properties_set_position( properties, "qimage_position", mlt_producer_position( producer ) );

		// Refresh the image
		self->qimage_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.qimage" );
		self->qimage = mlt_cache_item_data( self->qimage_cache, NULL );
		refresh_qimage( self, *frame );
		mlt_cache_item_close( self->qimage_cache );

		// Set producer-specific frame properties
		mlt_properties_set_int( properties, "progressive", mlt_properties_get_int( producer_properties, "progressive" ) );
		double force_ratio = mlt_properties_get_double( producer_properties, "force_aspect_ratio" );
		if ( force_ratio > 0.0 )
			mlt_properties_set_double( properties, "aspect_ratio", force_ratio );
		else
			mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_properties, "aspect_ratio" ) );

		// Push the get_image method
		mlt_frame_push_get_image( *frame, producer_get_image );
	}

	// Calculate the next timecode
	mlt_producer_prepare_next( producer );

	return 0;
}
Exemple #2
0
mlt_producer producer_qimage_init( mlt_profile profile, mlt_service_type type, const char *id, char *filename )
{
	producer_qimage self = calloc( sizeof( struct producer_qimage_s ), 1 );
	if ( self != NULL && mlt_producer_init( &self->parent, self ) == 0 )
	{
		mlt_producer producer = &self->parent;

		// Get the properties interface
		mlt_properties properties = MLT_PRODUCER_PROPERTIES( &self->parent );
	
		// Callback registration
#ifdef USE_KDE
		init_qimage();
#endif
		producer->get_frame = producer_get_frame;
		producer->close = ( mlt_destructor )producer_close;

		// Set the default properties
		mlt_properties_set( properties, "resource", filename );
		mlt_properties_set_int( properties, "ttl", 25 );
		mlt_properties_set_int( properties, "aspect_ratio", 1 );
		mlt_properties_set_int( properties, "progressive", 1 );
		mlt_properties_set_int( properties, "seekable", 1 );

		// Validate the resource
		if ( filename )
			load_filenames( self, properties );
		if ( self->count )
		{
			mlt_frame frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );
			if ( frame )
			{
				mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame );
				mlt_properties_set_data( frame_properties, "producer_qimage", self, 0, NULL, NULL );
				mlt_frame_set_position( frame, mlt_producer_position( producer ) );
				mlt_properties_set_position( frame_properties, "qimage_position", mlt_producer_position( producer ) );
				refresh_qimage( self, frame );
				mlt_cache_item_close( self->qimage_cache );
				mlt_frame_close( frame );
			}
		}
		if ( self->current_width == 0 )
		{
			producer_close( producer );
			producer = NULL;
		}
		return producer;
	}
	free( self );
	return NULL;
}
Exemple #3
0
static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
{
	if ( frame )
	{
		// Construct a new frame
		*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );

		// Stack the producer and producer's get image
		mlt_frame_push_service_int( *frame, index );
		mlt_frame_push_service( *frame, producer );
		mlt_frame_push_service( *frame, framebuffer_get_image );

		mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
		mlt_properties frame_properties = MLT_FRAME_PROPERTIES(*frame);

		// Get frame from the real producer
		mlt_frame first_frame = mlt_properties_get_data( properties, "first_frame", NULL );

		if ( first_frame == NULL )
		{
		    // Get the frame to cache from the real producer
		    mlt_producer real_producer = mlt_properties_get_data( properties, "producer", NULL );

		    // Seek the producer to the correct place
		    mlt_producer_seek( real_producer, mlt_producer_position( producer ) );

		    // Get the frame
		    mlt_service_get_frame( MLT_PRODUCER_SERVICE( real_producer ), &first_frame, index );
		    // Cache the frame
		    mlt_properties_set_data( properties, "first_frame", first_frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
		}

		mlt_properties_inherit( frame_properties, MLT_FRAME_PROPERTIES(first_frame) );
		
		double force_aspect_ratio = mlt_properties_get_double( properties, "force_aspect_ratio" );
		if ( force_aspect_ratio <= 0.0 ) force_aspect_ratio = mlt_properties_get_double( properties, "aspect_ratio" );
		mlt_properties_set_double( frame_properties, "aspect_ratio", force_aspect_ratio );
                
		// Give the returned frame temporal identity
		mlt_frame_set_position( *frame, mlt_producer_position( producer ) );

		mlt_properties_set_int( frame_properties, "meta.media.width", mlt_properties_get_int( properties, "width" ) );
		mlt_properties_set_int( frame_properties, "meta.media.height", mlt_properties_get_int( properties, "height" ) );
		mlt_properties_pass_list( frame_properties, properties, "width, height" );
	}

	return 0;
}
Exemple #4
0
static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
{
	// Generate a frame
	*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );

	// Check that we created a frame and initialize it
	if ( *frame != NULL )
	{
		// Obtain properties of frame
		mlt_properties frame_properties = MLT_FRAME_PROPERTIES( *frame );

		// Update timecode on the frame we're creating
		mlt_frame_set_position( *frame, mlt_producer_position( producer ) );

		// Save the producer to be used in get_audio
		mlt_properties_set_data( frame_properties, "_producer_ladspa", producer, 0, NULL, NULL );

		// Push the get_audio method
		mlt_frame_push_audio( *frame, producer_get_audio );
	}

	// Calculate the next time code
	mlt_producer_prepare_next( producer );

	return 0;
}
Exemple #5
0
int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
{
	// Generate a frame
	*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );

	if ( *frame != NULL )
	{
		// Obtain properties of frame and producer
		mlt_properties properties = MLT_FRAME_PROPERTIES( *frame );

		// Obtain properties of producer
		mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer );

		// Set the producer on the frame properties
		mlt_properties_set_data( properties, "producer_frei0r", producer, 0, NULL, NULL );

		// Update timecode on the frame we're creating
		mlt_frame_set_position( *frame, mlt_producer_position( producer ) );

		// Set producer-specific frame properties
		mlt_properties_set_int( properties, "progressive", 1 );
		mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) );
		mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) );

		// Push the get_image method
		mlt_frame_push_get_image( *frame, producer_get_image );
	}

	// Calculate the next timecode
	mlt_producer_prepare_next( producer );

	return 0;
}
Exemple #6
0
static int getFrame(mlt_producer producer, mlt_frame_ptr frame, int /*index*/) {
    // Generate a frame
    *frame = mlt_frame_init(MLT_PRODUCER_SERVICE(producer));

    if (*frame) {
        // Obtain properties of frame and producer
        mlt_properties properties = MLT_FRAME_PROPERTIES(*frame);

        // Set the producer on the frame properties
        mlt_properties_set_data(properties, kWebVfxProducerPropertyName, producer, 0, NULL, NULL);

        // Update timecode on the frame we're creating
        mlt_position position = mlt_producer_position(producer);
        mlt_frame_set_position(*frame, position);
        mlt_properties_set_position(properties, kWebVfxPositionPropertyName, position);
        
        // Set producer-specific frame properties
        mlt_properties_set_int(properties, "progressive", 1);

        // Push the get_image method
        mlt_frame_push_get_image(*frame, producerGetImage);
    }

    // Calculate the next timecode
    mlt_producer_prepare_next(producer);

    return 0;
}
Exemple #7
0
mlt_producer producer_pixbuf_init( char *filename )
{
	producer_pixbuf this = calloc( sizeof( struct producer_pixbuf_s ), 1 );
	if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 )
	{
		mlt_producer producer = &this->parent;

		// Get the properties interface
		mlt_properties properties = MLT_PRODUCER_PROPERTIES( &this->parent );
	
		// Callback registration
		producer->get_frame = producer_get_frame;
		producer->close = ( mlt_destructor )producer_close;

		// Set the default properties
		mlt_properties_set( properties, "resource", filename );
		mlt_properties_set_int( properties, "ttl", 25 );
		mlt_properties_set_int( properties, "aspect_ratio", 1 );
		mlt_properties_set_int( properties, "progressive", 1 );

		// Validate the resource
		if ( filename )
			load_filenames( this, properties );
		if ( this->count )
		{
			mlt_frame frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );
			if ( frame )
			{
				mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame );
				pthread_mutex_init( &this->mutex, NULL );
				mlt_properties_set_data( frame_properties, "producer_pixbuf", this, 0, NULL, NULL );
				mlt_frame_set_position( frame, mlt_producer_position( producer ) );
				mlt_properties_set_position( frame_properties, "pixbuf_position", mlt_producer_position( producer ) );
				refresh_image( this, frame, 0, 0 );
				mlt_frame_close( frame );
			}
		}
		if ( this->width == 0 )
		{
			producer_close( producer );
			producer = NULL;
		}
		return producer;
	}
	free( this );
	return NULL;
}
Exemple #8
0
uint32_t MltRuntime::get_frame_position() throw (Exception)
{
	Lock lk(&run_lock);
	if (producer)
		return mlt_producer_position(producer);
	else
		throw_error_v(ErrorRuntimeStatusError, "not loaded.");
}
bool TransitionHandler::moveTransition(QString type, int startTrack, int newTrack, int newTransitionTrack, GenTime oldIn, GenTime oldOut, GenTime newIn, GenTime newOut)
{
    double fps = m_tractor->get_fps();
    int new_in = (int)newIn.frames(fps);
    int new_out = (int)newOut.frames(fps) - 1;
    if (new_in >= new_out) return false;
    int old_in = (int)oldIn.frames(fps);
    int old_out = (int)oldOut.frames(fps) - 1;

    bool doRefresh = true;
    // Check if clip is visible in monitor
    int position = mlt_producer_position(m_tractor->get_producer());
    int diff = old_out - position;
    if (diff < 0 || diff > old_out - old_in) doRefresh = false;
    if (doRefresh) {
        diff = new_out - position;
        if (diff < 0 || diff > new_out - new_in) doRefresh = false;
    }
    QScopedPointer<Mlt::Field> field(m_tractor->field());
    field->lock();
    mlt_service nextservice = mlt_service_get_producer(field->get_service());
    mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
    QString resource = mlt_properties_get(properties, "mlt_service");
    int old_pos = (int)(old_in + old_out) / 2;
    bool found = false;
    mlt_service_type mlt_type = mlt_service_identify( nextservice );
    while (mlt_type == transition_type) {
        Mlt::Transition transition((mlt_transition) nextservice);
        nextservice = mlt_service_producer(nextservice);
        int currentTrack = transition.get_b_track();
        int currentIn = (int) transition.get_in();
        int currentOut = (int) transition.get_out();

        if (resource == type && startTrack == currentTrack && currentIn <= old_pos && currentOut >= old_pos) {
            found = true;
            if (newTrack - startTrack != 0) {
                Mlt::Properties trans_props(transition.get_properties());
                Mlt::Transition new_transition(*m_tractor->profile(), transition.get("mlt_service"));
                Mlt::Properties new_trans_props(new_transition.get_properties());
                // We cannot use MLT's property inherit because it also clones internal values like _unique_id which messes up the playlist
                cloneProperties(new_trans_props, trans_props);
                new_transition.set_in_and_out(new_in, new_out);
                field->disconnect_service(transition);
                plantTransition(field.data(), new_transition, newTransitionTrack, newTrack);
            } else transition.set_in_and_out(new_in, new_out);
            break;
        }
        if (nextservice == NULL) break;
        properties = MLT_SERVICE_PROPERTIES(nextservice);
        mlt_type = mlt_service_identify( nextservice );
        resource = mlt_properties_get(properties, "mlt_service");
    }
    field->unlock();
    if (doRefresh) refresh();
    //if (m_isBlocked == 0) m_mltConsumer->set("refresh", 1);
    return found;
}
Exemple #10
0
static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index )
{
	// Get the mutiltrack object
	mlt_multitrack self = parent->child;

	// Check if we have a track for this index
	if ( index >= 0 && index < self->count && self->list[ index ] != NULL )
	{
		// Get the producer for this track
		mlt_producer producer = self->list[ index ]->producer;

		// Get the track hide property
		int hide = mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( producer ) ), "hide" );

		// Obtain the current position
		mlt_position position = mlt_producer_frame( parent );

		// Get the parent properties
		mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( parent );

		// Get the speed
		double speed = mlt_properties_get_double( producer_properties, "_speed" );

		// Make sure we're at the same point
		mlt_producer_seek( producer, position );

		// Get the frame from the producer
		mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), frame, 0 );

		// Indicate speed of this producer
		mlt_properties properties = MLT_FRAME_PROPERTIES( *frame );
		mlt_properties_set_double( properties, "_speed", speed );
		mlt_frame_set_position( *frame, position );
		mlt_properties_set_int( properties, "hide", hide );
	}
	else
	{
		// Generate a test frame
		*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( parent ) );

		// Update position on the frame we're creating
		mlt_frame_set_position( *frame, mlt_producer_position( parent ) );

		// Move on to the next frame
		if ( index >= self->count )
		{
			// Let tractor know if we've reached the end
			mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "last_track", 1 );

			// Move to the next frame
			mlt_producer_prepare_next( parent );
		}
	}

	return 0;
}
void TransitionHandler::updateTransition(QString oldTag, QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml, bool force)
{
    if (oldTag == tag && !force) updateTransitionParams(tag, a_track, b_track, in, out, xml);
    else {
        ////qDebug()<<"// DELETING TRANS: "<<a_track<<"-"<<b_track;
        deleteTransition(oldTag, a_track, b_track, in, out, xml, false);
        addTransition(tag, a_track, b_track, in, out, xml, false);
    }

    int position = mlt_producer_position(m_tractor->get_producer());
    if (position >= in.frames(m_fps) && position <= out.frames(m_fps)) emit refresh();
}
static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
{
	/* Obtain properties of frame */
	mlt_properties properties = MLT_FRAME_PROPERTIES( frame );

	/* Obtain the producer for this frame */
	producer_ktitle this = mlt_properties_get_data( properties, "producer_kdenlivetitle", NULL );
	
	/* Obtain properties of producer */
	mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( &this->parent );
	
	*width = mlt_properties_get_int( properties, "rescale_width" );
	*height = mlt_properties_get_int( properties, "rescale_height" );
	
	/* Allocate the image */
	int size = *width * ( *height ) * 4;

	/* Allocate the image */
	*format = mlt_image_rgb24a;
	mlt_position time = mlt_producer_position( &this->parent ) + mlt_producer_get_in( &this->parent );
	if ( mlt_properties_get_int( producer_props, "force_reload" ) ) {
		if (mlt_properties_get_int( producer_props, "force_reload" ) > 1) read_xml(producer_props);
		mlt_properties_set_int( producer_props, "force_reload", 0 );
		drawKdenliveTitle( this, frame, *width, *height, time, 1);
	}
	else drawKdenliveTitle( this, frame, *width, *height, time, 0);

	// Get width and height (may have changed during the refresh)
	*width = mlt_properties_get_int( properties, "width" );
	*height = mlt_properties_get_int( properties, "height" );
		
	if ( this->current_image )
	{
		// Clone the image and the alpha
		int image_size = this->current_width * ( this->current_height ) * 4;
		uint8_t *image_copy = mlt_pool_alloc( image_size );
		memcpy( image_copy, this->current_image, image_size );
		// Now update properties so we free the copy after
		mlt_properties_set_data( properties, "image", image_copy, image_size, mlt_pool_release, NULL );
		// We're going to pass the copy on
		*buffer = image_copy;		
		
		/* Update the frame */
		mlt_properties_set_data( properties, "image", *buffer, size, mlt_pool_release, NULL );

		mlt_log_debug( MLT_PRODUCER_SERVICE( &this->parent ), "width:%d height:%d %s\n", *width, *height, mlt_image_format_name( *format ) );
	}

	return 0;
}
Exemple #13
0
static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
{
	// Generate a frame
	*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );

	if ( *frame != NULL )
	{
		mlt_properties frame_properties = MLT_FRAME_PROPERTIES( *frame );
		mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );

		// Regenerate the QPainterPath if necessary
		if( check_qpath( producer_properties ) )
		{
			generate_qpath( producer_properties );
		}

		// Give the frame a copy of the painter path
		QPainterPath* prodPath = static_cast<QPainterPath*>( mlt_properties_get_data( producer_properties, "_qpath", NULL ) );
		QPainterPath* framePath = new QPainterPath( *prodPath );
		mlt_properties_set_data( frame_properties, "_qpath", static_cast<void*>( framePath ), 0, close_qpath, NULL );

		// Pass properties to the frame that will be needed to render the path
		mlt_properties_set( frame_properties, "_path_sig", mlt_properties_get( producer_properties, "_path_sig" ) );
		mlt_properties_set( frame_properties, "_bgcolour", mlt_properties_get( producer_properties, "bgcolour" ) );
		mlt_properties_set( frame_properties, "_fgcolour", mlt_properties_get( producer_properties, "fgcolour" ) );
		mlt_properties_set( frame_properties, "_olcolour", mlt_properties_get( producer_properties, "olcolour" ) );
		mlt_properties_set( frame_properties, "_outline", mlt_properties_get( producer_properties, "outline" ) );
		mlt_properties_set_data( frame_properties, "_producer_qtext", static_cast<void*>( producer ), 0, NULL, NULL );

		// Set frame properties
		mlt_properties_set_int( frame_properties, "progressive", 1 );
		double force_ratio = mlt_properties_get_double( producer_properties, "force_aspect_ratio" );
		if ( force_ratio > 0.0 )
			mlt_properties_set_double( frame_properties, "aspect_ratio", force_ratio );
		else
			mlt_properties_set_double( frame_properties, "aspect_ratio", 1.0);

		// Update time code on the frame
		mlt_frame_set_position( *frame, mlt_producer_position( producer ) );

		// Configure callbacks
		mlt_frame_push_get_image( *frame, producer_get_image );
	}

	// Calculate the next time code
	mlt_producer_prepare_next( producer );

	return 0;
}
Exemple #14
0
mlt_producer producer_pixbuf_init( char *filename )
{
	producer_pixbuf self = calloc( 1, sizeof( struct producer_pixbuf_s ) );
	if ( self != NULL && mlt_producer_init( &self->parent, self ) == 0 )
	{
		mlt_producer producer = &self->parent;

		// Get the properties interface
		mlt_properties properties = MLT_PRODUCER_PROPERTIES( &self->parent );
	
		// Callback registration
		producer->get_frame = producer_get_frame;
		producer->close = ( mlt_destructor )producer_close;

		// Set the default properties
		mlt_properties_set( properties, "resource", filename );
		mlt_properties_set_int( properties, "ttl", 25 );
		mlt_properties_set_int( properties, "aspect_ratio", 1 );
		mlt_properties_set_int( properties, "progressive", 1 );
		mlt_properties_set_int( properties, "seekable", 1 );
		mlt_properties_set_int( properties, "loop", 1 );

		// Validate the resource
		if ( filename )
			load_filenames( self, properties );
		if ( self->count )
		{
			mlt_frame frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );
			if ( frame )
			{
				mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame );
				mlt_properties_set_data( frame_properties, "producer_pixbuf", self, 0, NULL, NULL );
				mlt_frame_set_position( frame, mlt_producer_position( producer ) );
				refresh_pixbuf( self, frame );
				mlt_cache_item_close( self->pixbuf_cache );
				mlt_frame_close( frame );
			}
		}
		if ( self->width == 0 )
		{
			producer_close( producer );
			producer = NULL;
		}
		return producer;
	}
	free( self );
	return NULL;
}
Exemple #15
0
static int get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
{
    DeckLinkProducer* decklink = (DeckLinkProducer*) producer->child;
    mlt_position pos = mlt_producer_position( producer );
    mlt_position end = mlt_producer_get_playtime( producer );
    end = ( mlt_producer_get_length( producer ) < end ? mlt_producer_get_length( producer ) : end ) - 1;

    // Re-open if needed
    if ( !decklink && pos < end )
    {
        producer->child = decklink = new DeckLinkProducer();
        decklink->setProducer( producer );
        decklink->open(	mlt_properties_get_int( MLT_PRODUCER_PROPERTIES(producer), "resource" ) );
    }

    // Start if needed
    if ( decklink )
    {
        decklink->start( mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) ) );

        // Get the next frame from the decklink object
        if ( ( *frame = decklink->getFrame() ))
        {
            // Add audio and video getters
            mlt_frame_push_audio( *frame, (void*) get_audio );
            mlt_frame_push_get_image( *frame, get_image );
        }
    }
    if ( !*frame )
        *frame = mlt_frame_init( MLT_PRODUCER_SERVICE(producer) );

    // Calculate the next timecode
    mlt_producer_prepare_next( producer );

    // Close DeckLink if at end
    if ( pos >= end && decklink )
    {
        decklink->stop();
        delete decklink;
        producer->child = NULL;
    }

    return 0;
}
Exemple #16
0
static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
{
	producer_kino this = producer->child;
	uint8_t *data = mlt_pool_alloc( FRAME_SIZE_625_50 );
	
	// Obtain the current frame number
	uint64_t position = mlt_producer_frame( producer );
	
	// Create an empty frame
	*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );

	// Seek and fetch
	if ( kino_wrapper_get_frame( this->wrapper, data, position ) )
	{
		// Get the frames properties
		mlt_properties properties = MLT_FRAME_PROPERTIES( *frame );

		// Determine if we're PAL or NTSC
		int is_pal = kino_wrapper_is_pal( this->wrapper );

		// Pass the dv data
		mlt_properties_set_data( properties, "dv_data", data, FRAME_SIZE_625_50, ( mlt_destructor )mlt_pool_release, NULL );

		// Update other info on the frame
		mlt_properties_set_int( properties, "width", 720 );
		mlt_properties_set_int( properties, "height", is_pal ? 576 : 480 );
		mlt_properties_set_int( properties, "top_field_first", is_pal ? 0 : ( data[ 5 ] & 0x07 ) == 0 ? 0 : 1 );
	}
	else
	{
		mlt_pool_release( data );
	}

	// Update timecode on the frame we're creating
	mlt_frame_set_position( *frame, mlt_producer_position( producer ) );

	// Calculate the next timecode
	mlt_producer_prepare_next( producer );

	return 0;
}
static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )

{
  	// Get the real structure for this producer
	producer_ktitle this = producer->child;

	/* Generate a frame */
	*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );

	if ( *frame != NULL )
	{
		/* Obtain properties of frame and producer */
		mlt_properties properties = MLT_FRAME_PROPERTIES( *frame );

		/* Obtain properties of producer */
		mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer );

		/* Set the producer on the frame properties */
		mlt_properties_set_data( properties, "producer_kdenlivetitle", this, 0, NULL, NULL );

		/* Update timecode on the frame we're creating */
		mlt_frame_set_position( *frame, mlt_producer_position( producer ) );

		// Set producer-specific frame properties
		mlt_properties_set_int( properties, "progressive", mlt_properties_get_int( producer_props, "progressive" ) );
		double force_ratio = mlt_properties_get_double( producer_props, "force_aspect_ratio" );
		if ( force_ratio > 0.0 )
			mlt_properties_set_double( properties, "aspect_ratio", force_ratio );
		else
			mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_props, "aspect_ratio" ) );

		/* Push the get_image method */
		mlt_frame_push_get_image( *frame, producer_get_image );
	}

	/* Calculate the next timecode */
	mlt_producer_prepare_next( producer );

	return 0;
}
bool TransitionHandler::addTransition(QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml, bool do_refresh)
{
    if (in >= out) return false;
    double fps = m_tractor->get_fps();
    QMap<QString, QString> args = getTransitionParamsFromXml(xml);
    QScopedPointer<Mlt::Field> field(m_tractor->field());

    Mlt::Transition transition(*m_tractor->profile(), tag.toUtf8().constData());
    if (!transition.is_valid()) return false;
    if (out != GenTime())
        transition.set_in_and_out((int) in.frames(fps), (int) out.frames(fps) - 1);

    int position = mlt_producer_position(m_tractor->get_producer());

    if (do_refresh && ((position < in.frames(fps)) || (position > out.frames(fps)))) do_refresh = false;
    QMap<QString, QString>::Iterator it;
    QString key;
    if (xml.attribute(QStringLiteral("automatic")) == QLatin1String("1")) transition.set("automatic", 1);
    ////qDebug() << " ------  ADDING TRANSITION PARAMs: " << args.count();
    if (xml.hasAttribute(QStringLiteral("id")))
        transition.set("kdenlive_id", xml.attribute(QStringLiteral("id")).toUtf8().constData());
    if (xml.hasAttribute(QStringLiteral("force_track")))
        transition.set("force_track", xml.attribute(QStringLiteral("force_track")).toInt());

    for (it = args.begin(); it != args.end(); ++it) {
        key = it.key();
        if (!it.value().isEmpty())
            transition.set(key.toUtf8().constData(), it.value().toUtf8().constData());
        ////qDebug() << " ------  ADDING TRANS PARAM: " << key << ": " << it.value();
    }
    // attach transition
    m_tractor->lock();
    plantTransition(field.data(), transition, a_track, b_track);
    // field->plant_transition(*transition, a_track, b_track);
    m_tractor->unlock();
    if (do_refresh) emit refresh();
    return true;
}
Exemple #19
0
static int framebuffer_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{

	// Get the filter object and properties
	mlt_producer producer = mlt_frame_pop_service( frame );
	int index = ( int )mlt_frame_pop_service( frame );
	mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );

	mlt_service_lock( MLT_PRODUCER_SERVICE( producer ) );

	// Frame properties objects
	mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame );
	mlt_frame first_frame = mlt_properties_get_data( properties, "first_frame", NULL );

	// Get producer parameters
	int strobe = mlt_properties_get_int( properties, "strobe" );
	int freeze = mlt_properties_get_int( properties, "freeze" );
	int freeze_after = mlt_properties_get_int( properties, "freeze_after" );
	int freeze_before = mlt_properties_get_int( properties, "freeze_before" );
	int in = mlt_properties_get_position( properties, "in" );

	// Determine the position
	mlt_position first_position = (first_frame != NULL) ? mlt_frame_get_position( first_frame ) : -1;
	mlt_position need_first = freeze;

	if ( !freeze || freeze_after || freeze_before )
	{
		double prod_speed = mlt_properties_get_double( properties, "_speed" );
		double actual_position = in + prod_speed * (double) mlt_producer_position( producer );

		if ( mlt_properties_get_int( properties, "reverse" ) )
			actual_position = mlt_producer_get_playtime( producer ) - actual_position;

		if ( strobe < 2 )
		{
			need_first = floor( actual_position );
		}
		else
		{
			// Strobe effect wanted, calculate frame position
			need_first = floor( actual_position );
			need_first -= need_first % strobe;
		}
		if ( freeze )
		{
			if ( freeze_after && need_first > freeze ) need_first = freeze;
			else if ( freeze_before && need_first < freeze ) need_first = freeze;
		}
	}
	
	// Determine output buffer size
	*width = mlt_properties_get_int( frame_properties, "width" );
	*height = mlt_properties_get_int( frame_properties, "height" );
	int size = mlt_image_format_size( *format, *width, *height, NULL );

	// Get output buffer
	int buffersize = 0;
        int alphasize = *width * *height;
	uint8_t *output = mlt_properties_get_data( properties, "output_buffer", &buffersize );
        uint8_t *output_alpha = mlt_properties_get_data( properties, "output_alpha", NULL );
	if( buffersize == 0 || buffersize != size )
	{
		// invalidate cached frame
		first_position = -1;
	}

	if ( need_first != first_position )
	{
		// invalidate cached frame
		first_position = -1;
		
		// Bust the cached frame
		mlt_properties_set_data( properties, "first_frame", NULL, 0, NULL, NULL );
		first_frame = NULL;
	}

	if ( output && first_position != -1 ) {
		// Using the cached frame
	  	uint8_t *image_copy = mlt_pool_alloc( size );
		memcpy( image_copy, output, size );
                uint8_t *alpha_copy = mlt_pool_alloc( alphasize );
                memcpy( alpha_copy, output_alpha, alphasize );

		// Set the output image
		*image = image_copy;
		mlt_frame_set_image( frame, image_copy, size, mlt_pool_release );
                mlt_frame_set_alpha( frame, alpha_copy, alphasize, mlt_pool_release );

		*width = mlt_properties_get_int( properties, "_output_width" );
		*height = mlt_properties_get_int( properties, "_output_height" );
		*format = mlt_properties_get_int( properties, "_output_format" );

		mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) );
		return 0;
	}

	// Get the cached frame
	if ( first_frame == NULL )
	{
		// Get the frame to cache from the real producer
		mlt_producer real_producer = mlt_properties_get_data( properties, "producer", NULL );

		// Seek the producer to the correct place
		mlt_producer_seek( real_producer, need_first );

		// Get the frame
		mlt_service_get_frame( MLT_PRODUCER_SERVICE( real_producer ), &first_frame, index );

		// Cache the frame
		mlt_properties_set_data( properties, "first_frame", first_frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
	}
	mlt_properties first_frame_properties = MLT_FRAME_PROPERTIES( first_frame );


	// Which frames are buffered?
	uint8_t *first_image = mlt_properties_get_data( first_frame_properties, "image", NULL );
        uint8_t *first_alpha = mlt_properties_get_data( first_frame_properties, "alpha", NULL );
	if ( !first_image )
	{
		mlt_properties_set( first_frame_properties, "rescale.interp", mlt_properties_get( frame_properties, "rescale.interp" ) );

		int error = mlt_frame_get_image( first_frame, &first_image, format, width, height, writable );

		if ( error != 0 ) {
			mlt_log_error( MLT_PRODUCER_SERVICE( producer ), "first_image == NULL get image died\n" );
			mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) );
			return error;
		}
		output = mlt_pool_alloc( size );
		memcpy( output, first_image, size );
		// Let someone else clean up
		mlt_properties_set_data( properties, "output_buffer", output, size, mlt_pool_release, NULL ); 
		mlt_properties_set_int( properties, "_output_width", *width );
		mlt_properties_set_int( properties, "_output_height", *height );
		mlt_properties_set_int( properties, "_output_format", *format );
	
	}

	if ( !first_alpha )
        {
                alphasize = *width * *height;
                first_alpha = mlt_frame_get_alpha_mask( first_frame );
                output_alpha = mlt_pool_alloc( alphasize );
                memcpy( output_alpha, first_alpha, alphasize );
                mlt_properties_set_data( properties, "output_alpha", output_alpha, alphasize, mlt_pool_release, NULL ); 
        }

	mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) );

	// Create a copy
	uint8_t *image_copy = mlt_pool_alloc( size );
	memcpy( image_copy, first_image, size );
        uint8_t *alpha_copy = mlt_pool_alloc( alphasize );
        memcpy( alpha_copy, first_alpha, alphasize );

	// Set the output image
	*image = image_copy;
	mlt_frame_set_image( frame, *image, size, mlt_pool_release );

	mlt_frame_set_alpha( frame, alpha_copy, alphasize, mlt_pool_release );

	return 0;
}
Exemple #20
0
static int producer_get_frame( mlt_service service, mlt_frame_ptr frame, int index )
{
	int result = 1;
	mlt_producer self = service != NULL ? service->child : NULL;

	if ( self != NULL && !mlt_producer_is_cut( self ) )
	{
		// Get the properties of this producer
		mlt_properties properties = MLT_PRODUCER_PROPERTIES( self );

		// Determine eof handling
		char *eof = mlt_properties_get( MLT_PRODUCER_PROPERTIES( self ), "eof" );

		// Get the speed of the producer
		double speed = mlt_producer_get_speed( self );

		// We need to use the clone if it's specified
		mlt_producer clone = mlt_properties_get_data( properties, "use_clone", NULL );

		// If no clone is specified, use self
		clone = clone == NULL ? self : clone;

		// A properly instatiated producer will have a get_frame method...
		if ( self->get_frame == NULL || ( eof && !strcmp( eof, "continue" ) && mlt_producer_position( self ) > mlt_producer_get_out( self ) ) )
		{
			// Generate a test frame
			*frame = mlt_frame_init( service );

			// Set the position
			result = mlt_frame_set_position( *frame, mlt_producer_position( self ) );

			// Mark as a test card
			mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "test_image", 1 );
			mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "test_audio", 1 );

			// Calculate the next position
			mlt_producer_prepare_next( self );
		}
		else
		{
			// Get the frame from the implementation
			result = self->get_frame( clone, frame, index );
		}

		// Copy the fps and speed of the producer onto the frame
		properties = MLT_FRAME_PROPERTIES( *frame );
		mlt_properties_set_double( properties, "_speed", speed );
		mlt_properties_set_int( properties, "test_audio", mlt_frame_is_test_audio( *frame ) );
		mlt_properties_set_int( properties, "test_image", mlt_frame_is_test_card( *frame ) );
		if ( mlt_properties_get_data( properties, "_producer", NULL ) == NULL )
			mlt_properties_set_data( properties, "_producer", service, 0, NULL, NULL );
	}
	else if ( self != NULL )
	{
		// Get the speed of the cut
		double speed = mlt_producer_get_speed( self );

		// Get the parent of the cut
		mlt_producer parent = mlt_producer_cut_parent( self );

		// Get the properties of the parent
		mlt_properties parent_properties = MLT_PRODUCER_PROPERTIES( parent );

		// Get the properties of the cut
		mlt_properties properties = MLT_PRODUCER_PROPERTIES( self );

		// Determine the clone index
		int clone_index = mlt_properties_get_int( properties, "_clone" );

		// Determine the clone to use
		mlt_producer clone = self;

		if ( clone_index > 0 )
		{
			char key[ 25 ];
			sprintf( key, "_clone.%d", clone_index - 1 );
			clone = mlt_properties_get_data( MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( self ) ), key, NULL );
			if ( clone == NULL ) mlt_log( service, MLT_LOG_ERROR, "requested clone doesn't exist %d\n", clone_index );
			clone = clone == NULL ? self : clone;
		}
		else
		{
			clone = parent;
		}

		// We need to seek to the correct position in the clone
		mlt_producer_seek( clone, mlt_producer_get_in( self ) + mlt_properties_get_int( properties, "_position" ) );

		// Assign the clone property to the parent
		mlt_properties_set_data( parent_properties, "use_clone", clone, 0, NULL, NULL );

		// Now get the frame from the parents service
		result = mlt_service_get_frame( MLT_PRODUCER_SERVICE( parent ), frame, index );

		// We're done with the clone now
		mlt_properties_set_data( parent_properties, "use_clone", NULL, 0, NULL, NULL );

		// This is useful and required by always_active transitions to determine in/out points of the cut
		if ( mlt_properties_get_data( MLT_FRAME_PROPERTIES( *frame ), "_producer", NULL ) == MLT_PRODUCER_SERVICE( parent ) )
			mlt_properties_set_data( MLT_FRAME_PROPERTIES( *frame ), "_producer", self, 0, NULL, NULL );

		mlt_properties_set_double( MLT_FRAME_PROPERTIES( *frame ), "_speed", speed );
		mlt_producer_prepare_next( self );
	}
	else
	{
		*frame = mlt_frame_init( service );
		result = 0;
	}

	// Pass on all meta properties from the producer/cut on to the frame
	if ( *frame != NULL && self != NULL )
	{
		int i = 0;
		mlt_properties p_props = MLT_PRODUCER_PROPERTIES( self );
		mlt_properties f_props = MLT_FRAME_PROPERTIES( *frame );
		mlt_properties_lock( p_props );
		int count = mlt_properties_count( p_props );
		for ( i = 0; i < count; i ++ )
		{
			char *name = mlt_properties_get_name( p_props, i );
			if ( !strncmp( name, "meta.", 5 ) )
				mlt_properties_set( f_props, name, mlt_properties_get_value( p_props, i ) );
			else if ( !strncmp( name, "set.", 4 ) )
				mlt_properties_set( f_props, name + 4, mlt_properties_get_value( p_props, i ) );
		}
		mlt_properties_unlock( p_props );
	}

	return result;
}
Exemple #21
0
void mlt_producer_prepare_next( mlt_producer self )
{
	if ( mlt_producer_get_speed( self ) != 0 )
		mlt_producer_seek( self, mlt_producer_position( self ) + mlt_producer_get_speed( self ) );
}
Exemple #22
0
mlt_position mlt_multitrack_clip( mlt_multitrack self, mlt_whence whence, int index )
{
	mlt_position position = 0;
	int i = 0;
	int j = 0;
	mlt_position *map = calloc( 1000, sizeof( mlt_position ) );
	int count = 0;

	for ( i = 0; i < self->count; i ++ )
	{
		// Get the producer for this track
		mlt_producer producer = self->list[ i ]->producer;

		// If it's assigned and not a hidden track
		if ( producer != NULL )
		{
			// Get the properties of this producer
			mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );

			// Determine if it's a playlist
			mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL );

			// Special case consideration of playlists
			if ( playlist != NULL )
			{
				for ( j = 0; j < mlt_playlist_count( playlist ); j ++ )
					count = add_unique( map, count, mlt_playlist_clip( playlist, mlt_whence_relative_start, j ) );
				count = add_unique( map, count, mlt_producer_get_out( producer ) + 1 );
			}
			else
			{
				count = add_unique( map, count, 0 );
				count = add_unique( map, count, mlt_producer_get_out( producer ) + 1 );
			}
		}
	}

	// Now sort the map
	qsort( map, count, sizeof( mlt_position ), position_compare );

	// Now locate the requested index
	switch( whence )
	{
		case mlt_whence_relative_start:
			if ( index < count )
				position = map[ index ];
			else
				position = map[ count - 1 ];
			break;

		case mlt_whence_relative_current:
			position = mlt_producer_position( MLT_MULTITRACK_PRODUCER( self ) );
			for ( i = 0; i < count - 2; i ++ )
				if ( position >= map[ i ] && position < map[ i + 1 ] )
					break;
			index += i;
			if ( index >= 0 && index < count )
				position = map[ index ];
			else if ( index < 0 )
				position = map[ 0 ];
			else
				position = map[ count - 1 ];
			break;

		case mlt_whence_relative_end:
			if ( index < count )
				position = map[ count - index - 1 ];
			else
				position = map[ 0 ];
			break;
	}

	// Free the map
	free( map );

	return position;
}
Exemple #23
0
int mlt_service_get_frame( mlt_service self, mlt_frame_ptr frame, int index )
{
	int result = 0;

	// Lock the service
	mlt_service_lock( self );

	// Ensure that the frame is NULL
	*frame = NULL;

	// Only process if we have a valid service
	if ( self != NULL && self->get_frame != NULL )
	{
		mlt_properties properties = MLT_SERVICE_PROPERTIES( self );
		mlt_position in = mlt_properties_get_position( properties, "in" );
		mlt_position out = mlt_properties_get_position( properties, "out" );
		mlt_position position = mlt_service_identify( self ) == producer_type ? mlt_producer_position( MLT_PRODUCER( self ) ) : -1;

		result = self->get_frame( self, frame, index );

		if ( result == 0 )
		{
			mlt_properties_inc_ref( properties );
			properties = MLT_FRAME_PROPERTIES( *frame );
			
			if ( in >=0 && out > 0 )
			{
				mlt_properties_set_position( properties, "in", in );
				mlt_properties_set_position( properties, "out", out );
			}
			mlt_service_apply_filters( self, *frame, 1 );
			mlt_deque_push_back( MLT_FRAME_SERVICE_STACK( *frame ), self );
			
			if ( mlt_service_identify( self ) == producer_type &&
			     mlt_properties_get_int( MLT_SERVICE_PROPERTIES( self ), "_need_previous_next" ) )
			{
				// Save the new position from self->get_frame
				mlt_position new_position = mlt_producer_position( MLT_PRODUCER( self ) );
				
				// Get the preceding frame, unfiltered
				mlt_frame previous_frame;
				mlt_producer_seek( MLT_PRODUCER(self), position - 1 );
				result = self->get_frame( self, &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(self), position + 1 );
				result = self->get_frame( self, &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(self), new_position );
			}
		}
	}

	// Make sure we return a frame
	if ( *frame == NULL )
		*frame = mlt_frame_init( self );

	// Unlock the service
	mlt_service_unlock( self );

	return result;
}
Exemple #24
0
    mlt_frame getFrame()
    {
        struct timeval now;
        struct timespec tm;
        double fps = mlt_producer_get_fps( getProducer() );
        mlt_position position = mlt_producer_position( getProducer() );
        mlt_frame frame = mlt_cache_get_frame( m_cache, position );

        // Allow the buffer to fill to the requested initial buffer level.
        if ( m_isBuffering )
        {
            int prefill = mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( getProducer() ), "prefill" );
            int buffer = mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( getProducer() ), "buffer" );

            m_isBuffering = false;
            prefill = prefill > buffer ? buffer : prefill;
            pthread_mutex_lock( &m_mutex );
            while ( mlt_deque_count( m_queue ) < prefill )
            {
                // Wait up to buffer/fps seconds
                gettimeofday( &now, NULL );
                long usec = now.tv_sec * 1000000 + now.tv_usec;
                usec += 1000000 * buffer / fps;
                tm.tv_sec = usec / 1000000;
                tm.tv_nsec = (usec % 1000000) * 1000;
                if ( pthread_cond_timedwait( &m_condition, &m_mutex, &tm ) )
                    break;
            }
            pthread_mutex_unlock( &m_mutex );
        }

        if ( !frame )
        {
            // Wait if queue is empty
            pthread_mutex_lock( &m_mutex );
            while ( mlt_deque_count( m_queue ) < 1 )
            {
                // Wait up to twice frame duration
                gettimeofday( &now, NULL );
                long usec = now.tv_sec * 1000000 + now.tv_usec;
                usec += 2000000 / fps;
                tm.tv_sec = usec / 1000000;
                tm.tv_nsec = (usec % 1000000) * 1000;
                if ( pthread_cond_timedwait( &m_condition, &m_mutex, &tm ) )
                    // Stop waiting if error (timed out)
                    break;
            }
            frame = ( mlt_frame ) mlt_deque_pop_front( m_queue );
            pthread_mutex_unlock( &m_mutex );

            // add to cache
            if ( frame )
            {
                mlt_frame_set_position( frame, position );
                mlt_cache_put_frame( m_cache, frame );
            }
        }

        // Set frame timestamp and properties
        if ( frame )
        {
            mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( getProducer() ) );
            mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
            mlt_properties_set_int( properties, "progressive", profile->progressive );
            mlt_properties_set_int( properties, "meta.media.progressive", profile->progressive );
            mlt_properties_set_int( properties, "top_field_first", m_topFieldFirst );
            mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) );
            mlt_properties_set_int( properties, "meta.media.sample_aspect_num", profile->sample_aspect_num );
            mlt_properties_set_int( properties, "meta.media.sample_aspect_den", profile->sample_aspect_den );
            mlt_properties_set_int( properties, "meta.media.frame_rate_num", profile->frame_rate_num );
            mlt_properties_set_int( properties, "meta.media.frame_rate_den", profile->frame_rate_den );
            mlt_properties_set_int( properties, "width", profile->width );
            mlt_properties_set_int( properties, "meta.media.width", profile->width );
            mlt_properties_set_int( properties, "height", profile->height );
            mlt_properties_set_int( properties, "meta.media.height", profile->height );
            mlt_properties_set_int( properties, "format", mlt_image_yuv422 );
            mlt_properties_set_int( properties, "colorspace", m_colorspace );
            mlt_properties_set_int( properties, "meta.media.colorspace", m_colorspace );
            mlt_properties_set_int( properties, "audio_frequency", 48000 );
            mlt_properties_set_int( properties, "audio_channels",
                                    mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( getProducer() ), "channels" ) );
        }
        else
            mlt_log_warning( getProducer(), "buffer underrun\n" );

        return frame;
    }
Exemple #25
0
static void transport( mlt_producer producer, mlt_consumer consumer )
{
    mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
    int silent = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( consumer ), "silent" );
    int progress = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( consumer ), "progress" );
    struct timespec tm = { 0, 40000000 };
    int total_length = mlt_producer_get_length( producer );
    int last_position = 0;

    if ( mlt_properties_get_int( properties, "done" ) == 0 && !mlt_consumer_is_stopped( consumer ) )
    {
        if ( !silent && !progress )
        {
            term_init( );

            fprintf( stderr, "+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+\n" );
            fprintf( stderr, "|1=-10| |2= -5| |3= -2| |4= -1| |5=  0| |6=  1| |7=  2| |8=  5| |9= 10|\n" );
            fprintf( stderr, "+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+\n" );

            fprintf( stderr, "+---------------------------------------------------------------------+\n" );
            fprintf( stderr, "|               H = back 1 minute,  L = forward 1 minute              |\n" );
            fprintf( stderr, "|                 h = previous frame,  l = next frame                 |\n" );
            fprintf( stderr, "|           g = start of clip, j = next clip, k = previous clip       |\n" );
            fprintf( stderr, "|                0 = restart, q = quit, space = play                  |\n" );
            fprintf( stderr, "+---------------------------------------------------------------------+\n" );
        }

        while( mlt_properties_get_int( properties, "done" ) == 0 && !mlt_consumer_is_stopped( consumer ) )
        {
            int value = ( silent || progress )? -1 : term_read( );

            if ( value != -1 )
            {
                char string[ 2 ] = { value, 0 };
                transport_action( producer, string );
            }

#if (defined(__DARWIN__) || defined(WIN32)) && !defined(MELT_NOSDL)
            event_handling( producer, consumer );
#endif

            if ( !silent && mlt_properties_get_int( properties, "stats_off" ) == 0 )
            {
                if ( progress )
                {
                    int current_position = mlt_producer_position( producer );
                    if ( current_position > last_position )
                    {
                        fprintf( stderr, "Current Frame: %10d, percentage: %10d%c",
                                 current_position, 100 * current_position / total_length,
                                 progress == 2 ? '\n' : '\r' );
                        last_position = current_position;
                    }
                }
                else
                {
                    fprintf( stderr, "Current Position: %10d\r", (int)mlt_consumer_position( consumer ) );
                }
                fflush( stderr );
            }

            if ( silent || progress )
                nanosleep( &tm, NULL );
        }

        if ( !silent )
            fprintf( stderr, "\n" );
    }
}
Exemple #26
0
static int get_frame( mlt_producer self, mlt_frame_ptr frame, int index )
{
	mlt_properties properties = MLT_PRODUCER_PROPERTIES(self);
	context cx = mlt_properties_get_data( properties, "context", NULL );

	if ( !cx )
	{
		// Allocate and initialize our context
		cx = mlt_pool_alloc( sizeof( struct context_s ) );
		memset( cx, 0, sizeof( *cx ) );
		mlt_properties_set_data( properties, "context", cx, 0, mlt_pool_release, NULL );
		cx->self = self;
		char *profile_name = mlt_properties_get( properties, "profile" );
		if ( !profile_name )
			profile_name = mlt_properties_get( properties, "mlt_profile" );
		mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( self ) );

		if ( profile_name )
		{
			cx->profile = mlt_profile_init( profile_name );
			cx->profile->is_explicit = 1;
		}
		else
		{
			cx->profile = mlt_profile_clone( profile );
			cx->profile->is_explicit = 0;
		}

		// Encapsulate a real producer for the resource
		cx->producer = mlt_factory_producer( cx->profile, NULL,
			mlt_properties_get( properties, "resource" ) );
		if ( ( profile_name && !strcmp( profile_name, "auto" ) ) ||
			mlt_properties_get_int( properties, "autoprofile" ) )
		{
			mlt_profile_from_producer( cx->profile, cx->producer );
			mlt_producer_close( cx->producer );
			cx->producer = mlt_factory_producer( cx->profile, NULL,	mlt_properties_get( properties, "resource" ) );
		}

		// Since we control the seeking, prevent it from seeking on its own
		mlt_producer_set_speed( cx->producer, 0 );
		cx->audio_position = -1;

		// We will encapsulate a consumer
		cx->consumer = mlt_consumer_new( cx->profile );
		// Do not use _pass_list on real_time so that it defaults to 0 in the absence of
		// an explicit real_time property.
		mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( cx->consumer ), "real_time",
			mlt_properties_get_int( properties, "real_time" ) );
		mlt_properties_pass_list( MLT_CONSUMER_PROPERTIES( cx->consumer ), properties,
			"buffer, prefill, deinterlace_method, rescale" );
	
		// Connect it all together
		mlt_consumer_connect( cx->consumer, MLT_PRODUCER_SERVICE( cx->producer ) );
		mlt_consumer_start( cx->consumer );
	}

	// Generate a frame
	*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( self ) );
	if ( *frame )
	{
		// Seek the producer to the correct place
		// Calculate our positions
		double actual_position = (double) mlt_producer_frame( self );
		if ( mlt_producer_get_speed( self ) != 0 )
			actual_position *= mlt_producer_get_speed( self );
		mlt_position need_first = floor( actual_position );
		mlt_producer_seek( cx->producer,
			lrint( need_first * mlt_profile_fps( cx->profile ) / mlt_producer_get_fps( self ) ) );

		// Get the nested frame
		mlt_frame nested_frame = mlt_consumer_rt_frame( cx->consumer );

		// Stack the producer and our methods on the nested frame
		mlt_frame_push_service( *frame, nested_frame );
		mlt_frame_push_service( *frame, cx );
		mlt_frame_push_get_image( *frame, get_image );
		mlt_frame_push_audio( *frame, nested_frame );
		mlt_frame_push_audio( *frame, cx );
		mlt_frame_push_audio( *frame, get_audio );
		
		// Give the returned frame temporal identity
		mlt_frame_set_position( *frame, mlt_producer_position( self ) );
		
		// Store the nested frame on the produced frame for destruction
		mlt_properties frame_props = MLT_FRAME_PROPERTIES( *frame );
		mlt_properties_set_data( frame_props, "_producer_consumer.frame", nested_frame, 0, (mlt_destructor) mlt_frame_close, NULL );

		// Inform the normalizers about our video properties
		mlt_properties_set_double( frame_props, "aspect_ratio", mlt_profile_sar( cx->profile ) );
		mlt_properties_set_int( frame_props, "width", cx->profile->width );
		mlt_properties_set_int( frame_props, "height", cx->profile->height );
		mlt_properties_set_int( frame_props, "meta.media.width", cx->profile->width );
		mlt_properties_set_int( frame_props, "meta.media.height", cx->profile->height );
		mlt_properties_set_int( frame_props, "progressive", cx->profile->progressive );
	}

	// Calculate the next timecode
	mlt_producer_prepare_next( self );

	return 0;
}
Exemple #27
0
static void transport_action( mlt_producer producer, char *value )
{
    mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
    mlt_multitrack multitrack = mlt_properties_get_data( properties, "multitrack", NULL );
    mlt_consumer consumer = mlt_properties_get_data( properties, "transport_consumer", NULL );
    mlt_properties jack = mlt_properties_get_data( MLT_CONSUMER_PROPERTIES( consumer ), "jack_filter", NULL );
    mlt_position position = producer? mlt_producer_position( producer ) : 0;

    mlt_properties_set_int( properties, "stats_off", 1 );

    if ( strlen( value ) == 1 )
    {
        switch( value[ 0 ] )
        {
        case 'q':
        case 'Q':
            mlt_properties_set_int( properties, "done", 1 );
            mlt_events_fire( jack, "jack-stop", NULL );
            break;
        case '0':
            position = 0;
            mlt_producer_set_speed( producer, 1 );
            mlt_producer_seek( producer, position );
            mlt_consumer_purge( consumer );
            mlt_events_fire( jack, "jack-seek", &position, NULL );
            break;
        case '1':
            mlt_producer_set_speed( producer, -10 );
            break;
        case '2':
            mlt_producer_set_speed( producer, -5 );
            break;
        case '3':
            mlt_producer_set_speed( producer, -2 );
            break;
        case '4':
            mlt_producer_set_speed( producer, -1 );
            break;
        case '5':
            mlt_producer_set_speed( producer, 0 );
            mlt_consumer_purge( consumer );
            mlt_producer_seek( producer, mlt_consumer_position( consumer ) + 1 );
            mlt_events_fire( jack, "jack-stop", NULL );
            break;
        case '6':
        case ' ':
            if ( !jack || mlt_producer_get_speed( producer ) != 0 )
                mlt_producer_set_speed( producer, 1 );
            mlt_consumer_purge( consumer );
            mlt_events_fire( jack, "jack-start", NULL );
            break;
        case '7':
            mlt_producer_set_speed( producer, 2 );
            break;
        case '8':
            mlt_producer_set_speed( producer, 5 );
            break;
        case '9':
            mlt_producer_set_speed( producer, 10 );
            break;
        case 'd':
            if ( multitrack != NULL )
            {
                int i = 0;
                mlt_position last = -1;
                fprintf( stderr, "\n" );
                for ( i = 0; 1; i ++ )
                {
                    position = mlt_multitrack_clip( multitrack, mlt_whence_relative_start, i );
                    if ( position == last )
                        break;
                    last = position;
                    fprintf( stderr, "%d: %d\n", i, (int)position );
                }
            }
            break;

        case 'g':
            if ( multitrack != NULL )
            {
                position = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 0 );
                mlt_producer_seek( producer, position );
                mlt_consumer_purge( consumer );
                mlt_events_fire( jack, "jack-seek", &position, NULL );
            }
            break;
        case 'H':
            if ( producer != NULL )
            {
                position -= mlt_producer_get_fps( producer ) * 60;
                mlt_consumer_purge( consumer );
                mlt_producer_seek( producer, position );
                mlt_events_fire( jack, "jack-seek", &position, NULL );
            }
            break;
        case 'h':
            if ( producer != NULL )
            {
                position--;
                mlt_producer_set_speed( producer, 0 );
                mlt_consumer_purge( consumer );
                mlt_producer_seek( producer, position );
                mlt_events_fire( jack, "jack-stop", NULL );
                mlt_events_fire( jack, "jack-seek", &position, NULL );
            }
            break;
        case 'j':
            if ( multitrack != NULL )
            {
                position = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 1 );
                mlt_consumer_purge( consumer );
                mlt_producer_seek( producer, position );
                mlt_events_fire( jack, "jack-seek", &position, NULL );
            }
            break;
        case 'k':
            if ( multitrack != NULL )
            {
                position = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, -1 );
                mlt_consumer_purge( consumer );
                mlt_producer_seek( producer, position );
                mlt_events_fire( jack, "jack-seek", &position, NULL );
            }
            break;
        case 'l':
            if ( producer != NULL )
            {
                position++;
                mlt_consumer_purge( consumer );
                if ( mlt_producer_get_speed( producer ) != 0 )
                {
                    mlt_producer_set_speed( producer, 0 );
                    mlt_events_fire( jack, "jack-stop", NULL );
                }
                else
                {
                    mlt_producer_seek( producer, position );
                    mlt_events_fire( jack, "jack-seek", &position, NULL );
                }
            }
            break;
        case 'L':
            if ( producer != NULL )
            {
                position += mlt_producer_get_fps( producer ) * 60;
                mlt_consumer_purge( consumer );
                mlt_producer_seek( producer, position );
                mlt_events_fire( jack, "jack-seek", &position, NULL );
            }
            break;
        }

        mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( consumer ), "refresh", 1 );
    }

    mlt_properties_set_int( properties, "stats_off", 0 );
}
Exemple #28
0
static void transport_action( mlt_producer producer, char *value )
{
	mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
	mlt_multitrack multitrack = mlt_properties_get_data( properties, "multitrack", NULL );
	mlt_consumer consumer = mlt_properties_get_data( properties, "transport_consumer", NULL );

	mlt_properties_set_int( properties, "stats_off", 1 );

	if ( strlen( value ) == 1 )
	{
		switch( value[ 0 ] )
		{
			case 'q':
				mlt_properties_set_int( properties, "done", 1 );
				break;
			case '0':
				mlt_producer_set_speed( producer, 1 );
				mlt_producer_seek( producer, 0 );
				break;
			case '1':
				mlt_producer_set_speed( producer, -10 );
				break;
			case '2':
				mlt_producer_set_speed( producer, -5 );
				break;
			case '3':
				mlt_producer_set_speed( producer, -2 );
				break;
			case '4':
				mlt_producer_set_speed( producer, -1 );
				break;
			case '5':
				mlt_producer_set_speed( producer, 0 );
				break;
			case '6':
			case ' ':
				mlt_producer_set_speed( producer, 1 );
				break;
			case '7':
				mlt_producer_set_speed( producer, 2 );
				break;
			case '8':
				mlt_producer_set_speed( producer, 5 );
				break;
			case '9':
				mlt_producer_set_speed( producer, 10 );
				break;
			case 'd':
				if ( multitrack != NULL )
				{
					int i = 0;
					mlt_position last = -1;
					fprintf( stderr, "\n" );
					for ( i = 0; 1; i ++ )
					{
						mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_start, i );
						if ( time == last )
							break;
						last = time;
						fprintf( stderr, "%d: %d\n", i, (int)time );
					}
				}
				break;

			case 'g':
				if ( multitrack != NULL )
				{
					mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 0 );
					mlt_producer_seek( producer, time );
				}
				break;
			case 'H':
				if ( producer != NULL )
				{
					mlt_position position = mlt_producer_position( producer );
					mlt_producer_seek( producer, position - ( mlt_producer_get_fps( producer ) * 60 ) );
				}
				break;
			case 'h':
				if ( producer != NULL )
				{
					mlt_position position = mlt_producer_position( producer );
					mlt_producer_set_speed( producer, 0 );
					mlt_producer_seek( producer, position - 1 );
				}
				break;
			case 'j':
				if ( multitrack != NULL )
				{
					mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 1 );
					mlt_producer_seek( producer, time );
				}
				break;
			case 'k':
				if ( multitrack != NULL )
				{
					mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, -1 );
					mlt_producer_seek( producer, time );
				}
				break;
			case 'l':
				if ( producer != NULL )
				{
					mlt_position position = mlt_producer_position( producer );
					if ( mlt_producer_get_speed( producer ) != 0 )
						mlt_producer_set_speed( producer, 0 );
					else
						mlt_producer_seek( producer, position + 1 );
				}
				break;
			case 'L':
				if ( producer != NULL )
				{
					mlt_position position = mlt_producer_position( producer );
					mlt_producer_seek( producer, position + ( mlt_producer_get_fps( producer ) * 60 ) );
				}
				break;
		}

		mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( consumer ), "refresh", 1 );
	}

	mlt_properties_set_int( properties, "stats_off", 0 );
}