From 97e801a4bf29374230eb4025997e7ddde0650ac2 Mon Sep 17 00:00:00 2001 From: lilo_booter Date: Mon, 3 Oct 2005 07:00:20 +0000 Subject: [PATCH] + Added producer_sdl_image as an alternative image and image sequence producer git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@838 d19143bc-622f-0410-bfdd-b5b2a6649095 --- src/modules/fezzik.dict | 14 +- src/modules/sdl/Makefile | 7 + src/modules/sdl/configure | 5 + src/modules/sdl/factory.c | 3 + src/modules/sdl/producer_sdl_image.c | 225 ++++++++++++++++++++++++++++++++++ 5 files changed, 247 insertions(+), 7 deletions(-) create mode 100644 src/modules/sdl/producer_sdl_image.c diff --git a/src/modules/fezzik.dict b/src/modules/fezzik.dict index 2d1ff7c..7e4b0a0 100644 --- a/src/modules/fezzik.dict +++ b/src/modules/fezzik.dict @@ -4,15 +4,15 @@ http://*=avformat *.inigo=inigo_file *.asf=avformat *.avi=mcdv,libdv,avformat -*.bmp=pixbuf +*.bmp=pixbuf,sdl_image *.dv=mcdv,libdv,avformat *.dif=mcdv,libdv -*.gif=pixbuf +*.gif=pixbuf,sdl_image *.graphics=westley *.jfx=westley *.jef=westley -*.jpg=pixbuf -*.jpeg=pixbuf +*.jpg=pixbuf,sdl_image +*.jpeg=pixbuf,sdl_image *.kino=westley *.mp3=avformat *.mov=mcdv,libdv,avformat @@ -20,11 +20,11 @@ http://*=avformat *.mpeg=mcmpeg,avformat *.mpl=pango *.ogg=vorbis -*.pgm=pgm,pixbuf -*.png=pixbuf +*.pgm=pgm,pixbuf,sdl_image +*.png=pixbuf,sdl_image *.story=westley *.svg=pixbuf -*.tga=pixbuf +*.tga=pixbuf,sdl_image *.txt=pango *.vob=mcmpeg,avformat *.wav=avformat diff --git a/src/modules/sdl/Makefile b/src/modules/sdl/Makefile index f9aac55..929c03f 100644 --- a/src/modules/sdl/Makefile +++ b/src/modules/sdl/Makefile @@ -1,5 +1,7 @@ include ../../../config.mak +include config.mak + TARGET = ../libmltsdl$(LIBSUF) OBJS = factory.o \ @@ -18,6 +20,11 @@ LDFLAGS +=`sdl-config --libs` LDFLAGS +=-L../../framework -lmlt +ifeq ($(WITH_SDL_IMAGE),1) +OBJS += producer_sdl_image.o +CFLAGS += -DWITH_SDL_IMAGE +LDFLAGS += -lSDL_image +endif SRCS := $(OBJS:.o=.c) diff --git a/src/modules/sdl/configure b/src/modules/sdl/configure index 8d2a204..253d181 100755 --- a/src/modules/sdl/configure +++ b/src/modules/sdl/configure @@ -8,9 +8,14 @@ then if [ "$disable_sdl" = "0" ] then + echo > config.mak + image=`sdl-config --prefix`/include/SDL/SDL_image.h echo "sdl libmltsdl$LIBSUF" >> ../consumers.dat echo "sdl_preview libmltsdl$LIBSUF" >> ../consumers.dat echo "sdl_still libmltsdl$LIBSUF" >> ../consumers.dat + [ -f "$image" ] && + echo "sdl_image libmltsdl$LIBSUF" >> ../producers.dat && + echo "WITH_SDL_IMAGE=1" >> config.mak else echo "- sdl development libs not found: disabling" touch ../disable-sdl diff --git a/src/modules/sdl/factory.c b/src/modules/sdl/factory.c index dd43f99..91d1b0a 100644 --- a/src/modules/sdl/factory.c +++ b/src/modules/sdl/factory.c @@ -21,9 +21,12 @@ #include #include "consumer_sdl.h" +#include "producer_sdl_image.h" void *mlt_create_producer( char *id, void *arg ) { + if ( !strcmp( id, "sdl_image" ) ) + return producer_sdl_image_init( arg ); return NULL; } diff --git a/src/modules/sdl/producer_sdl_image.c b/src/modules/sdl/producer_sdl_image.c new file mode 100644 index 0000000..d1c13f9 --- /dev/null +++ b/src/modules/sdl/producer_sdl_image.c @@ -0,0 +1,225 @@ +/* + * producer_sdl_image.c -- Image loader which wraps SDL_image + * Copyright (C) 2005 Visual Media FX + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "producer_sdl_image.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static int producer_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) +{ + mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); + SDL_Surface *surface = mlt_properties_get_data( properties, "surface", NULL ); + uint8_t *alpha; + + *width = surface->w; + *height = surface->h; + *format = mlt_image_yuv422; + *image = mlt_pool_alloc( *width * *height * 2 ); + alpha = mlt_pool_alloc( *width * *height ); + + switch( surface->format->BitsPerPixel ) + { + case 32: + mlt_convert_rgb24a_to_yuv422( surface->pixels, *width, *height, surface->pitch, *image, alpha ); + break; + case 24: + mlt_convert_rgb24_to_yuv422( surface->pixels, *width, *height, surface->pitch, *image ); + memset( alpha, 255, *width * *height ); + break; + default: + break; + } + + // Update the frame + mlt_properties_set_data( properties, "image", *image, *width * *height * 2, mlt_pool_release, NULL ); + mlt_properties_set_data( properties, "alpha", alpha, *width * *height, mlt_pool_release, NULL ); + mlt_properties_set_int( properties, "width", *width ); + mlt_properties_set_int( properties, "height", *height ); + + return 0; +} + +static int filter_files( const struct dirent *de ) +{ + return de->d_name[ 0 ] != '.'; +} + +static mlt_properties parse_file_names( char *resource ) +{ + mlt_properties properties = mlt_properties_new( ); + + if ( strstr( resource, "/.all." ) != NULL ) + { + char *dir_name = strdup( resource ); + char *extension = strrchr( resource, '.' ); + *( strstr( dir_name, "/.all." ) + 1 ) = '\0'; + char fullname[ 1024 ]; + strcpy( fullname, dir_name ); + struct dirent **de = NULL; + int n = scandir( fullname, &de, filter_files, alphasort ); + int i; + struct stat info; + + for (i = 0; i < n; i++ ) + { + snprintf( fullname, 1023, "%s%s", dir_name, de[i]->d_name ); + if ( strstr( fullname, extension ) && lstat( fullname, &info ) == 0 && + ( S_ISREG( info.st_mode ) || info.st_mode | S_IXUSR ) ) + { + char temp[ 20 ]; + sprintf( temp, "%d", i ); + mlt_properties_set( properties, temp, fullname ); + } + free( de[ i ] ); + } + + free( de ); + free( dir_name ); + } + else + { + mlt_properties_set( properties, "0", resource ); + } + + return properties; +} + +static SDL_Surface *load_image( mlt_producer producer ) +{ + mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); + char *resource = mlt_properties_get( properties, "resource" ); + char *last_resource = mlt_properties_get( properties, "_last_resource" ); + int image_idx = 0; + char *this_resource = NULL; + double ttl = mlt_properties_get_int( properties, "ttl" ); + mlt_position position = mlt_producer_position( producer ); + SDL_Surface *surface = mlt_properties_get_data( properties, "_surface", NULL ); + mlt_properties filenames = mlt_properties_get_data( properties, "_filenames", NULL ); + + if ( filenames == NULL ) + { + filenames = parse_file_names( resource ); + mlt_properties_set_data( properties, "_surface", surface, 0, ( mlt_destructor )SDL_FreeSurface, 0 ); + } + + image_idx = ( int )floor( ( double )position / ttl ) % mlt_properties_count( filenames ); + this_resource = mlt_properties_get_value( filenames, image_idx ); + + if ( last_resource == NULL || strcmp( last_resource, this_resource ) ) + { + surface = IMG_Load( this_resource ); + if ( surface != NULL ) + { + surface->refcount ++; + mlt_properties_set_data( properties, "_surface", surface, 0, ( mlt_destructor )SDL_FreeSurface, 0 ); + mlt_properties_set( properties, "_last_resource", this_resource ); + } + } + else if ( surface != NULL ) + { + surface->refcount ++; + } + + return surface; +} + +static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) +{ + // Generate a frame + *frame = mlt_frame_init( ); + + if ( *frame != NULL ) + { + // Create the surface for the current image + SDL_Surface *surface = load_image( producer ); + + if ( surface != 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 ); + + // 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_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_props, "aspect_ratio" ) ); + mlt_properties_set_data( properties, "surface", surface, 0, ( mlt_destructor )SDL_FreeSurface, NULL ); + mlt_properties_set_int( properties, "real_width", surface->w ); + mlt_properties_set_int( properties, "real_height", surface->h ); + + // 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; +} + +static void producer_close( mlt_producer producer ) +{ + producer->close = NULL; + mlt_producer_close( producer ); + free( producer ); +} + +mlt_producer producer_sdl_image_init( char *file ) +{ + mlt_producer producer = calloc( 1, sizeof( struct mlt_producer_s ) ); + if ( producer != NULL && mlt_producer_init( producer, NULL ) == 0 ) + { + // Get the properties interface + mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); + + // Callback registration + producer->get_frame = producer_get_frame; + producer->close = ( mlt_destructor )producer_close; + + // Set the default properties + mlt_properties_set( properties, "resource", file ); + mlt_properties_set( properties, "_resource", "" ); + mlt_properties_set_double( properties, "aspect_ratio", 1 ); + mlt_properties_set_int( properties, "ttl", 25 ); + mlt_properties_set_int( properties, "progressive", 1 ); + + return producer; + } + free( producer ); + return NULL; +} + + -- 1.7.4.4