Skip to content

Commit

Permalink
Presets!
Browse files Browse the repository at this point in the history
Put property setters in a file and apply them to a service using
properties=filename. Alternatively, apply a supplied preset using
properties=preset. For example, melt ... -consumer avformat:my.vob
properties=DVD.
  • Loading branch information
ddennedy committed May 13, 2011
1 parent e3c3b7a commit 46fc89b
Show file tree
Hide file tree
Showing 16 changed files with 307 additions and 41 deletions.
6 changes: 2 additions & 4 deletions Makefile
Expand Up @@ -35,10 +35,8 @@ install:
list='$(SUBDIRS)'; \
for subdir in $$list; do \
$(MAKE) DESTDIR=$(DESTDIR) -C $$subdir $@ || exit 1; \
done; \
# if test -z "$(DESTDIR)"; then \
# /sbin/ldconfig -n "$(DESTDIR)$(libdir)" 2> /dev/null || true; \
# fi
done
cp -R presets "$(DESTDIR)$(prefix)/share/mlt"

uninstall:
rm -f "$(DESTDIR)$(bindir)"/mlt-config
Expand Down
15 changes: 15 additions & 0 deletions presets/consumer/avformat/dv_ntsc/DVD
@@ -0,0 +1,15 @@
f=dvd
vcodec=mpeg2video
acodec=ac3
b=6000k
maxrate=9000k
minrate=0
bufsize=1835008
packetsize=2048
muxrate=10080000
ab=192k
ar=48000
g=18
me_range=63
trellis=1

15 changes: 15 additions & 0 deletions presets/consumer/avformat/dv_ntsc_wide/DVD
@@ -0,0 +1,15 @@
f=dvd
vcodec=mpeg2video
acodec=ac3
b=6000k
maxrate=9000k
minrate=0
bufsize=1835008
packetsize=2048
muxrate=10080000
ab=192k
ar=48000
g=18
me_range=63
trellis=1

15 changes: 15 additions & 0 deletions presets/consumer/avformat/dv_pal/DVD
@@ -0,0 +1,15 @@
f=dvd
vcodec=mpeg2video
acodec=ac3
b=5000k
maxrate=8000k
minrate=0
bufsize=1835008
packetsize=2048
muxrate=10080000
ab=192k
ar=48000
g=15
me_range=63
trellis=1

15 changes: 15 additions & 0 deletions presets/consumer/avformat/dv_pal_wide/DVD
@@ -0,0 +1,15 @@
f=dvd
vcodec=mpeg2video
acodec=ac3
b=5000k
maxrate=8000k
minrate=0
bufsize=1835008
packetsize=2048
muxrate=10080000
ab=192k
ar=48000
g=15
me_range=63
trellis=1

1 change: 1 addition & 0 deletions setenv
Expand Up @@ -4,6 +4,7 @@
export MLT_REPOSITORY=`pwd`/src/modules
export MLT_DATA=`pwd`/src/modules
export MLT_PROFILES_PATH=`pwd`/profiles
export MLT_PRESETS_PATH=`pwd`/presets

export LD_LIBRARY_PATH=\
`pwd`/src/framework:\
Expand Down
158 changes: 121 additions & 37 deletions src/framework/mlt_properties.c
Expand Up @@ -26,6 +26,7 @@
#include "mlt_property.h"
#include "mlt_deque.h"
#include "mlt_log.h"
#include "mlt_factory.h"

#include <stdio.h>
#include <stdlib.h>
Expand All @@ -35,7 +36,8 @@
#include <pthread.h>
#include <sys/types.h>
#include <dirent.h>

#include <sys/stat.h>
#include <errno.h>

/** \brief private implementation of the property list */

Expand Down Expand Up @@ -116,12 +118,54 @@ mlt_properties mlt_properties_new( )
return self;
}

static int load_properties( mlt_properties self, const char *filename )
{
// Open the file
FILE *file = fopen( filename, "r" );

// Load contents of file
if ( file != NULL )
{
// Temp string
char temp[ 1024 ];
char last[ 1024 ] = "";

// Read each string from the file
while( fgets( temp, 1024, file ) )
{
// Chomp the string
temp[ strlen( temp ) - 1 ] = '\0';

// Check if the line starts with a .
if ( temp[ 0 ] == '.' )
{
char temp2[ 1024 ];
sprintf( temp2, "%s%s", last, temp );
strcpy( temp, temp2 );
}
else if ( strchr( temp, '=' ) )
{
strcpy( last, temp );
*( strchr( last, '=' ) ) = '\0';
}

// Parse and set the property
if ( strcmp( temp, "" ) && temp[ 0 ] != '#' )
mlt_properties_parse( self, temp );
}

// Close the file
fclose( file );
}
return file? 0 : errno;
}

/** Create a properties object by reading a .properties text file.
*
* Free the properties object with mlt_properties_close().
* \deprecated Please start using mlt_properties_parse_yaml().
* \public \memberof mlt_properties_s
* \param filename a string contain the absolute file name
* \param filename the absolute file name
* \return a new properties object
*/

Expand All @@ -131,48 +175,81 @@ mlt_properties mlt_properties_load( const char *filename )
mlt_properties self = mlt_properties_new( );

if ( self != NULL )
{
// Open the file
FILE *file = fopen( filename, "r" );
load_properties( self, filename );

// Load contents of file
if ( file != NULL )
{
// Temp string
char temp[ 1024 ];
char last[ 1024 ] = "";
// Return the pointer
return self;
}

// Read each string from the file
while( fgets( temp, 1024, file ) )
{
// Chomp the string
temp[ strlen( temp ) - 1 ] = '\0';
/** Set properties from a preset.
*
* Presets are typically installed to $prefix/share/mlt/presets/{type}/{service}/[{profile}/]{name}.
* For example, "/usr/share/mlt/presets/consumer/avformat/dv_ntsc_wide/DVD"
* could be an encoding preset for a widescreen NTSC DVD Video.
* Do not specify the type and service in the preset name parameter; these are
* inferred automatically from the service to which you are applying the preset.
* Using the example above and assuming you are calling this function on the
* avformat consumer, the name passed to the function should simply be DVD.
* Note that the profile portion of the path is optional, but a profile-specific
* preset with the same name as a more generic one is given a higher priority.
* \todo Look in a user-specific location - somewhere in the home directory.
*
* \public \memberof mlt_properties_s
* \param self a properties list
* \param name the name of a preset in a well-known location or the explicit path
* \return true if error
*/

// Check if the line starts with a .
if ( temp[ 0 ] == '.' )
{
char temp2[ 1024 ];
sprintf( temp2, "%s%s", last, temp );
strcpy( temp, temp2 );
}
else if ( strchr( temp, '=' ) )
{
strcpy( last, temp );
*( strchr( last, '=' ) ) = '\0';
}
int mlt_properties_preset( mlt_properties self, const char *name )
{
struct stat stat_buff;

// Parse and set the property
if ( strcmp( temp, "" ) && temp[ 0 ] != '#' )
mlt_properties_parse( self, temp );
}
// validate input
if ( !( self && name && strlen( name ) ) )
return 1;

// Close the file
fclose( file );
// See if name is an explicit file
if ( ! stat( name, &stat_buff ) )
{
return load_properties( self, name );
}
else
{
// Look for profile-specific preset before a generic one.
char *data = getenv( "MLT_PRESETS_PATH" );
const char *type = mlt_properties_get( self, "mlt_type" );
const char *service = mlt_properties_get( self, "mlt_service" );
const char *profile = mlt_environment( "MLT_PROFILE" );
int error = 0;

if ( data )
{
data = strdup( data );
}
else
{
data = malloc( strlen( mlt_environment( "MLT_DATA" ) ) + 9 );
strcpy( data, mlt_environment( "MLT_DATA" ) );
strcat( data, "/presets" );
}
if ( data && type && service )
{
char *path = malloc( 5 + strlen(name) + strlen(data) + strlen(type) + strlen(service) + ( profile? strlen(profile) : 0 ) );
sprintf( path, "%s/%s/%s/%s/%s", data, type, service, profile, name );
if ( load_properties( self, path ) )
{
sprintf( path, "%s/%s/%s/%s", data, type, service, name );
error = load_properties( self, path );
}
free( path );
}
else
{
error = 1;
}
free( data );
return error;
}

// Return the pointer
return self;
}

/** Generate a hash key.
Expand Down Expand Up @@ -491,6 +568,11 @@ int mlt_properties_pass_list( mlt_properties self, mlt_properties that, const ch


/** Set a property to a string.
*
* The property name "properties" is reserved to load the preset in \p value.
* When the value begins with '@' then it is interpreted as a very simple math
* expression containing only the +, -, *, and / operators.
* The event "property-changed" is fired after the property has been set.
*
* This makes a copy of the string value you supply.
* \public \memberof mlt_properties_s
Expand Down Expand Up @@ -521,6 +603,8 @@ int mlt_properties_set( mlt_properties self, const char *name, const char *value
{
error = mlt_property_set_string( property, value );
mlt_properties_do_mirror( self, name );
if ( !strcmp( name, "properties" ) )
mlt_properties_preset( self, value );
}
else if ( value[ 0 ] == '@' )
{
Expand Down
1 change: 1 addition & 0 deletions src/framework/mlt_properties.h
Expand Up @@ -48,6 +48,7 @@ struct mlt_properties_s
extern int mlt_properties_init( mlt_properties, void *child );
extern mlt_properties mlt_properties_new( );
extern mlt_properties mlt_properties_load( const char *file );
extern int mlt_properties_preset( mlt_properties self, const char *name );
extern int mlt_properties_inc_ref( mlt_properties self );
extern int mlt_properties_dec_ref( mlt_properties self );
extern int mlt_properties_ref_count( mlt_properties self );
Expand Down
71 changes: 71 additions & 0 deletions src/framework/mlt_repository.c
Expand Up @@ -26,11 +26,14 @@
#include "mlt_properties.h"
#include "mlt_tokeniser.h"
#include "mlt_log.h"
#include "mlt_factory.h"

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <string.h>
#include <limits.h>
#include <dirent.h>

/** \brief Repository class
*
Expand Down Expand Up @@ -426,3 +429,71 @@ mlt_properties mlt_repository_languages( mlt_repository self )
mlt_properties_set_data( &self->parent, "languages", languages, 0, ( mlt_destructor )mlt_properties_close, NULL );
return languages;
}

static void list_presets( mlt_properties properties, const char *path, const char *dirname )
{
DIR *dir = opendir( dirname );

if ( dir )
{
struct dirent *de = readdir( dir );
char fullname[ PATH_MAX ];

while ( de != NULL )
{
if ( de->d_name[0] != '.' && de->d_name[strlen( de->d_name ) - 1] != '~' )
{
snprintf( fullname, sizeof(fullname), "%s/%s", dirname, de->d_name );
if ( de->d_type & DT_DIR )
{
// recurse into subdirectories
char sub[ PATH_MAX ];
if ( path )
snprintf( sub, sizeof(sub), "%s/%s", path, de->d_name );
else
strncpy( sub, de->d_name, sizeof(sub) );
list_presets( properties, sub, fullname );
}
else
{
// load the preset
mlt_properties preset = mlt_properties_load( fullname );
if ( preset && mlt_properties_count( preset ) )
{
snprintf( fullname, 1024, "%s/%s", path, de->d_name );
mlt_properties_set_data( properties, fullname, preset, 0, (mlt_destructor) mlt_properties_close, NULL );
}
}
}
de = readdir( dir );
}
closedir( dir );
}
}

/** Get the list of presets.
*
* \public \memberof mlt_repository_s
* \return a properties list of all the presets
*/

mlt_properties mlt_repository_presets( )
{
mlt_properties result = mlt_properties_new();
char *path = getenv( "MLT_PRESETS_PATH" );

if ( path )
{
path = strdup( path );
}
else
{
path = malloc( strlen( mlt_environment( "MLT_DATA" ) ) + 9 );
strcpy( path, mlt_environment( "MLT_DATA" ) );
strcat( path, "/presets" );
}
list_presets( result, NULL, path );
free( path );

return result;
}
1 change: 1 addition & 0 deletions src/framework/mlt_repository.h
Expand Up @@ -66,6 +66,7 @@ extern mlt_properties mlt_repository_transitions( mlt_repository self );
extern void mlt_repository_register_metadata( mlt_repository self, mlt_service_type type, const char *service, mlt_metadata_callback, void *callback_data );
extern mlt_properties mlt_repository_metadata( mlt_repository self, mlt_service_type type, const char *service );
extern mlt_properties mlt_repository_languages( mlt_repository self );
extern mlt_properties mlt_repository_presets( );

#endif

0 comments on commit 46fc89b

Please sign in to comment.