Exemplo n.º 1
0
int mlt_frame_get_image( mlt_frame self, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
{
	mlt_properties properties = MLT_FRAME_PROPERTIES( self );
	mlt_get_image get_image = mlt_frame_pop_get_image( self );
	mlt_image_format requested_format = *format;
	int error = 0;

	if ( get_image )
	{
		mlt_properties_set_int( properties, "image_count", mlt_properties_get_int( properties, "image_count" ) - 1 );
		error = get_image( self, buffer, format, width, height, writable );
		if ( !error && buffer && *buffer )
		{
			mlt_properties_set_int( properties, "width", *width );
			mlt_properties_set_int( properties, "height", *height );
			if ( self->convert_image && requested_format != mlt_image_none )
				self->convert_image( self, buffer, format, requested_format );
			mlt_properties_set_int( properties, "format", *format );
		}
		else
		{
			error = generate_test_image( properties, buffer, format, width, height, writable );
		}
	}
	else if ( mlt_properties_get_data( properties, "image", NULL ) && buffer )
	{
		*format = mlt_properties_get_int( properties, "format" );
		*buffer = mlt_properties_get_data( properties, "image", NULL );
		*width = mlt_properties_get_int( properties, "width" );
		*height = mlt_properties_get_int( properties, "height" );
		if ( self->convert_image && *buffer && requested_format != mlt_image_none )
		{
			self->convert_image( self, buffer, format, requested_format );
			mlt_properties_set_int( properties, "format", *format );
		}
	}
	else
	{
		error = generate_test_image( properties, buffer, format, width, height, writable );
	}

	return error;
}
Exemplo n.º 2
0
static int convert_on_cpu( mlt_frame frame, uint8_t **image, mlt_image_format *format, mlt_image_format output_format )
{
	int error = 0;
	mlt_filter cpu_csc = (mlt_filter) mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "cpu_csc", NULL );
	if ( cpu_csc ) {
		int (* save_fp )( mlt_frame self, uint8_t **image, mlt_image_format *input, mlt_image_format output )
			= frame->convert_image;
		frame->convert_image = NULL;
		mlt_filter_process( cpu_csc, frame );
		error = frame->convert_image( frame, image, format, output_format );
		frame->convert_image = save_fp;
	} else {
		error = 1;
	}
	return error;
}
Exemplo n.º 3
0
static int resample_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
{
	// Get the filter service
	mlt_filter filter = mlt_frame_pop_audio( frame );

	// Get the filter properties
	mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter );

	// Get the resample information
	int output_rate = mlt_properties_get_int( filter_properties, "frequency" );

	// If no resample frequency is specified, default to requested value
	if ( output_rate == 0 )
		output_rate = *frequency;

	// Get the producer's audio
	int error = mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
	if ( error ) return error;

	// Return now if no work to do
	if ( output_rate != *frequency && *frequency > 0 && *channels > 0 )
	{
		mlt_log_debug( MLT_FILTER_SERVICE(filter), "channels %d samples %d frequency %d -> %d\n",
			*channels, *samples, *frequency, output_rate );

		// Do not convert to float unless we need to change the rate
		if ( *format != mlt_audio_f32le )
			frame->convert_audio( frame, buffer, format, mlt_audio_f32le );

		mlt_service_lock( MLT_FILTER_SERVICE(filter) );

		SRC_DATA data;
		data.data_in = *buffer;
		data.data_out = mlt_properties_get_data( filter_properties, "output_buffer", NULL );
		data.src_ratio = ( float ) output_rate / ( float ) *frequency;
		data.input_frames = *samples;
		data.output_frames = BUFFER_LEN / *channels;
		data.end_of_input = 0;

		SRC_STATE *state = mlt_properties_get_data( filter_properties, "state", NULL );
		if ( !state || mlt_properties_get_int( filter_properties, "channels" ) != *channels )
		{
			// Recreate the resampler if the number of channels changed
			state = src_new( RESAMPLE_TYPE, *channels, &error );
			mlt_properties_set_data( filter_properties, "state", state, 0, (mlt_destructor) src_delete, NULL );
			mlt_properties_set_int( filter_properties, "channels", *channels );
		}

		// Resample the audio
		error = src_process( state, &data );
		if ( !error )
		{
			// Update output variables
			*samples = data.output_frames_gen;
			*frequency = output_rate;
			*buffer = data.data_out;
		}
		else
		{
			mlt_log_error( MLT_FILTER_SERVICE( filter ), "%s %d,%d,%d\n", src_strerror( error ), *frequency, *samples, output_rate );
		}
		mlt_service_unlock( MLT_FILTER_SERVICE(filter) );
	}

	return error;
}
Exemplo n.º 4
0
static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{
	int error = 0;
	mlt_profile profile = mlt_frame_pop_service( frame );

	// Get the properties from the frame
	mlt_properties properties = MLT_FRAME_PROPERTIES( frame );

	// Correct Width/height if necessary
	if ( *width == 0 || *height == 0 )
	{
		*width  = profile->width;
		*height = profile->height;
	}

	int left    = mlt_properties_get_int( properties, "crop.left" );
	int right   = mlt_properties_get_int( properties, "crop.right" );
	int top     = mlt_properties_get_int( properties, "crop.top" );
	int bottom  = mlt_properties_get_int( properties, "crop.bottom" );

	// Request the image at its original resolution
	if ( left || right || top || bottom )
	{
		mlt_properties_set_int( properties, "rescale_width", mlt_properties_get_int( properties, "crop.original_width" ) );
		mlt_properties_set_int( properties, "rescale_height", mlt_properties_get_int( properties, "crop.original_height" ) );
	}

	// Now get the image
	error = mlt_frame_get_image( frame, image, format, width, height, writable );

	int owidth  = *width - left - right;
	int oheight = *height - top - bottom;
	owidth = owidth < 0 ? 0 : owidth;
	oheight = oheight < 0 ? 0 : oheight;

	if ( ( owidth != *width || oheight != *height ) &&
		error == 0 && *image != NULL && owidth > 0 && oheight > 0 )
	{
		int bpp;

		// Subsampled YUV is messy and less precise.
		if ( *format == mlt_image_yuv422 && frame->convert_image )
		{
			mlt_image_format requested_format = mlt_image_rgb24;
			frame->convert_image( frame, image, format, requested_format );
		}
	
		mlt_log_debug( NULL, "[filter crop] %s %dx%d -> %dx%d\n", mlt_image_format_name(*format),
				 *width, *height, owidth, oheight);

		// Provides a manual override for misreported field order
		if ( mlt_properties_get( properties, "meta.top_field_first" ) )
		{
			mlt_properties_set_int( properties, "top_field_first", mlt_properties_get_int( properties, "meta.top_field_first" ) );
			mlt_properties_set_int( properties, "meta.top_field_first", 0 );
		}

		if ( top % 2 )
			mlt_properties_set_int( properties, "top_field_first", !mlt_properties_get_int( properties, "top_field_first" ) );
		
		// Create the output image
		int size = mlt_image_format_size( *format, owidth, oheight, &bpp );
		uint8_t *output = mlt_pool_alloc( size );
		if ( output )
		{
			// Call the generic resize
			crop( *image, output, bpp, *width, *height, left, right, top, bottom );

			// Now update the frame
			mlt_frame_set_image( frame, output, size, mlt_pool_release );
			*image = output;
		}

		// We should resize the alpha too
		uint8_t *alpha = mlt_frame_get_alpha_mask( frame );
		int alpha_size = 0;
		mlt_properties_get_data( properties, "alpha", &alpha_size );
		if ( alpha && alpha_size >= ( *width * *height ) )
		{
			uint8_t *newalpha = mlt_pool_alloc( owidth * oheight );
			if ( newalpha )
			{
				crop( alpha, newalpha, 1, *width, *height, left, right, top, bottom );
				mlt_frame_set_alpha( frame, newalpha, owidth * oheight, mlt_pool_release );
			}
		}
		*width = owidth;
		*height = oheight;
	}

	return error;
}
Exemplo n.º 5
0
int mlt_frame_get_audio( mlt_frame self, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
{
	mlt_get_audio get_audio = mlt_frame_pop_audio( self );
	mlt_properties properties = MLT_FRAME_PROPERTIES( self );
	int hide = mlt_properties_get_int( properties, "test_audio" );
	mlt_audio_format requested_format = *format;

	if ( hide == 0 && get_audio != NULL )
	{
		get_audio( self, buffer, format, frequency, channels, samples );
		mlt_properties_set_int( properties, "audio_frequency", *frequency );
		mlt_properties_set_int( properties, "audio_channels", *channels );
		mlt_properties_set_int( properties, "audio_samples", *samples );
		mlt_properties_set_int( properties, "audio_format", *format );
		if ( self->convert_audio && *buffer && requested_format != mlt_audio_none )
			self->convert_audio( self, buffer, format, requested_format );
	}
	else if ( mlt_properties_get_data( properties, "audio", NULL ) )
	{
		*buffer = mlt_properties_get_data( properties, "audio", NULL );
		*format = mlt_properties_get_int( properties, "audio_format" );
		*frequency = mlt_properties_get_int( properties, "audio_frequency" );
		*channels = mlt_properties_get_int( properties, "audio_channels" );
		*samples = mlt_properties_get_int( properties, "audio_samples" );
		if ( self->convert_audio && *buffer && requested_format != mlt_audio_none )
			self->convert_audio( self, buffer, format, requested_format );
	}
	else
	{
		int size = 0;
		*samples = *samples <= 0 ? 1920 : *samples;
		*channels = *channels <= 0 ? 2 : *channels;
		*frequency = *frequency <= 0 ? 48000 : *frequency;
		mlt_properties_set_int( properties, "audio_frequency", *frequency );
		mlt_properties_set_int( properties, "audio_channels", *channels );
		mlt_properties_set_int( properties, "audio_samples", *samples );
		mlt_properties_set_int( properties, "audio_format", *format );

		switch( *format )
		{
			case mlt_image_none:
				size = 0;
				*buffer = NULL;
				break;
			case mlt_audio_s16:
				size = *samples * *channels * sizeof( int16_t );
				break;
			case mlt_audio_s32:
				size = *samples * *channels * sizeof( int32_t );
				break;
			case mlt_audio_float:
				size = *samples * *channels * sizeof( float );
				break;
			default:
				break;
		}
		if ( size )
			*buffer = mlt_pool_alloc( size );
		if ( *buffer )
			memset( *buffer, 0, size );
		mlt_properties_set_data( properties, "audio", *buffer, size, ( mlt_destructor )mlt_pool_release, NULL );
		mlt_properties_set_int( properties, "test_audio", 1 );
	}

	// TODO: This does not belong here
	if ( *format == mlt_audio_s16 && mlt_properties_get( properties, "meta.volume" ) )
	{
		double value = mlt_properties_get_double( properties, "meta.volume" );

		if ( value == 0.0 )
		{
			memset( *buffer, 0, *samples * *channels * 2 );
		}
		else if ( value != 1.0 )
		{
			int total = *samples * *channels;
			int16_t *p = *buffer;
			while ( total -- )
			{
				*p = *p * value;
				p ++;
			}
		}

		mlt_properties_set( properties, "meta.volume", NULL );
	}

	return 0;
}
Exemplo n.º 6
0
int mlt_frame_get_image( mlt_frame self, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
{
	mlt_properties properties = MLT_FRAME_PROPERTIES( self );
	mlt_get_image get_image = mlt_frame_pop_get_image( self );
	mlt_producer producer = mlt_properties_get_data( properties, "test_card_producer", NULL );
	mlt_image_format requested_format = *format;
	int error = 0;

	if ( get_image )
	{
		mlt_properties_set_int( properties, "image_count", mlt_properties_get_int( properties, "image_count" ) - 1 );
		error = get_image( self, buffer, format, width, height, writable );
		if ( !error && *buffer )
		{
			mlt_properties_set_int( properties, "width", *width );
			mlt_properties_set_int( properties, "height", *height );
			if ( self->convert_image && *buffer && requested_format != mlt_image_none )
				self->convert_image( self, buffer, format, requested_format );
			mlt_properties_set_int( properties, "format", *format );
		}
		else
		{
			// Cause the image to be loaded from test card or fallback (white) below.
			mlt_frame_get_image( self, buffer, format, width, height, writable );
		}
	}
	else if ( mlt_properties_get_data( properties, "image", NULL ) )
	{
		*format = mlt_properties_get_int( properties, "format" );
		*buffer = mlt_properties_get_data( properties, "image", NULL );
		*width = mlt_properties_get_int( properties, "width" );
		*height = mlt_properties_get_int( properties, "height" );
		if ( self->convert_image && *buffer && requested_format != mlt_image_none )
		{
			self->convert_image( self, buffer, format, requested_format );
			mlt_properties_set_int( properties, "format", *format );
		}
	}
	else if ( producer )
	{
		mlt_frame test_frame = NULL;
		mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &test_frame, 0 );
		if ( test_frame )
		{
			mlt_properties test_properties = MLT_FRAME_PROPERTIES( test_frame );
			mlt_properties_set( test_properties, "rescale.interp", mlt_properties_get( properties, "rescale.interp" ) );
			mlt_frame_get_image( test_frame, buffer, format, width, height, writable );
			mlt_properties_set_data( properties, "test_card_frame", test_frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
			mlt_properties_set_double( properties, "aspect_ratio", mlt_frame_get_aspect_ratio( test_frame ) );
// 			mlt_properties_set_data( properties, "image", *buffer, *width * *height * 2, NULL, NULL );
// 			mlt_properties_set_int( properties, "width", *width );
// 			mlt_properties_set_int( properties, "height", *height );
// 			mlt_properties_set_int( properties, "format", *format );
		}
		else
		{
			mlt_properties_set_data( properties, "test_card_producer", NULL, 0, NULL, NULL );
			mlt_frame_get_image( self, buffer, format, width, height, writable );
		}
	}
	else
	{
		register uint8_t *p;
		register uint8_t *q;
		int size = 0;

		*width = *width == 0 ? 720 : *width;
		*height = *height == 0 ? 576 : *height;
		size = *width * *height;

		mlt_properties_set_int( properties, "format", *format );
		mlt_properties_set_int( properties, "width", *width );
		mlt_properties_set_int( properties, "height", *height );
		mlt_properties_set_int( properties, "aspect_ratio", 0 );

		switch( *format )
		{
			case mlt_image_none:
				size = 0;
				*buffer = NULL;
				break;
			case mlt_image_rgb24:
				size *= 3;
				size += *width * 3;
				*buffer = mlt_pool_alloc( size );
				if ( *buffer )
					memset( *buffer, 255, size );
				break;
			case mlt_image_rgb24a:
			case mlt_image_opengl:
				size *= 4;
				size += *width * 4;
				*buffer = mlt_pool_alloc( size );
				if ( *buffer )
					memset( *buffer, 255, size );
				break;
			case mlt_image_yuv422:
				size *= 2;
				size += *width * 2;
				*buffer = mlt_pool_alloc( size );
				p = *buffer;
				q = p + size;
				while ( p != NULL && p != q )
				{
					*p ++ = 235;
					*p ++ = 128;
				}
				break;
			case mlt_image_yuv420p:
				size = size * 3 / 2;
				*buffer = mlt_pool_alloc( size );
				if ( *buffer )
					memset( *buffer, 255, size );
				break;
		}

		mlt_properties_set_data( properties, "image", *buffer, size, ( mlt_destructor )mlt_pool_release, NULL );
		mlt_properties_set_int( properties, "test_image", 1 );
	}

	return error;
}