From: lilo_booter Date: Wed, 7 Jan 2004 14:58:21 +0000 (+0000) Subject: miracle part 1 X-Git-Url: https://git.sesse.net/?p=mlt;a=commitdiff_plain;h=9390e8b584f3f717f0a326893c0e37cf187a0a51 miracle part 1 git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@39 d19143bc-622f-0410-bfdd-b5b2a6649095 --- diff --git a/Makefile b/Makefile index ef218098..fe7ee8e4 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -SUBDIRS = src/framework src/modules src/inigo src/valerie # src/miracle src/humperdink +SUBDIRS = src/framework src/modules src/inigo src/valerie src/miracle src/humperdink all clean dist-clean depend install: list='$(SUBDIRS)'; \ diff --git a/docs/services.txt b/docs/services.txt index d56ef2c6..8118894f 100644 --- a/docs/services.txt +++ b/docs/services.txt @@ -31,7 +31,8 @@ Producers Read Only Properties - end_of_clip - holds 1 when input is exhausted + string resource - file or "v4l" + int end_of_clip - holds 1 when input is exhausted Dependencies @@ -39,7 +40,7 @@ Producers Known Bugs - in/out point setting is broken. + in point setting is broken. Implementation does not allow fast random access. @@ -55,12 +56,12 @@ Producers Initialisation Properties - string file - file location timecode in - in point timecode out - out point Read Only Properties + string resource - file location double fps - output frames per second double aspect_ratio - aspect ratio of video @@ -70,7 +71,7 @@ Producers Known Bugs - 'file' is not populated on properties? + None. mcdv @@ -84,12 +85,12 @@ Producers Initialisation Properties - string file - file location timecode in - in point timecode out - out point Read Only Properties + string resource - file location double fps - output frames per second double aspect_ratio - aspect ratio of video @@ -99,7 +100,7 @@ Producers Known Bugs - 'file' is not populated on properties? + Can be problematic with source NTSC DV files? mcmpeg @@ -113,12 +114,12 @@ Producers Initialisation Properties - string file - file location timecode in - in point timecode out - out point Read Only Properties + string resource - file location double fps - output frames per second double aspect_ratio - aspect ratio of video @@ -128,7 +129,7 @@ Producers Known Bugs - 'file' is not populated on properties? + None. pango pixbuf diff --git a/mlt/Makefile b/mlt/Makefile index ef218098..fe7ee8e4 100644 --- a/mlt/Makefile +++ b/mlt/Makefile @@ -1,4 +1,4 @@ -SUBDIRS = src/framework src/modules src/inigo src/valerie # src/miracle src/humperdink +SUBDIRS = src/framework src/modules src/inigo src/valerie src/miracle src/humperdink all clean dist-clean depend install: list='$(SUBDIRS)'; \ diff --git a/mlt/docs/services.txt b/mlt/docs/services.txt index d56ef2c6..8118894f 100644 --- a/mlt/docs/services.txt +++ b/mlt/docs/services.txt @@ -31,7 +31,8 @@ Producers Read Only Properties - end_of_clip - holds 1 when input is exhausted + string resource - file or "v4l" + int end_of_clip - holds 1 when input is exhausted Dependencies @@ -39,7 +40,7 @@ Producers Known Bugs - in/out point setting is broken. + in point setting is broken. Implementation does not allow fast random access. @@ -55,12 +56,12 @@ Producers Initialisation Properties - string file - file location timecode in - in point timecode out - out point Read Only Properties + string resource - file location double fps - output frames per second double aspect_ratio - aspect ratio of video @@ -70,7 +71,7 @@ Producers Known Bugs - 'file' is not populated on properties? + None. mcdv @@ -84,12 +85,12 @@ Producers Initialisation Properties - string file - file location timecode in - in point timecode out - out point Read Only Properties + string resource - file location double fps - output frames per second double aspect_ratio - aspect ratio of video @@ -99,7 +100,7 @@ Producers Known Bugs - 'file' is not populated on properties? + Can be problematic with source NTSC DV files? mcmpeg @@ -113,12 +114,12 @@ Producers Initialisation Properties - string file - file location timecode in - in point timecode out - out point Read Only Properties + string resource - file location double fps - output frames per second double aspect_ratio - aspect ratio of video @@ -128,7 +129,7 @@ Producers Known Bugs - 'file' is not populated on properties? + None. pango pixbuf diff --git a/mlt/setenv b/mlt/setenv index 01363eb6..9d665ed0 100644 --- a/mlt/setenv +++ b/mlt/setenv @@ -1,10 +1,17 @@ + +# Environment variable settings to allow execution without install + export MLT_REPOSITORY=`pwd`/src/modules export LD_LIBRARY_PATH=`pwd`/src/framework:\ +`pwd`/src/valerie:\ `pwd`/src/modules/bluefish:\ `pwd`/../bluefish/lib:\ `pwd`/../mpeg_sdk_demo/bin:\ `pwd`/../dv_sdk -export PATH=$PATH:`pwd`/src/inigo:`pwd`/src/miracle +export PATH=$PATH:\ +`pwd`/src/inigo:\ +`pwd`/src/humperdink:\ +`pwd`/src/miracle diff --git a/mlt/src/framework/Makefile b/mlt/src/framework/Makefile index d01ee347..6d804016 100644 --- a/mlt/src/framework/Makefile +++ b/mlt/src/framework/Makefile @@ -1,20 +1,20 @@ -FRAMEWORK_OBJS = mlt_frame.o \ - mlt_property.o \ - mlt_properties.o \ - mlt_service.o \ - mlt_producer.o \ - mlt_multitrack.o \ - mlt_playlist.o \ - mlt_consumer.o \ - mlt_filter.o \ - mlt_transition.o \ - mlt_field.o \ - mlt_tractor.o \ - mlt_factory.o \ - mlt_repository.o - -OBJS = $(FRAMEWORK_OBJS) +TARGET = libmlt.so + +OBJS = mlt_frame.o \ + mlt_property.o \ + mlt_properties.o \ + mlt_service.o \ + mlt_producer.o \ + mlt_multitrack.o \ + mlt_playlist.o \ + mlt_consumer.o \ + mlt_filter.o \ + mlt_transition.o \ + mlt_field.o \ + mlt_tractor.o \ + mlt_factory.o \ + mlt_repository.o SRCS := $(OBJS:.o=.c) @@ -22,9 +22,9 @@ CFLAGS = -g -Wall -D_FILE_OFFSET_BITS=64 -pthread LDFLAGS = -lm -ldl -lpthread -all: libmlt.so +all: $(TARGET) -libmlt.so: $(OBJS) +$(TARGET): $(OBJS) $(CC) -shared -o $@ $(OBJS) $(LDFLAGS) depend: $(SRCS) @@ -34,7 +34,7 @@ dist-clean: clean rm -f .depend clean: - rm -f $(FRAMEWORK_OBJS) libmlt.so + rm -f $(OBJS) $(TARGET) ifneq ($(wildcard .depend),) include .depend diff --git a/mlt/src/framework/mlt_frame.c b/mlt/src/framework/mlt_frame.c index 16d51f89..dd179837 100644 --- a/mlt/src/framework/mlt_frame.c +++ b/mlt/src/framework/mlt_frame.c @@ -659,7 +659,7 @@ uint8_t *mlt_frame_rescale_yuv422( mlt_frame this, int owidth, int oheight ) if ( abs( dx ) < in_x_range && abs( dy ) < in_y_range ) { // We're in the input range for this row. - in_ptr = in_line + ( dx >> 1 ) * 4 - 2 * ( x & 1 ); + in_ptr = in_line + ( dx >> 1 ) * 4 + 2 * ( x & 1 ); *out_ptr ++ = *in_ptr ++; *out_ptr ++ = *in_ptr ++; } diff --git a/mlt/src/framework/mlt_playlist.c b/mlt/src/framework/mlt_playlist.c index 7a2ad658..d11f9562 100644 --- a/mlt/src/framework/mlt_playlist.c +++ b/mlt/src/framework/mlt_playlist.c @@ -105,31 +105,52 @@ mlt_properties mlt_playlist_properties( mlt_playlist this ) return mlt_producer_properties( &this->parent ); } -/** Append to the virtual playlist. -*/ - -static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer, mlt_timecode in, mlt_timecode out ) +static int mlt_playlist_virtual_refresh( mlt_playlist this ) { + int i = 0; + // Get the fps of the first producer double fps = mlt_properties_get_double( mlt_playlist_properties( this ), "first_fps" ); + mlt_timecode playtime = 0; - mlt_timecode playtime = mlt_producer_get_playtime( mlt_playlist_producer( this ) ) + out - in; - - // If fps is 0 - if ( fps == 0 ) - { - // Inherit it from the producer - fps = mlt_producer_get_fps( producer ); - } - else if ( fps != mlt_properties_get_double( mlt_producer_properties( producer ), "fps" ) ) + for ( i = 0; i < this->count; i ++ ) { - // Generate a warning for now - the following attempt to fix may fail - fprintf( stderr, "Warning: fps mismatch on playlist producer %d\n", this->count ); + // Get the producer + mlt_producer producer = this->list[ i ]->producer; + + // If fps is 0 + if ( fps == 0 ) + { + // Inherit it from the producer + fps = mlt_producer_get_fps( producer ); + } + else if ( fps != mlt_properties_get_double( mlt_producer_properties( producer ), "fps" ) ) + { + // Generate a warning for now - the following attempt to fix may fail + fprintf( stderr, "Warning: fps mismatch on playlist producer %d\n", this->count ); + + // It should be safe to impose fps on an image producer, but not necessarily safe for video + mlt_properties_set_double( mlt_producer_properties( producer ), "fps", fps ); + } - // It should be safe to impose fps on an image producer, but not necessarily safe for video - mlt_properties_set_double( mlt_producer_properties( producer ), "fps", fps ); + // Update the playtime for this clip + playtime += this->list[ i ]->playtime; } + // Refresh all properties + mlt_properties_set_double( mlt_playlist_properties( this ), "first_fps", fps ); + mlt_properties_set_double( mlt_playlist_properties( this ), "fps", fps ); + mlt_properties_set_timecode( mlt_playlist_properties( this ), "length", playtime ); + mlt_properties_set_timecode( mlt_playlist_properties( this ), "out", playtime ); + + return 0; +} + +/** Append to the virtual playlist. +*/ + +static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer, mlt_timecode in, mlt_timecode out ) +{ // Check that we have room if ( this->count >= this->size ) { @@ -147,12 +168,7 @@ static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer this->count ++; - mlt_properties_set_double( mlt_playlist_properties( this ), "first_fps", fps ); - mlt_properties_set_double( mlt_playlist_properties( this ), "fps", fps ); - mlt_properties_set_timecode( mlt_playlist_properties( this ), "length", playtime ); - mlt_properties_set_timecode( mlt_playlist_properties( this ), "out", playtime ); - - return 0; + return mlt_playlist_virtual_refresh( this ); } /** Seek in the virtual playlist. @@ -221,14 +237,17 @@ static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this ) // Seek in real producer to relative position if ( i < this->count ) { - fprintf( stderr, "END OF CLIP %d AT %e\n", i, position ); + // Update the playtime for the changed clip (hmmm) this->list[ i ]->playtime = position - this->list[ i ]->in; + + // Refresh the playlist + mlt_playlist_virtual_refresh( this ); } return producer; } -static int mlt_playlist_current_clip( mlt_playlist this ) +int mlt_playlist_current_clip( mlt_playlist this ) { // Map playlist position to real producer in virtual playlist mlt_timecode position = mlt_producer_position( &this->parent ); @@ -253,6 +272,15 @@ static int mlt_playlist_current_clip( mlt_playlist this ) return i; } +mlt_producer mlt_playlist_current( mlt_playlist this ) +{ + int i = mlt_playlist_current_clip( this ); + if ( i < this->count ) + return this->list[ i ]->producer; + else + return &this->blank; +} + /** Get the timecode which corresponds to the start of the next clip. */ @@ -291,6 +319,40 @@ mlt_timecode mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index return position; } +int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info, int index ) +{ + int error = index < 0 || index >= this->count; + if ( !error ) + { + mlt_producer producer = this->list[ index ]->producer; + mlt_properties properties = mlt_producer_properties( producer ); + info->resource = mlt_properties_get( properties, "resource" ); + info->in = this->list[ index ]->in; + info->out = this->list[ index ]->in + this->list[ index ]->playtime; + info->playtime = this->list[ index ]->playtime; + info->length = mlt_producer_get_length( producer ); + info->fps = mlt_producer_get_fps( producer ); + } + return error; +} + +/** Get number of clips in the playlist. +*/ + +int mlt_playlist_count( mlt_playlist this ) +{ + return this->count; +} + +/** Clear the playlist. +*/ + +int mlt_playlist_clear( mlt_playlist this ) +{ + this->count = 0; + return mlt_playlist_virtual_refresh( this ); +} + /** Append a producer to the playlist. */ @@ -300,6 +362,18 @@ int mlt_playlist_append( mlt_playlist this, mlt_producer producer ) return mlt_playlist_virtual_append( this, producer, 0, mlt_producer_get_playtime( producer ) ); } +/** Append a producer to the playlist with in/out points. +*/ + +int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, double in, double out ) +{ + // Append to virtual list + if ( in != -1 && out != -1 ) + return mlt_playlist_virtual_append( this, producer, in, out - in ); + else + return mlt_playlist_virtual_append( this, producer, 0, mlt_producer_get_playtime( producer ) ); +} + /** Append a blank to the playlist of a given length. */ @@ -328,6 +402,15 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i if ( mlt_properties_get_int( properties, "end_of_clip" ) ) mlt_playlist_virtual_set_out( this ); + // Check for notifier and call with appropriate argument + mlt_properties playlist_properties = mlt_producer_properties( producer ); + void ( *notifier )( void * ) = mlt_properties_get_data( playlist_properties, "notifier", NULL ); + if ( notifier != NULL ) + { + void *argument = mlt_properties_get_data( playlist_properties, "notifier_arg", NULL ); + notifier( argument ); + } + // Update timecode on the frame we're creating mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) ); diff --git a/mlt/src/framework/mlt_playlist.h b/mlt/src/framework/mlt_playlist.h index c6013860..3e30ba6b 100644 --- a/mlt/src/framework/mlt_playlist.h +++ b/mlt/src/framework/mlt_playlist.h @@ -23,6 +23,20 @@ #include "mlt_producer.h" +/** Structur for returning clip information. +*/ + +typedef struct +{ + char *resource; + double in; + double out; + double playtime; + double length; + float fps; +} +mlt_playlist_clip_info; + /** Public final methods */ @@ -30,9 +44,15 @@ extern mlt_playlist mlt_playlist_init( ); extern mlt_producer mlt_playlist_producer( mlt_playlist this ); extern mlt_service mlt_playlist_service( mlt_playlist this ); extern mlt_properties mlt_playlist_properties( mlt_playlist this ); +extern int mlt_playlist_count( mlt_playlist this ); +extern int mlt_playlist_clear( mlt_playlist this ); extern int mlt_playlist_append( mlt_playlist this, mlt_producer producer ); +extern int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, double in, double out ); extern int mlt_playlist_blank( mlt_playlist this, mlt_timecode length ); extern mlt_timecode mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index ); +extern int mlt_playlist_current_clip( mlt_playlist this ); +extern mlt_producer mlt_playlist_current( mlt_playlist this ); +extern int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info, int index ); extern void mlt_playlist_close( mlt_playlist this ); #endif diff --git a/mlt/src/framework/mlt_producer.c b/mlt/src/framework/mlt_producer.c index 87c2f089..751e19a9 100644 --- a/mlt/src/framework/mlt_producer.c +++ b/mlt/src/framework/mlt_producer.c @@ -265,6 +265,10 @@ static int producer_get_frame( mlt_service service, mlt_frame_ptr frame, int ind { // Get the frame from the implementation result = this->get_frame( this, frame, index ); + + mlt_properties frame_properties = mlt_frame_properties( *frame ); + double speed = mlt_producer_get_speed( this ); + mlt_properties_set_double( frame_properties, "speed", speed ); } else { diff --git a/mlt/src/humperdink/Makefile b/mlt/src/humperdink/Makefile new file mode 100644 index 00000000..53f2f96f --- /dev/null +++ b/mlt/src/humperdink/Makefile @@ -0,0 +1,29 @@ +TARGET = humperdink + +OBJS = client.o \ + io.o \ + remote.o + +CFLAGS = -I .. -Wall -g -D_FILE_OFFSET_BITS=64 -pthread -rdynamic + +LDFLAGS = -L ../valerie -lvalerie + +SRCS := $(OBJS:.o=.c) + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CC) -o $@ $(OBJS) $(LDFLAGS) + +depend: $(SRCS) + $(CC) -MM $(CFLAGS) $^ 1>.depend + +dist-clean: clean + rm -f .depend + +clean: + rm -f $(OBJS) $(TARGET) + +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/mlt/src/humperdink/client.c b/mlt/src/humperdink/client.c new file mode 100644 index 00000000..1f0ff3d7 --- /dev/null +++ b/mlt/src/humperdink/client.c @@ -0,0 +1,1026 @@ +/* + * client.c -- dv1394d client demo + * Copyright (C) 2002-2003 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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. + */ + +/* System header files */ +#include +#include +#include + +/* Application header files */ +#include "client.h" +#include "io.h" + +/** Clip navigation enumeration. +*/ + +typedef enum +{ + absolute, + relative +} +dv_demo_whence; + +/** Function prototype for menu handling. +*/ + +typedef valerie_error_code (*demo_function)( dv_demo ); + +/** The menu structure. +*/ + +typedef struct +{ + char *description; + struct menu_item + { + char *option; + demo_function function; + } + array[ 50 ]; +} +*dv_demo_menu, dv_demo_menu_t; + +/** Forward reference to menu runner. +*/ + +extern valerie_error_code dv_demo_run_menu( dv_demo, dv_demo_menu ); + +/** Foward references. +*/ + +extern valerie_error_code dv_demo_list_nodes( dv_demo ); +extern valerie_error_code dv_demo_add_unit( dv_demo ); +extern valerie_error_code dv_demo_select_unit( dv_demo ); +extern valerie_error_code dv_demo_execute( dv_demo ); +extern valerie_error_code dv_demo_load( dv_demo ); +extern valerie_error_code dv_demo_transport( dv_demo ); +static void *dv_demo_status_thread( void * ); + +/** Connected menu definition. +*/ + +dv_demo_menu_t connected_menu = +{ + "Connected Menu", + { + { "Add Unit", dv_demo_add_unit }, + { "Select Unit", dv_demo_select_unit }, + { "Command Shell", dv_demo_execute }, + { NULL, NULL } + } +}; + +/** Initialise the demo structure. +*/ + +dv_demo dv_demo_init( valerie_parser parser ) +{ + dv_demo this = malloc( sizeof( dv_demo_t ) ); + if ( this != NULL ) + { + int index = 0; + memset( this, 0, sizeof( dv_demo_t ) ); + strcpy( this->last_directory, "/" ); + for ( index = 0; index < 4; index ++ ) + { + this->queues[ index ].unit = index; + this->queues[ index ].position = -1; + } + this->parser = parser; + } + return this; +} + +/** Display a status record. +*/ + +void dv_demo_show_status( dv_demo demo, valerie_status status ) +{ + if ( status->unit == demo->selected_unit && demo->showing ) + { + char temp[ 1024 ] = ""; + + sprintf( temp, "U%d ", demo->selected_unit ); + + switch( status->status ) + { + case unit_offline: + strcat( temp, "offline " ); + break; + case unit_undefined: + strcat( temp, "undefined " ); + break; + case unit_not_loaded: + strcat( temp, "unloaded " ); + break; + case unit_stopped: + strcat( temp, "stopped " ); + break; + case unit_playing: + strcat( temp, "playing " ); + break; + case unit_paused: + strcat( temp, "paused " ); + break; + case unit_disconnected: + strcat( temp, "disconnect" ); + break; + default: + strcat( temp, "unknown " ); + break; + } + + sprintf( temp + strlen( temp ), " %9.2f %9.2f %9.2f ", status->in, status->position, status->out ); + strcat( temp, status->clip ); + + printf( "%-80.80s\r", temp ); + fflush( stdout ); + } +} + +/** Determine action to carry out as dictated by the client unit queue. +*/ + +void dv_demo_queue_action( dv_demo demo, valerie_status status ) +{ + dv_demo_queue queue = &demo->queues[ status->unit ]; + + /* SPECIAL CASE STATUS NOTIFICATIONS TO IGNORE */ + + /* When we've issued a LOAD on the previous notification, then ignore this one. */ + if ( queue->ignore ) + { + queue->ignore --; + return; + } + + if ( queue->mode && status->status != unit_offline && queue->head != queue->tail ) + { + if ( ( status->position >= status->out && status->speed > 0 ) || status->status == unit_not_loaded ) + { + queue->position = ( queue->position + 1 ) % 50; + if ( queue->position == queue->tail ) + queue->position = queue->head; + valerie_unit_load( demo->dv_status, status->unit, queue->list[ queue->position ] ); + if ( status->status == unit_not_loaded ) + valerie_unit_play( demo->dv, queue->unit ); + queue->ignore = 1; + } + else if ( ( status->position <= status->in && status->speed < 0 ) || status->status == unit_not_loaded ) + { + if ( queue->position == -1 ) + queue->position = queue->head; + valerie_unit_load( demo->dv_status, status->unit, queue->list[ queue->position ] ); + if ( status->status == unit_not_loaded ) + valerie_unit_play( demo->dv, queue->unit ); + queue->position = ( queue->position - 1 ) % 50; + queue->ignore = 1; + } + } +} + +/** Status thread. +*/ + +static void *dv_demo_status_thread( void *arg ) +{ + dv_demo demo = arg; + valerie_status_t status; + valerie_notifier notifier = valerie_get_notifier( demo->dv_status ); + + while ( !demo->terminated ) + { + if ( valerie_notifier_wait( notifier, &status ) != -1 ) + { + dv_demo_queue_action( demo, &status ); + dv_demo_show_status( demo, &status ); + if ( status.status == unit_disconnected ) + demo->disconnected = 1; + } + } + + return NULL; +} + +/** Turn on/off status display. +*/ + +void dv_demo_change_status( dv_demo demo, int flag ) +{ + if ( demo->disconnected && flag ) + { + valerie_error_code error = valerie_connect( demo->dv ); + if ( error == valerie_ok ) + demo->disconnected = 0; + else + beep(); + } + + if ( flag ) + { + valerie_status_t status; + valerie_notifier notifier = valerie_get_notifier( demo->dv ); + valerie_notifier_get( notifier, &status, demo->selected_unit ); + demo->showing = 1; + dv_demo_show_status( demo, &status ); + } + else + { + demo->showing = 0; + printf( "%-80.80s\r", " " ); + fflush( stdout ); + } +} + +/** Add a unit. +*/ + +valerie_error_code dv_demo_add_unit( dv_demo demo ) +{ + valerie_error_code error = valerie_ok; + valerie_nodes nodes = valerie_nodes_init( demo->dv ); + valerie_units units = valerie_units_init( demo->dv ); + + if ( valerie_nodes_count( nodes ) != -1 && valerie_units_count( units ) != -1 ) + { + char pressed; + valerie_node_entry_t node; + valerie_unit_entry_t unit; + int node_index = 0; + int unit_index = 0; + + printf( "Select a Node\n\n" ); + + for ( node_index = 0; node_index < valerie_nodes_count( nodes ); node_index ++ ) + { + valerie_nodes_get( nodes, node_index, &node ); + printf( "%d: %s - %s ", node_index + 1, node.guid, node.name ); + for ( unit_index = 0; unit_index < valerie_units_count( units ); unit_index ++ ) + { + valerie_units_get( units, unit_index, &unit ); + if ( !strcmp( unit.guid, node.guid ) ) + printf( "[U%d] ", unit.unit ); + } + printf( "\n" ); + } + + printf( "0. Exit\n\n" ); + + printf( "Node: " ); + + while ( ( pressed = get_keypress( ) ) != '0' ) + { + node_index = pressed - '1'; + if ( node_index >= 0 && node_index < valerie_nodes_count( nodes ) ) + { + int unit; + printf( "%c\n\n", pressed ); + valerie_nodes_get( nodes, node_index, &node ); + if ( valerie_unit_add( demo->dv, node.guid, &unit ) == valerie_ok ) + { + printf( "Unit added as U%d\n", unit ); + demo->selected_unit = unit; + } + else + { + int index = 0; + valerie_response response = valerie_get_last_response( demo->dv ); + printf( "Failed to add unit:\n\n" ); + for( index = 1; index < valerie_response_count( response ) - 1; index ++ ) + printf( "%s\n", valerie_response_get_line( response, index ) ); + } + printf( "\n" ); + wait_for_any_key( NULL ); + break; + } + else + { + beep( ); + } + } + } + else + { + printf( "Invalid response from the server.\n\n" ); + wait_for_any_key( NULL ); + } + + valerie_nodes_close( nodes ); + valerie_units_close( units ); + + return error; +} + +/** Select a unit. +*/ + +valerie_error_code dv_demo_select_unit( dv_demo demo ) +{ + int terminated = 0; + int refresh = 1; + + while ( !terminated ) + { + valerie_units units = valerie_units_init( demo->dv ); + + if ( valerie_units_count( units ) > 0 ) + { + valerie_unit_entry_t unit; + int index = 0; + char key = '\0'; + + if ( refresh ) + { + printf( "Select a Unit\n\n" ); + + for ( index = 0; index < valerie_units_count( units ); index ++ ) + { + valerie_units_get( units, index, &unit ); + printf( "%d: U%d - %s [%s]\n", index + 1, + unit.unit, + unit.guid, + unit.online ? "online" : "offline" ); + } + printf( "0: Exit\n\n" ); + + printf( "Unit [%d]: ", demo->selected_unit + 1 ); + refresh = 0; + } + + key = get_keypress( ); + + if ( key == '\r' ) + key = demo->selected_unit + '1'; + + if ( key != '0' ) + { + if ( key >= '1' && key < '1' + valerie_units_count( units ) ) + { + demo->selected_unit = key - '1'; + printf( "%c\n\n", key ); + dv_demo_load( demo ); + refresh = 1; + } + else + { + beep( ); + } + } + else + { + printf( "0\n\n" ); + terminated = 1; + } + } + else if ( valerie_units_count( units ) == 0 ) + { + printf( "No units added - add a unit first\n\n" ); + dv_demo_add_unit( demo ); + } + else + { + printf( "Unable to obtain Unit List.\n" ); + terminated = 1; + } + + valerie_units_close( units ); + } + + return valerie_ok; +} + +/** Execute an arbitrary command. +*/ + +valerie_error_code dv_demo_execute( dv_demo demo ) +{ + valerie_error_code error = valerie_ok; + char command[ 10240 ]; + int terminated = 0; + + printf( "DV1394D Shell\n" ); + printf( "Enter an empty command to exit.\n\n" ); + + while ( !terminated ) + { + terminated = 1; + printf( "Command> " ); + + if ( chomp( get_string( command, 10240, "" ) ) != NULL ) + { + if ( strcmp( command, "" ) ) + { + int index = 0; + valerie_response response = NULL; + error = valerie_execute( demo->dv, 10240, command ); + printf( "\n" ); + response = valerie_get_last_response( demo->dv ); + for ( index = 0; index < valerie_response_count( response ); index ++ ) + { + char *line = valerie_response_get_line( response, index ); + printf( "%4d: %s\n", index, line ); + } + printf( "\n" ); + terminated = 0; + } + } + } + + printf( "\n" ); + + return error; +} + +/** Add a file to the queue. +*/ + +valerie_error_code dv_demo_queue_add( dv_demo demo, dv_demo_queue queue, char *file ) +{ + valerie_status_t status; + valerie_notifier notifier = valerie_get_notifier( demo->dv ); + + if ( ( queue->tail + 1 ) % 50 == queue->head ) + queue->head = ( queue->head + 1 ) % 50; + strcpy( queue->list[ queue->tail ], file ); + queue->tail = ( queue->tail + 1 ) % 50; + + valerie_notifier_get( notifier, &status, queue->unit ); + valerie_notifier_put( notifier, &status ); + + return valerie_ok; +} + +/** Basic queue maintenance and status reports. +*/ + +valerie_error_code dv_demo_queue_maintenance( dv_demo demo, dv_demo_queue queue ) +{ + printf( "Queue Maintenance for Unit %d\n\n", queue->unit ); + + if ( !queue->mode ) + { + char ch; + printf( "Activate queueing? [Y] " ); + ch = get_keypress( ); + if ( ch == 'y' || ch == 'Y' || ch == '\r' ) + queue->mode = 1; + printf( "\n\n" ); + } + + if ( queue->mode ) + { + int terminated = 0; + int last_position = -2; + + term_init( ); + + while ( !terminated ) + { + int first = ( queue->position + 1 ) % 50; + int index = first; + + if ( first == queue->tail ) + index = first = queue->head; + + if ( queue->head == queue->tail ) + { + if ( last_position == -2 ) + { + printf( "Queue is empty\n" ); + printf( "\n" ); + printf( "0 = exit, t = turn off queueing\n\n" ); + last_position = -1; + } + } + else if ( last_position != queue->position ) + { + printf( "Order of play\n\n" ); + + do + { + printf( "%c%02d: %s\n", index == first ? '*' : ' ', index, queue->list[ index ] + 1 ); + index = ( index + 1 ) % 50; + if ( index == queue->tail ) + index = queue->head; + } + while( index != first ); + + printf( "\n" ); + printf( "0 = exit, t = turn off queueing, c = clear queue\n\n" ); + last_position = queue->position; + } + + dv_demo_change_status( demo, 1 ); + + switch( term_read( ) ) + { + case -1: + break; + case '0': + terminated = 1; + break; + case 't': + terminated = 1; + queue->mode = 0; + break; + case 'c': + queue->head = queue->tail = 0; + queue->position = -1; + last_position = -2; + break; + } + + dv_demo_change_status( demo, 0 ); + } + + term_exit( ); + } + + return valerie_ok; +} + +/** Load a file to the selected unit. Horrible function - sorry :-/. Not a good + demo.... +*/ + +valerie_error_code dv_demo_load( dv_demo demo ) +{ + valerie_error_code error = valerie_ok; + int terminated = 0; + int refresh = 1; + int start = 0; + + strcpy( demo->current_directory, demo->last_directory ); + + term_init( ); + + while ( !terminated ) + { + valerie_dir dir = valerie_dir_init( demo->dv, demo->current_directory ); + + if ( valerie_dir_count( dir ) == -1 ) + { + printf( "Invalid directory - retrying %s\n", demo->last_directory ); + valerie_dir_close( dir ); + dir = valerie_dir_init( demo->dv, demo->last_directory ); + if ( valerie_dir_count( dir ) == -1 ) + { + printf( "Invalid directory - going back to /\n" ); + valerie_dir_close( dir ); + dir = valerie_dir_init( demo->dv, "/" ); + strcpy( demo->current_directory, "/" ); + } + else + { + strcpy( demo->current_directory, demo->last_directory ); + } + } + + terminated = valerie_dir_count( dir ) == -1; + + if ( !terminated ) + { + int index = 0; + int selected = 0; + int max = 9; + int end = 0; + + end = valerie_dir_count( dir ); + + strcpy( demo->last_directory, demo->current_directory ); + + while ( !selected && !terminated ) + { + valerie_dir_entry_t entry; + int pressed; + + if ( refresh ) + { + char *action = "Load & Play"; + if ( demo->queues[ demo->selected_unit ].mode ) + action = "Queue"; + printf( "%s from %s\n\n", action, demo->current_directory ); + if ( strcmp( demo->current_directory, "/" ) ) + printf( "-: Parent directory\n" ); + for ( index = start; index < end && ( index - start ) < max; index ++ ) + { + valerie_dir_get( dir, index, &entry ); + printf( "%d: %s\n", index - start + 1, entry.name ); + } + while ( ( index ++ % 9 ) != 0 ) + printf( "\n" ); + printf( "\n" ); + if ( start + max < end ) + printf( "space = more files" ); + else if ( end > max ) + printf( "space = return to start of list" ); + if ( start > 0 ) + printf( ", b = previous files" ); + printf( "\n" ); + printf( "0 = abort, t = transport, x = execute command, q = queue maintenance\n\n" ); + refresh = 0; + } + + dv_demo_change_status( demo, 1 ); + + pressed = term_read( ); + switch( pressed ) + { + case -1: + break; + case '0': + terminated = 1; + break; + case 'b': + refresh = start - max >= 0; + if ( refresh ) + start = start - max; + break; + case ' ': + refresh = start + max < end; + if ( refresh ) + { + start = start + max; + } + else if ( end > max ) + { + start = 0; + refresh = 1; + } + break; + case '-': + if ( strcmp( demo->current_directory, "/" ) ) + { + selected = 1; + ( *strrchr( demo->current_directory, '/' ) ) = '\0'; + ( *( strrchr( demo->current_directory, '/' ) + 1 ) ) = '\0'; + } + break; + case 't': + dv_demo_change_status( demo, 0 ); + term_exit( ); + dv_demo_transport( demo ); + term_init( ); + selected = 1; + break; + case 'x': + dv_demo_change_status( demo, 0 ); + term_exit( ); + dv_demo_execute( demo ); + term_init( ); + selected = 1; + break; + case 'q': + dv_demo_change_status( demo, 0 ); + term_exit( ); + dv_demo_queue_maintenance( demo, &demo->queues[ demo->selected_unit ] ); + term_init( ); + selected = 1; + break; + default: + if ( pressed >= '1' && pressed <= '9' ) + { + if ( ( start + pressed - '1' ) < end ) + { + valerie_dir_get( dir, start + pressed - '1', &entry ); + selected = 1; + strcat( demo->current_directory, entry.name ); + } + } + break; + } + + dv_demo_change_status( demo, 0 ); + } + + valerie_dir_close( dir ); + } + + if ( !terminated && demo->current_directory[ strlen( demo->current_directory ) - 1 ] != '/' ) + { + if ( demo->queues[ demo->selected_unit ].mode == 0 ) + { + error = valerie_unit_load( demo->dv, demo->selected_unit, demo->current_directory ); + valerie_unit_play( demo->dv, demo->selected_unit ); + } + else + { + dv_demo_queue_add( demo, &demo->queues[ demo->selected_unit ], demo->current_directory ); + printf( "File %s added to queue.\n", demo->current_directory ); + } + strcpy( demo->current_directory, demo->last_directory ); + refresh = 0; + } + else + { + refresh = 1; + start = 0; + } + } + + term_exit( ); + + return error; +} + +/** Set the in point of the clip on the select unit. +*/ + +valerie_error_code dv_demo_set_in( dv_demo demo ) +{ + int position = 0; + valerie_status_t status; + valerie_notifier notifier = valerie_parser_get_notifier( demo->parser ); + valerie_notifier_get( notifier, &status, demo->selected_unit ); + position = status.position; + return valerie_unit_set_in( demo->dv, demo->selected_unit, position ); +} + +/** Set the out point of the clip on the selected unit. +*/ + +valerie_error_code dv_demo_set_out( dv_demo demo ) +{ + int position = 0; + valerie_status_t status; + valerie_notifier notifier = valerie_parser_get_notifier( demo->parser ); + valerie_notifier_get( notifier, &status, demo->selected_unit ); + position = status.position; + return valerie_unit_set_out( demo->dv, demo->selected_unit, position ); +} + +/** Clear the in and out points on the selected unit. +*/ + +valerie_error_code dv_demo_clear_in_out( dv_demo demo ) +{ + return valerie_unit_clear_in_out( demo->dv, demo->selected_unit ); +} + +/** Goto a user specified frame on the selected unit. +*/ + +valerie_error_code dv_demo_goto( dv_demo demo ) +{ + int frame = 0; + printf( "Frame: " ); + if ( get_int( &frame, 0 ) ) + return valerie_unit_goto( demo->dv, demo->selected_unit, frame ); + return valerie_ok; +} + +/** Manipulate playback on the selected unit. +*/ + +valerie_error_code dv_demo_transport( dv_demo demo ) +{ + valerie_error_code error = valerie_ok; + int refresh = 1; + int terminated = 0; + valerie_status_t status; + valerie_notifier notifier = valerie_get_notifier( demo->dv ); + + while ( !terminated ) + { + if ( refresh ) + { + printf( " +----+ +------+ +----+ +------+ +---+ +-----+ +------+ +-----+ +---+ \n" ); + printf( " |1=-5| |2=-2.5| |3=-1| |4=-0.5| |5=1| |6=0.5| |7=1.25| |8=2.5| |9=5| \n" ); + printf( " +----+ +------+ +----+ +------+ +---+ +-----+ +------+ +-----+ +---+ \n" ); + printf( "\n" ); + printf( "+----------------------------------------------------------------------+\n" ); + printf( "| 0 = quit, x = eXecute, 'space' = pause |\n" ); + printf( "| g = goto a frame, q = queue maintenance |\n" ); + printf( "| h = step -1, j = end of clip, k = start of clip, l = step 1 |\n" ); + printf( "| eof handling: p = pause, r = repeat, t = terminate |\n" ); + printf( "| i = set in point, o = set out point, c = clear in/out |\n" ); + printf( "| u = use point settings, d = don't use point settings |\n" ); + printf( "+----------------------------------------------------------------------+\n" ); + printf( "\n" ); + term_init( ); + refresh = 0; + } + + dv_demo_change_status( demo, 1 ); + + switch( term_read( ) ) + { + case '0': + terminated = 1; + break; + case -1: + break; + case ' ': + error = valerie_unit_pause( demo->dv, demo->selected_unit ); + break; + case '1': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, -5000 ); + break; + case '2': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, -2500 ); + break; + case '3': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, -1000 ); + break; + case '4': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, -500 ); + break; + case '5': + error = valerie_unit_play( demo->dv, demo->selected_unit ); + break; + case '6': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, 500 ); + break; + case '7': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, 1250 ); + break; + case '8': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, 2500 ); + break; + case '9': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, 5000 ); + break; + case 's': + error = valerie_unit_goto( demo->dv, demo->selected_unit, 0 ); + break; + case 'h': + error = valerie_unit_step( demo->dv, demo->selected_unit, -1 ); + break; + case 'j': + valerie_notifier_get( notifier, &status, demo->selected_unit ); + error = valerie_unit_goto( demo->dv, demo->selected_unit, status.tail_out ); + break; + case 'k': + valerie_notifier_get( notifier, &status, demo->selected_unit ); + error = valerie_unit_goto( demo->dv, demo->selected_unit, status.in ); + break; + case 'l': + error = valerie_unit_step( demo->dv, demo->selected_unit, 1 ); + break; + case 'p': + error = valerie_unit_set( demo->dv, demo->selected_unit, "eof", "pause" ); + break; + case 'r': + error = valerie_unit_set( demo->dv, demo->selected_unit, "eof", "loop" ); + break; + case 't': + error = valerie_unit_set( demo->dv, demo->selected_unit, "eof", "stop" ); + break; + case 'i': + error = dv_demo_set_in( demo ); + break; + case 'o': + error = dv_demo_set_out( demo ); + break; + case 'g': + dv_demo_change_status( demo, 0 ); + term_exit( ); + error = dv_demo_goto( demo ); + refresh = 1; + break; + case 'c': + error = dv_demo_clear_in_out( demo ); + break; + case 'u': + error = valerie_unit_set( demo->dv, demo->selected_unit, "points", "use" ); + break; + case 'd': + error = valerie_unit_set( demo->dv, demo->selected_unit, "points", "ignore" ); + break; + case 'x': + dv_demo_change_status( demo, 0 ); + term_exit( ); + dv_demo_execute( demo ); + refresh = 1; + break; + case 'q': + dv_demo_change_status( demo, 0 ); + term_exit( ); + dv_demo_queue_maintenance( demo, &demo->queues[ demo->selected_unit ] ); + refresh = 1; + break; + } + + dv_demo_change_status( demo, 0 ); + } + + term_exit( ); + + return error; +} + +/** Recursive menu execution. +*/ + +valerie_error_code dv_demo_run_menu( dv_demo demo, dv_demo_menu menu ) +{ + char *items = "123456789abcdefghijklmnopqrstuvwxyz"; + int refresh_menu = 1; + int terminated = 0; + int item_count = 0; + int item_selected = 0; + int index = 0; + char key; + + while( !terminated ) + { + + if ( refresh_menu ) + { + printf( "%s\n\n", menu->description ); + for ( index = 0; menu->array[ index ].option != NULL; index ++ ) + printf( "%c: %s\n", items[ index ], menu->array[ index ].option ); + printf( "0: Exit\n\n" ); + printf( "Select Option: " ); + refresh_menu = 0; + item_count = index; + } + + key = get_keypress( ); + + if ( demo->disconnected && key != '0' ) + { + valerie_error_code error = valerie_connect( demo->dv ); + if ( error == valerie_ok ) + demo->disconnected = 0; + else + beep(); + } + + if ( !demo->disconnected || key == '0' ) + { + item_selected = strchr( items, key ) - items; + + if ( key == '0' ) + { + printf( "%c\n\n", key ); + terminated = 1; + } + else if ( item_selected >= 0 && item_selected < item_count ) + { + printf( "%c\n\n", key ); + menu->array[ item_selected ].function( demo ); + refresh_menu = 1; + } + else + { + beep( ); + } + } + } + + return valerie_ok; +} + +/** Entry point for main menu. +*/ + +void dv_demo_run( dv_demo this ) +{ + this->dv = valerie_init( this->parser ); + this->dv_status = valerie_init( this->parser ); + if ( valerie_connect( this->dv ) == valerie_ok ) + { + pthread_create( &this->thread, NULL, dv_demo_status_thread, this ); + dv_demo_run_menu( this, &connected_menu ); + this->terminated = 1; + pthread_join( this->thread, NULL ); + this->terminated = 0; + } + else + { + printf( "Unable to connect." ); + wait_for_any_key( "" ); + } + + valerie_close( this->dv_status ); + valerie_close( this->dv ); + + printf( "Demo Exit.\n" ); +} + +/** Close the demo structure. +*/ + +void dv_demo_close( dv_demo demo ) +{ + free( demo ); +} + diff --git a/mlt/src/humperdink/client.h b/mlt/src/humperdink/client.h new file mode 100644 index 00000000..9490360d --- /dev/null +++ b/mlt/src/humperdink/client.h @@ -0,0 +1,66 @@ +/* + * client.h -- dv1394d client demo + * Copyright (C) 2002-2003 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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. + */ + +#ifndef _DEMO_CLIENT_H_ +#define _DEMO_CLIENT_H_ + +#include +#include +#include + +/** Queue for unit playback +*/ + +typedef struct +{ + int mode; + int unit; + int position; + int head; + int tail; + char list[ 50 ][ PATH_MAX + NAME_MAX ]; + int ignore; +} +*dv_demo_queue, dv_demo_queue_t; + +/** Structure for storing app state. +*/ + +typedef struct +{ + int disconnected; + valerie_parser parser; + valerie dv; + valerie dv_status; + int selected_unit; + char current_directory[ 512 ]; + char last_directory[ 512 ]; + int showing; + int terminated; + pthread_t thread; + dv_demo_queue_t queues[ MAX_UNITS ]; +} +*dv_demo, dv_demo_t; + +extern dv_demo dv_demo_init( valerie_parser ); +extern void dv_demo_run( dv_demo ); +extern void dv_demo_close( dv_demo ); + +#endif diff --git a/mlt/src/humperdink/io.c b/mlt/src/humperdink/io.c new file mode 100644 index 00000000..b9e92f28 --- /dev/null +++ b/mlt/src/humperdink/io.c @@ -0,0 +1,204 @@ +/* + * io.c -- dv1394d client demo input/output + * Copyright (C) 2002-2003 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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. + */ + +/* System header files */ +#include +#include +#include +#include +#include +#include + +/* Application header files */ +#include "io.h" + +char *chomp( char *input ) +{ + if ( input != NULL ) + { + int length = strlen( input ); + if ( length && input[ length - 1 ] == '\n' ) + input[ length - 1 ] = '\0'; + if ( length > 1 && input[ length - 2 ] == '\r' ) + input[ length - 2 ] = '\0'; + } + return input; +} + +char *trim( char *input ) +{ + if ( input != NULL ) + { + int length = strlen( input ); + int first = 0; + while( first < length && isspace( input[ first ] ) ) + first ++; + memmove( input, input + first, length - first + 1 ); + length = length - first; + while ( length > 0 && isspace( input[ length - 1 ] ) ) + input[ -- length ] = '\0'; + } + return input; +} + +char *strip_quotes( char *input ) +{ + if ( input != NULL ) + { + char *ptr = strrchr( input, '\"' ); + if ( ptr != NULL ) + *ptr = '\0'; + if ( input[ 0 ] == '\"' ) + strcpy( input, input + 1 ); + } + return input; +} + +char *get_string( char *output, int maxlength, char *use ) +{ + char *value = NULL; + strcpy( output, use ); + if ( trim( chomp( fgets( output, maxlength, stdin ) ) ) != NULL ) + { + if ( !strcmp( output, "" ) ) + strcpy( output, use ); + value = output; + } + return value; +} + +int *get_int( int *output, int use ) +{ + int *value = NULL; + char temp[ 132 ]; + *output = use; + if ( trim( chomp( fgets( temp, 132, stdin ) ) ) != NULL ) + { + if ( strcmp( temp, "" ) ) + *output = atoi( temp ); + value = output; + } + return value; +} + +/** This stores the previous settings +*/ + +static struct termios oldtty; +static int mode = 0; + +/** This is called automatically on application exit to restore the + previous tty settings. +*/ + +void term_exit(void) +{ + if ( mode == 1 ) + { + tcsetattr( 0, TCSANOW, &oldtty ); + mode = 0; + } +} + +/** Init terminal so that we can grab keys without blocking. +*/ + +void term_init( ) +{ + struct termios tty; + + tcgetattr( 0, &tty ); + oldtty = tty; + + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); + tty.c_oflag |= OPOST; + tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); + tty.c_cflag &= ~(CSIZE|PARENB); + tty.c_cflag |= CS8; + tty.c_cc[ VMIN ] = 1; + tty.c_cc[ VTIME ] = 0; + + tcsetattr( 0, TCSANOW, &tty ); + + mode = 1; + + atexit( term_exit ); +} + +/** Check for a keypress without blocking infinitely. + Returns: ASCII value of keypress or -1 if no keypress detected. +*/ + +int term_read( ) +{ + int n = 1; + unsigned char ch; + struct timeval tv; + fd_set rfds; + + FD_ZERO( &rfds ); + FD_SET( 0, &rfds ); + tv.tv_sec = 1; + tv.tv_usec = 0; + n = select( 1, &rfds, NULL, NULL, &tv ); + if (n > 0) + { + n = read( 0, &ch, 1 ); + tcflush( 0, TCIFLUSH ); + if (n == 1) + return ch; + return n; + } + return -1; +} + +char get_keypress( ) +{ + char value = '\0'; + int pressed = 0; + + fflush( stdout ); + + term_init( ); + while ( ( pressed = term_read( ) ) == -1 ) ; + term_exit( ); + + value = (char)pressed; + + return value; +} + +void wait_for_any_key( char *message ) +{ + if ( message == NULL ) + printf( "Press any key to continue: " ); + else + printf( "%s", message ); + + get_keypress( ); + + printf( "\n\n" ); +} + +void beep( ) +{ + printf( "%c", 7 ); + fflush( stdout ); +} diff --git a/mlt/src/humperdink/io.h b/mlt/src/humperdink/io.h new file mode 100644 index 00000000..6c4b609a --- /dev/null +++ b/mlt/src/humperdink/io.h @@ -0,0 +1,36 @@ +/* + * io.h -- dv1394d client demo input/output + * Copyright (C) 2002-2003 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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. + */ + +#ifndef _DEMO_IO_H_ +#define _DEMO_IO_H_ + +extern char *chomp( char * ); +extern char *trim( char * ); +extern char *strip_quotes( char * ); +extern char *get_string( char *, int, char * ); +extern int *get_int( int *, int ); +extern void term_init( ); +extern int term_read( ); +extern void term_exit( ); +extern char get_keypress( ); +extern void wait_for_any_key( char * ); +extern void beep( ); + +#endif diff --git a/mlt/src/humperdink/remote.c b/mlt/src/humperdink/remote.c new file mode 100644 index 00000000..18ac5a56 --- /dev/null +++ b/mlt/src/humperdink/remote.c @@ -0,0 +1,73 @@ +/* + * remote.c -- Remote dv1394d client demo + * Copyright (C) 2002-2003 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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. + */ + +/* System header files */ +#include + +/* dv1394d header files */ +#include + +/* Application header files */ +#include "client.h" +#include "io.h" + +/** Connect to a remote server. +*/ + +static valerie_parser create_parser( ) +{ + char server[ 132 ]; + int port; + valerie_parser parser = NULL; + + printf( "Connecting to a Server\n\n" ); + + printf( "Server [localhost]: " ); + + if ( get_string( server, sizeof( server ), "localhost" ) != NULL ) + { + printf( "Port [5250]: " ); + + if ( get_int( &port, 5250 ) != NULL ) + parser = valerie_parser_init_remote( server, port ); + } + + printf( "\n" ); + + return parser; +} + +/** Main function. +*/ + +int main( int argc, char **argv ) +{ + valerie_parser parser = create_parser( ); + + if ( parser != NULL ) + { + dv_demo demo = dv_demo_init( parser ); + dv_demo_run( demo ); + dv_demo_close( demo ); + valerie_parser_close( parser ); + } + + return 0; +} diff --git a/mlt/src/inigo/inigo.c b/mlt/src/inigo/inigo.c index bc087ba3..8b840438 100644 --- a/mlt/src/inigo/inigo.c +++ b/mlt/src/inigo/inigo.c @@ -178,13 +178,15 @@ void transport( mlt_producer producer ) int main( int argc, char **argv ) { int i; + int track = 0; mlt_consumer consumer = NULL; - mlt_multitrack multitrack = NULL; mlt_producer producer = NULL; mlt_playlist playlist = NULL; - mlt_field field = NULL; mlt_properties group = mlt_properties_new( ); mlt_properties properties = group; + mlt_field field = mlt_field_init( ); + mlt_properties field_properties = mlt_field_properties( field ); + mlt_multitrack multitrack = mlt_field_multitrack( field ); // Construct the factory mlt_factory_init( getenv( "MLT_REPOSITORY" ) ); @@ -192,16 +194,9 @@ int main( int argc, char **argv ) // Set up containers playlist = mlt_playlist_init( ); - // Construct the field - field = mlt_field_init( ); - // We need to track the number of registered filters - mlt_properties field_properties = mlt_field_properties( field ); mlt_properties_set_int( field_properties, "registered", 0 ); - // Get the multitrack from the field - multitrack = mlt_field_multitrack( field ); - // Parse the arguments for ( i = 1; i < argc; i ++ ) { @@ -233,6 +228,13 @@ int main( int argc, char **argv ) mlt_properties_inherit( properties, group ); } } + else if ( !strcmp( argv[ i ], "-blank" ) ) + { + if ( producer != NULL ) + mlt_playlist_append( playlist, producer ); + producer = NULL; + mlt_playlist_blank( playlist, atof( argv[ ++ i ] ) ); + } else if ( !strstr( argv[ i ], "=" ) ) { if ( producer != NULL ) @@ -250,8 +252,13 @@ int main( int argc, char **argv ) } } - // We must have a producer at this point + // Connect producer to playlist if ( producer != NULL ) + mlt_playlist_append( playlist, producer ); + + + // We must have a producer at this point + if ( mlt_playlist_count( playlist ) > 0 ) { // If we have no consumer, default to sdl if ( consumer == NULL ) @@ -264,11 +271,8 @@ int main( int argc, char **argv ) } } - // Connect producer to playlist - mlt_playlist_append( playlist, producer ); - // Connect multitrack to producer - mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist ), 0 ); + mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist ), track ); // Connect consumer to tractor mlt_consumer_connect( consumer, mlt_field_service( field ) ); diff --git a/mlt/src/miracle/Makefile b/mlt/src/miracle/Makefile new file mode 100644 index 00000000..6568199c --- /dev/null +++ b/mlt/src/miracle/Makefile @@ -0,0 +1,34 @@ +TARGET = miracle + +OBJS = miracle.o \ + miracle_log.o \ + miracle_server.o \ + miracle_connection.o \ + miracle_local.o \ + miracle_unit.o \ + miracle_commands.o \ + miracle_unit_commands.o + +CFLAGS = -I .. -Wall -g -D_FILE_OFFSET_BITS=64 -pthread -rdynamic + +LDFLAGS = -L ../valerie -lvalerie -L ../framework -lmlt + +SRCS := $(OBJS:.o=.c) + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CC) -o $@ $(OBJS) $(LDFLAGS) + +depend: $(SRCS) + $(CC) -MM $(CFLAGS) $^ 1>.depend + +dist-clean: clean + rm -f .depend + +clean: + rm -f $(OBJS) $(TARGET) + +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/mlt/src/miracle/miracle.c b/mlt/src/miracle/miracle.c index 47a645ab..8d1294d0 100644 --- a/mlt/src/miracle/miracle.c +++ b/mlt/src/miracle/miracle.c @@ -1,5 +1,5 @@ /* - * dv1394d.c -- A DV over IEEE 1394 TCP Server + * miracle.c -- A DV over IEEE 1394 TCP Server * * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Authors: @@ -21,10 +21,6 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifdef HAVE_CONFIG_H -#include -#endif - /* System header files */ #include #include @@ -33,21 +29,24 @@ #include #include +#include + /* Application header files */ -#include "dvserver.h" -#include "log.h" +#include "miracle_server.h" +#include "miracle_log.h" /** Our dv server. */ -static dv_server server = NULL; +static miracle_server server = NULL; /** atexit shutdown handler for the server. */ static void main_cleanup( ) { - dv_server_shutdown( server ); + miracle_server_shutdown( server ); + mlt_factory_close( ); } /** Report usage and exit. @@ -69,14 +68,17 @@ int main( int argc, char **argv ) int background = 1; struct timespec tm = { 5, 0 }; - server = dv_server_init( argv[ 0 ] ); + // Construct the factory + mlt_factory_init( getenv( "MLT_REPOSITORY" ) ); + + server = miracle_server_init( argv[ 0 ] ); for ( index = 1; index < argc; index ++ ) { if ( !strcmp( argv[ index ], "-port" ) ) - dv_server_set_port( server, atoi( argv[ ++ index ] ) ); + miracle_server_set_port( server, atoi( argv[ ++ index ] ) ); else if ( !strcmp( argv[ index ], "-proxy" ) ) - dv_server_set_proxy( server, argv[ ++ index ] ); + miracle_server_set_proxy( server, argv[ ++ index ] ); else if ( !strcmp( argv[ index ], "-test" ) ) background = 0; else @@ -90,17 +92,17 @@ int main( int argc, char **argv ) if ( fork() ) return 0; setsid(); - dv1394d_log_init( log_syslog, LOG_INFO ); + miracle_log_init( log_syslog, LOG_INFO ); } else { - dv1394d_log_init( log_stderr, LOG_INFO ); + miracle_log_init( log_stderr, LOG_DEBUG ); } atexit( main_cleanup ); /* Execute the server */ - error = dv_server_execute( server ); + error = miracle_server_execute( server ); /* We need to wait until we're exited.. */ while ( !server->shutdown ) diff --git a/mlt/src/miracle/miracle_commands.c b/mlt/src/miracle/miracle_commands.c index 8a492d1a..4a23e439 100644 --- a/mlt/src/miracle/miracle_commands.c +++ b/mlt/src/miracle/miracle_commands.c @@ -18,10 +18,6 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifdef HAVE_CONFIG_H -#include -#endif - #include #include #include @@ -33,19 +29,17 @@ #include #include -#include "dvunit.h" -#include "global_commands.h" -#include "raw1394util.h" -#include -#include "log.h" +#include "miracle_unit.h" +#include "miracle_commands.h" +#include "miracle_log.h" -static dv_unit g_units[MAX_UNITS]; +static miracle_unit g_units[MAX_UNITS]; -/** Return the dv_unit given a numeric index. +/** Return the miracle_unit given a numeric index. */ -dv_unit dv1394d_get_unit( int n ) +miracle_unit miracle_get_unit( int n ) { if (n < MAX_UNITS) return g_units[n]; @@ -53,19 +47,19 @@ dv_unit dv1394d_get_unit( int n ) return NULL; } -/** Destroy the dv_unit given its numeric index. +/** Destroy the miracle_unit given its numeric index. */ -void dv1394d_delete_unit( int n ) +void miracle_delete_unit( int n ) { if (n < MAX_UNITS) { - dv_unit unit = dv1394d_get_unit(n); + miracle_unit unit = miracle_get_unit(n); if (unit != NULL) { - dv_unit_close( unit ); + miracle_unit_close( unit ); g_units[ n ] = NULL; - dv1394d_log( LOG_NOTICE, "Deleted unit U%d.", n ); + miracle_log( LOG_NOTICE, "Deleted unit U%d.", n ); } } } @@ -73,67 +67,36 @@ void dv1394d_delete_unit( int n ) /** Destroy all allocated units on the server. */ -void dv1394d_delete_all_units( void ) +void miracle_delete_all_units( void ) { int i; for (i = 0; i < MAX_UNITS; i++) - if ( dv1394d_get_unit(i) != NULL ) + { + if ( miracle_get_unit(i) != NULL ) { - dv_unit_close( dv1394d_get_unit(i) ); - dv1394d_log( LOG_NOTICE, "Deleted unit U%d.", i ); + miracle_unit_close( miracle_get_unit(i) ); + miracle_log( LOG_NOTICE, "Deleted unit U%d.", i ); } + } } /** Add a DV virtual vtr to the server. */ -response_codes dv1394d_add_unit( command_argument cmd_arg ) +response_codes miracle_add_unit( command_argument cmd_arg ) { - int i; - int channel = -1; - char *guid_str = (char*) cmd_arg->argument; - octlet_t guid; - uint32_t guid_hi; - uint32_t guid_lo; - - sscanf( guid_str, "%08x%08x", &guid_hi, &guid_lo ); - guid = (octlet_t)guid_hi << 32 | (octlet_t) guid_lo; + int i = 0; + for ( i = 0; i < MAX_UNITS; i ++ ) + if ( g_units[ i ] == NULL ) + break; - if ( dv_tokeniser_count( cmd_arg->tokeniser ) == 3 ) - channel = atoi( dv_tokeniser_get_string( cmd_arg->tokeniser, 2 ) ); - - /* make sure unit does not already exit */ - for (i = 0; i < MAX_UNITS; i++) + if ( i < MAX_UNITS ) { - if (g_units[i] != NULL) - if ( dv_unit_get_guid( g_units[i] ) == guid ) - { - dv_response_printf( cmd_arg->response, 1024, "a unit already exists for that node\n\n" ); - return RESPONSE_ERROR; - } + char *arg = cmd_arg->argument; + g_units[ i ] = miracle_unit_init( i, arg ); + if ( g_units[ i ] != NULL ) + miracle_unit_set_notifier( g_units[ i ], valerie_parser_get_notifier( cmd_arg->parser ), cmd_arg->root_dir ); + return g_units[ i ] != NULL ? RESPONSE_SUCCESS : RESPONSE_ERROR; } - - for (i = 0; i < MAX_UNITS; i++) - { - if (g_units[i] == NULL) - { - - g_units[ i ] = dv_unit_init( guid, channel ); - if ( g_units[ i ] == NULL ) - { - dv_response_printf( cmd_arg->response, 1024, "failed to allocate unit\n" ); - return RESPONSE_ERROR; - } - g_units[ i ]->unit = i; - dv_unit_set_notifier( g_units[ i ], dv_parser_get_notifier( cmd_arg->parser ), cmd_arg->root_dir ); - - dv1394d_log( LOG_NOTICE, "added unit %d to send to node %d over channel %d", - i, dv_unit_get_nodeid( g_units[i] ), dv_unit_get_channel( g_units[i] ) ); - dv_response_printf( cmd_arg->response, 10, "U%1d\n\n", i ); - return RESPONSE_SUCCESS_N; - } - } - - dv_response_printf( cmd_arg->response, 1024, "no more units can be created\n\n" ); return RESPONSE_ERROR; } @@ -141,79 +104,44 @@ response_codes dv1394d_add_unit( command_argument cmd_arg ) /** List all AV/C nodes on the bus. */ -response_codes dv1394d_list_nodes( command_argument cmd_arg ) +response_codes miracle_list_nodes( command_argument cmd_arg ) { response_codes error = RESPONSE_SUCCESS_N; - raw1394handle_t handle; - int i, j; - char line[1024]; - octlet_t guid; - rom1394_directory dir; - - for ( j = 0; j < raw1394_get_num_ports(); j++ ) - { - handle = raw1394_open(j); - for ( i = 0; i < raw1394_get_nodecount(handle); ++i ) - { - rom1394_get_directory( handle, i, &dir); - if ( (rom1394_get_node_type(&dir) == ROM1394_NODE_TYPE_AVC) ) - { - guid = rom1394_get_guid(handle, i); - if (dir.label != NULL) - { - snprintf( line, 1023, "%02d %08x%08x \"%s\"\n", i, - (quadlet_t) (guid>>32), (quadlet_t) (guid & 0xffffffff), dir.label ); - } else { - snprintf( line, 1023, "%02d %08x%08x \"Unlabeled Node %d\"\n", i, - (quadlet_t) (guid>>32), (quadlet_t) (guid & 0xffffffff), i ); - } - dv_response_write( cmd_arg->response, line, strlen(line) ); - rom1394_free_directory( &dir); - } - } - raw1394_close( handle ); - } - dv_response_write( cmd_arg->response, "\n", 1 ); return error; } /** List units already added to server. */ -response_codes dv1394d_list_units( command_argument cmd_arg ) +response_codes miracle_list_units( command_argument cmd_arg ) { response_codes error = RESPONSE_SUCCESS_N; - char line[1024]; - int i; - - for (i = 0; i < MAX_UNITS; i++) + int i = 0; + + for ( i = 0; i < MAX_UNITS; i ++ ) { - if (dv1394d_get_unit(i) != NULL) + miracle_unit unit = miracle_get_unit( i ); + if ( unit != NULL ) { - snprintf( line, 1023, "U%d %02d %08x%08x %d\n", i, dv_unit_get_nodeid(g_units[i]), - (quadlet_t) (dv_unit_get_guid(g_units[i]) >> 32), - (quadlet_t) (dv_unit_get_guid(g_units[i]) & 0xffffffff), - !dv_unit_is_offline( g_units[i] ) ); - dv_response_write( cmd_arg->response, line, strlen(line) ); + mlt_properties properties = unit->properties; + char *constructor = mlt_properties_get( properties, "constructor" ); + int node = mlt_properties_get_int( properties, "node" ); + int online = !mlt_properties_get_int( properties, "offline" ); + valerie_response_printf( cmd_arg->response, 1024, "U%d %02d %s %d\n", i, node, constructor, online ); } } - dv_response_write( cmd_arg->response, "\n", 1 ); return error; } -static int -filter_files( const struct dirent *de ) +static int filter_files( const struct dirent *de ) { - if ( de->d_name[ 0 ] != '.' ) - return 1; - else - return 0; + return de->d_name[ 0 ] != '.'; } /** List clips in a directory. */ -response_codes dv1394d_list_clips( command_argument cmd_arg ) +response_codes miracle_list_clips( command_argument cmd_arg ) { response_codes error = RESPONSE_BAD_FILE; const char *dir_name = (const char*) cmd_arg->argument; @@ -233,19 +161,19 @@ response_codes dv1394d_list_clips( command_argument cmd_arg ) { snprintf( fullname, 1023, "%s%s/%s", cmd_arg->root_dir, dir_name, de[i]->d_name ); if ( stat( fullname, &info ) == 0 && S_ISDIR( info.st_mode ) ) - dv_response_printf( cmd_arg->response, 1024, "\"%s/\"\n", de[i]->d_name ); + valerie_response_printf( cmd_arg->response, 1024, "\"%s/\"\n", de[i]->d_name ); } for (i = 0; i < n; i++ ) { snprintf( fullname, 1023, "%s%s/%s", cmd_arg->root_dir, dir_name, de[i]->d_name ); if ( lstat( fullname, &info ) == 0 && ( S_ISREG( info.st_mode ) || ( strstr( fullname, ".clip" ) && info.st_mode | S_IXUSR ) ) ) - dv_response_printf( cmd_arg->response, 1024, "\"%s\" %llu\n", de[i]->d_name, (unsigned long long) info.st_size ); + valerie_response_printf( cmd_arg->response, 1024, "\"%s\" %llu\n", de[i]->d_name, (unsigned long long) info.st_size ); free( de[ i ] ); } free( de ); closedir( dir ); - dv_response_write( cmd_arg->response, "\n", 1 ); + valerie_response_write( cmd_arg->response, "\n", 1 ); } return error; @@ -254,7 +182,7 @@ response_codes dv1394d_list_clips( command_argument cmd_arg ) /** Set a server configuration property. */ -response_codes dv1394d_set_global_property( command_argument cmd_arg ) +response_codes miracle_set_global_property( command_argument cmd_arg ) { char *key = (char*) cmd_arg->argument; char *value = NULL; @@ -264,7 +192,7 @@ response_codes dv1394d_set_global_property( command_argument cmd_arg ) return RESPONSE_OUT_OF_RANGE; *value = 0; value++; - dv1394d_log( LOG_DEBUG, "SET %s = %s", key, value ); + miracle_log( LOG_DEBUG, "SET %s = %s", key, value ); if ( strncasecmp( key, "root", 1024) == 0 ) { @@ -275,7 +203,7 @@ response_codes dv1394d_set_global_property( command_argument cmd_arg ) for (i = 0; i < MAX_UNITS; i++) { if (g_units[i] != NULL) - dv_unit_terminate( g_units[i] ); + miracle_unit_terminate( g_units[i] ); } /* set the property */ @@ -297,13 +225,13 @@ response_codes dv1394d_set_global_property( command_argument cmd_arg ) /** Get a server configuration property. */ -response_codes dv1394d_get_global_property( command_argument cmd_arg ) +response_codes miracle_get_global_property( command_argument cmd_arg ) { char *key = (char*) cmd_arg->argument; if ( strncasecmp( key, "root", 1024) == 0 ) { - dv_response_write( cmd_arg->response, cmd_arg->root_dir, strlen(cmd_arg->root_dir) ); + valerie_response_write( cmd_arg->response, cmd_arg->root_dir, strlen(cmd_arg->root_dir) ); return RESPONSE_SUCCESS_1; } else @@ -312,142 +240,4 @@ response_codes dv1394d_get_global_property( command_argument cmd_arg ) return RESPONSE_SUCCESS; } -/** IEEE 1394 Bus Reset handler - - This is included here for now due to all the unit management involved. -*/ - -static int reset_handler( raw1394handle_t h, unsigned int generation ) -{ - int i, j, count, retry = 3; - int port = (int) raw1394_get_userdata( h ); - - raw1394_update_generation( h, generation ); - dv1394d_log( LOG_NOTICE, "bus reset on port %d", port ); - - while ( retry-- > 0 ) - { - raw1394handle_t handle = raw1394_open( port ); - count = raw1394_get_nodecount( handle ); - - if ( count > 0 ) - { - dv1394d_log( LOG_DEBUG, "bus reset, checking units" ); - - /* suspend all units on this port */ - for ( j = MAX_UNITS; j > 0; j-- ) - { - if ( g_units[ j-1 ] != NULL && dv_unit_get_port( g_units[ j-1 ] ) == port ) - dv_unit_suspend( g_units[ j-1 ] ); - } - dv1394d_log( LOG_DEBUG, "All units are now stopped" ); - - /* restore units with known guid, take others offline */ - for ( j = 0; j < MAX_UNITS; j++ ) - { - if ( g_units[j] != NULL && - ( dv_unit_get_port( g_units[ j ] ) == port || dv_unit_get_port( g_units[ j ] ) == -1 ) ) - { - int found = 0; - for ( i = 0; i < count; i++ ) - { - octlet_t guid; - dv1394d_log( LOG_DEBUG, "attempting to get guid for node %d", i ); - guid = rom1394_get_guid( handle, i ); - if ( guid == g_units[ j ]->guid ) - { - dv1394d_log( LOG_NOTICE, "unit with GUID %08x%08x found", - (quadlet_t) (g_units[j]->guid>>32), (quadlet_t) (g_units[j]->guid & 0xffffffff)); - if ( dv_unit_is_offline( g_units[ j ] ) ) - dv_unit_online( g_units[ j ] ); - else - dv_unit_restore( g_units[ j ] ); - found = 1; - break; - } - } - if ( found == 0 ) - dv_unit_offline( g_units[ j ] ); - } - } - dv1394d_log( LOG_DEBUG, "completed bus reset handler"); - raw1394_close( handle ); - return 0; - } - raw1394_close( handle ); - } - dv1394d_log( LOG_CRIT, "raw1394 reported zero nodes on the bus!" ); - return 0; -} - - -/** One pthread per IEEE 1394 port -*/ - -static pthread_t raw1394service_thread[4]; - -/** One raw1394 handle for each pthread/port -*/ - -static raw1394handle_t raw1394service_handle[4]; - -/** The service thread that polls raw1394 for new events. -*/ - -static void* raw1394_service( void *arg ) -{ - raw1394handle_t handle = (raw1394handle_t) arg; - struct pollfd raw1394_poll; - raw1394_poll.fd = raw1394_get_fd( handle ); - raw1394_poll.events = POLLIN; - raw1394_poll.revents = 0; - while ( 1 ) - { - if ( poll( &raw1394_poll, 1, 200) > 0 ) - { - if ( (raw1394_poll.revents & POLLIN) - || (raw1394_poll.revents & POLLPRI) ) - raw1394_loop_iterate( handle ); - } - pthread_testcancel(); - } - -} - - -/** Start the raw1394 service threads for handling bus reset. - - One thread is launched per port on the system. -*/ - -void raw1394_start_service_threads( void ) -{ - int port; - for ( port = 0; port < raw1394_get_num_ports(); port++ ) - { - raw1394service_handle[port] = raw1394_open( port ); - raw1394_set_bus_reset_handler( raw1394service_handle[port], reset_handler ); - pthread_create( &(raw1394service_thread[port]), NULL, raw1394_service, raw1394service_handle[port] ); - } - for ( ; port < 4; port++ ) - raw1394service_handle[port] = NULL; -} - -/** Shutdown all the raw1394 service threads. -*/ - -void raw1394_stop_service_threads( void ) -{ - int i; - for ( i = 0; i < 4; i++ ) - { - if ( raw1394service_handle[i] != NULL ) - { - pthread_cancel( raw1394service_thread[i] ); - pthread_join( raw1394service_thread[i], NULL ); - raw1394_close( raw1394service_handle[i] ); - } - } -} - diff --git a/mlt/src/miracle/miracle_commands.h b/mlt/src/miracle/miracle_commands.h index 6c60d7da..9d79683c 100644 --- a/mlt/src/miracle/miracle_commands.h +++ b/mlt/src/miracle/miracle_commands.h @@ -22,28 +22,28 @@ #ifndef _GLOBAL_COMMANDS_H_ #define _GLOBAL_COMMANDS_H_ -#include -#include "dvunit.h" -#include "dvconnection.h" +#include +#include "miracle_unit.h" +#include "miracle_connection.h" #ifdef __cplusplus extern "C" { #endif -dv_unit dv1394d_get_unit( int ); -void dv1394d_delete_unit( int ); -void dv1394d_delete_all_units( void ); -int dv1394d_unit_status( int n, dv1394_status status, int root_offset ); -void raw1394_start_service_threads( void ); -void raw1394_stop_service_threads( void ); - -extern response_codes dv1394d_add_unit( command_argument ); -extern response_codes dv1394d_list_nodes( command_argument ); -extern response_codes dv1394d_list_units( command_argument ); -extern response_codes dv1394d_list_clips( command_argument ); -extern response_codes dv1394d_set_global_property( command_argument ); -extern response_codes dv1394d_get_global_property( command_argument ); +extern miracle_unit miracle_get_unit( int ); +extern void miracle_delete_unit( int ); +extern void miracle_delete_all_units( void ); +extern int miracle_unit_status( int n, valerie_status status, int root_offset ); +//extern void raw1394_start_service_threads( void ); +//extern void raw1394_stop_service_threads( void ); + +extern response_codes miracle_add_unit( command_argument ); +extern response_codes miracle_list_nodes( command_argument ); +extern response_codes miracle_list_units( command_argument ); +extern response_codes miracle_list_clips( command_argument ); +extern response_codes miracle_set_global_property( command_argument ); +extern response_codes miracle_get_global_property( command_argument ); #ifdef __cplusplus } diff --git a/mlt/src/miracle/miracle_connection.c b/mlt/src/miracle/miracle_connection.c index 6c65e351..563a769a 100644 --- a/mlt/src/miracle/miracle_connection.c +++ b/mlt/src/miracle/miracle_connection.c @@ -1,5 +1,5 @@ /* - * dvconnection.c -- DV Connection Handler + * miracle_connection.c -- DV Connection Handler * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Charles Yates * @@ -34,12 +34,13 @@ #include #include +#include + /* Application header files */ -#include "global_commands.h" -#include "dvconnection.h" -#include "dvsocket.h" -#include "dvserver.h" -#include "log.h" +#include "miracle_commands.h" +#include "miracle_connection.h" +#include "miracle_server.h" +#include "miracle_log.h" /** This is a generic replacement for fgets which operates on a file descriptor. Unlike fgets, we can also specify a line terminator. Maximum @@ -80,46 +81,46 @@ int fdgetline( int fd, char *buf, int max, char line_terminator, int *eof_chk ) } static int connection_initiate( int ); -static int connection_send( int, dv_response ); +static int connection_send( int, valerie_response ); static int connection_read( int, char *, int ); static void connection_close( int ); static int connection_initiate( int fd ) { int error = 0; - dv_response response = dv_response_init( ); - dv_response_set_error( response, 100, "VTR Ready" ); + valerie_response response = valerie_response_init( ); + valerie_response_set_error( response, 100, "VTR Ready" ); error = connection_send( fd, response ); - dv_response_close( response ); + valerie_response_close( response ); return error; } -static int connection_send( int fd, dv_response response ) +static int connection_send( int fd, valerie_response response ) { int error = 0; int index = 0; - int code = dv_response_get_error_code( response ); + int code = valerie_response_get_error_code( response ); if ( code != -1 ) { - int items = dv_response_count( response ); + int items = valerie_response_count( response ); if ( items == 0 ) - dv_response_set_error( response, 500, "Unknown error" ); + valerie_response_set_error( response, 500, "Unknown error" ); if ( code == 200 && items > 2 ) - dv_response_set_error( response, 201, "OK" ); + valerie_response_set_error( response, 201, "OK" ); else if ( code == 200 && items > 1 ) - dv_response_set_error( response, 202, "OK" ); + valerie_response_set_error( response, 202, "OK" ); - code = dv_response_get_error_code( response ); - items = dv_response_count( response ); + code = valerie_response_get_error_code( response ); + items = valerie_response_count( response ); for ( index = 0; !error && index < items; index ++ ) { - char *line = dv_response_get_line( response, index ); + char *line = valerie_response_get_line( response, index ); int length = strlen( line ); - if ( length == 0 && index != dv_response_count( response ) - 1 && write( fd, " ", 1 ) != 1 ) + if ( length == 0 && index != valerie_response_count( response ) - 1 && write( fd, " ", 1 ) != 1 ) error = -1; else if ( length > 0 && write( fd, line, length ) != length ) error = -1; @@ -127,7 +128,7 @@ static int connection_send( int fd, dv_response response ) error = -1; } - if ( ( code == 201 || code == 500 ) && strcmp( dv_response_get_line( response, items - 1 ), "" ) ) + if ( ( code == 201 || code == 500 ) && strcmp( valerie_response_get_line( response, items - 1 ), "" ) ) write( fd, "\r\n", 2 ); } else @@ -151,27 +152,27 @@ static int connection_read( int fd, char *command, int length ) return nchars; } -int connection_status( int fd, dv1394_notifier notifier ) +int connection_status( int fd, valerie_notifier notifier ) { int error = 0; int index = 0; - dv1394_status_t status; + valerie_status_t status; char text[ 10240 ]; - dv_socket socket = dv_socket_init_fd( fd ); + valerie_socket socket = valerie_socket_init_fd( fd ); for ( index = 0; !error && index < MAX_UNITS; index ++ ) { - dv1394_notifier_get( notifier, &status, index ); - dv1394_status_serialise( &status, text, sizeof( text ) ); - error = dv_socket_write_data( socket, text, strlen( text ) ) != strlen( text ); + valerie_notifier_get( notifier, &status, index ); + valerie_status_serialise( &status, text, sizeof( text ) ); + error = valerie_socket_write_data( socket, text, strlen( text ) ) != strlen( text ); } while ( !error ) { - if ( dv1394_notifier_wait( notifier, &status ) == 0 ) + if ( valerie_notifier_wait( notifier, &status ) == 0 ) { - dv1394_status_serialise( &status, text, sizeof( text ) ); - error = dv_socket_write_data( socket, text, strlen( text ) ) != strlen( text ); + valerie_status_serialise( &status, text, sizeof( text ) ); + error = valerie_socket_write_data( socket, text, strlen( text ) ) != strlen( text ); } else { @@ -186,7 +187,7 @@ int connection_status( int fd, dv1394_notifier notifier ) } } - dv_socket_close( socket ); + valerie_socket_close( socket ); return error; } @@ -203,11 +204,8 @@ void *parser_thread( void *arg ) char address[ 512 ]; char command[ 1024 ]; int fd = connection->fd; - dv_parser parser = connection->parser; - dv_response response = NULL; - - /* We definitely want to ignore broken pipes. */ - signal( SIGPIPE, SIG_IGN ); + valerie_parser parser = connection->parser; + valerie_response response = NULL; /* Get the connecting clients ip information */ he = gethostbyaddr( (char *) &( connection->sin.sin_addr.s_addr ), sizeof(u_int32_t), AF_INET); @@ -216,7 +214,7 @@ void *parser_thread( void *arg ) else inet_ntop( AF_INET, &( connection->sin.sin_addr.s_addr), address, 32 ); - dv1394d_log( LOG_NOTICE, "Connection established with %s (%d)", address, fd ); + miracle_log( LOG_NOTICE, "Connection established with %s (%d)", address, fd ); /* Execute the commands received. */ if ( connection_initiate( fd ) == 0 ) @@ -227,14 +225,14 @@ void *parser_thread( void *arg ) { if ( strncmp( command, "STATUS", 6 ) ) { - response = dv_parser_execute( parser, command ); - dv1394d_log( LOG_INFO, "%s \"%s\" %d", address, command, dv_response_get_error_code( response ) ); + response = valerie_parser_execute( parser, command ); + miracle_log( LOG_INFO, "%s \"%s\" %d", address, command, valerie_response_get_error_code( response ) ); error = connection_send( fd, response ); - dv_response_close( response ); + valerie_response_close( response ); } else { - error = connection_status( fd, dv_parser_get_notifier( parser ) ); + error = connection_status( fd, valerie_parser_get_notifier( parser ) ); } } } @@ -242,7 +240,7 @@ void *parser_thread( void *arg ) /* Free the resources associated with this connection. */ connection_close( fd ); - dv1394d_log( LOG_NOTICE, "Connection with %s (%d) closed", address, fd ); + miracle_log( LOG_NOTICE, "Connection with %s (%d) closed", address, fd ); free( connection ); diff --git a/mlt/src/miracle/miracle_connection.h b/mlt/src/miracle/miracle_connection.h index 1c5d00b0..ce19115f 100644 --- a/mlt/src/miracle/miracle_connection.h +++ b/mlt/src/miracle/miracle_connection.h @@ -1,5 +1,5 @@ /* - * dvconnection.h -- DV Connection Handler + * miracle_connection.h -- DV Connection Handler * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Charles Yates * @@ -25,8 +25,8 @@ #include #include -#include -#include +#include +#include #ifdef __cplusplus extern "C" @@ -40,7 +40,7 @@ typedef struct { int fd; struct sockaddr_in sin; - dv_parser parser; + valerie_parser parser; } connection_t; @@ -68,9 +68,9 @@ response_codes; typedef struct { - dv_parser parser; - dv_response response; - dv_tokeniser tokeniser; + valerie_parser parser; + valerie_response response; + valerie_tokeniser tokeniser; char *command; int unit; void *argument; diff --git a/mlt/src/miracle/miracle_local.c b/mlt/src/miracle/miracle_local.c index fce4ab22..ac6c7578 100644 --- a/mlt/src/miracle/miracle_local.c +++ b/mlt/src/miracle/miracle_local.c @@ -1,5 +1,5 @@ /* - * dvlocal.c -- Local dv1394d Parser + * miracle_local.c -- Local Miracle Parser * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Charles Yates * @@ -27,59 +27,59 @@ #include #include -/* Library header files */ -#include +/* Valerie header files */ +#include + +/* MLT header files. */ +#include /* Application header files */ -#include -#include -#include "dvlocal.h" -#include "dvconnection.h" -#include "global_commands.h" -#include "unit_commands.h" -#include "log.h" -#include "raw1394util.h" - -/** Private dv_local structure. +#include "miracle_local.h" +#include "miracle_connection.h" +#include "miracle_commands.h" +#include "miracle_unit_commands.h" +#include "miracle_log.h" + +/** Private miracle_local structure. */ typedef struct { - dv_parser parser; + valerie_parser parser; char root_dir[1024]; } -*dv_local, dv_local_t; +*miracle_local, miracle_local_t; /** Forward declarations. */ -static dv_response dv_local_connect( dv_local ); -static dv_response dv_local_execute( dv_local, char * ); -static void dv_local_close( dv_local ); -response_codes print_help( command_argument arg ); -response_codes dv1394d_run( command_argument arg ); -response_codes dv1394d_shutdown( command_argument arg ); +static valerie_response miracle_local_connect( miracle_local ); +static valerie_response miracle_local_execute( miracle_local, char * ); +static void miracle_local_close( miracle_local ); +response_codes miracle_help( command_argument arg ); +response_codes miracle_run( command_argument arg ); +response_codes miracle_shutdown( command_argument arg ); /** DV Parser constructor. */ -dv_parser dv_parser_init_local( ) +valerie_parser miracle_parser_init_local( ) { - dv_parser parser = malloc( sizeof( dv_parser_t ) ); - dv_local local = malloc( sizeof( dv_local_t ) ); + valerie_parser parser = malloc( sizeof( valerie_parser_t ) ); + miracle_local local = malloc( sizeof( miracle_local_t ) ); if ( parser != NULL ) { - memset( parser, 0, sizeof( dv_parser_t ) ); + memset( parser, 0, sizeof( valerie_parser_t ) ); - parser->connect = (parser_connect)dv_local_connect; - parser->execute = (parser_execute)dv_local_execute; - parser->close = (parser_close)dv_local_close; + parser->connect = (parser_connect)miracle_local_connect; + parser->execute = (parser_execute)miracle_local_execute; + parser->close = (parser_close)miracle_local_close; parser->real = local; if ( local != NULL ) { - memset( local, 0, sizeof( dv_local_t ) ); + memset( local, 0, sizeof( miracle_local_t ) ); local->parser = parser; local->root_dir[0] = '/'; } @@ -156,35 +156,35 @@ command_t; static command_t vocabulary[] = { {"BYE", NULL, 0, ATYPE_NONE, "Terminates the session. Units are not removed and task queue is not flushed."}, - {"HELP", print_help, 0, ATYPE_NONE, "Display this information!"}, - {"NLS", dv1394d_list_nodes, 0, ATYPE_NONE, "List the AV/C nodes on the 1394 bus."}, - {"UADD", dv1394d_add_unit, 0, ATYPE_STRING, "Create a new DV unit (virtual VTR) to transmit to receiver specified in GUID argument."}, - {"ULS", dv1394d_list_units, 0, ATYPE_NONE, "Lists the units that have already been added to the server."}, - {"CLS", dv1394d_list_clips, 0, ATYPE_STRING, "Lists the clips at directory name argument."}, - {"SET", dv1394d_set_global_property, 0, ATYPE_STRING, "Set a server configuration property."}, - {"GET", dv1394d_get_global_property, 0, ATYPE_STRING, "Get a server configuration property."}, - {"RUN", dv1394d_run, 0, ATYPE_STRING, "Run a batch file." }, - {"LIST", dv1394d_list, 1, ATYPE_NONE, "List the playlist associated to a unit."}, - {"LOAD", dv1394d_load, 1, ATYPE_STRING, "Load clip specified in absolute filename argument."}, - {"INSERT", dv1394d_insert, 1, ATYPE_STRING, "Insert a clip at the given clip index."}, - {"REMOVE", dv1394d_remove, 1, ATYPE_NONE, "Remove a clip at the given clip index."}, - {"CLEAN", dv1394d_clean, 1, ATYPE_NONE, "Clean a unit by removing all but the currently playing clip."}, - {"MOVE", dv1394d_move, 1, ATYPE_INT, "Move a clip to another clip index."}, - {"APND", dv1394d_append, 1, ATYPE_STRING, "Append a clip specified in absolute filename argument."}, - {"PLAY", dv1394d_play, 1, ATYPE_NONE, "Play a loaded clip at speed -2000 to 2000 where 1000 = normal forward speed."}, - {"STOP", dv1394d_stop, 1, ATYPE_NONE, "Stop a loaded and playing clip."}, - {"PAUSE", dv1394d_pause, 1, ATYPE_NONE, "Pause a playing clip."}, - {"REW", dv1394d_rewind, 1, ATYPE_NONE, "Rewind a unit. If stopped, seek to beginning of clip. If playing, play fast backwards."}, - {"FF", dv1394d_ff, 1, ATYPE_NONE, "Fast forward a unit. If stopped, seek to beginning of clip. If playing, play fast forwards."}, - {"STEP", dv1394d_step, 1, ATYPE_INT, "Step argument number of frames forward or backward."}, - {"GOTO", dv1394d_goto, 1, ATYPE_INT, "Jump to frame number supplied as argument."}, - {"SIN", dv1394d_set_in_point, 1, ATYPE_INT, "Set the IN point of the loaded clip to frame number argument. -1 = reset in point to 0"}, - {"SOUT", dv1394d_set_out_point, 1, ATYPE_INT, "Set the OUT point of the loaded clip to frame number argument. -1 = reset out point to maximum."}, - {"USTA", dv1394d_get_unit_status, 1, ATYPE_NONE, "Report information about the unit."}, - {"USET", dv1394d_set_unit_property, 1, ATYPE_STRING, "Set a unit configuration property."}, - {"UGET", dv1394d_get_unit_property, 1, ATYPE_STRING, "Get a unit configuration property."}, - {"XFER", dv1394d_transfer, 1, ATYPE_STRING, "Transfer the unit's clip to another unit specified as argument."}, - {"SHUTDOWN", dv1394d_shutdown, 0, ATYPE_NONE, "Shutdown the server."}, + {"HELP", miracle_help, 0, ATYPE_NONE, "Display this information!"}, + {"NLS", miracle_list_nodes, 0, ATYPE_NONE, "List the AV/C nodes on the 1394 bus."}, + {"UADD", miracle_add_unit, 0, ATYPE_STRING, "Create a new DV unit (virtual VTR) to transmit to receiver specified in GUID argument."}, + {"ULS", miracle_list_units, 0, ATYPE_NONE, "Lists the units that have already been added to the server."}, + {"CLS", miracle_list_clips, 0, ATYPE_STRING, "Lists the clips at directory name argument."}, + {"SET", miracle_set_global_property, 0, ATYPE_STRING, "Set a server configuration property."}, + {"GET", miracle_get_global_property, 0, ATYPE_STRING, "Get a server configuration property."}, + {"RUN", miracle_run, 0, ATYPE_STRING, "Run a batch file." }, + {"LIST", miracle_list, 1, ATYPE_NONE, "List the playlist associated to a unit."}, + {"LOAD", miracle_load, 1, ATYPE_STRING, "Load clip specified in absolute filename argument."}, + {"INSERT", miracle_insert, 1, ATYPE_STRING, "Insert a clip at the given clip index."}, + {"REMOVE", miracle_remove, 1, ATYPE_NONE, "Remove a clip at the given clip index."}, + {"CLEAN", miracle_clean, 1, ATYPE_NONE, "Clean a unit by removing all but the currently playing clip."}, + {"MOVE", miracle_move, 1, ATYPE_INT, "Move a clip to another clip index."}, + {"APND", miracle_append, 1, ATYPE_STRING, "Append a clip specified in absolute filename argument."}, + {"PLAY", miracle_play, 1, ATYPE_NONE, "Play a loaded clip at speed -2000 to 2000 where 1000 = normal forward speed."}, + {"STOP", miracle_stop, 1, ATYPE_NONE, "Stop a loaded and playing clip."}, + {"PAUSE", miracle_pause, 1, ATYPE_NONE, "Pause a playing clip."}, + {"REW", miracle_rewind, 1, ATYPE_NONE, "Rewind a unit. If stopped, seek to beginning of clip. If playing, play fast backwards."}, + {"FF", miracle_ff, 1, ATYPE_NONE, "Fast forward a unit. If stopped, seek to beginning of clip. If playing, play fast forwards."}, + {"STEP", miracle_step, 1, ATYPE_INT, "Step argument number of frames forward or backward."}, + {"GOTO", miracle_goto, 1, ATYPE_INT, "Jump to frame number supplied as argument."}, + {"SIN", miracle_set_in_point, 1, ATYPE_INT, "Set the IN point of the loaded clip to frame number argument. -1 = reset in point to 0"}, + {"SOUT", miracle_set_out_point, 1, ATYPE_INT, "Set the OUT point of the loaded clip to frame number argument. -1 = reset out point to maximum."}, + {"USTA", miracle_get_unit_status, 1, ATYPE_NONE, "Report information about the unit."}, + {"USET", miracle_set_unit_property, 1, ATYPE_STRING, "Set a unit configuration property."}, + {"UGET", miracle_get_unit_property, 1, ATYPE_STRING, "Get a unit configuration property."}, + {"XFER", miracle_transfer, 1, ATYPE_STRING, "Transfer the unit's clip to another unit specified as argument."}, + {"SHUTDOWN", miracle_shutdown, 0, ATYPE_NONE, "Shutdown the server."}, {NULL, NULL, 0, ATYPE_NONE, NULL} }; @@ -192,7 +192,7 @@ static command_t vocabulary[] = */ static char helpstr [] = - "dv1394d -- A DV over IEEE 1394 TCP Server\n" + "Miracle -- A Multimedia Playout Server\n" " Copyright (C) 2002-2003 Ushodaya Enterprises Limited\n" " Authors:\n" " Dan Dennedy \n" @@ -209,22 +209,22 @@ inline char *get_response_msg( int code ) return responses[ i ].message; } -/** Tell the user the dv1394d command set +/** Tell the user the miracle command set */ -response_codes print_help( command_argument cmd_arg ) +response_codes miracle_help( command_argument cmd_arg ) { int i = 0; - dv_response_printf( cmd_arg->response, 10240, "%s", helpstr ); + valerie_response_printf( cmd_arg->response, 10240, "%s", helpstr ); for ( i = 0; vocabulary[ i ].command != NULL; i ++ ) - dv_response_printf( cmd_arg->response, 1024, + valerie_response_printf( cmd_arg->response, 1024, "%-10.10s%s\n", vocabulary[ i ].command, vocabulary[ i ].help ); - dv_response_printf( cmd_arg->response, 2, "\n" ); + valerie_response_printf( cmd_arg->response, 2, "\n" ); return RESPONSE_SUCCESS_N; } @@ -232,28 +232,28 @@ response_codes print_help( command_argument cmd_arg ) /** Execute a batch file. */ -response_codes dv1394d_run( command_argument cmd_arg ) +response_codes miracle_run( command_argument cmd_arg ) { - dv_response temp = dv_parser_run( cmd_arg->parser, (char *)cmd_arg->argument ); + valerie_response temp = valerie_parser_run( cmd_arg->parser, (char *)cmd_arg->argument ); if ( temp != NULL ) { int index = 0; - dv_response_set_error( cmd_arg->response, - dv_response_get_error_code( temp ), - dv_response_get_error_string( temp ) ); + valerie_response_set_error( cmd_arg->response, + valerie_response_get_error_code( temp ), + valerie_response_get_error_string( temp ) ); - for ( index = 1; index < dv_response_count( temp ); index ++ ) - dv_response_printf( cmd_arg->response, 10240, "%s\n", dv_response_get_line( temp, index ) ); + for ( index = 1; index < valerie_response_count( temp ); index ++ ) + valerie_response_printf( cmd_arg->response, 10240, "%s\n", valerie_response_get_line( temp, index ) ); - dv_response_close( temp ); + valerie_response_close( temp ); } - return dv_response_get_error_code( cmd_arg->response ); + return valerie_response_get_error_code( cmd_arg->response ); } -response_codes dv1394d_shutdown( command_argument cmd_arg ) +response_codes miracle_shutdown( command_argument cmd_arg ) { exit( 0 ); return RESPONSE_SUCCESS; @@ -274,9 +274,9 @@ void signal_handler( int sig ) { #ifdef _GNU_SOURCE - dv1394d_log( LOG_DEBUG, "Received %s - shutting down.", strsignal(sig) ); + miracle_log( LOG_DEBUG, "Received %s - shutting down.", strsignal(sig) ); #else - dv1394d_log( LOG_DEBUG, "Received signal %i - shutting down.", sig ); + miracle_log( LOG_DEBUG, "Received signal %i - shutting down.", sig ); #endif exit(EXIT_SUCCESS); @@ -286,23 +286,21 @@ void signal_handler( int sig ) /** Local 'connect' function. */ -static dv_response dv_local_connect( dv_local local ) +static valerie_response miracle_local_connect( miracle_local local ) { - dv_response response = dv_response_init( ); + valerie_response response = valerie_response_init( ); self = pthread_self( ); - dv_response_set_error( response, 100, "VTR Ready" ); + valerie_response_set_error( response, 100, "VTR Ready" ); signal( SIGHUP, signal_handler ); signal( SIGINT, signal_handler ); - signal( SIGTERM, signal_handler ); + signal( SIGTERM, SIG_DFL ); signal( SIGSTOP, signal_handler ); + signal( SIGPIPE, signal_handler ); + signal( SIGALRM, signal_handler ); signal( SIGCHLD, SIG_IGN ); - - raw1394_reconcile_bus(); - /* Start the raw1394 service threads for handling bus resets */ - raw1394_start_service_threads(); return response; } @@ -310,18 +308,18 @@ static dv_response dv_local_connect( dv_local local ) /** Set the error and determine the message associated to this command. */ -void dv_command_set_error( command_argument cmd, response_codes code ) +void miracle_command_set_error( command_argument cmd, response_codes code ) { - dv_response_set_error( cmd->response, code, get_response_msg( code ) ); + valerie_response_set_error( cmd->response, code, get_response_msg( code ) ); } /** Parse the unit argument. */ -int dv_command_parse_unit( command_argument cmd, int argument ) +int miracle_command_parse_unit( command_argument cmd, int argument ) { int unit = -1; - char *string = dv_tokeniser_get_string( cmd->tokeniser, argument ); + char *string = valerie_tokeniser_get_string( cmd->tokeniser, argument ); if ( string != NULL && ( string[ 0 ] == 'U' || string[ 0 ] == 'u' ) && strlen( string ) > 1 ) unit = atoi( string + 1 ); return unit; @@ -330,10 +328,10 @@ int dv_command_parse_unit( command_argument cmd, int argument ) /** Parse a normal argument. */ -void *dv_command_parse_argument( command_argument cmd, int argument, arguments_types type ) +void *miracle_command_parse_argument( command_argument cmd, int argument, arguments_types type ) { void *ret = NULL; - char *value = dv_tokeniser_get_string( cmd->tokeniser, argument ); + char *value = valerie_tokeniser_get_string( cmd->tokeniser, argument ); if ( value != NULL ) { @@ -366,9 +364,9 @@ void *dv_command_parse_argument( command_argument cmd, int argument, arguments_t /** Get the error code - note that we simply the success return. */ -response_codes dv_command_get_error( command_argument cmd ) +response_codes miracle_command_get_error( command_argument cmd ) { - response_codes ret = dv_response_get_error_code( cmd->response ); + response_codes ret = valerie_response_get_error_code( cmd->response ); if ( ret == RESPONSE_SUCCESS_N || ret == RESPONSE_SUCCESS_1 ) ret = RESPONSE_SUCCESS; return ret; @@ -377,30 +375,30 @@ response_codes dv_command_get_error( command_argument cmd ) /** Execute the command. */ -static dv_response dv_local_execute( dv_local local, char *command ) +static valerie_response miracle_local_execute( miracle_local local, char *command ) { command_argument_t cmd; cmd.parser = local->parser; - cmd.response = dv_response_init( ); - cmd.tokeniser = dv_tokeniser_init( ); + cmd.response = valerie_response_init( ); + cmd.tokeniser = valerie_tokeniser_init( ); cmd.command = command; cmd.unit = -1; cmd.argument = NULL; cmd.root_dir = local->root_dir; /* Set the default error */ - dv_command_set_error( &cmd, RESPONSE_UNKNOWN_COMMAND ); + miracle_command_set_error( &cmd, RESPONSE_UNKNOWN_COMMAND ); /* Parse the command */ - if ( dv_tokeniser_parse_new( cmd.tokeniser, command, " " ) > 0 ) + if ( valerie_tokeniser_parse_new( cmd.tokeniser, command, " " ) > 0 ) { int index = 0; - char *value = dv_tokeniser_get_string( cmd.tokeniser, 0 ); + char *value = valerie_tokeniser_get_string( cmd.tokeniser, 0 ); int found = 0; /* Strip quotes from all tokens */ - for ( index = 0; index < dv_tokeniser_count( cmd.tokeniser ); index ++ ) - dv_util_strip( dv_tokeniser_get_string( cmd.tokeniser, index ), '\"' ); + for ( index = 0; index < valerie_tokeniser_count( cmd.tokeniser ); index ++ ) + valerie_util_strip( valerie_tokeniser_get_string( cmd.tokeniser, index ), '\"' ); /* Search the vocabulary array for value */ for ( index = 1; !found && vocabulary[ index ].command != NULL; index ++ ) @@ -412,35 +410,35 @@ static dv_response dv_local_execute( dv_local local, char *command ) { int position = 1; - dv_command_set_error( &cmd, RESPONSE_SUCCESS ); + miracle_command_set_error( &cmd, RESPONSE_SUCCESS ); if ( vocabulary[ index ].is_unit ) { - cmd.unit = dv_command_parse_unit( &cmd, position ); + cmd.unit = miracle_command_parse_unit( &cmd, position ); if ( cmd.unit == -1 ) - dv_command_set_error( &cmd, RESPONSE_MISSING_ARG ); + miracle_command_set_error( &cmd, RESPONSE_MISSING_ARG ); position ++; } - if ( dv_command_get_error( &cmd ) == RESPONSE_SUCCESS ) + if ( miracle_command_get_error( &cmd ) == RESPONSE_SUCCESS ) { - cmd.argument = dv_command_parse_argument( &cmd, position, vocabulary[ index ].type ); + cmd.argument = miracle_command_parse_argument( &cmd, position, vocabulary[ index ].type ); if ( cmd.argument == NULL && vocabulary[ index ].type != ATYPE_NONE ) - dv_command_set_error( &cmd, RESPONSE_MISSING_ARG ); + miracle_command_set_error( &cmd, RESPONSE_MISSING_ARG ); position ++; } - if ( dv_command_get_error( &cmd ) == RESPONSE_SUCCESS ) + if ( miracle_command_get_error( &cmd ) == RESPONSE_SUCCESS ) { response_codes error = vocabulary[ index ].operation( &cmd ); - dv_command_set_error( &cmd, error ); + miracle_command_set_error( &cmd, error ); } free( cmd.argument ); } } - dv_tokeniser_close( cmd.tokeniser ); + valerie_tokeniser_close( cmd.tokeniser ); return cmd.response; } @@ -448,13 +446,10 @@ static dv_response dv_local_execute( dv_local local, char *command ) /** Close the parser. */ -static void dv_local_close( dv_local local ) +static void miracle_local_close( miracle_local local ) { - raw1394_stop_service_threads(); - dv1394d_delete_all_units(); + miracle_delete_all_units(); pthread_kill_other_threads_np(); - dv1394d_log( LOG_DEBUG, "Clean shutdown." ); + miracle_log( LOG_DEBUG, "Clean shutdown." ); free( local ); - dv_clip_factory_close( ); - dv_frame_pool_close( ); } diff --git a/mlt/src/miracle/miracle_local.h b/mlt/src/miracle/miracle_local.h index fbbe4447..6baf0350 100644 --- a/mlt/src/miracle/miracle_local.h +++ b/mlt/src/miracle/miracle_local.h @@ -1,5 +1,5 @@ /* - * dvlocal.h -- Local dv1394d Parser + * miracle_local.h -- Local dv1394d Parser * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Charles Yates * @@ -18,11 +18,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _DV_LOCAL_H_ -#define _DV_LOCAL_H_ +#ifndef _MIRACLE_LOCAL_H_ +#define _MIRACLE_LOCAL_H_ /* Application header files */ -#include +#include #ifdef __cplusplus extern "C" @@ -32,7 +32,7 @@ extern "C" /** Local parser API. */ -extern dv_parser dv_parser_init_local( ); +extern valerie_parser miracle_parser_init_local( ); #ifdef __cplusplus } diff --git a/mlt/src/miracle/miracle_log.c b/mlt/src/miracle/miracle_log.c index cdb5d82f..adfc5467 100644 --- a/mlt/src/miracle/miracle_log.c +++ b/mlt/src/miracle/miracle_log.c @@ -1,5 +1,5 @@ /* - * log.h -- logging facility implementation + * miracle_log.c -- logging facility implementation * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Dan Dennedy * @@ -18,21 +18,16 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifdef HAVE_CONFIG_H -#include -#endif - #include #include #include -#include "log.h" +#include "miracle_log.h" static int log_output = log_stderr; static int threshold = LOG_DEBUG; -void -dv1394d_log_init( enum log_output method, int new_threshold ) +void miracle_log_init( enum log_output method, int new_threshold ) { log_output = method; threshold = new_threshold; @@ -41,8 +36,7 @@ dv1394d_log_init( enum log_output method, int new_threshold ) } -void -dv1394d_log( int priority, char *format, ... ) +void miracle_log( int priority, char *format, ... ) { va_list list; va_start( list, format ); diff --git a/mlt/src/miracle/miracle_log.h b/mlt/src/miracle/miracle_log.h index 04505e97..3788ee52 100644 --- a/mlt/src/miracle/miracle_log.h +++ b/mlt/src/miracle/miracle_log.h @@ -1,5 +1,5 @@ /* - * log.h -- logging facility header + * miracle_log.h -- logging facility header * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Dan Dennedy * @@ -33,8 +33,8 @@ enum log_output { log_syslog }; -void dv1394d_log_init( enum log_output method, int threshold ); -void dv1394d_log( int priority, char *format, ... ); +void miracle_log_init( enum log_output method, int threshold ); +void miracle_log( int priority, char *format, ... ); #ifdef __cplusplus } diff --git a/mlt/src/miracle/miracle_server.c b/mlt/src/miracle/miracle_server.c index d4f886b9..3c82c338 100644 --- a/mlt/src/miracle/miracle_server.c +++ b/mlt/src/miracle/miracle_server.c @@ -1,5 +1,5 @@ /* - * dvserver.c -- DV Server + * miracle_server.c -- DV Server * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Charles Yates * @@ -18,10 +18,6 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifdef HAVE_CONFIG_H -#include -#endif - /* System header files */ #include #include @@ -36,28 +32,29 @@ #include #include -#include "log.h" #include #include #include /* Application header files */ -#include "dvserver.h" -#include "dvconnection.h" -#include "dvlocal.h" -#include "log.h" -#include -#include +#include "miracle_server.h" +#include "miracle_connection.h" +#include "miracle_local.h" +#include "miracle_log.h" +#include +#include + +#define VERSION "0.0.1" /** Initialise a server structure. */ -dv_server dv_server_init( char *id ) +miracle_server miracle_server_init( char *id ) { - dv_server server = malloc( sizeof( dv_server_t ) ); + miracle_server server = malloc( sizeof( miracle_server_t ) ); if ( server != NULL ) { - memset( server, 0, sizeof( dv_server_t ) ); + memset( server, 0, sizeof( miracle_server_t ) ); server->id = id; server->port = DEFAULT_TCP_PORT; server->socket = -1; @@ -68,27 +65,27 @@ dv_server dv_server_init( char *id ) /** Set the port of the server. */ -void dv_server_set_port( dv_server server, int port ) +void miracle_server_set_port( miracle_server server, int port ) { server->port = port; } -void dv_server_set_proxy( dv_server server, char *proxy ) +void miracle_server_set_proxy( miracle_server server, char *proxy ) { - dv_tokeniser tokeniser = dv_tokeniser_init( ); + valerie_tokeniser tokeniser = valerie_tokeniser_init( ); server->proxy = 1; server->remote_port = DEFAULT_TCP_PORT; - dv_tokeniser_parse_new( tokeniser, proxy, ":" ); - strcpy( server->remote_server, dv_tokeniser_get_string( tokeniser, 0 ) ); - if ( dv_tokeniser_count( tokeniser ) == 2 ) - server->remote_port = atoi( dv_tokeniser_get_string( tokeniser, 1 ) ); - dv_tokeniser_close( tokeniser ); + valerie_tokeniser_parse_new( tokeniser, proxy, ":" ); + strcpy( server->remote_server, valerie_tokeniser_get_string( tokeniser, 0 ) ); + if ( valerie_tokeniser_count( tokeniser ) == 2 ) + server->remote_port = atoi( valerie_tokeniser_get_string( tokeniser, 1 ) ); + valerie_tokeniser_close( tokeniser ); } /** Wait for a connection. */ -static int dv_server_wait_for_connect( dv_server server ) +static int miracle_server_wait_for_connect( miracle_server server ) { struct timeval tv; fd_set rfds; @@ -106,9 +103,9 @@ static int dv_server_wait_for_connect( dv_server server ) /** Run the server thread. */ -static void *dv_server_run( void *arg ) +static void *miracle_server_run( void *arg ) { - dv_server server = arg; + miracle_server server = arg; pthread_t cmd_parse_info; connection_t *tmp = NULL; pthread_attr_t thread_attributes; @@ -116,7 +113,7 @@ static void *dv_server_run( void *arg ) socksize = sizeof( struct sockaddr ); - dv1394d_log( LOG_NOTICE, "%s version %s listening on port %i", server->id, VERSION, server->port ); + miracle_log( LOG_NOTICE, "%s version %s listening on port %i", server->id, VERSION, server->port ); /* Create the initial thread. We want all threads to be created detached so their resources get freed automatically. (CY: ... hmmph...) */ @@ -129,7 +126,7 @@ static void *dv_server_run( void *arg ) while ( !server->shutdown ) { /* Wait for a new connection. */ - if ( dv_server_wait_for_connect( server ) ) + if ( miracle_server_wait_for_connect( server ) ) { /* Create a new block of data to hold a copy of the incoming connection for our server thread. The thread should free this when it terminates. */ @@ -144,7 +141,7 @@ static void *dv_server_run( void *arg ) } } - dv1394d_log( LOG_NOTICE, "%s version %s server terminated.", server->id, VERSION ); + miracle_log( LOG_NOTICE, "%s version %s server terminated.", server->id, VERSION ); return NULL; } @@ -152,10 +149,10 @@ static void *dv_server_run( void *arg ) /** Execute the server thread. */ -int dv_server_execute( dv_server server ) +int miracle_server_execute( miracle_server server ) { int error = 0; - dv_response response = NULL; + valerie_response response = NULL; int index = 0; struct sockaddr_in ServerAddr; int flag = 1; @@ -172,7 +169,7 @@ int dv_server_execute( dv_server server ) { server->shutdown = 1; perror( "socket" ); - dv1394d_log( LOG_ERR, "%s unable to create socket.", server->id ); + miracle_log( LOG_ERR, "%s unable to create socket.", server->id ); return -1; } @@ -182,7 +179,7 @@ int dv_server_execute( dv_server server ) { server->shutdown = 1; perror( "bind" ); - dv1394d_log( LOG_ERR, "%s unable to bind to port %d.", server->id, server->port ); + miracle_log( LOG_ERR, "%s unable to bind to port %d.", server->id, server->port ); return -1; } @@ -190,7 +187,7 @@ int dv_server_execute( dv_server server ) { server->shutdown = 1; perror( "listen" ); - dv1394d_log( LOG_ERR, "%s unable to listen on port %d.", server->id, server->port ); + miracle_log( LOG_ERR, "%s unable to listen on port %d.", server->id, server->port ); return -1; } @@ -198,31 +195,31 @@ int dv_server_execute( dv_server server ) if ( !server->proxy ) { - dv1394d_log( LOG_NOTICE, "Starting server on %d.", server->port ); - server->parser = dv_parser_init_local( ); + miracle_log( LOG_NOTICE, "Starting server on %d.", server->port ); + server->parser = miracle_parser_init_local( ); } else { - dv1394d_log( LOG_NOTICE, "Starting proxy for %s:%d on %d.", server->remote_server, server->remote_port, server->port ); - server->parser = dv_parser_init_remote( server->remote_server, server->remote_port ); + miracle_log( LOG_NOTICE, "Starting proxy for %s:%d on %d.", server->remote_server, server->remote_port, server->port ); + server->parser = valerie_parser_init_remote( server->remote_server, server->remote_port ); } - response = dv_parser_connect( server->parser ); + response = valerie_parser_connect( server->parser ); - if ( response != NULL && dv_response_get_error_code( response ) == 100 ) + if ( response != NULL && valerie_response_get_error_code( response ) == 100 ) { /* read configuration file */ if ( response != NULL && !server->proxy ) { - dv_response_close( response ); - response = dv_parser_run( server->parser, "/etc/dv1394d.conf" ); + valerie_response_close( response ); + response = valerie_parser_run( server->parser, "/etc/miracle.conf" ); - if ( dv_response_count( response ) > 1 ) + if ( valerie_response_count( response ) > 1 ) { - if ( dv_response_get_error_code( response ) > 299 ) - dv1394d_log( LOG_ERR, "Error evaluating server configuration. Processing stopped." ); - for ( index = 0; index < dv_response_count( response ); index ++ ) - dv1394d_log( LOG_DEBUG, "%4d: %s", index, dv_response_get_line( response, index ) ); + if ( valerie_response_get_error_code( response ) > 299 ) + miracle_log( LOG_ERR, "Error evaluating server configuration. Processing stopped." ); + for ( index = 0; index < valerie_response_count( response ); index ++ ) + miracle_log( LOG_DEBUG, "%4d: %s", index, valerie_response_get_line( response, index ) ); } } @@ -235,16 +232,16 @@ int dv_server_execute( dv_server server ) pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ); pthread_attr_setschedpolicy( &attr, SCHED_FIFO ); pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ); - dv_response_close( response ); - result = pthread_create( &server->thread, &attr, dv_server_run, server ); + valerie_response_close( response ); + result = pthread_create( &server->thread, &attr, miracle_server_run, server ); if ( result ) { - dv1394d_log( LOG_WARNING, "Failed to schedule realtime (%s)", strerror(errno) ); + miracle_log( LOG_WARNING, "Failed to schedule realtime (%s)", strerror(errno) ); pthread_attr_setschedpolicy( &attr, SCHED_OTHER ); - result = pthread_create( &server->thread, &attr, dv_server_run, server ); + result = pthread_create( &server->thread, &attr, miracle_server_run, server ); if ( result ) { - dv1394d_log( LOG_CRIT, "Failed to launch TCP listener thread" ); + miracle_log( LOG_CRIT, "Failed to launch TCP listener thread" ); error = -1; } } @@ -252,7 +249,7 @@ int dv_server_execute( dv_server server ) } else { - dv1394d_log( LOG_ERR, "Error connecting to parser. Processing stopped." ); + miracle_log( LOG_ERR, "Error connecting to parser. Processing stopped." ); server->shutdown = 1; error = -1; } @@ -263,13 +260,13 @@ int dv_server_execute( dv_server server ) /** Shutdown the server. */ -void dv_server_shutdown( dv_server server ) +void miracle_server_shutdown( miracle_server server ) { if ( server != NULL && !server->shutdown ) { server->shutdown = 1; pthread_join( server->thread, NULL ); - dv_parser_close( server->parser ); + valerie_parser_close( server->parser ); close( server->socket ); } } diff --git a/mlt/src/miracle/miracle_server.h b/mlt/src/miracle/miracle_server.h index 96b22cee..95dfb524 100644 --- a/mlt/src/miracle/miracle_server.h +++ b/mlt/src/miracle/miracle_server.h @@ -1,5 +1,5 @@ /* - * dvserver.h -- DV Server + * miracle_server.h -- DV Server * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Charles Yates * @@ -18,14 +18,14 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef _DV_SERVER_H_ -#define _DV_SERVER_H_ +#ifndef _MIRACLE_SERVER_H_ +#define _MIRACLE_SERVER_H_ /* System header files */ #include /* Application header files */ -#include +#include #ifdef __cplusplus extern "C" @@ -45,23 +45,23 @@ typedef struct char *id; int port; int socket; - dv_parser parser; + valerie_parser parser; pthread_t thread; int shutdown; int proxy; char remote_server[ 50 ]; int remote_port; } -*dv_server, dv_server_t; +*miracle_server, miracle_server_t; /** API for the server */ -extern dv_server dv_server_init( char * ); -extern void dv_server_set_port( dv_server, int ); -extern void dv_server_set_proxy( dv_server, char * ); -extern int dv_server_execute( dv_server ); -extern void dv_server_shutdown( dv_server ); +extern miracle_server miracle_server_init( char * ); +extern void miracle_server_set_port( miracle_server, int ); +extern void miracle_server_set_proxy( miracle_server, char * ); +extern int miracle_server_execute( miracle_server ); +extern void miracle_server_shutdown( miracle_server ); #ifdef __cplusplus } diff --git a/mlt/src/miracle/miracle_unit.c b/mlt/src/miracle/miracle_unit.c index bc8adcfb..31c01cf7 100644 --- a/mlt/src/miracle/miracle_unit.c +++ b/mlt/src/miracle/miracle_unit.c @@ -1,5 +1,5 @@ /* - * dvunit.c -- DV Transmission Unit Implementation + * miracle_unit.c -- DV Transmission Unit Implementation * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Dan Dennedy * @@ -34,393 +34,306 @@ #include #include -#include -#include -#include #include -#include "dvunit.h" -#include "dvframe.h" -#include "dvframepool.h" -#include "dvqueue.h" -#include "dvpump.h" -#include "dverror.h" -#include "dvplayer.h" -#include "raw1394util.h" -#include "log.h" -#include "dvlocal.h" +#include "miracle_unit.h" +#include "miracle_log.h" +#include "miracle_local.h" + +#include /* Forward references */ -static void dv_unit_status_communicate( dv_unit ); +static void miracle_unit_status_communicate( miracle_unit ); + +/** Allocate a new DV transmission unit. + + \return A new miracle_unit handle. +*/ + +miracle_unit miracle_unit_init( int index, char *constructor ) +{ + miracle_unit this = NULL; + mlt_consumer consumer = NULL; + + char *id = strdup( constructor ); + char *arg = strchr( id, ':' ); + + if ( arg != NULL ) + *arg ++ = '\0'; -/** dv1394 device file names based upon devfs default names. */ + consumer = mlt_factory_consumer( id, arg ); -static char *devices[4][4] = { + if ( consumer != NULL ) { - "/dev/ieee1394/dv/host0/NTSC/in", - "/dev/ieee1394/dv/host0/NTSC/out", - "/dev/ieee1394/dv/host0/PAL/in", - "/dev/ieee1394/dv/host0/PAL/out", - },{ - "/dev/ieee1394/dv/host1/NTSC/in", - "/dev/ieee1394/dv/host1/NTSC/out", - "/dev/ieee1394/dv/host1/PAL/in", - "/dev/ieee1394/dv/host1/PAL/out" - },{ - "/dev/ieee1394/dv/host2/NTSC/in", - "/dev/ieee1394/dv/host2/NTSC/out", - "/dev/ieee1394/dv/host2/PAL/in", - "/dev/ieee1394/dv/host2/PAL/out" - },{ - "/dev/ieee1394/dv/host3/NTSC/in", - "/dev/ieee1394/dv/host3/NTSC/out", - "/dev/ieee1394/dv/host3/PAL/in", - "/dev/ieee1394/dv/host3/PAL/out" + mlt_playlist playlist = mlt_playlist_init( ); + this = calloc( sizeof( miracle_unit_t ), 1 ); + this->properties = mlt_properties_new( ); + this->producers = mlt_properties_new( ); + mlt_properties_init( this->properties, this ); + mlt_properties_set_int( this->properties, "unit", index ); + mlt_properties_set_int( this->properties, "generation", 0 ); + mlt_properties_set( this->properties, "constructor", constructor ); + mlt_properties_set( this->properties, "id", id ); + mlt_properties_set( this->properties, "arg", arg ); + mlt_properties_set_data( this->properties, "consumer", consumer, 0, ( mlt_destructor )mlt_consumer_close, NULL ); + mlt_properties_set_data( this->properties, "playlist", playlist, 0, ( mlt_destructor )mlt_playlist_close, NULL ); + mlt_consumer_connect( consumer, mlt_playlist_service( playlist ) ); } -}; -static int device_count[4] = {0,0,0,0}; - -/** Allocate a new DV transmission unit. + return this; +} - \param dv1394d_fd The file descriptor of a dv1394 device file to - use for transmission. - \param guid The node GUID of the receiving device. - \param channel The channel to use for transmission. - \return A new dv_unit handle. +/** Communicate the current status to all threads waiting on the notifier. */ -dv_unit dv_unit_init( octlet_t guid, int channel ) +static void miracle_unit_status_communicate( miracle_unit unit ) { - dv_unit unit = malloc( sizeof( dv_unit_t ) ); if ( unit != NULL ) { - int node_id; - - memset( unit, 0, sizeof( dv_unit_t ) ); - unit->guid = guid; - unit->buffer_size = 25; - unit->is_terminated = 1; - unit->channel = channel; - unit->dv1394_fd = -1; - unit->n_frames = DV1394_MAX_FRAMES / 2; - unit->n_fill = 1; - - /* get a raw1394 handle for plug control */ - if ( ( node_id = raw1394_find_node( &(unit->raw1394), guid ) ) != -1 ) - { - if ( dv_unit_online( unit ) == 1 ) - dv1394d_log( LOG_DEBUG, "Added online unit with GUID %08x%08x", - (quadlet_t) (unit->guid>>32), (quadlet_t) (unit->guid & 0xffffffff) ); - else - { - dv_unit_close( unit ); - unit = NULL; - } - } - else + mlt_properties properties = unit->properties; + char *root_dir = mlt_properties_get( properties, "root" ); + valerie_notifier notifier = mlt_properties_get_data( properties, "notifier", NULL ); + valerie_status_t status; + + if ( root_dir != NULL && notifier != NULL ) { - dv1394d_log( LOG_DEBUG, "Added offline unit with GUID %08x%08x", - (quadlet_t) (unit->guid>>32), (quadlet_t) (unit->guid & 0xffffffff) ); + if ( miracle_unit_get_status( unit, &status ) == 0 ) + /* if ( !( ( status.status == unit_playing || status.status == unit_paused ) && + strcmp( status.clip, "" ) && + !strcmp( status.tail_clip, "" ) && + status.position == 0 && + status.in == 0 && + status.out == 0 ) ) */ + valerie_notifier_put( notifier, &status ); } } - return unit; } -/** Allow stdin to feed the unit (redundant now that senddv has been dropped). +/** Set the notifier info */ -void dv_unit_allow_stdin( dv_unit unit, int flag ) +void miracle_unit_set_notifier( miracle_unit this, valerie_notifier notifier, char *root_dir ) { - unit->allow_stdin = flag; + mlt_properties properties = this->properties; + mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); + mlt_properties playlist_properties = mlt_playlist_properties( playlist ); + + mlt_properties_set( properties, "root", root_dir ); + mlt_properties_set_data( properties, "notifier", notifier, 0, NULL, NULL ); + mlt_properties_set_data( playlist_properties, "notifier_arg", this, 0, NULL, NULL ); + mlt_properties_set_data( playlist_properties, "notifier", miracle_unit_status_communicate, 0, NULL, NULL ); + + miracle_unit_status_communicate( this ); } -/** Override the default buffer/pump size - this must be done prior to the pumps - creation. +/** Create or locate a producer for the file specified. */ -void dv_unit_set_buffer_size( dv_unit unit, int size ) +static mlt_producer create_producer( miracle_unit unit, char *file ) { - if ( size > 0 ) + // Get the unit properties + mlt_properties properties = unit->producers; + + // Check if we already have loaded this file + mlt_producer result = mlt_properties_get_data( properties, file, NULL ); + + if ( result == NULL ) { - if ( unit->pump == NULL ) - unit->buffer_size = size; - else - unit->buffer_size = dv_pump_resize( unit->pump, size ); + // 1st Line preferences + if ( strstr( file, ".mpg" ) ) + result = mlt_factory_producer( "mcmpeg", file ); + else if ( strstr( file, ".mpeg" ) ) + result = mlt_factory_producer( "mcmpeg", file ); + else if ( strstr( file, ".dv" ) ) + result = mlt_factory_producer( "mcdv", file ); + else if ( strstr( file, ".dif" ) ) + result = mlt_factory_producer( "mcdv", file ); + else if ( strstr( file, ".jpg" ) ) + result = mlt_factory_producer( "pixbuf", file ); + else if ( strstr( file, ".JPG" ) ) + result = mlt_factory_producer( "pixbuf", file ); + else if ( strstr( file, ".jpeg" ) ) + result = mlt_factory_producer( "pixbuf", file ); + else if ( strstr( file, ".png" ) ) + result = mlt_factory_producer( "pixbuf", file ); + + // 2nd Line fallbacks + if ( result == NULL && strstr( file, ".dv" ) ) + result = mlt_factory_producer( "libdv", file ); + else if ( result == NULL && strstr( file, ".dif" ) ) + result = mlt_factory_producer( "libdv", file ); + + // 3rd line fallbacks + if ( result == NULL ) + result = mlt_factory_producer( "ffmpeg", file ); + + // Now store the result + mlt_properties_set_data( properties, file, result, 0, ( mlt_destructor )mlt_producer_close, NULL ); } -} -int dv_unit_get_buffer_size( dv_unit unit ) -{ - return unit->buffer_size; + return result; } -void dv_unit_set_n_frames( dv_unit unit, int size ) -{ - if ( size > 0 && size <= DV1394_MAX_FRAMES / 2 ) - unit->n_frames = size; -} +/** Update the generation count. +*/ -int dv_unit_get_n_frames( dv_unit unit ) +static void update_generation( miracle_unit unit ) { - return unit->n_frames; + mlt_properties properties = unit->properties; + int generation = mlt_properties_get_int( properties, "generation" ); + mlt_properties_set_int( properties, "generation", ++ generation ); } -void dv_unit_set_n_fill( dv_unit unit, int size ) +static void clear_unit( miracle_unit unit ) { - unit->n_fill = size; -} + mlt_properties properties = unit->properties; + mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); + mlt_producer producer = mlt_playlist_producer( playlist ); -int dv_unit_get_n_fill( dv_unit unit ) -{ - return unit->n_fill; -} + mlt_playlist_clear( playlist ); + mlt_producer_seek( producer, 0 ); -/** Set the notifier info -*/ + if ( unit->old_producers != NULL ) + mlt_properties_close( unit->old_producers ); + unit->old_producers = unit->producers; + unit->producers = mlt_properties_new( ); -void dv_unit_set_notifier( dv_unit this, dv1394_notifier notifier, char *root_dir ) -{ - this->notifier = notifier; - this->root_dir = root_dir; - dv_unit_status_communicate( this ); + update_generation( unit ); } -/** Communicate the current status to all threads waiting on the notifier. +/** Generate a report on all loaded clips. */ -static void dv_unit_status_communicate( dv_unit unit ) +void miracle_unit_report_list( miracle_unit unit, valerie_response response ) { - if ( unit != NULL && unit->notifier != NULL && unit->root_dir != NULL ) + int i; + mlt_properties properties = unit->properties; + int generation = mlt_properties_get_int( properties, "generation" ); + mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); + + valerie_response_printf( response, 1024, "%d\n", generation ); + + for ( i = 0; i < mlt_playlist_count( playlist ); i ++ ) { - dv1394_status_t status; - if ( dv_unit_get_status( unit, &status ) == 0 ) - if ( !( ( status.status == unit_playing || status.status == unit_paused ) && - strcmp( status.clip, "" ) && - !strcmp( status.tail_clip, "" ) && - status.position == 0 && - status.in == 0 && - status.out == 0 ) ) - dv1394_notifier_put( unit->notifier, &status ); + mlt_playlist_clip_info info; + mlt_playlist_get_clip_info( playlist , &info, i ); + valerie_response_printf( response, 10240, "%d \"%s\" %e %e %e %e %.2f\n", + i, info.resource, info.in, info.out, info.playtime, info.length, info.fps ); } } /** Load a clip into the unit clearing existing play list. \todo error handling - \param unit A dv_unit handle. + \param unit A miracle_unit handle. \param clip The absolute file name of the clip to load. \param in The starting frame (-1 for 0) \param out The ending frame (-1 for maximum) */ -dv_error_code dv_unit_load( dv_unit unit, const char *clip, long in, long out, int flush ) +valerie_error_code miracle_unit_load( miracle_unit unit, char *clip, double in, double out, int flush ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_error_code error = dv_player_get_error( player ); - if ( error == dv_pump_ok ) + // Have to clear the unit first + clear_unit( unit ); + + // Now try to create an producer + mlt_producer instance = create_producer( unit, clip ); + + if ( instance != NULL ) { - error = dv_player_replace_file( player, (char*) clip, in, out, flush ); - dv1394d_log( LOG_DEBUG, "loaded clip %s", clip ); - if ( unit->is_terminated ) - dv_unit_status_communicate( unit ); + mlt_properties properties = unit->properties; + mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); + mlt_playlist_append_io( playlist, instance, in, out ); + miracle_log( LOG_DEBUG, "loaded clip %s", clip ); + miracle_unit_status_communicate( unit ); + return valerie_ok; } - return error; + + return valerie_invalid_file; } -dv_error_code dv_unit_insert( dv_unit unit, const char *clip, int index, long in, long out ) +valerie_error_code miracle_unit_insert( miracle_unit unit, const char *clip, int index, double in, double out ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_error_code error = dv_player_get_error( player ); + /* + dv_player player = miracle_unit_get_dv_player( unit ); + valerie_error_code error = dv_player_get_error( player ); if ( error == dv_pump_ok ) { error = dv_player_insert_file( player, (char*) clip, index, in, out ); dv1394d_log( LOG_DEBUG, "inserted clip %s", clip ); if ( unit->is_terminated ) - dv_unit_status_communicate( unit ); + miracle_unit_status_communicate( unit ); } return error; + */ + return valerie_ok; } -dv_error_code dv_unit_remove( dv_unit unit, int index ) +valerie_error_code miracle_unit_remove( miracle_unit unit, int index ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_error_code error = dv_player_get_error( player ); + /* + dv_player player = miracle_unit_get_dv_player( unit ); + valerie_error_code error = dv_player_get_error( player ); if ( error == dv_pump_ok ) { error = dv_player_remove_clip( player, index ); dv1394d_log( LOG_DEBUG, "removed clip %d", index ); if ( unit->is_terminated ) - dv_unit_status_communicate( unit ); + miracle_unit_status_communicate( unit ); } return error; + */ + return valerie_ok; } -dv_error_code dv_unit_clean( dv_unit unit ) +valerie_error_code miracle_unit_clean( miracle_unit unit ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_error_code error = dv_player_get_error( player ); - if ( error == dv_pump_ok ) - { - error = dv_player_clean( player ); - dv1394d_log( LOG_DEBUG, "Cleaned playlist" ); - if ( unit->is_terminated ) - dv_unit_status_communicate( unit ); - } - return error; + clear_unit( unit ); + miracle_log( LOG_DEBUG, "Cleaned playlist" ); + return valerie_ok; } -dv_error_code dv_unit_move( dv_unit unit, int src, int dest ) +valerie_error_code miracle_unit_move( miracle_unit unit, int src, int dest ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_error_code error = dv_player_get_error( player ); + /* + dv_player player = miracle_unit_get_dv_player( unit ); + valerie_error_code error = dv_player_get_error( player ); if ( error == dv_pump_ok ) { error = dv_player_move_clip( player, src, dest ); dv1394d_log( LOG_DEBUG, "moved clip %d to %d", src, dest ); if ( unit->is_terminated ) - dv_unit_status_communicate( unit ); + miracle_unit_status_communicate( unit ); } return error; + */ + return valerie_ok; } /** Add a clip to the unit play list. \todo error handling - \param unit A dv_unit handle. + \param unit A miracle_unit handle. \param clip The absolute file name of the clip to load. \param in The starting frame (-1 for 0) \param out The ending frame (-1 for maximum) */ -dv_error_code dv_unit_append( dv_unit unit, const char *clip, long in, long out ) +valerie_error_code miracle_unit_append( miracle_unit unit, char *clip, double in, double out ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_error_code error = dv_player_add_file( player, (char*) clip, in, out ); - dv_unit_status_communicate( unit ); - return error; -} + mlt_producer instance = create_producer( unit, clip ); -void *output_cleanup( void *arg ) -{ - dv_unit unit = arg; - if ( unit != NULL && unit->mmap != NULL ) + if ( instance != NULL ) { - unit->is_terminated = 1; - dv_unit_status_communicate( unit ); - munmap( unit->mmap, unit->mmap_length ); - /* this actually stops transmission as opposed to allowing the - last frame to loop in the OHCI DMA context. */ - ioctl( unit->dv1394_fd, DV1394_SHUTDOWN, NULL ); + mlt_properties properties = unit->properties; + mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); + mlt_playlist_append_io( playlist, instance, in, out ); + miracle_log( LOG_DEBUG, "appended clip %s", clip ); + miracle_unit_status_communicate( unit ); + return valerie_ok; } - return NULL; -} - -/** The dv1394 transmission thread. - - \param arg A dv_unit handle. -*/ - -static void *output( void *arg ) -{ - dv_unit unit = arg; - dv_frame frames[ DV1394_MAX_FRAMES ]; - int frames_dropped = 0; /* count of total frames dropped (repeated) */ - struct dv1394_status status; - char errstr[64]; - int n_fill = unit->n_fill; - int n_frames = unit->n_frames; - - /* Determine the number of frames to wait for/fill on each iteration */ - if ( n_fill < 1 ) - n_fill = 1; - else if ( n_fill > unit->n_frames ) - n_fill = n_frames / 2; - - unit->mmap = mmap( NULL,unit->mmap_length,PROT_WRITE,MAP_SHARED,unit->dv1394_fd,0 ); - if ( unit->mmap == MAP_FAILED || unit->mmap == NULL ) - { - perror( "mmap" ); - return NULL; - } - - pthread_cleanup_push( output_cleanup, (void *)arg ); - - while ( dv_pump_get_available_output_count( unit->pump ) || - !( dv_unit_has_terminated( unit ) || dv_pump_has_terminated( unit->pump) ) ) - { - int available = 0; - - if ( ioctl( unit->dv1394_fd, DV1394_WAIT_FRAMES, n_fill ) < 0) - perror( "DV1394_WAIT_FRAMES" ); - - pthread_testcancel(); - - /* update the status for the next iteration and detect dropped frames */ - if ( ioctl( unit->dv1394_fd, DV1394_GET_STATUS, &status ) >= 0) - { - pthread_testcancel(); - - /* - printf( "dv1394 status: active=%02d, #clear=%02d, first clear=%02d\n", - status.active_frame, status.n_clear_frames, status.first_clear_frame); - */ - - /* report dropped frames */ - if( status.dropped_frames > 0 ) - { - frames_dropped += status.dropped_frames; - dv1394d_log( LOG_WARNING, "dv1394 repeated %d frames with %d available.", - status.dropped_frames, dv_pump_get_available_output_count( unit->pump ) ); - } - - available = dv_pump_get_output_block( unit->pump, (void **)frames, n_fill ); - - dv_unit_status_communicate( unit ); - - /* The only time we get 0 frames is when the unit is being stopped. */ - if ( available != 0 ) - { - int size = dv_frame_size( frames[ 0 ] ); - int pos = status.first_clear_frame; - int index = 0; - - for ( index = 0; index < available; index ++ ) - memcpy( unit->mmap + ( ( pos + index ) % n_frames ) * size, dv_frame_data( frames[ index ] ), size ); - - if ( ioctl( unit->dv1394_fd, DV1394_SUBMIT_FRAMES, available ) >= 0) - { - for ( index = 0; index < available - 1; index ++ ) - { - dv_frame_clear_error( frames[ index ] ); - dv_frame_id_clear( dv_frame_get_id( frames[ index ] ) ); - } - dv_pump_return_output_block( unit->pump ); - pthread_testcancel(); - } - else - { - dv1394d_log( LOG_ERR, "failed to write frames to dv1394: %s.", strerror_r( errno, errstr, 63 ) ); - dv_pump_terminate( unit->pump ); - dv_pump_flush( unit->pump ); - pthread_testcancel(); - } - } - } - else - { - dv1394d_log( LOG_ERR, "failed to get dv1394 status: %s.", strerror_r( errno, errstr, 63 ) ); - dv_pump_return_used_output( unit->pump ); - } - } - - if ( frames_dropped > 0 ) - dv1394d_log( LOG_WARNING, "dv1394 repeated %d frames total during this transmission.", frames_dropped ); - - pthread_cleanup_pop( 1 ); - - return NULL; + return valerie_invalid_file; } /** Start playing the clip. @@ -428,317 +341,92 @@ static void *output( void *arg ) Start a dv-pump and commence dv1394 transmission. \todo error handling - \param unit A dv_unit handle. + \param unit A miracle_unit handle. \param speed An integer that specifies the playback rate as a percentage multiplied by 100. */ -void dv_unit_play( dv_unit_t *unit, int speed ) +void miracle_unit_play( miracle_unit_t *unit, int speed ) { - dv_player player = dv_unit_get_dv_player( unit ); - - if ( unit->is_terminated == 1 && ( dv_player_get_total_frames( player ) > 0 || unit->allow_stdin ) ) - { - int retval; - dv_frame frame = NULL; - struct dv1394_init setup = - { - api_version: DV1394_API_VERSION, - channel: unit->channel, - /* this only sets the *requested* size of the ringbuffer, - in frames */ - n_frames: unit->n_frames, - /* we set the format later */ - cip_n: unit->dv1394_cip_n, - cip_d: unit->dv1394_cip_d, - syt_offset: unit->dv1394_syt_offset - }; - pthread_attr_t attr; - - if ( unit->in == NULL ) - { - if ( !unit->allow_stdin || dv_player_get_total_frames( player ) != 0 ) - unit->in = dv_player_get_dv_input( player ); - else - unit->in = dv_input_init( unit->pump ); - } - else - { - dv_input_join_thread( unit->in ); - pthread_join( unit->out, NULL ); - } - - unit->is_terminated = 0; - dv_pump_restart( unit->pump ); - dv_input_start_thread( unit->in ); - dv_player_set_speed( player, (double) speed/1000.0 ); - - /* first we read a little data to see if this is PAL or NTSC - so we can initialize dv1394 properly */ - frame = dv_pump_get_available_output( unit->pump ); - - /* initialize dv1394 */ - setup.format = dv_frame_is_pal(frame) ? DV1394_PAL : DV1394_NTSC; - - retval = ioctl( unit->dv1394_fd, DV1394_INIT, &setup ); - if (retval < 0) - { - perror( "DV1394_INIT" ); - return; - } - - unit->mmap_length = unit->n_frames * dv_frame_size( frame ); - - pthread_attr_init( &attr ); - pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); - pthread_attr_setinheritsched( &attr, PTHREAD_INHERIT_SCHED ); - pthread_create( &unit->out, &attr, output, unit ); - } - else - { - dv_player_set_speed( player, (double) speed/1000.0 ); - } - dv_unit_status_communicate( unit ); + mlt_properties properties = unit->properties; + mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); + mlt_producer producer = mlt_playlist_producer( playlist ); + mlt_producer_set_speed( producer, ( double )speed / 1000 ); + miracle_unit_status_communicate( unit ); } /** Stop playback. Terminates the dv_pump and halts dv1394 transmission. - \param unit A dv_unit handle. + \param unit A miracle_unit handle. */ -void dv_unit_terminate( dv_unit unit ) +void miracle_unit_terminate( miracle_unit unit ) { - unit->is_terminated = 1; - if ( unit->pump != NULL ) - { - dv_pump_terminate( unit->pump ); - dv_pump_flush( unit->pump ); - } } /** Query the status of unit playback. - \param unit A dv_unit handle. + \param unit A miracle_unit handle. \return 1 if the unit is not playing, 0 if playing. */ -int dv_unit_has_terminated( dv_unit unit ) +int miracle_unit_has_terminated( miracle_unit unit ) { - return unit->is_terminated; -} - -/** Get the dv_player from the dv_unit. - - \param unit A dv_unit handle. - \return A dv_player handle. -*/ - -dv_player dv_unit_get_dv_player( dv_unit unit ) -{ - if ( unit != NULL ) - { - if ( unit->pump == NULL ) - { - unit->pump = dv_pump_init( unit->buffer_size ); - if ( unit->pump != NULL ) - unit->player = dv_player_init( unit->pump ); - } - return unit->player; - } - return NULL; + return 0; } - /** Transfer the currently loaded clip to another unit */ -int dv_unit_transfer( dv_unit dest_unit, dv_unit src_unit ) +int miracle_unit_transfer( miracle_unit dest_unit, miracle_unit src_unit ) { - dv_player src_player = dv_unit_get_dv_player( src_unit ); - dv_player dest_player = dv_unit_get_dv_player( dest_unit ); - - if( dest_player != NULL && src_player != NULL ) - dv_player_replace_player( dest_player, src_player ); - return 0; } -/** Get the guid associated to this unit. -*/ - -octlet_t dv_unit_get_guid( dv_unit unit ) -{ - return unit->guid; -} - -/** Get the node id associated to this unit. -*/ - -int dv_unit_get_nodeid( dv_unit unit ) -{ - return (unit->node_id & 0x3f); -} - -/** Get the channel associated to this unit. -*/ - -int dv_unit_get_channel( dv_unit unit ) -{ - return (unit->channel); -} - -/** Turn unit online. -*/ - -int dv_unit_online( dv_unit unit ) -{ - int result = 0; - int port, node_id; - - if ( unit->raw1394 != NULL ) - raw1394_close( unit->raw1394 ); - - node_id = raw1394_find_node( &(unit->raw1394), unit->guid ); - if ( node_id != -1 ) - { - unit->node_id = 0xffc0 | node_id; - port = dv_unit_get_port( unit ); - - unit->dv1394_fd = open( devices[ port ][ device_count[port] ], O_RDWR ); - if ( unit->dv1394_fd < 0 ) - { - dv1394d_log( LOG_ERR, "failed to open dv1394 device - %s\n", devices[ port ][ device_count[port] ] ); - dv_unit_close( unit ); - } - else - { - device_count[ port ] ++; - if ( establish_p2p_connection( unit->raw1394, unit->node_id, (unsigned int *) &(unit->channel) ) ) - { - avc1394_vcr_record( unit->raw1394, unit->node_id ); - unit->online = 1; - dv_unit_status_communicate( unit ); - result = 1; - } - } - } - - return result; -} - -/** Turn unit offline. -*/ - -void dv_unit_offline( dv_unit unit ) -{ - if ( unit->online == 1 ) - { - if ( unit->is_terminated == 0 ) - dv_unit_terminate( unit ); - unit->online = 0; - if ( unit->raw1394 != NULL ) - { - avc1394_vcr_stop( unit->raw1394, unit->node_id ); - break_p2p_connection( unit->raw1394, unit->node_id, unit->channel ); - } - if ( unit->dv1394_fd > -1 ) - { - close( unit->dv1394_fd ); - device_count[ dv_unit_get_port( unit ) ] --; - } - dv_unit_status_communicate( unit ); - dv1394d_log( LOG_DEBUG, "Unit with GUID %08x%08x is now offline.", - (quadlet_t) (unit->guid>>32), (quadlet_t) (unit->guid & 0xffffffff) ); - } -} - /** Determine if unit is offline. */ -int dv_unit_is_offline( dv_unit unit ) +int miracle_unit_is_offline( miracle_unit unit ) { - return (unit->online == 0); + return 0; } /** Obtain the status for a given unit */ -int dv_unit_get_status( dv_unit unit, dv1394_status status ) +int miracle_unit_get_status( miracle_unit unit, valerie_status status ) { - int error = -1; + int error = unit == NULL; - memset( status, 0, sizeof( dv1394_status_t ) ); + memset( status, 0, sizeof( valerie_status_t ) ); - if ( unit != NULL ) + if ( !error ) { - dv_player player = dv_unit_get_dv_player( unit ); + mlt_properties properties = unit->properties; + mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); + mlt_producer producer = mlt_playlist_producer( playlist ); + mlt_producer clip = mlt_playlist_current( playlist ); - error = 0; + mlt_playlist_clip_info info; + int clip_index = mlt_playlist_current_clip( playlist ); + mlt_playlist_get_clip_info( playlist, &info, clip_index ); - if ( player != NULL ) + if ( info.resource != NULL && strcmp( info.resource, "" ) ) { - dv_frame head = dv_pump_get_head( player->pump ); - dv_frame tail = dv_pump_get_tail( player->pump ); - - status->speed = (int)( dv_player_get_speed( player ) * 1000.0 ); - status->fps = dv_player_frames_per_second( player, 0 ); - - if ( head != NULL ) - { - dv_frame_id id = dv_frame_get_id( head ); - if ( id->resource != NULL ) - { - const char *resource = id->resource; - if ( resource != NULL && unit->root_dir != NULL ) - resource += strlen( unit->root_dir ) - ( unit->root_dir[ strlen( unit->root_dir ) - 1 ] == '/' ); - strncpy( status->clip, resource, sizeof( status->clip ) ); - } - else - { - char *title = dv_player_get_name( player, dv_player_get_clip_containing( player, 0 ), unit->root_dir ); - if ( title != NULL ) - strncpy( status->clip, title, sizeof( status->clip ) ); - } - - status->position = id->relative; - status->in = id->in; - status->out = id->out; - status->length = id->length; - status->seek_flag = id->seek_flag; - } - else - { - char *title = dv_player_get_name( player, dv_player_get_clip_containing( player, 0 ), unit->root_dir ); - if ( title != NULL ) - strncpy( status->clip, title, sizeof( status->clip ) ); - } - - if ( tail != NULL ) - { - dv_frame_id id = dv_frame_get_id( tail ); - const char *resource = id->resource; - if ( resource != NULL && unit->root_dir != NULL ) - resource += strlen( unit->root_dir ) - ( unit->root_dir[ strlen( unit->root_dir ) - 1 ] == '/' ); - if ( resource != NULL ) - strncpy( status->tail_clip, resource, sizeof( status->clip ) ); - status->tail_position = id->relative; - status->tail_in = id->in; - status->tail_out = id->out; - status->tail_length = id->length; - } - - status->generation = player->generation; - status->clip_index = dv_unit_get_current_clip( unit ); + strncpy( status->clip, info.resource, sizeof( status->clip ) ); + status->speed = (int)( mlt_producer_get_speed( producer ) * 1000.0 ); + status->fps = mlt_producer_get_fps( producer ); + status->in = info.in; + status->out = info.in + info.playtime; + status->position = mlt_producer_position( clip ); + status->length = mlt_producer_get_length( clip ); + status->seek_flag = 1; } - if ( dv_unit_is_offline( unit ) ) - status->status = unit_offline; - else if ( !strcmp( status->clip, "" ) ) + if ( !strcmp( status->clip, "" ) ) status->status = unit_not_loaded; - else if ( dv_unit_has_terminated( unit ) ) - status->status = unit_stopped; else if ( status->speed == 0 ) status->status = unit_paused; else @@ -749,7 +437,7 @@ int dv_unit_get_status( dv_unit unit, dv1394_status status ) status->status = unit_undefined; } - status->unit = unit->unit; + status->unit = mlt_properties_get_int( unit->properties, "unit" ); return error; } @@ -757,344 +445,104 @@ int dv_unit_get_status( dv_unit unit, dv1394_status status ) /** Change position in the playlist. */ -void dv_unit_change_position( dv_unit unit, int clip, long position ) +void miracle_unit_change_position( miracle_unit unit, int clip, double position ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_player_set_clip_position( player, clip, position ); - dv_unit_status_communicate( unit ); + miracle_unit_status_communicate( unit ); } /** Change speed. */ -void dv_unit_change_speed( dv_unit unit, int speed ) +void miracle_unit_change_speed( miracle_unit unit, int speed ) { - if ( dv_unit_has_terminated( unit ) ) - dv_unit_change_position( unit, 0, 0 ); - else - dv_unit_play( unit, speed ); } -int dv_unit_get_current_clip( dv_unit unit ) +int miracle_unit_get_current_clip( miracle_unit unit ) { - dv_player player = dv_unit_get_dv_player( unit ); - unsigned long position = dv_player_get_position( player ); - return dv_player_get_clip_containing( player, position ); + return 0; } /** Set a clip's in point */ -int dv_unit_set_clip_in( dv_unit unit, int index, long position ) +int miracle_unit_set_clip_in( miracle_unit unit, int index, double position ) { int error = 0; - dv_player player = dv_unit_get_dv_player( unit ); - - if ( player != NULL ) - { - dv_unit_change_speed( unit, 0 ); - if ( dv_player_set_in_point( player, index, (unsigned long) position ) == position ) - dv_player_set_clip_position( player, index, position ); - else - error = -2; - } - else - { - error = -1; - } - - dv_unit_status_communicate( unit ); - return error; - } /** Set a clip's out point. */ -int dv_unit_set_clip_out( dv_unit unit, int index, long position ) +int miracle_unit_set_clip_out( miracle_unit unit, int index, double position ) { int error = 0; - dv_player player = dv_unit_get_dv_player( unit ); - - if ( player != NULL ) - { - dv_unit_change_speed( unit, 0 ); - if ( dv_player_set_out_point( player, index, position ) == position ) - dv_player_set_clip_position( player, index, position ); - else - error = -2; - } - else - { - error = -1; - } - - dv_unit_status_communicate( unit ); - return error; } /** Step by specified position. */ -void dv_unit_step( dv_unit unit, int offset ) +void miracle_unit_step( miracle_unit unit, double offset ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_player_change_position( player, dv_seek_relative, offset ); } /** Set the unit's clip mode regarding in and out points. */ -void dv_unit_set_mode( dv_unit unit, dv_player_clip_mode mode ) -{ - dv_player player = dv_unit_get_dv_player( unit ); - if ( player != NULL ) - dv_player_set_clip_mode( player, mode ); - dv_unit_status_communicate( unit ); -} +//void miracle_unit_set_mode( miracle_unit unit, dv_player_clip_mode mode ) +//{ + //dv_player player = miracle_unit_get_dv_player( unit ); + //if ( player != NULL ) + //dv_player_set_clip_mode( player, mode ); + //miracle_unit_status_communicate( unit ); +//} /** Get the unit's clip mode regarding in and out points. */ -dv_player_clip_mode dv_unit_get_mode( dv_unit unit ) -{ - dv_player player = dv_unit_get_dv_player( unit ); - return dv_player_get_clip_mode( player ); -} +//dv_player_clip_mode miracle_unit_get_mode( miracle_unit unit ) +//{ + //dv_player player = miracle_unit_get_dv_player( unit ); + //return dv_player_get_clip_mode( player ); +//} /** Set the unit's clip mode regarding eof handling. */ -void dv_unit_set_eof_action( dv_unit unit, dv_player_eof_action action ) -{ - dv_player player = dv_unit_get_dv_player( unit ); - dv_player_set_eof_action( player, action ); - dv_unit_status_communicate( unit ); -} +//void miracle_unit_set_eof_action( miracle_unit unit, dv_player_eof_action action ) +//{ + //dv_player player = miracle_unit_get_dv_player( unit ); + //dv_player_set_eof_action( player, action ); + //miracle_unit_status_communicate( unit ); +//} /** Get the unit's clip mode regarding eof handling. */ -dv_player_eof_action dv_unit_get_eof_action( dv_unit unit ) -{ - dv_player player = dv_unit_get_dv_player( unit ); - return dv_player_get_eof_action( player ); -} +//dv_player_eof_action miracle_unit_get_eof_action( miracle_unit unit ) +//{ + //dv_player player = miracle_unit_get_dv_player( unit ); + //return dv_player_get_eof_action( player ); +//} /** Release the unit \todo error handling - \param unit A dv_unit handle. + \param unit A miracle_unit handle. */ -void dv_unit_close( dv_unit unit ) +void miracle_unit_close( miracle_unit unit ) { if ( unit != NULL ) { - dv1394d_log( LOG_DEBUG, "closing unit..." ); - dv_unit_offline( unit ); - if ( unit->pump != NULL ) - { - dv_pump_terminate( unit->pump ); - dv_pump_flush( unit->pump ); - dv_pump_return_used_output( unit->pump ); - dv_input_join_thread( unit->in ); - if ( !unit->is_terminated ) - pthread_join( unit->out, NULL ); - dv_pump_close( unit->pump ); - unit->pump = NULL; - } - raw1394_close( unit->raw1394 ); + miracle_log( LOG_DEBUG, "closing unit..." ); + if ( unit->old_producers != NULL ) + mlt_properties_close( unit->old_producers ); + mlt_properties_close( unit->properties ); + mlt_properties_close( unit->producers ); free( unit ); - dv1394d_log( LOG_DEBUG, "... unit closed." ); - } -} - -/** Get the raw1394 port associated to this unit. -*/ - -int dv_unit_get_port( dv_unit unit ) -{ - if ( unit->raw1394 != NULL ) - return (int) raw1394_get_userdata( unit->raw1394 ); - else - return -1; -} - -/** Set the dv1394 file descriptor for the unit. -*/ - -void dv_unit_set_dv1394_fd( dv_unit unit, int fd ) -{ - unit->dv1394_fd = fd; -} - -/** Get the dv1394 syt_offset (timestamp latency) property. -*/ - -unsigned int dv_unit_get_syt_offset( dv_unit unit ) -{ - return unit->dv1394_syt_offset; -} - -/** Get the dv1394 cip_n (timing numerator) property. -*/ - -unsigned int dv_unit_get_cip_n( dv_unit unit ) -{ - return unit->dv1394_cip_n; -} - -/** Get the dv1394 cip_d (timing denominator) property. -*/ - -unsigned int dv_unit_get_cip_d( dv_unit unit ) -{ - return unit->dv1394_cip_d; -} - -/** Set the dv1394 syt_offset (timestamp latency) property. - - Stops and restarts the unit if playing. -*/ - -void dv_unit_set_syt_offset( dv_unit unit, unsigned int syt_offset ) -{ - int restart = !unit->is_terminated; - int speed = (int)( dv_player_get_speed( dv_unit_get_dv_player(unit) ) * 1000.0 ); - - dv_unit_terminate( unit ); - unit->dv1394_syt_offset = syt_offset; - if ( restart ) - dv_unit_play( unit, speed ); -} - -/** Set the dv1394 cip_n (timing numerator) property. - - Stops and restarts the unit if playing. -*/ - -void dv_unit_set_cip_n( dv_unit unit, unsigned int cip_n ) -{ - int restart = !unit->is_terminated; - int speed = (int)( dv_player_get_speed( dv_unit_get_dv_player(unit) ) * 1000.0 ); - - dv_unit_terminate( unit ); - unit->dv1394_cip_n = cip_n; - if ( restart ) - dv_unit_play( unit, speed ); -} - -/** Set the dv1394 cip_d (timing denominator) property. - - Stops and restarts the unit if playing. -*/ - -void dv_unit_set_cip_d( dv_unit unit, unsigned int cip_d ) -{ - int restart = !unit->is_terminated; - int speed = (int)( dv_player_get_speed( dv_unit_get_dv_player(unit) ) * 1000.0 ); - - dv_unit_terminate( unit ); - unit->dv1394_cip_d = cip_d; - if ( restart ) - dv_unit_play( unit, speed ); -} - -/** Terminate, but only the output thread and close dv1394. -*/ - -void dv_unit_suspend( dv_unit unit ) -{ - if ( unit->is_terminated == 0 ) - { - unit->is_terminated = 1; - unit->is_suspended = 1; - dv_pump_terminate( unit->pump ); - dv_pump_flush( unit->pump ); - pthread_cancel( unit->out ); - } - if ( unit->dv1394_fd > -1 ) - { - close( unit->dv1394_fd ); - device_count[ dv_unit_get_port( unit ) ] --; + miracle_log( LOG_DEBUG, "... unit closed." ); } - unit->dv1394_fd = -1; - dv_unit_status_communicate( unit ); } - -/** Restore unit on the bus, re-open dv1394, start playback if pump is running. -*/ - -void dv_unit_restore( dv_unit unit ) -{ - int result = 0; - int port, node_id; - - if ( unit->raw1394 != NULL ) - raw1394_close( unit->raw1394 ); - - node_id = raw1394_find_node( &(unit->raw1394), unit->guid ); - if ( node_id != -1 ) - { - unit->node_id = 0xffc0 | node_id; - port = dv_unit_get_port( unit ); - - unit->dv1394_fd = open( devices[ port ][ device_count[port] ], O_RDWR ); - if ( unit->dv1394_fd < 0 ) - { - dv1394d_log( LOG_ERR, "failed to open dv1394 device - %s\n", devices[ port ][ device_count[port] ] ); - dv_unit_close( unit ); - } - else - { - device_count[ port ] ++; - break_p2p_connection( unit->raw1394, unit->node_id, unit->channel ); - if ( establish_p2p_connection( unit->raw1394, unit->node_id, (unsigned int *) &(unit->channel) ) ) - { - avc1394_vcr_record( unit->raw1394, unit->node_id ); - unit->online = 1; - result = 1; - } - } - } - if ( unit->is_suspended == 1 ) - { - int retval; - dv_frame frame = dv_pump_get_available_output( unit->pump ); - struct dv1394_init setup = - { - api_version: DV1394_API_VERSION, - channel: unit->channel, - /* this only sets the *requested* size of the ringbuffer, - in frames */ - n_frames: unit->n_frames, - format: dv_frame_is_pal(frame) ? DV1394_PAL : DV1394_NTSC, - cip_n: unit->dv1394_cip_n, - cip_d: unit->dv1394_cip_d, - syt_offset: unit->dv1394_syt_offset - }; - pthread_attr_t attr; - - dv_input_join_thread( unit->in ); - unit->is_terminated = 0; - unit->is_suspended = 0; - dv_pump_restart( unit->pump ); - dv_input_start_thread( unit->in ); - - /* initialize dv1394 */ - retval = ioctl( unit->dv1394_fd, DV1394_INIT, &setup ); - if ( retval < 0 ) - return; - - pthread_attr_init( &attr ); - pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); - pthread_attr_setinheritsched( &attr, PTHREAD_INHERIT_SCHED ); - /* pthread_attr_setschedpolicy( &attr, SCHED_RR ); */ - pthread_create( &unit->out, &attr, output, unit ); - } - dv_unit_status_communicate( unit ); -} diff --git a/mlt/src/miracle/miracle_unit.h b/mlt/src/miracle/miracle_unit.h index 54338182..fabfe5a8 100644 --- a/mlt/src/miracle/miracle_unit.h +++ b/mlt/src/miracle/miracle_unit.h @@ -22,14 +22,9 @@ #define _DV_UNIT_H_ #include -#include -#include -#include -#include -#include -#include -#include +#include +#include #ifdef __cplusplus extern "C" @@ -38,81 +33,43 @@ extern "C" typedef struct { - int unit; - dv_pump pump; - dv_player player; - dv_input in; - int dv1394_fd; - int is_terminated; - int is_suspended; - pthread_t out; - int channel; - nodeid_t node_id; - octlet_t guid; - raw1394handle_t raw1394; - int allow_stdin; - int buffer_size; - int online; - dv1394_notifier notifier; - char *root_dir; - unsigned int dv1394_syt_offset; - unsigned int dv1394_cip_n; - unsigned int dv1394_cip_d; - unsigned int n_frames; - unsigned int n_fill; - uint8_t *mmap; - int mmap_pos; - int mmap_length; -} dv_unit_t, *dv_unit; + mlt_properties properties; + mlt_properties producers; + mlt_properties old_producers; +} +miracle_unit_t, *miracle_unit; -extern dv_unit dv_unit_init( octlet_t guid, int channel ); -extern void dv_unit_allow_stdin( dv_unit unit, int flag ); -extern void dv_unit_set_buffer_size( dv_unit unit, int size ); -extern int dv_unit_get_buffer_size( dv_unit unit ); -extern void dv_unit_set_n_frames( dv_unit unit, int size ); -extern int dv_unit_get_n_frames( dv_unit unit ); -extern void dv_unit_set_n_fill( dv_unit unit, int size ); -extern int dv_unit_get_n_fill( dv_unit unit ); -extern dv_error_code dv_unit_load( dv_unit unit, const char *clip, long in, long out, int flush ); -extern dv_error_code dv_unit_insert( dv_unit unit, const char *clip, int index, long in, long out ); -extern dv_error_code dv_unit_append( dv_unit unit, const char *clip, long in, long out ); -extern dv_error_code dv_unit_remove( dv_unit unit, int index ); -extern dv_error_code dv_unit_clean( dv_unit unit ); -extern dv_error_code dv_unit_move( dv_unit unit, int src, int dest ); -extern int dv_unit_transfer( dv_unit dest_unit, dv_unit src_unit ); -extern void dv_unit_play( dv_unit_t *unit, int speed ); -extern void dv_unit_terminate( dv_unit ); -extern int dv_unit_has_terminated( dv_unit ); -extern octlet_t dv_unit_get_guid( dv_unit unit ); -extern int dv_unit_get_nodeid( dv_unit unit ); -extern int dv_unit_get_channel( dv_unit unit ); -extern int dv_unit_online( dv_unit unit ); -extern void dv_unit_offline( dv_unit unit ); -extern int dv_unit_is_offline( dv_unit unit ); -extern void dv_unit_set_notifier( dv_unit, dv1394_notifier, char * ); -extern int dv_unit_get_status( dv_unit, dv1394_status ); -extern void dv_unit_change_position( dv_unit, int, long position ); -extern void dv_unit_change_speed( dv_unit unit, int speed ); -extern int dv_unit_set_clip_in( dv_unit unit, int index, long position ); -extern int dv_unit_set_clip_out( dv_unit unit, int index, long position ); -extern void dv_unit_set_mode( dv_unit unit, dv_player_clip_mode mode ); -extern dv_player_clip_mode dv_unit_get_mode( dv_unit unit ); -extern void dv_unit_set_eof_action( dv_unit unit, dv_player_eof_action mode ); -extern dv_player_eof_action dv_unit_get_eof_action( dv_unit unit ); -extern void dv_unit_step( dv_unit unit, int offset ); -extern void dv_unit_close( dv_unit unit ); -extern int dv_unit_get_port( dv_unit unit ); -extern void dv_unit_set_dv1394_fd( dv_unit unit, int fd ); -extern unsigned int dv_unit_get_syt_offset( dv_unit unit ); -extern unsigned int dv_unit_get_cip_n( dv_unit unit ); -extern unsigned int dv_unit_get_cip_d( dv_unit unit ); -extern void dv_unit_set_syt_offset( dv_unit unit, unsigned int ); -extern void dv_unit_set_cip_n( dv_unit unit, unsigned int ); -extern void dv_unit_set_cip_d( dv_unit unit, unsigned int ); -extern void dv_unit_suspend( dv_unit ); -extern void dv_unit_restore( dv_unit ); -extern dv_player dv_unit_get_dv_player( dv_unit ); -extern int dv_unit_get_current_clip( dv_unit ); +extern miracle_unit miracle_unit_init( int index, char *arg ); +extern void miracle_unit_report_list( miracle_unit unit, valerie_response response ); +extern void miracle_unit_allow_stdin( miracle_unit unit, int flag ); +extern valerie_error_code miracle_unit_load( miracle_unit unit, char *clip, double in, double out, int flush ); +extern valerie_error_code miracle_unit_insert( miracle_unit unit, const char *clip, int index, double in, double out ); +extern valerie_error_code miracle_unit_append( miracle_unit unit, char *clip, double in, double out ); +extern valerie_error_code miracle_unit_remove( miracle_unit unit, int index ); +extern valerie_error_code miracle_unit_clean( miracle_unit unit ); +extern valerie_error_code miracle_unit_move( miracle_unit unit, int src, int dest ); +extern int miracle_unit_transfer( miracle_unit dest_unit, miracle_unit src_unit ); +extern void miracle_unit_play( miracle_unit_t *unit, int speed ); +extern void miracle_unit_terminate( miracle_unit ); +extern int miracle_unit_has_terminated( miracle_unit ); +extern int miracle_unit_get_nodeid( miracle_unit unit ); +extern int miracle_unit_get_channel( miracle_unit unit ); +extern int miracle_unit_is_offline( miracle_unit unit ); +extern void miracle_unit_set_notifier( miracle_unit, valerie_notifier, char * ); +extern int miracle_unit_get_status( miracle_unit, valerie_status ); +extern void miracle_unit_change_position( miracle_unit, int, double position ); +extern void miracle_unit_change_speed( miracle_unit unit, int speed ); +extern int miracle_unit_set_clip_in( miracle_unit unit, int index, double position ); +extern int miracle_unit_set_clip_out( miracle_unit unit, int index, double position ); +//extern void miracle_unit_set_mode( miracle_unit unit, dv_player_clip_mode mode ); +//extern dv_player_clip_mode miracle_unit_get_mode( miracle_unit unit ); +//extern void miracle_unit_set_eof_action( miracle_unit unit, dv_player_eof_action mode ); +//extern dv_player_eof_action miracle_unit_get_eof_action( miracle_unit unit ); +extern void miracle_unit_step( miracle_unit unit, double offset ); +extern void miracle_unit_close( miracle_unit unit ); +extern void miracle_unit_suspend( miracle_unit ); +extern void miracle_unit_restore( miracle_unit ); +extern int miracle_unit_get_current_clip( miracle_unit ); #ifdef __cplusplus diff --git a/mlt/src/miracle/miracle_unit_commands.c b/mlt/src/miracle/miracle_unit_commands.c index b12f2c72..a630422b 100644 --- a/mlt/src/miracle/miracle_unit_commands.c +++ b/mlt/src/miracle/miracle_unit_commands.c @@ -28,16 +28,15 @@ #include #include #include +#include -#include "dvunit.h" -#include "global_commands.h" -#include "dverror.h" -#include "dvframepool.h" -#include "log.h" +#include "miracle_unit.h" +#include "miracle_commands.h" +#include "miracle_log.h" -int dv1394d_load( command_argument cmd_arg ) +int miracle_load( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + miracle_unit unit = miracle_get_unit(cmd_arg->unit); char *filename = (char*) cmd_arg->argument; char fullname[1024]; int flush = 1; @@ -57,53 +56,34 @@ int dv1394d_load( command_argument cmd_arg ) return RESPONSE_INVALID_UNIT; else { - long in = -1, out = -1; - if ( dv_tokeniser_count( cmd_arg->tokeniser ) == 5 ) + double in = -1, out = -1; + if ( valerie_tokeniser_count( cmd_arg->tokeniser ) == 5 ) { - in = atoi( dv_tokeniser_get_string( cmd_arg->tokeniser, 3 ) ); - out = atoi( dv_tokeniser_get_string( cmd_arg->tokeniser, 4 ) ); + in = atof( valerie_tokeniser_get_string( cmd_arg->tokeniser, 3 ) ); + out = atof( valerie_tokeniser_get_string( cmd_arg->tokeniser, 4 ) ); } - if ( dv_unit_load( unit, fullname, in, out, flush ) != dv_pump_ok ) + if ( miracle_unit_load( unit, fullname, in, out, flush ) != valerie_ok ) return RESPONSE_BAD_FILE; } return RESPONSE_SUCCESS; } -int dv1394d_list( command_argument cmd_arg ) +int miracle_list( command_argument cmd_arg ) { - int i = 0; - dv_unit unit = dv1394d_get_unit( cmd_arg->unit ); - dv_player player = dv_unit_get_dv_player( unit ); - - if ( player != NULL ) + miracle_unit unit = miracle_get_unit( cmd_arg->unit ); + + if ( unit != NULL ) { - dv_response_printf( cmd_arg->response, 1024, "%d\n", player->generation ); - - for ( i = 0; i < dv_player_get_clip_count( player ); i ++ ) - { - dv_clip clip = dv_player_get_clip( player, i ); - - dv_response_printf( cmd_arg->response, 10240, - "%d \"%s\" %d %d %d %d %.2f\n", - i, - dv_clip_get_resource( clip, cmd_arg->root_dir ), - dv_clip_get_in( clip ), - ( !dv_clip_is_seekable( clip ) && clip->out_frame == -1 ? -1 : dv_clip_get_out( clip ) ), - dv_clip_get_max_frames( clip ), - ( !dv_clip_is_seekable( clip ) && clip->out_frame == -1 ? -1 : dv_player_get_length_of_clip( player, i ) ), - dv_clip_frames_per_second( clip ) ); - } - - dv_response_printf( cmd_arg->response, 2, "\n" ); - + miracle_unit_report_list( unit, cmd_arg->response ); return RESPONSE_SUCCESS; } + return RESPONSE_INVALID_UNIT; } - +/* static int parse_clip( command_argument cmd_arg, int arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + dv_unit unit = miracle_get_unit(cmd_arg->unit); int clip = dv_unit_get_current_clip( unit ); if ( dv_tokeniser_count( cmd_arg->tokeniser ) > arg ) @@ -124,10 +104,12 @@ static int parse_clip( command_argument cmd_arg, int arg ) return clip; } +*/ -int dv1394d_insert( command_argument cmd_arg ) +int miracle_insert( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); char *filename = (char*) cmd_arg->argument; char fullname[1024]; @@ -159,12 +141,14 @@ int dv1394d_insert( command_argument cmd_arg ) return RESPONSE_BAD_FILE; } } + */ return RESPONSE_SUCCESS; } -int dv1394d_remove( command_argument cmd_arg ) +int miracle_remove( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); if (unit == NULL) return RESPONSE_INVALID_UNIT; @@ -175,12 +159,14 @@ int dv1394d_remove( command_argument cmd_arg ) if ( dv_unit_remove( unit, index ) != dv_pump_ok ) return RESPONSE_BAD_FILE; } + */ return RESPONSE_SUCCESS; } -int dv1394d_clean( command_argument cmd_arg ) +int miracle_clean( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); if (unit == NULL) return RESPONSE_INVALID_UNIT; @@ -189,12 +175,14 @@ int dv1394d_clean( command_argument cmd_arg ) if ( dv_unit_clean( unit ) != dv_pump_ok ) return RESPONSE_BAD_FILE; } + */ return RESPONSE_SUCCESS; } -int dv1394d_move( command_argument cmd_arg ) +int miracle_move( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); if ( unit != NULL ) { @@ -215,36 +203,36 @@ int dv1394d_move( command_argument cmd_arg ) { return RESPONSE_INVALID_UNIT; } - + */ + return RESPONSE_SUCCESS; } -int dv1394d_append( command_argument cmd_arg ) +int miracle_append( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + miracle_unit unit = miracle_get_unit(cmd_arg->unit); char *filename = (char*) cmd_arg->argument; char fullname[1024]; if ( filename[0] == '/' ) filename++; + snprintf( fullname, 1023, "%s%s", cmd_arg->root_dir, filename ); if (unit == NULL) return RESPONSE_INVALID_UNIT; else { - long in = -1, out = -1; - if ( dv_tokeniser_count( cmd_arg->tokeniser ) == 5 ) + double in = -1, out = -1; + if ( valerie_tokeniser_count( cmd_arg->tokeniser ) == 5 ) { - in = atoi( dv_tokeniser_get_string( cmd_arg->tokeniser, 3 ) ); - out = atoi( dv_tokeniser_get_string( cmd_arg->tokeniser, 4 ) ); + in = atof( valerie_tokeniser_get_string( cmd_arg->tokeniser, 3 ) ); + out = atof( valerie_tokeniser_get_string( cmd_arg->tokeniser, 4 ) ); } - switch ( dv_unit_append( unit, fullname, in, out ) ) + switch ( miracle_unit_append( unit, fullname, in, out ) ) { - case dv_pump_ok: + case valerie_ok: return RESPONSE_SUCCESS; - case dv_pump_too_many_files_open: - return RESPONSE_TOO_MANY_FILES; default: return RESPONSE_BAD_FILE; } @@ -252,62 +240,59 @@ int dv1394d_append( command_argument cmd_arg ) return RESPONSE_SUCCESS; } -int dv1394d_play( command_argument cmd_arg ) +int miracle_play( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + miracle_unit unit = miracle_get_unit(cmd_arg->unit); - if (unit == NULL || dv_unit_is_offline(unit)) + if ( unit == NULL ) + { return RESPONSE_INVALID_UNIT; + } else { int speed = 1000; - if ( dv_tokeniser_count( cmd_arg->tokeniser ) == 3 ) - speed = atoi( dv_tokeniser_get_string( cmd_arg->tokeniser, 2 ) ); - dv_unit_play( unit, speed ); + if ( valerie_tokeniser_count( cmd_arg->tokeniser ) == 3 ) + speed = atoi( valerie_tokeniser_get_string( cmd_arg->tokeniser, 2 ) ); + miracle_unit_play( unit, speed ); } - + return RESPONSE_SUCCESS; } -int dv1394d_stop( command_argument cmd_arg ) +int miracle_stop( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); - - if (unit == NULL || dv_unit_is_offline(unit)) + miracle_unit unit = miracle_get_unit(cmd_arg->unit); + if ( unit == NULL ) return RESPONSE_INVALID_UNIT; - else - dv_unit_terminate( unit ); - + else + miracle_unit_play( unit, 0 ); return RESPONSE_SUCCESS; } -int dv1394d_pause( command_argument cmd_arg ) +int miracle_pause( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); - - if (unit == NULL || dv_unit_is_offline(unit)) + miracle_unit unit = miracle_get_unit(cmd_arg->unit); + if ( unit == NULL ) return RESPONSE_INVALID_UNIT; else - dv_unit_play( unit, 0 ); - + miracle_unit_play( unit, 0 ); return RESPONSE_SUCCESS; } -int dv1394d_rewind( command_argument cmd_arg ) +int miracle_rewind( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); - - if (unit == NULL || dv_unit_is_offline(unit)) + miracle_unit unit = miracle_get_unit(cmd_arg->unit); + if ( unit == NULL ) return RESPONSE_INVALID_UNIT; - else - dv_unit_change_speed( unit, -2000 ); - + else + miracle_unit_play( unit, -2000 ); return RESPONSE_SUCCESS; } -int dv1394d_step( command_argument cmd_arg ) +int miracle_step( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); if (unit == NULL || dv_unit_is_offline(unit)) return RESPONSE_INVALID_UNIT; @@ -316,38 +301,38 @@ int dv1394d_step( command_argument cmd_arg ) dv_unit_play( unit, 0 ); dv_unit_step( unit, *(int*) cmd_arg->argument ); } - + */ return RESPONSE_SUCCESS; } -int dv1394d_goto( command_argument cmd_arg ) +int miracle_goto( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); int clip = parse_clip( cmd_arg, 3 ); if (unit == NULL || dv_unit_is_offline(unit)) return RESPONSE_INVALID_UNIT; else dv_unit_change_position( unit, clip, *(int*) cmd_arg->argument ); - + */ return RESPONSE_SUCCESS; } -int dv1394d_ff( command_argument cmd_arg ) +int miracle_ff( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); - - if (unit == NULL || dv_unit_is_offline(unit)) + miracle_unit unit = miracle_get_unit(cmd_arg->unit); + if ( unit == NULL ) return RESPONSE_INVALID_UNIT; - else - dv_unit_change_speed( unit, 2000 ); - + else + miracle_unit_play( unit, 2000 ); return RESPONSE_SUCCESS; } -int dv1394d_set_in_point( command_argument cmd_arg ) +int miracle_set_in_point( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); int clip = parse_clip( cmd_arg, 3 ); if (unit == NULL || dv_unit_is_offline(unit)) @@ -364,13 +349,14 @@ int dv1394d_set_in_point( command_argument cmd_arg ) return RESPONSE_OUT_OF_RANGE; } } - + */ return RESPONSE_SUCCESS; } -int dv1394d_set_out_point( command_argument cmd_arg ) +int miracle_set_out_point( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); int clip = parse_clip( cmd_arg, 3 ); if (unit == NULL || dv_unit_is_offline(unit)) @@ -387,35 +373,31 @@ int dv1394d_set_out_point( command_argument cmd_arg ) return RESPONSE_OUT_OF_RANGE; } } - + */ return RESPONSE_SUCCESS; } -int dv1394d_get_unit_status( command_argument cmd_arg ) +int miracle_get_unit_status( command_argument cmd_arg ) { - dv1394_status_t status; - int error = dv_unit_get_status( dv1394d_get_unit( cmd_arg->unit ), &status ); + valerie_status_t status; + int error = miracle_unit_get_status( miracle_get_unit( cmd_arg->unit ), &status ); if ( error == -1 ) return RESPONSE_INVALID_UNIT; else { char text[ 10240 ]; - - dv_response_printf( cmd_arg->response, - sizeof( text ), - dv1394_status_serialise( &status, text, sizeof( text ) ) ); - + valerie_response_printf( cmd_arg->response, sizeof( text ), valerie_status_serialise( &status, text, sizeof( text ) ) ); return RESPONSE_SUCCESS_1; } - return 0; } -int dv1394d_set_unit_property( command_argument cmd_arg ) +int miracle_set_unit_property( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); if (unit == NULL) return RESPONSE_INVALID_UNIT; @@ -429,7 +411,7 @@ int dv1394d_set_unit_property( command_argument cmd_arg ) return RESPONSE_OUT_OF_RANGE; value[0] = 0; value++; - dv1394d_log( LOG_DEBUG, "USET %s = %s", key, value ); + miracle_log( LOG_DEBUG, "USET %s = %s", key, value ); if ( strncasecmp( key, "eof", 1024) == 0 ) { if ( strncasecmp( value, "pause", 1024) == 0) @@ -479,13 +461,14 @@ int dv1394d_set_unit_property( command_argument cmd_arg ) else return RESPONSE_OUT_OF_RANGE; } - + */ return RESPONSE_SUCCESS; } -int dv1394d_get_unit_property( command_argument cmd_arg ) +int miracle_get_unit_property( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); if (unit == NULL) return RESPONSE_INVALID_UNIT; @@ -585,14 +568,15 @@ int dv1394d_get_unit_property( command_argument cmd_arg ) dv_response_printf( cmd_arg->response, 1024, "n_fill=%d\n", dv_unit_get_n_fill( unit ) ); } } - + */ return RESPONSE_SUCCESS; } -int dv1394d_transfer( command_argument cmd_arg ) +int miracle_transfer( command_argument cmd_arg ) { - dv_unit src_unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit src_unit = miracle_get_unit(cmd_arg->unit); int dest_unit_id = -1; char *string = (char*) cmd_arg->argument; if ( string != NULL && ( string[ 0 ] == 'U' || string[ 0 ] == 'u' ) && strlen( string ) > 1 ) @@ -600,13 +584,13 @@ int dv1394d_transfer( command_argument cmd_arg ) if ( src_unit != NULL && dest_unit_id != -1 ) { - dv_unit dest_unit = dv1394d_get_unit( dest_unit_id ); + dv_unit dest_unit = miracle_get_unit( dest_unit_id ); if ( dest_unit != NULL && !dv_unit_is_offline(dest_unit) && dest_unit != src_unit ) { dv_unit_transfer( dest_unit, src_unit ); return RESPONSE_SUCCESS; } } - + */ return RESPONSE_INVALID_UNIT; } diff --git a/mlt/src/miracle/miracle_unit_commands.h b/mlt/src/miracle/miracle_unit_commands.h index a7163bdc..575ff1be 100644 --- a/mlt/src/miracle/miracle_unit_commands.h +++ b/mlt/src/miracle/miracle_unit_commands.h @@ -22,33 +22,33 @@ #ifndef _UNIT_COMMANDS_H_ #define _UNIT_COMMANDS_H_ -#include "dvconnection.h" +#include "miracle_connection.h" #ifdef __cplusplus extern "C" { #endif -extern response_codes dv1394d_list( command_argument ); -extern response_codes dv1394d_load( command_argument ); -extern response_codes dv1394d_insert( command_argument ); -extern response_codes dv1394d_remove( command_argument ); -extern response_codes dv1394d_clean( command_argument ); -extern response_codes dv1394d_move( command_argument ); -extern response_codes dv1394d_append( command_argument ); -extern response_codes dv1394d_play( command_argument ); -extern response_codes dv1394d_stop( command_argument ); -extern response_codes dv1394d_pause( command_argument ); -extern response_codes dv1394d_rewind( command_argument ); -extern response_codes dv1394d_step( command_argument ); -extern response_codes dv1394d_goto( command_argument ); -extern response_codes dv1394d_ff( command_argument ); -extern response_codes dv1394d_set_in_point( command_argument ); -extern response_codes dv1394d_set_out_point( command_argument ); -extern response_codes dv1394d_get_unit_status( command_argument ); -extern response_codes dv1394d_set_unit_property( command_argument ); -extern response_codes dv1394d_get_unit_property( command_argument ); -extern response_codes dv1394d_transfer( command_argument ); +extern response_codes miracle_list( command_argument ); +extern response_codes miracle_load( command_argument ); +extern response_codes miracle_insert( command_argument ); +extern response_codes miracle_remove( command_argument ); +extern response_codes miracle_clean( command_argument ); +extern response_codes miracle_move( command_argument ); +extern response_codes miracle_append( command_argument ); +extern response_codes miracle_play( command_argument ); +extern response_codes miracle_stop( command_argument ); +extern response_codes miracle_pause( command_argument ); +extern response_codes miracle_rewind( command_argument ); +extern response_codes miracle_step( command_argument ); +extern response_codes miracle_goto( command_argument ); +extern response_codes miracle_ff( command_argument ); +extern response_codes miracle_set_in_point( command_argument ); +extern response_codes miracle_set_out_point( command_argument ); +extern response_codes miracle_get_unit_status( command_argument ); +extern response_codes miracle_set_unit_property( command_argument ); +extern response_codes miracle_get_unit_property( command_argument ); +extern response_codes miracle_transfer( command_argument ); #ifdef __cplusplus } diff --git a/mlt/src/modules/core/producer_ppm.c b/mlt/src/modules/core/producer_ppm.c index 3d3f5839..b508654b 100644 --- a/mlt/src/modules/core/producer_ppm.c +++ b/mlt/src/modules/core/producer_ppm.c @@ -43,12 +43,20 @@ mlt_producer producer_ppm_init( void *command ) if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) { mlt_producer producer = &this->parent; + mlt_properties properties = mlt_producer_properties( producer ); producer->get_frame = producer_get_frame; producer->close = producer_close; if ( command != NULL ) + { + mlt_properties_set( properties, "resource", command ); this->command = strdup( command ); + } + else + { + mlt_properties_set( properties, "resource", "ppm test" ); + } return producer; } diff --git a/mlt/src/modules/dv/producer_libdv.c b/mlt/src/modules/dv/producer_libdv.c index 05218cf3..c2921e3d 100644 --- a/mlt/src/modules/dv/producer_libdv.c +++ b/mlt/src/modules/dv/producer_libdv.c @@ -51,9 +51,10 @@ mlt_producer producer_libdv_init( char *filename ) { producer_libdv this = calloc( sizeof( struct producer_libdv_s ), 1 ); - if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) + if ( filename != NULL && this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) { mlt_producer producer = &this->parent; + mlt_properties properties = mlt_producer_properties( producer ); // Register transport implementation with the producer producer->close = producer_close; @@ -68,11 +69,11 @@ mlt_producer producer_libdv_init( char *filename ) dv_set_audio_correction( this->dv_decoder, DV_AUDIO_CORRECT_AVERAGE ); // Open the file if specified - if ( filename != NULL ) - { - this->fd = open( filename, O_RDONLY ); - producer_collect_info( this ); - } + this->fd = open( filename, O_RDONLY ); + producer_collect_info( this ); + + // Set the resource property (required for all producers) + mlt_properties_set( properties, "resource", filename ); // Return the producer return producer; diff --git a/mlt/src/modules/ffmpeg/audio.sh b/mlt/src/modules/ffmpeg/audio.sh index 3c7475a2..2d6aeda3 100755 --- a/mlt/src/modules/ffmpeg/audio.sh +++ b/mlt/src/modules/ffmpeg/audio.sh @@ -1,5 +1,7 @@ #!/bin/bash +trap exit + audio_type="$1" audio_file="$2" audio_position=$3 @@ -8,7 +10,7 @@ audio_channels=$5 audio_track=$5 if [ "$audio_type" == "dsp" ] -then ffmpeg -ad "$audio_file" -f s16le -ar $audio_frequency -ac $audio_channels - -else ffmpeg -i "$audio_file" -ss $audio_position -f s16le -ar $audio_frequency -ac $audio_channels - +then ffmpeg -ad "$audio_file" -f s16le -ar $audio_frequency -ac $audio_channels - +else ffmpeg -i "$audio_file" -ss $audio_position -f s16le -ar $audio_frequency -ac $audio_channels - fi diff --git a/mlt/src/modules/ffmpeg/producer_ffmpeg.c b/mlt/src/modules/ffmpeg/producer_ffmpeg.c index 8777fb11..2af9de37 100644 --- a/mlt/src/modules/ffmpeg/producer_ffmpeg.c +++ b/mlt/src/modules/ffmpeg/producer_ffmpeg.c @@ -26,12 +26,118 @@ #include #include #include +#include +#include +#include +#include typedef struct producer_ffmpeg_s *producer_ffmpeg; +/** Bi-directional pipe structure. +*/ + +typedef struct rwpipe +{ + int pid; + FILE *reader; + FILE *writer; +} +rwpipe; + +/** Create a bidirectional pipe for the given command. +*/ + +rwpipe *rwpipe_open( char *command ) +{ + rwpipe *this = malloc( sizeof( rwpipe ) ); + + if ( this != NULL ) + { + int input[ 2 ]; + int output[ 2 ]; + + pipe( input ); + pipe( output ); + + this->pid = fork(); + + if ( this->pid == 0 ) + { + signal( SIGPIPE, SIG_DFL ); + signal( SIGHUP, SIG_DFL ); + signal( SIGINT, SIG_DFL ); + signal( SIGTERM, SIG_DFL ); + signal( SIGSTOP, SIG_DFL ); + signal( SIGCHLD, SIG_DFL ); + + dup2( output[ 0 ], STDIN_FILENO ); + dup2( input[ 1 ], STDOUT_FILENO ); + + close( input[ 0 ] ); + close( input[ 1 ] ); + close( output[ 0 ] ); + close( output[ 1 ] ); + + execl( "/bin/sh", "sh", "-c", command, NULL ); + exit( 255 ); + } + else + { + setpgid( this->pid, this->pid ); + + close( input[ 1 ] ); + close( output[ 0 ] ); + + this->reader = fdopen( input[ 0 ], "r" ); + this->writer = fdopen( output[ 1 ], "w" ); + } + } + + return this; +} + +/** Read data from the pipe. +*/ + +FILE *rwpipe_reader( rwpipe *this ) +{ + if ( this != NULL ) + return this->reader; + else + return NULL; +} + +/** Write data to the pipe. +*/ + +FILE *rwpipe_writer( rwpipe *this ) +{ + if ( this != NULL ) + return this->writer; + else + return NULL; +} + +/** Close the pipe and process. +*/ + +void rwpipe_close( rwpipe *this ) +{ + if ( this != NULL ) + { + fclose( this->reader ); + fclose( this->writer ); + kill( - this->pid, SIGKILL ); + waitpid( - this->pid, NULL, 0 ); + free( this ); + } +} + struct producer_ffmpeg_s { struct mlt_producer_s parent; + rwpipe *video_pipe; + rwpipe *audio_pipe; FILE *video; FILE *audio; uint64_t expected; @@ -52,7 +158,7 @@ static void producer_close( mlt_producer parent ); mlt_producer producer_ffmpeg_init( char *file ) { producer_ffmpeg this = calloc( sizeof( struct producer_ffmpeg_s ), 1 ); - if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) + if ( file != NULL && this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) { // Get the producer mlt_producer producer = &this->parent; @@ -67,7 +173,7 @@ mlt_producer producer_ffmpeg_init( char *file ) // Set the properties mlt_properties_set( properties, "mlt_type", "producer_ffmpeg" ); - if ( file != NULL && !strcmp( file, "v4l" ) ) + if ( !strcmp( file, "v4l" ) ) { mlt_properties_set( properties, "video_type", "v4l" ); mlt_properties_set( properties, "video_file", "/dev/video0" ); @@ -89,6 +195,7 @@ mlt_producer producer_ffmpeg_init( char *file ) mlt_properties_set_int( properties, "audio_track", 0 ); mlt_properties_set( properties, "log_id", file ); + mlt_properties_set( properties, "resource", file ); this->buffer = malloc( 1024 * 1024 * 2 ); @@ -151,7 +258,8 @@ FILE *producer_ffmpeg_run_video( producer_ffmpeg this, mlt_timecode position ) video_rate, ( float )position ); - this->video = popen( command, "r" ); + this->video_pipe = rwpipe_open( command ); + this->video = rwpipe_reader( this->video_pipe ); } } return this->video; @@ -188,7 +296,8 @@ FILE *producer_ffmpeg_run_audio( producer_ffmpeg this, mlt_timecode position ) channels, track ); - this->audio = popen( command, "r" ); + this->audio_pipe = rwpipe_open( command ); + this->audio = rwpipe_reader( this->audio_pipe ); } } return this->audio; @@ -207,12 +316,12 @@ static void producer_ffmpeg_position( producer_ffmpeg this, uint64_t requested, { // Close the video pipe if ( this->video != NULL ) - pclose( this->video ); + rwpipe_close( this->video_pipe ); this->video = NULL; // Close the audio pipe if ( this->audio != NULL ) - pclose( this->audio ); + rwpipe_close( this->audio_pipe ); this->audio = NULL; // We should not be open now @@ -309,7 +418,7 @@ static int producer_get_audio( mlt_frame this, int16_t **buffer, mlt_audio_forma *samples = sample_calculator( fps, *frequency, target - skip ); if ( fread( *buffer, *samples * *channels * 2, 1, producer->audio ) != 1 ) { - pclose( producer->audio ); + rwpipe_close( producer->audio_pipe ); producer->audio = NULL; producer->end_of_audio = 1; } @@ -423,7 +532,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i // Inform caller that end of clip is reached this->end_of_video = !video_loop; - pclose( this->video ); + rwpipe_close( this->video_pipe ); this->video = NULL; } @@ -472,9 +581,9 @@ static void producer_close( mlt_producer parent ) { producer_ffmpeg this = parent->child; if ( this->video ) - pclose( this->video ); + rwpipe_close( this->video_pipe ); if ( this->audio ) - pclose( this->audio ); + rwpipe_close( this->audio_pipe ); parent->close = NULL; mlt_producer_close( parent ); free( this->buffer ); diff --git a/mlt/src/modules/ffmpeg/video.sh b/mlt/src/modules/ffmpeg/video.sh index 481718cc..f8689fe7 100755 --- a/mlt/src/modules/ffmpeg/video.sh +++ b/mlt/src/modules/ffmpeg/video.sh @@ -1,5 +1,7 @@ #!/bin/bash +trap exit + video_type="$1" video_file="$2" video_size="$3" diff --git a/mlt/src/modules/gtk2/producer_pango.c b/mlt/src/modules/gtk2/producer_pango.c index 5877d524..c1bf1d3f 100644 --- a/mlt/src/modules/gtk2/producer_pango.c +++ b/mlt/src/modules/gtk2/producer_pango.c @@ -84,6 +84,8 @@ mlt_producer producer_pango_init( const char *markup ) mlt_properties_set_int( properties, "y", 0 ); mlt_properties_set_double( properties, "mix", 1.0 ); + mlt_properties_set( properties, "resource", "pango" ); + return producer; } free( this ); diff --git a/mlt/src/modules/gtk2/producer_pixbuf.c b/mlt/src/modules/gtk2/producer_pixbuf.c index 7114979a..f1f1f45f 100644 --- a/mlt/src/modules/gtk2/producer_pixbuf.c +++ b/mlt/src/modules/gtk2/producer_pixbuf.c @@ -49,10 +49,10 @@ static int filter_files( const struct dirent *de ) } -mlt_producer producer_pixbuf_init( const char *filename ) +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 ) + if ( filename != NULL && this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) { mlt_producer producer = &this->parent; @@ -63,6 +63,7 @@ mlt_producer producer_pixbuf_init( const char *filename ) mlt_properties properties = mlt_producer_properties( &this->parent ); // Set the default properties + mlt_properties_set( properties, "resource", filename ); mlt_properties_set_int( properties, "video_standard", mlt_video_standard_pal ); mlt_properties_set_double( properties, "ttl", 5 ); diff --git a/mlt/src/modules/gtk2/producer_pixbuf.h b/mlt/src/modules/gtk2/producer_pixbuf.h index 346a6544..74b8f7a3 100644 --- a/mlt/src/modules/gtk2/producer_pixbuf.h +++ b/mlt/src/modules/gtk2/producer_pixbuf.h @@ -40,6 +40,6 @@ struct producer_pixbuf_s uint8_t *alpha; }; -extern mlt_producer producer_pixbuf_init( const char *filename ); +extern mlt_producer producer_pixbuf_init( char *filename ); #endif diff --git a/mlt/src/modules/sdl/consumer_sdl.c b/mlt/src/modules/sdl/consumer_sdl.c index 714fc66f..85852d57 100644 --- a/mlt/src/modules/sdl/consumer_sdl.c +++ b/mlt/src/modules/sdl/consumer_sdl.c @@ -232,13 +232,10 @@ static int consumer_play_audio( consumer_sdl this, mlt_frame frame, int init_aud fprintf( stderr, "SDL failed to open audio: %s\n", SDL_GetError() ); init_audio = 2; } - else + else if ( got.size != 0 ) { - if ( got.size != 0 ) - { - SDL_PauseAudio( 0 ); - init_audio = 0; - } + SDL_PauseAudio( 0 ); + init_audio = 0; } } diff --git a/mlt/src/valerie/Makefile b/mlt/src/valerie/Makefile index 908c432f..6afae187 100644 --- a/mlt/src/valerie/Makefile +++ b/mlt/src/valerie/Makefile @@ -1,5 +1,5 @@ -AR = ar +TARGET = libvalerie.so OBJS = valerie.o \ valerie_notifier.o \ @@ -17,11 +17,10 @@ CFLAGS=-Wall -g -D_FILE_OFFSET_BITS=64 -pthread LDFLAGS=-ldv -lpthread -all: libvalerie.a +all: $(TARGET) -libvalerie.a: $(OBJS) - $(AR) rvu $@ $(OBJS) - ranlib $@ +$(TARGET): $(OBJS) + $(CC) -shared -o $@ $(OBJS) $(LDFLAGS) depend: $(SRCS) $(CC) -MM $(CFLAGS) $^ 1>.depend @@ -30,7 +29,7 @@ dist-clean: clean rm -f .depend clean: - rm -f $(OBJS) libvalerie.a + rm -f $(OBJS) $(TARGET) ifneq ($(wildcard .depend),) include .depend diff --git a/mlt/src/valerie/valerie.c b/mlt/src/valerie/valerie.c index 2e1f2895..4157284b 100644 --- a/mlt/src/valerie/valerie.c +++ b/mlt/src/valerie/valerie.c @@ -311,9 +311,9 @@ valerie_error_code valerie_unit_play( valerie this, int unit ) /** Play the unit at specified speed. */ -valerie_error_code valerie_unit_play_at_speed( valerie this, int unit, double speed ) +valerie_error_code valerie_unit_play_at_speed( valerie this, int unit, int speed ) { - return valerie_execute( this, 10240, "PLAY U%d %e", unit, speed ); + return valerie_execute( this, 10240, "PLAY U%d %d", unit, speed ); } /** Stop playback on the specified unit. diff --git a/mlt/src/valerie/valerie.h b/mlt/src/valerie/valerie.h index 91c09878..fc3b059b 100644 --- a/mlt/src/valerie/valerie.h +++ b/mlt/src/valerie/valerie.h @@ -100,7 +100,7 @@ extern valerie_error_code valerie_unit_clip_remove( valerie, int, valerie_clip_o extern valerie_error_code valerie_unit_remove_current_clip( valerie, int ); extern valerie_error_code valerie_unit_clip_insert( valerie, int, valerie_clip_offset, int, char *, double, double ); extern valerie_error_code valerie_unit_play( valerie, int ); -extern valerie_error_code valerie_unit_play_at_speed( valerie, int, double ); +extern valerie_error_code valerie_unit_play_at_speed( valerie, int, int ); extern valerie_error_code valerie_unit_stop( valerie, int ); extern valerie_error_code valerie_unit_pause( valerie, int ); extern valerie_error_code valerie_unit_rewind( valerie, int ); @@ -227,7 +227,7 @@ typedef struct { int unit; int node; - char guid[ 17 ]; + char guid[ 512 ]; int online; } *valerie_unit_entry, valerie_unit_entry_t; diff --git a/setenv b/setenv index 01363eb6..9d665ed0 100644 --- a/setenv +++ b/setenv @@ -1,10 +1,17 @@ + +# Environment variable settings to allow execution without install + export MLT_REPOSITORY=`pwd`/src/modules export LD_LIBRARY_PATH=`pwd`/src/framework:\ +`pwd`/src/valerie:\ `pwd`/src/modules/bluefish:\ `pwd`/../bluefish/lib:\ `pwd`/../mpeg_sdk_demo/bin:\ `pwd`/../dv_sdk -export PATH=$PATH:`pwd`/src/inigo:`pwd`/src/miracle +export PATH=$PATH:\ +`pwd`/src/inigo:\ +`pwd`/src/humperdink:\ +`pwd`/src/miracle diff --git a/src/framework/Makefile b/src/framework/Makefile index d01ee347..6d804016 100644 --- a/src/framework/Makefile +++ b/src/framework/Makefile @@ -1,20 +1,20 @@ -FRAMEWORK_OBJS = mlt_frame.o \ - mlt_property.o \ - mlt_properties.o \ - mlt_service.o \ - mlt_producer.o \ - mlt_multitrack.o \ - mlt_playlist.o \ - mlt_consumer.o \ - mlt_filter.o \ - mlt_transition.o \ - mlt_field.o \ - mlt_tractor.o \ - mlt_factory.o \ - mlt_repository.o - -OBJS = $(FRAMEWORK_OBJS) +TARGET = libmlt.so + +OBJS = mlt_frame.o \ + mlt_property.o \ + mlt_properties.o \ + mlt_service.o \ + mlt_producer.o \ + mlt_multitrack.o \ + mlt_playlist.o \ + mlt_consumer.o \ + mlt_filter.o \ + mlt_transition.o \ + mlt_field.o \ + mlt_tractor.o \ + mlt_factory.o \ + mlt_repository.o SRCS := $(OBJS:.o=.c) @@ -22,9 +22,9 @@ CFLAGS = -g -Wall -D_FILE_OFFSET_BITS=64 -pthread LDFLAGS = -lm -ldl -lpthread -all: libmlt.so +all: $(TARGET) -libmlt.so: $(OBJS) +$(TARGET): $(OBJS) $(CC) -shared -o $@ $(OBJS) $(LDFLAGS) depend: $(SRCS) @@ -34,7 +34,7 @@ dist-clean: clean rm -f .depend clean: - rm -f $(FRAMEWORK_OBJS) libmlt.so + rm -f $(OBJS) $(TARGET) ifneq ($(wildcard .depend),) include .depend diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index 16d51f89..dd179837 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -659,7 +659,7 @@ uint8_t *mlt_frame_rescale_yuv422( mlt_frame this, int owidth, int oheight ) if ( abs( dx ) < in_x_range && abs( dy ) < in_y_range ) { // We're in the input range for this row. - in_ptr = in_line + ( dx >> 1 ) * 4 - 2 * ( x & 1 ); + in_ptr = in_line + ( dx >> 1 ) * 4 + 2 * ( x & 1 ); *out_ptr ++ = *in_ptr ++; *out_ptr ++ = *in_ptr ++; } diff --git a/src/framework/mlt_playlist.c b/src/framework/mlt_playlist.c index 7a2ad658..d11f9562 100644 --- a/src/framework/mlt_playlist.c +++ b/src/framework/mlt_playlist.c @@ -105,31 +105,52 @@ mlt_properties mlt_playlist_properties( mlt_playlist this ) return mlt_producer_properties( &this->parent ); } -/** Append to the virtual playlist. -*/ - -static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer, mlt_timecode in, mlt_timecode out ) +static int mlt_playlist_virtual_refresh( mlt_playlist this ) { + int i = 0; + // Get the fps of the first producer double fps = mlt_properties_get_double( mlt_playlist_properties( this ), "first_fps" ); + mlt_timecode playtime = 0; - mlt_timecode playtime = mlt_producer_get_playtime( mlt_playlist_producer( this ) ) + out - in; - - // If fps is 0 - if ( fps == 0 ) - { - // Inherit it from the producer - fps = mlt_producer_get_fps( producer ); - } - else if ( fps != mlt_properties_get_double( mlt_producer_properties( producer ), "fps" ) ) + for ( i = 0; i < this->count; i ++ ) { - // Generate a warning for now - the following attempt to fix may fail - fprintf( stderr, "Warning: fps mismatch on playlist producer %d\n", this->count ); + // Get the producer + mlt_producer producer = this->list[ i ]->producer; + + // If fps is 0 + if ( fps == 0 ) + { + // Inherit it from the producer + fps = mlt_producer_get_fps( producer ); + } + else if ( fps != mlt_properties_get_double( mlt_producer_properties( producer ), "fps" ) ) + { + // Generate a warning for now - the following attempt to fix may fail + fprintf( stderr, "Warning: fps mismatch on playlist producer %d\n", this->count ); + + // It should be safe to impose fps on an image producer, but not necessarily safe for video + mlt_properties_set_double( mlt_producer_properties( producer ), "fps", fps ); + } - // It should be safe to impose fps on an image producer, but not necessarily safe for video - mlt_properties_set_double( mlt_producer_properties( producer ), "fps", fps ); + // Update the playtime for this clip + playtime += this->list[ i ]->playtime; } + // Refresh all properties + mlt_properties_set_double( mlt_playlist_properties( this ), "first_fps", fps ); + mlt_properties_set_double( mlt_playlist_properties( this ), "fps", fps ); + mlt_properties_set_timecode( mlt_playlist_properties( this ), "length", playtime ); + mlt_properties_set_timecode( mlt_playlist_properties( this ), "out", playtime ); + + return 0; +} + +/** Append to the virtual playlist. +*/ + +static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer, mlt_timecode in, mlt_timecode out ) +{ // Check that we have room if ( this->count >= this->size ) { @@ -147,12 +168,7 @@ static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer this->count ++; - mlt_properties_set_double( mlt_playlist_properties( this ), "first_fps", fps ); - mlt_properties_set_double( mlt_playlist_properties( this ), "fps", fps ); - mlt_properties_set_timecode( mlt_playlist_properties( this ), "length", playtime ); - mlt_properties_set_timecode( mlt_playlist_properties( this ), "out", playtime ); - - return 0; + return mlt_playlist_virtual_refresh( this ); } /** Seek in the virtual playlist. @@ -221,14 +237,17 @@ static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this ) // Seek in real producer to relative position if ( i < this->count ) { - fprintf( stderr, "END OF CLIP %d AT %e\n", i, position ); + // Update the playtime for the changed clip (hmmm) this->list[ i ]->playtime = position - this->list[ i ]->in; + + // Refresh the playlist + mlt_playlist_virtual_refresh( this ); } return producer; } -static int mlt_playlist_current_clip( mlt_playlist this ) +int mlt_playlist_current_clip( mlt_playlist this ) { // Map playlist position to real producer in virtual playlist mlt_timecode position = mlt_producer_position( &this->parent ); @@ -253,6 +272,15 @@ static int mlt_playlist_current_clip( mlt_playlist this ) return i; } +mlt_producer mlt_playlist_current( mlt_playlist this ) +{ + int i = mlt_playlist_current_clip( this ); + if ( i < this->count ) + return this->list[ i ]->producer; + else + return &this->blank; +} + /** Get the timecode which corresponds to the start of the next clip. */ @@ -291,6 +319,40 @@ mlt_timecode mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index return position; } +int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info, int index ) +{ + int error = index < 0 || index >= this->count; + if ( !error ) + { + mlt_producer producer = this->list[ index ]->producer; + mlt_properties properties = mlt_producer_properties( producer ); + info->resource = mlt_properties_get( properties, "resource" ); + info->in = this->list[ index ]->in; + info->out = this->list[ index ]->in + this->list[ index ]->playtime; + info->playtime = this->list[ index ]->playtime; + info->length = mlt_producer_get_length( producer ); + info->fps = mlt_producer_get_fps( producer ); + } + return error; +} + +/** Get number of clips in the playlist. +*/ + +int mlt_playlist_count( mlt_playlist this ) +{ + return this->count; +} + +/** Clear the playlist. +*/ + +int mlt_playlist_clear( mlt_playlist this ) +{ + this->count = 0; + return mlt_playlist_virtual_refresh( this ); +} + /** Append a producer to the playlist. */ @@ -300,6 +362,18 @@ int mlt_playlist_append( mlt_playlist this, mlt_producer producer ) return mlt_playlist_virtual_append( this, producer, 0, mlt_producer_get_playtime( producer ) ); } +/** Append a producer to the playlist with in/out points. +*/ + +int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, double in, double out ) +{ + // Append to virtual list + if ( in != -1 && out != -1 ) + return mlt_playlist_virtual_append( this, producer, in, out - in ); + else + return mlt_playlist_virtual_append( this, producer, 0, mlt_producer_get_playtime( producer ) ); +} + /** Append a blank to the playlist of a given length. */ @@ -328,6 +402,15 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i if ( mlt_properties_get_int( properties, "end_of_clip" ) ) mlt_playlist_virtual_set_out( this ); + // Check for notifier and call with appropriate argument + mlt_properties playlist_properties = mlt_producer_properties( producer ); + void ( *notifier )( void * ) = mlt_properties_get_data( playlist_properties, "notifier", NULL ); + if ( notifier != NULL ) + { + void *argument = mlt_properties_get_data( playlist_properties, "notifier_arg", NULL ); + notifier( argument ); + } + // Update timecode on the frame we're creating mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) ); diff --git a/src/framework/mlt_playlist.h b/src/framework/mlt_playlist.h index c6013860..3e30ba6b 100644 --- a/src/framework/mlt_playlist.h +++ b/src/framework/mlt_playlist.h @@ -23,6 +23,20 @@ #include "mlt_producer.h" +/** Structur for returning clip information. +*/ + +typedef struct +{ + char *resource; + double in; + double out; + double playtime; + double length; + float fps; +} +mlt_playlist_clip_info; + /** Public final methods */ @@ -30,9 +44,15 @@ extern mlt_playlist mlt_playlist_init( ); extern mlt_producer mlt_playlist_producer( mlt_playlist this ); extern mlt_service mlt_playlist_service( mlt_playlist this ); extern mlt_properties mlt_playlist_properties( mlt_playlist this ); +extern int mlt_playlist_count( mlt_playlist this ); +extern int mlt_playlist_clear( mlt_playlist this ); extern int mlt_playlist_append( mlt_playlist this, mlt_producer producer ); +extern int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, double in, double out ); extern int mlt_playlist_blank( mlt_playlist this, mlt_timecode length ); extern mlt_timecode mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index ); +extern int mlt_playlist_current_clip( mlt_playlist this ); +extern mlt_producer mlt_playlist_current( mlt_playlist this ); +extern int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info, int index ); extern void mlt_playlist_close( mlt_playlist this ); #endif diff --git a/src/framework/mlt_producer.c b/src/framework/mlt_producer.c index 87c2f089..751e19a9 100644 --- a/src/framework/mlt_producer.c +++ b/src/framework/mlt_producer.c @@ -265,6 +265,10 @@ static int producer_get_frame( mlt_service service, mlt_frame_ptr frame, int ind { // Get the frame from the implementation result = this->get_frame( this, frame, index ); + + mlt_properties frame_properties = mlt_frame_properties( *frame ); + double speed = mlt_producer_get_speed( this ); + mlt_properties_set_double( frame_properties, "speed", speed ); } else { diff --git a/src/humperdink/Makefile b/src/humperdink/Makefile new file mode 100644 index 00000000..53f2f96f --- /dev/null +++ b/src/humperdink/Makefile @@ -0,0 +1,29 @@ +TARGET = humperdink + +OBJS = client.o \ + io.o \ + remote.o + +CFLAGS = -I .. -Wall -g -D_FILE_OFFSET_BITS=64 -pthread -rdynamic + +LDFLAGS = -L ../valerie -lvalerie + +SRCS := $(OBJS:.o=.c) + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CC) -o $@ $(OBJS) $(LDFLAGS) + +depend: $(SRCS) + $(CC) -MM $(CFLAGS) $^ 1>.depend + +dist-clean: clean + rm -f .depend + +clean: + rm -f $(OBJS) $(TARGET) + +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/src/humperdink/client.c b/src/humperdink/client.c new file mode 100644 index 00000000..1f0ff3d7 --- /dev/null +++ b/src/humperdink/client.c @@ -0,0 +1,1026 @@ +/* + * client.c -- dv1394d client demo + * Copyright (C) 2002-2003 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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. + */ + +/* System header files */ +#include +#include +#include + +/* Application header files */ +#include "client.h" +#include "io.h" + +/** Clip navigation enumeration. +*/ + +typedef enum +{ + absolute, + relative +} +dv_demo_whence; + +/** Function prototype for menu handling. +*/ + +typedef valerie_error_code (*demo_function)( dv_demo ); + +/** The menu structure. +*/ + +typedef struct +{ + char *description; + struct menu_item + { + char *option; + demo_function function; + } + array[ 50 ]; +} +*dv_demo_menu, dv_demo_menu_t; + +/** Forward reference to menu runner. +*/ + +extern valerie_error_code dv_demo_run_menu( dv_demo, dv_demo_menu ); + +/** Foward references. +*/ + +extern valerie_error_code dv_demo_list_nodes( dv_demo ); +extern valerie_error_code dv_demo_add_unit( dv_demo ); +extern valerie_error_code dv_demo_select_unit( dv_demo ); +extern valerie_error_code dv_demo_execute( dv_demo ); +extern valerie_error_code dv_demo_load( dv_demo ); +extern valerie_error_code dv_demo_transport( dv_demo ); +static void *dv_demo_status_thread( void * ); + +/** Connected menu definition. +*/ + +dv_demo_menu_t connected_menu = +{ + "Connected Menu", + { + { "Add Unit", dv_demo_add_unit }, + { "Select Unit", dv_demo_select_unit }, + { "Command Shell", dv_demo_execute }, + { NULL, NULL } + } +}; + +/** Initialise the demo structure. +*/ + +dv_demo dv_demo_init( valerie_parser parser ) +{ + dv_demo this = malloc( sizeof( dv_demo_t ) ); + if ( this != NULL ) + { + int index = 0; + memset( this, 0, sizeof( dv_demo_t ) ); + strcpy( this->last_directory, "/" ); + for ( index = 0; index < 4; index ++ ) + { + this->queues[ index ].unit = index; + this->queues[ index ].position = -1; + } + this->parser = parser; + } + return this; +} + +/** Display a status record. +*/ + +void dv_demo_show_status( dv_demo demo, valerie_status status ) +{ + if ( status->unit == demo->selected_unit && demo->showing ) + { + char temp[ 1024 ] = ""; + + sprintf( temp, "U%d ", demo->selected_unit ); + + switch( status->status ) + { + case unit_offline: + strcat( temp, "offline " ); + break; + case unit_undefined: + strcat( temp, "undefined " ); + break; + case unit_not_loaded: + strcat( temp, "unloaded " ); + break; + case unit_stopped: + strcat( temp, "stopped " ); + break; + case unit_playing: + strcat( temp, "playing " ); + break; + case unit_paused: + strcat( temp, "paused " ); + break; + case unit_disconnected: + strcat( temp, "disconnect" ); + break; + default: + strcat( temp, "unknown " ); + break; + } + + sprintf( temp + strlen( temp ), " %9.2f %9.2f %9.2f ", status->in, status->position, status->out ); + strcat( temp, status->clip ); + + printf( "%-80.80s\r", temp ); + fflush( stdout ); + } +} + +/** Determine action to carry out as dictated by the client unit queue. +*/ + +void dv_demo_queue_action( dv_demo demo, valerie_status status ) +{ + dv_demo_queue queue = &demo->queues[ status->unit ]; + + /* SPECIAL CASE STATUS NOTIFICATIONS TO IGNORE */ + + /* When we've issued a LOAD on the previous notification, then ignore this one. */ + if ( queue->ignore ) + { + queue->ignore --; + return; + } + + if ( queue->mode && status->status != unit_offline && queue->head != queue->tail ) + { + if ( ( status->position >= status->out && status->speed > 0 ) || status->status == unit_not_loaded ) + { + queue->position = ( queue->position + 1 ) % 50; + if ( queue->position == queue->tail ) + queue->position = queue->head; + valerie_unit_load( demo->dv_status, status->unit, queue->list[ queue->position ] ); + if ( status->status == unit_not_loaded ) + valerie_unit_play( demo->dv, queue->unit ); + queue->ignore = 1; + } + else if ( ( status->position <= status->in && status->speed < 0 ) || status->status == unit_not_loaded ) + { + if ( queue->position == -1 ) + queue->position = queue->head; + valerie_unit_load( demo->dv_status, status->unit, queue->list[ queue->position ] ); + if ( status->status == unit_not_loaded ) + valerie_unit_play( demo->dv, queue->unit ); + queue->position = ( queue->position - 1 ) % 50; + queue->ignore = 1; + } + } +} + +/** Status thread. +*/ + +static void *dv_demo_status_thread( void *arg ) +{ + dv_demo demo = arg; + valerie_status_t status; + valerie_notifier notifier = valerie_get_notifier( demo->dv_status ); + + while ( !demo->terminated ) + { + if ( valerie_notifier_wait( notifier, &status ) != -1 ) + { + dv_demo_queue_action( demo, &status ); + dv_demo_show_status( demo, &status ); + if ( status.status == unit_disconnected ) + demo->disconnected = 1; + } + } + + return NULL; +} + +/** Turn on/off status display. +*/ + +void dv_demo_change_status( dv_demo demo, int flag ) +{ + if ( demo->disconnected && flag ) + { + valerie_error_code error = valerie_connect( demo->dv ); + if ( error == valerie_ok ) + demo->disconnected = 0; + else + beep(); + } + + if ( flag ) + { + valerie_status_t status; + valerie_notifier notifier = valerie_get_notifier( demo->dv ); + valerie_notifier_get( notifier, &status, demo->selected_unit ); + demo->showing = 1; + dv_demo_show_status( demo, &status ); + } + else + { + demo->showing = 0; + printf( "%-80.80s\r", " " ); + fflush( stdout ); + } +} + +/** Add a unit. +*/ + +valerie_error_code dv_demo_add_unit( dv_demo demo ) +{ + valerie_error_code error = valerie_ok; + valerie_nodes nodes = valerie_nodes_init( demo->dv ); + valerie_units units = valerie_units_init( demo->dv ); + + if ( valerie_nodes_count( nodes ) != -1 && valerie_units_count( units ) != -1 ) + { + char pressed; + valerie_node_entry_t node; + valerie_unit_entry_t unit; + int node_index = 0; + int unit_index = 0; + + printf( "Select a Node\n\n" ); + + for ( node_index = 0; node_index < valerie_nodes_count( nodes ); node_index ++ ) + { + valerie_nodes_get( nodes, node_index, &node ); + printf( "%d: %s - %s ", node_index + 1, node.guid, node.name ); + for ( unit_index = 0; unit_index < valerie_units_count( units ); unit_index ++ ) + { + valerie_units_get( units, unit_index, &unit ); + if ( !strcmp( unit.guid, node.guid ) ) + printf( "[U%d] ", unit.unit ); + } + printf( "\n" ); + } + + printf( "0. Exit\n\n" ); + + printf( "Node: " ); + + while ( ( pressed = get_keypress( ) ) != '0' ) + { + node_index = pressed - '1'; + if ( node_index >= 0 && node_index < valerie_nodes_count( nodes ) ) + { + int unit; + printf( "%c\n\n", pressed ); + valerie_nodes_get( nodes, node_index, &node ); + if ( valerie_unit_add( demo->dv, node.guid, &unit ) == valerie_ok ) + { + printf( "Unit added as U%d\n", unit ); + demo->selected_unit = unit; + } + else + { + int index = 0; + valerie_response response = valerie_get_last_response( demo->dv ); + printf( "Failed to add unit:\n\n" ); + for( index = 1; index < valerie_response_count( response ) - 1; index ++ ) + printf( "%s\n", valerie_response_get_line( response, index ) ); + } + printf( "\n" ); + wait_for_any_key( NULL ); + break; + } + else + { + beep( ); + } + } + } + else + { + printf( "Invalid response from the server.\n\n" ); + wait_for_any_key( NULL ); + } + + valerie_nodes_close( nodes ); + valerie_units_close( units ); + + return error; +} + +/** Select a unit. +*/ + +valerie_error_code dv_demo_select_unit( dv_demo demo ) +{ + int terminated = 0; + int refresh = 1; + + while ( !terminated ) + { + valerie_units units = valerie_units_init( demo->dv ); + + if ( valerie_units_count( units ) > 0 ) + { + valerie_unit_entry_t unit; + int index = 0; + char key = '\0'; + + if ( refresh ) + { + printf( "Select a Unit\n\n" ); + + for ( index = 0; index < valerie_units_count( units ); index ++ ) + { + valerie_units_get( units, index, &unit ); + printf( "%d: U%d - %s [%s]\n", index + 1, + unit.unit, + unit.guid, + unit.online ? "online" : "offline" ); + } + printf( "0: Exit\n\n" ); + + printf( "Unit [%d]: ", demo->selected_unit + 1 ); + refresh = 0; + } + + key = get_keypress( ); + + if ( key == '\r' ) + key = demo->selected_unit + '1'; + + if ( key != '0' ) + { + if ( key >= '1' && key < '1' + valerie_units_count( units ) ) + { + demo->selected_unit = key - '1'; + printf( "%c\n\n", key ); + dv_demo_load( demo ); + refresh = 1; + } + else + { + beep( ); + } + } + else + { + printf( "0\n\n" ); + terminated = 1; + } + } + else if ( valerie_units_count( units ) == 0 ) + { + printf( "No units added - add a unit first\n\n" ); + dv_demo_add_unit( demo ); + } + else + { + printf( "Unable to obtain Unit List.\n" ); + terminated = 1; + } + + valerie_units_close( units ); + } + + return valerie_ok; +} + +/** Execute an arbitrary command. +*/ + +valerie_error_code dv_demo_execute( dv_demo demo ) +{ + valerie_error_code error = valerie_ok; + char command[ 10240 ]; + int terminated = 0; + + printf( "DV1394D Shell\n" ); + printf( "Enter an empty command to exit.\n\n" ); + + while ( !terminated ) + { + terminated = 1; + printf( "Command> " ); + + if ( chomp( get_string( command, 10240, "" ) ) != NULL ) + { + if ( strcmp( command, "" ) ) + { + int index = 0; + valerie_response response = NULL; + error = valerie_execute( demo->dv, 10240, command ); + printf( "\n" ); + response = valerie_get_last_response( demo->dv ); + for ( index = 0; index < valerie_response_count( response ); index ++ ) + { + char *line = valerie_response_get_line( response, index ); + printf( "%4d: %s\n", index, line ); + } + printf( "\n" ); + terminated = 0; + } + } + } + + printf( "\n" ); + + return error; +} + +/** Add a file to the queue. +*/ + +valerie_error_code dv_demo_queue_add( dv_demo demo, dv_demo_queue queue, char *file ) +{ + valerie_status_t status; + valerie_notifier notifier = valerie_get_notifier( demo->dv ); + + if ( ( queue->tail + 1 ) % 50 == queue->head ) + queue->head = ( queue->head + 1 ) % 50; + strcpy( queue->list[ queue->tail ], file ); + queue->tail = ( queue->tail + 1 ) % 50; + + valerie_notifier_get( notifier, &status, queue->unit ); + valerie_notifier_put( notifier, &status ); + + return valerie_ok; +} + +/** Basic queue maintenance and status reports. +*/ + +valerie_error_code dv_demo_queue_maintenance( dv_demo demo, dv_demo_queue queue ) +{ + printf( "Queue Maintenance for Unit %d\n\n", queue->unit ); + + if ( !queue->mode ) + { + char ch; + printf( "Activate queueing? [Y] " ); + ch = get_keypress( ); + if ( ch == 'y' || ch == 'Y' || ch == '\r' ) + queue->mode = 1; + printf( "\n\n" ); + } + + if ( queue->mode ) + { + int terminated = 0; + int last_position = -2; + + term_init( ); + + while ( !terminated ) + { + int first = ( queue->position + 1 ) % 50; + int index = first; + + if ( first == queue->tail ) + index = first = queue->head; + + if ( queue->head == queue->tail ) + { + if ( last_position == -2 ) + { + printf( "Queue is empty\n" ); + printf( "\n" ); + printf( "0 = exit, t = turn off queueing\n\n" ); + last_position = -1; + } + } + else if ( last_position != queue->position ) + { + printf( "Order of play\n\n" ); + + do + { + printf( "%c%02d: %s\n", index == first ? '*' : ' ', index, queue->list[ index ] + 1 ); + index = ( index + 1 ) % 50; + if ( index == queue->tail ) + index = queue->head; + } + while( index != first ); + + printf( "\n" ); + printf( "0 = exit, t = turn off queueing, c = clear queue\n\n" ); + last_position = queue->position; + } + + dv_demo_change_status( demo, 1 ); + + switch( term_read( ) ) + { + case -1: + break; + case '0': + terminated = 1; + break; + case 't': + terminated = 1; + queue->mode = 0; + break; + case 'c': + queue->head = queue->tail = 0; + queue->position = -1; + last_position = -2; + break; + } + + dv_demo_change_status( demo, 0 ); + } + + term_exit( ); + } + + return valerie_ok; +} + +/** Load a file to the selected unit. Horrible function - sorry :-/. Not a good + demo.... +*/ + +valerie_error_code dv_demo_load( dv_demo demo ) +{ + valerie_error_code error = valerie_ok; + int terminated = 0; + int refresh = 1; + int start = 0; + + strcpy( demo->current_directory, demo->last_directory ); + + term_init( ); + + while ( !terminated ) + { + valerie_dir dir = valerie_dir_init( demo->dv, demo->current_directory ); + + if ( valerie_dir_count( dir ) == -1 ) + { + printf( "Invalid directory - retrying %s\n", demo->last_directory ); + valerie_dir_close( dir ); + dir = valerie_dir_init( demo->dv, demo->last_directory ); + if ( valerie_dir_count( dir ) == -1 ) + { + printf( "Invalid directory - going back to /\n" ); + valerie_dir_close( dir ); + dir = valerie_dir_init( demo->dv, "/" ); + strcpy( demo->current_directory, "/" ); + } + else + { + strcpy( demo->current_directory, demo->last_directory ); + } + } + + terminated = valerie_dir_count( dir ) == -1; + + if ( !terminated ) + { + int index = 0; + int selected = 0; + int max = 9; + int end = 0; + + end = valerie_dir_count( dir ); + + strcpy( demo->last_directory, demo->current_directory ); + + while ( !selected && !terminated ) + { + valerie_dir_entry_t entry; + int pressed; + + if ( refresh ) + { + char *action = "Load & Play"; + if ( demo->queues[ demo->selected_unit ].mode ) + action = "Queue"; + printf( "%s from %s\n\n", action, demo->current_directory ); + if ( strcmp( demo->current_directory, "/" ) ) + printf( "-: Parent directory\n" ); + for ( index = start; index < end && ( index - start ) < max; index ++ ) + { + valerie_dir_get( dir, index, &entry ); + printf( "%d: %s\n", index - start + 1, entry.name ); + } + while ( ( index ++ % 9 ) != 0 ) + printf( "\n" ); + printf( "\n" ); + if ( start + max < end ) + printf( "space = more files" ); + else if ( end > max ) + printf( "space = return to start of list" ); + if ( start > 0 ) + printf( ", b = previous files" ); + printf( "\n" ); + printf( "0 = abort, t = transport, x = execute command, q = queue maintenance\n\n" ); + refresh = 0; + } + + dv_demo_change_status( demo, 1 ); + + pressed = term_read( ); + switch( pressed ) + { + case -1: + break; + case '0': + terminated = 1; + break; + case 'b': + refresh = start - max >= 0; + if ( refresh ) + start = start - max; + break; + case ' ': + refresh = start + max < end; + if ( refresh ) + { + start = start + max; + } + else if ( end > max ) + { + start = 0; + refresh = 1; + } + break; + case '-': + if ( strcmp( demo->current_directory, "/" ) ) + { + selected = 1; + ( *strrchr( demo->current_directory, '/' ) ) = '\0'; + ( *( strrchr( demo->current_directory, '/' ) + 1 ) ) = '\0'; + } + break; + case 't': + dv_demo_change_status( demo, 0 ); + term_exit( ); + dv_demo_transport( demo ); + term_init( ); + selected = 1; + break; + case 'x': + dv_demo_change_status( demo, 0 ); + term_exit( ); + dv_demo_execute( demo ); + term_init( ); + selected = 1; + break; + case 'q': + dv_demo_change_status( demo, 0 ); + term_exit( ); + dv_demo_queue_maintenance( demo, &demo->queues[ demo->selected_unit ] ); + term_init( ); + selected = 1; + break; + default: + if ( pressed >= '1' && pressed <= '9' ) + { + if ( ( start + pressed - '1' ) < end ) + { + valerie_dir_get( dir, start + pressed - '1', &entry ); + selected = 1; + strcat( demo->current_directory, entry.name ); + } + } + break; + } + + dv_demo_change_status( demo, 0 ); + } + + valerie_dir_close( dir ); + } + + if ( !terminated && demo->current_directory[ strlen( demo->current_directory ) - 1 ] != '/' ) + { + if ( demo->queues[ demo->selected_unit ].mode == 0 ) + { + error = valerie_unit_load( demo->dv, demo->selected_unit, demo->current_directory ); + valerie_unit_play( demo->dv, demo->selected_unit ); + } + else + { + dv_demo_queue_add( demo, &demo->queues[ demo->selected_unit ], demo->current_directory ); + printf( "File %s added to queue.\n", demo->current_directory ); + } + strcpy( demo->current_directory, demo->last_directory ); + refresh = 0; + } + else + { + refresh = 1; + start = 0; + } + } + + term_exit( ); + + return error; +} + +/** Set the in point of the clip on the select unit. +*/ + +valerie_error_code dv_demo_set_in( dv_demo demo ) +{ + int position = 0; + valerie_status_t status; + valerie_notifier notifier = valerie_parser_get_notifier( demo->parser ); + valerie_notifier_get( notifier, &status, demo->selected_unit ); + position = status.position; + return valerie_unit_set_in( demo->dv, demo->selected_unit, position ); +} + +/** Set the out point of the clip on the selected unit. +*/ + +valerie_error_code dv_demo_set_out( dv_demo demo ) +{ + int position = 0; + valerie_status_t status; + valerie_notifier notifier = valerie_parser_get_notifier( demo->parser ); + valerie_notifier_get( notifier, &status, demo->selected_unit ); + position = status.position; + return valerie_unit_set_out( demo->dv, demo->selected_unit, position ); +} + +/** Clear the in and out points on the selected unit. +*/ + +valerie_error_code dv_demo_clear_in_out( dv_demo demo ) +{ + return valerie_unit_clear_in_out( demo->dv, demo->selected_unit ); +} + +/** Goto a user specified frame on the selected unit. +*/ + +valerie_error_code dv_demo_goto( dv_demo demo ) +{ + int frame = 0; + printf( "Frame: " ); + if ( get_int( &frame, 0 ) ) + return valerie_unit_goto( demo->dv, demo->selected_unit, frame ); + return valerie_ok; +} + +/** Manipulate playback on the selected unit. +*/ + +valerie_error_code dv_demo_transport( dv_demo demo ) +{ + valerie_error_code error = valerie_ok; + int refresh = 1; + int terminated = 0; + valerie_status_t status; + valerie_notifier notifier = valerie_get_notifier( demo->dv ); + + while ( !terminated ) + { + if ( refresh ) + { + printf( " +----+ +------+ +----+ +------+ +---+ +-----+ +------+ +-----+ +---+ \n" ); + printf( " |1=-5| |2=-2.5| |3=-1| |4=-0.5| |5=1| |6=0.5| |7=1.25| |8=2.5| |9=5| \n" ); + printf( " +----+ +------+ +----+ +------+ +---+ +-----+ +------+ +-----+ +---+ \n" ); + printf( "\n" ); + printf( "+----------------------------------------------------------------------+\n" ); + printf( "| 0 = quit, x = eXecute, 'space' = pause |\n" ); + printf( "| g = goto a frame, q = queue maintenance |\n" ); + printf( "| h = step -1, j = end of clip, k = start of clip, l = step 1 |\n" ); + printf( "| eof handling: p = pause, r = repeat, t = terminate |\n" ); + printf( "| i = set in point, o = set out point, c = clear in/out |\n" ); + printf( "| u = use point settings, d = don't use point settings |\n" ); + printf( "+----------------------------------------------------------------------+\n" ); + printf( "\n" ); + term_init( ); + refresh = 0; + } + + dv_demo_change_status( demo, 1 ); + + switch( term_read( ) ) + { + case '0': + terminated = 1; + break; + case -1: + break; + case ' ': + error = valerie_unit_pause( demo->dv, demo->selected_unit ); + break; + case '1': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, -5000 ); + break; + case '2': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, -2500 ); + break; + case '3': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, -1000 ); + break; + case '4': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, -500 ); + break; + case '5': + error = valerie_unit_play( demo->dv, demo->selected_unit ); + break; + case '6': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, 500 ); + break; + case '7': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, 1250 ); + break; + case '8': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, 2500 ); + break; + case '9': + error = valerie_unit_play_at_speed( demo->dv, demo->selected_unit, 5000 ); + break; + case 's': + error = valerie_unit_goto( demo->dv, demo->selected_unit, 0 ); + break; + case 'h': + error = valerie_unit_step( demo->dv, demo->selected_unit, -1 ); + break; + case 'j': + valerie_notifier_get( notifier, &status, demo->selected_unit ); + error = valerie_unit_goto( demo->dv, demo->selected_unit, status.tail_out ); + break; + case 'k': + valerie_notifier_get( notifier, &status, demo->selected_unit ); + error = valerie_unit_goto( demo->dv, demo->selected_unit, status.in ); + break; + case 'l': + error = valerie_unit_step( demo->dv, demo->selected_unit, 1 ); + break; + case 'p': + error = valerie_unit_set( demo->dv, demo->selected_unit, "eof", "pause" ); + break; + case 'r': + error = valerie_unit_set( demo->dv, demo->selected_unit, "eof", "loop" ); + break; + case 't': + error = valerie_unit_set( demo->dv, demo->selected_unit, "eof", "stop" ); + break; + case 'i': + error = dv_demo_set_in( demo ); + break; + case 'o': + error = dv_demo_set_out( demo ); + break; + case 'g': + dv_demo_change_status( demo, 0 ); + term_exit( ); + error = dv_demo_goto( demo ); + refresh = 1; + break; + case 'c': + error = dv_demo_clear_in_out( demo ); + break; + case 'u': + error = valerie_unit_set( demo->dv, demo->selected_unit, "points", "use" ); + break; + case 'd': + error = valerie_unit_set( demo->dv, demo->selected_unit, "points", "ignore" ); + break; + case 'x': + dv_demo_change_status( demo, 0 ); + term_exit( ); + dv_demo_execute( demo ); + refresh = 1; + break; + case 'q': + dv_demo_change_status( demo, 0 ); + term_exit( ); + dv_demo_queue_maintenance( demo, &demo->queues[ demo->selected_unit ] ); + refresh = 1; + break; + } + + dv_demo_change_status( demo, 0 ); + } + + term_exit( ); + + return error; +} + +/** Recursive menu execution. +*/ + +valerie_error_code dv_demo_run_menu( dv_demo demo, dv_demo_menu menu ) +{ + char *items = "123456789abcdefghijklmnopqrstuvwxyz"; + int refresh_menu = 1; + int terminated = 0; + int item_count = 0; + int item_selected = 0; + int index = 0; + char key; + + while( !terminated ) + { + + if ( refresh_menu ) + { + printf( "%s\n\n", menu->description ); + for ( index = 0; menu->array[ index ].option != NULL; index ++ ) + printf( "%c: %s\n", items[ index ], menu->array[ index ].option ); + printf( "0: Exit\n\n" ); + printf( "Select Option: " ); + refresh_menu = 0; + item_count = index; + } + + key = get_keypress( ); + + if ( demo->disconnected && key != '0' ) + { + valerie_error_code error = valerie_connect( demo->dv ); + if ( error == valerie_ok ) + demo->disconnected = 0; + else + beep(); + } + + if ( !demo->disconnected || key == '0' ) + { + item_selected = strchr( items, key ) - items; + + if ( key == '0' ) + { + printf( "%c\n\n", key ); + terminated = 1; + } + else if ( item_selected >= 0 && item_selected < item_count ) + { + printf( "%c\n\n", key ); + menu->array[ item_selected ].function( demo ); + refresh_menu = 1; + } + else + { + beep( ); + } + } + } + + return valerie_ok; +} + +/** Entry point for main menu. +*/ + +void dv_demo_run( dv_demo this ) +{ + this->dv = valerie_init( this->parser ); + this->dv_status = valerie_init( this->parser ); + if ( valerie_connect( this->dv ) == valerie_ok ) + { + pthread_create( &this->thread, NULL, dv_demo_status_thread, this ); + dv_demo_run_menu( this, &connected_menu ); + this->terminated = 1; + pthread_join( this->thread, NULL ); + this->terminated = 0; + } + else + { + printf( "Unable to connect." ); + wait_for_any_key( "" ); + } + + valerie_close( this->dv_status ); + valerie_close( this->dv ); + + printf( "Demo Exit.\n" ); +} + +/** Close the demo structure. +*/ + +void dv_demo_close( dv_demo demo ) +{ + free( demo ); +} + diff --git a/src/humperdink/client.h b/src/humperdink/client.h new file mode 100644 index 00000000..9490360d --- /dev/null +++ b/src/humperdink/client.h @@ -0,0 +1,66 @@ +/* + * client.h -- dv1394d client demo + * Copyright (C) 2002-2003 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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. + */ + +#ifndef _DEMO_CLIENT_H_ +#define _DEMO_CLIENT_H_ + +#include +#include +#include + +/** Queue for unit playback +*/ + +typedef struct +{ + int mode; + int unit; + int position; + int head; + int tail; + char list[ 50 ][ PATH_MAX + NAME_MAX ]; + int ignore; +} +*dv_demo_queue, dv_demo_queue_t; + +/** Structure for storing app state. +*/ + +typedef struct +{ + int disconnected; + valerie_parser parser; + valerie dv; + valerie dv_status; + int selected_unit; + char current_directory[ 512 ]; + char last_directory[ 512 ]; + int showing; + int terminated; + pthread_t thread; + dv_demo_queue_t queues[ MAX_UNITS ]; +} +*dv_demo, dv_demo_t; + +extern dv_demo dv_demo_init( valerie_parser ); +extern void dv_demo_run( dv_demo ); +extern void dv_demo_close( dv_demo ); + +#endif diff --git a/src/humperdink/io.c b/src/humperdink/io.c new file mode 100644 index 00000000..b9e92f28 --- /dev/null +++ b/src/humperdink/io.c @@ -0,0 +1,204 @@ +/* + * io.c -- dv1394d client demo input/output + * Copyright (C) 2002-2003 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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. + */ + +/* System header files */ +#include +#include +#include +#include +#include +#include + +/* Application header files */ +#include "io.h" + +char *chomp( char *input ) +{ + if ( input != NULL ) + { + int length = strlen( input ); + if ( length && input[ length - 1 ] == '\n' ) + input[ length - 1 ] = '\0'; + if ( length > 1 && input[ length - 2 ] == '\r' ) + input[ length - 2 ] = '\0'; + } + return input; +} + +char *trim( char *input ) +{ + if ( input != NULL ) + { + int length = strlen( input ); + int first = 0; + while( first < length && isspace( input[ first ] ) ) + first ++; + memmove( input, input + first, length - first + 1 ); + length = length - first; + while ( length > 0 && isspace( input[ length - 1 ] ) ) + input[ -- length ] = '\0'; + } + return input; +} + +char *strip_quotes( char *input ) +{ + if ( input != NULL ) + { + char *ptr = strrchr( input, '\"' ); + if ( ptr != NULL ) + *ptr = '\0'; + if ( input[ 0 ] == '\"' ) + strcpy( input, input + 1 ); + } + return input; +} + +char *get_string( char *output, int maxlength, char *use ) +{ + char *value = NULL; + strcpy( output, use ); + if ( trim( chomp( fgets( output, maxlength, stdin ) ) ) != NULL ) + { + if ( !strcmp( output, "" ) ) + strcpy( output, use ); + value = output; + } + return value; +} + +int *get_int( int *output, int use ) +{ + int *value = NULL; + char temp[ 132 ]; + *output = use; + if ( trim( chomp( fgets( temp, 132, stdin ) ) ) != NULL ) + { + if ( strcmp( temp, "" ) ) + *output = atoi( temp ); + value = output; + } + return value; +} + +/** This stores the previous settings +*/ + +static struct termios oldtty; +static int mode = 0; + +/** This is called automatically on application exit to restore the + previous tty settings. +*/ + +void term_exit(void) +{ + if ( mode == 1 ) + { + tcsetattr( 0, TCSANOW, &oldtty ); + mode = 0; + } +} + +/** Init terminal so that we can grab keys without blocking. +*/ + +void term_init( ) +{ + struct termios tty; + + tcgetattr( 0, &tty ); + oldtty = tty; + + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); + tty.c_oflag |= OPOST; + tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); + tty.c_cflag &= ~(CSIZE|PARENB); + tty.c_cflag |= CS8; + tty.c_cc[ VMIN ] = 1; + tty.c_cc[ VTIME ] = 0; + + tcsetattr( 0, TCSANOW, &tty ); + + mode = 1; + + atexit( term_exit ); +} + +/** Check for a keypress without blocking infinitely. + Returns: ASCII value of keypress or -1 if no keypress detected. +*/ + +int term_read( ) +{ + int n = 1; + unsigned char ch; + struct timeval tv; + fd_set rfds; + + FD_ZERO( &rfds ); + FD_SET( 0, &rfds ); + tv.tv_sec = 1; + tv.tv_usec = 0; + n = select( 1, &rfds, NULL, NULL, &tv ); + if (n > 0) + { + n = read( 0, &ch, 1 ); + tcflush( 0, TCIFLUSH ); + if (n == 1) + return ch; + return n; + } + return -1; +} + +char get_keypress( ) +{ + char value = '\0'; + int pressed = 0; + + fflush( stdout ); + + term_init( ); + while ( ( pressed = term_read( ) ) == -1 ) ; + term_exit( ); + + value = (char)pressed; + + return value; +} + +void wait_for_any_key( char *message ) +{ + if ( message == NULL ) + printf( "Press any key to continue: " ); + else + printf( "%s", message ); + + get_keypress( ); + + printf( "\n\n" ); +} + +void beep( ) +{ + printf( "%c", 7 ); + fflush( stdout ); +} diff --git a/src/humperdink/io.h b/src/humperdink/io.h new file mode 100644 index 00000000..6c4b609a --- /dev/null +++ b/src/humperdink/io.h @@ -0,0 +1,36 @@ +/* + * io.h -- dv1394d client demo input/output + * Copyright (C) 2002-2003 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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. + */ + +#ifndef _DEMO_IO_H_ +#define _DEMO_IO_H_ + +extern char *chomp( char * ); +extern char *trim( char * ); +extern char *strip_quotes( char * ); +extern char *get_string( char *, int, char * ); +extern int *get_int( int *, int ); +extern void term_init( ); +extern int term_read( ); +extern void term_exit( ); +extern char get_keypress( ); +extern void wait_for_any_key( char * ); +extern void beep( ); + +#endif diff --git a/src/humperdink/remote.c b/src/humperdink/remote.c new file mode 100644 index 00000000..18ac5a56 --- /dev/null +++ b/src/humperdink/remote.c @@ -0,0 +1,73 @@ +/* + * remote.c -- Remote dv1394d client demo + * Copyright (C) 2002-2003 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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. + */ + +/* System header files */ +#include + +/* dv1394d header files */ +#include + +/* Application header files */ +#include "client.h" +#include "io.h" + +/** Connect to a remote server. +*/ + +static valerie_parser create_parser( ) +{ + char server[ 132 ]; + int port; + valerie_parser parser = NULL; + + printf( "Connecting to a Server\n\n" ); + + printf( "Server [localhost]: " ); + + if ( get_string( server, sizeof( server ), "localhost" ) != NULL ) + { + printf( "Port [5250]: " ); + + if ( get_int( &port, 5250 ) != NULL ) + parser = valerie_parser_init_remote( server, port ); + } + + printf( "\n" ); + + return parser; +} + +/** Main function. +*/ + +int main( int argc, char **argv ) +{ + valerie_parser parser = create_parser( ); + + if ( parser != NULL ) + { + dv_demo demo = dv_demo_init( parser ); + dv_demo_run( demo ); + dv_demo_close( demo ); + valerie_parser_close( parser ); + } + + return 0; +} diff --git a/src/inigo/inigo.c b/src/inigo/inigo.c index bc087ba3..8b840438 100644 --- a/src/inigo/inigo.c +++ b/src/inigo/inigo.c @@ -178,13 +178,15 @@ void transport( mlt_producer producer ) int main( int argc, char **argv ) { int i; + int track = 0; mlt_consumer consumer = NULL; - mlt_multitrack multitrack = NULL; mlt_producer producer = NULL; mlt_playlist playlist = NULL; - mlt_field field = NULL; mlt_properties group = mlt_properties_new( ); mlt_properties properties = group; + mlt_field field = mlt_field_init( ); + mlt_properties field_properties = mlt_field_properties( field ); + mlt_multitrack multitrack = mlt_field_multitrack( field ); // Construct the factory mlt_factory_init( getenv( "MLT_REPOSITORY" ) ); @@ -192,16 +194,9 @@ int main( int argc, char **argv ) // Set up containers playlist = mlt_playlist_init( ); - // Construct the field - field = mlt_field_init( ); - // We need to track the number of registered filters - mlt_properties field_properties = mlt_field_properties( field ); mlt_properties_set_int( field_properties, "registered", 0 ); - // Get the multitrack from the field - multitrack = mlt_field_multitrack( field ); - // Parse the arguments for ( i = 1; i < argc; i ++ ) { @@ -233,6 +228,13 @@ int main( int argc, char **argv ) mlt_properties_inherit( properties, group ); } } + else if ( !strcmp( argv[ i ], "-blank" ) ) + { + if ( producer != NULL ) + mlt_playlist_append( playlist, producer ); + producer = NULL; + mlt_playlist_blank( playlist, atof( argv[ ++ i ] ) ); + } else if ( !strstr( argv[ i ], "=" ) ) { if ( producer != NULL ) @@ -250,8 +252,13 @@ int main( int argc, char **argv ) } } - // We must have a producer at this point + // Connect producer to playlist if ( producer != NULL ) + mlt_playlist_append( playlist, producer ); + + + // We must have a producer at this point + if ( mlt_playlist_count( playlist ) > 0 ) { // If we have no consumer, default to sdl if ( consumer == NULL ) @@ -264,11 +271,8 @@ int main( int argc, char **argv ) } } - // Connect producer to playlist - mlt_playlist_append( playlist, producer ); - // Connect multitrack to producer - mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist ), 0 ); + mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist ), track ); // Connect consumer to tractor mlt_consumer_connect( consumer, mlt_field_service( field ) ); diff --git a/src/miracle/Makefile b/src/miracle/Makefile new file mode 100644 index 00000000..6568199c --- /dev/null +++ b/src/miracle/Makefile @@ -0,0 +1,34 @@ +TARGET = miracle + +OBJS = miracle.o \ + miracle_log.o \ + miracle_server.o \ + miracle_connection.o \ + miracle_local.o \ + miracle_unit.o \ + miracle_commands.o \ + miracle_unit_commands.o + +CFLAGS = -I .. -Wall -g -D_FILE_OFFSET_BITS=64 -pthread -rdynamic + +LDFLAGS = -L ../valerie -lvalerie -L ../framework -lmlt + +SRCS := $(OBJS:.o=.c) + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CC) -o $@ $(OBJS) $(LDFLAGS) + +depend: $(SRCS) + $(CC) -MM $(CFLAGS) $^ 1>.depend + +dist-clean: clean + rm -f .depend + +clean: + rm -f $(OBJS) $(TARGET) + +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/src/miracle/miracle.c b/src/miracle/miracle.c index 47a645ab..8d1294d0 100644 --- a/src/miracle/miracle.c +++ b/src/miracle/miracle.c @@ -1,5 +1,5 @@ /* - * dv1394d.c -- A DV over IEEE 1394 TCP Server + * miracle.c -- A DV over IEEE 1394 TCP Server * * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Authors: @@ -21,10 +21,6 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifdef HAVE_CONFIG_H -#include -#endif - /* System header files */ #include #include @@ -33,21 +29,24 @@ #include #include +#include + /* Application header files */ -#include "dvserver.h" -#include "log.h" +#include "miracle_server.h" +#include "miracle_log.h" /** Our dv server. */ -static dv_server server = NULL; +static miracle_server server = NULL; /** atexit shutdown handler for the server. */ static void main_cleanup( ) { - dv_server_shutdown( server ); + miracle_server_shutdown( server ); + mlt_factory_close( ); } /** Report usage and exit. @@ -69,14 +68,17 @@ int main( int argc, char **argv ) int background = 1; struct timespec tm = { 5, 0 }; - server = dv_server_init( argv[ 0 ] ); + // Construct the factory + mlt_factory_init( getenv( "MLT_REPOSITORY" ) ); + + server = miracle_server_init( argv[ 0 ] ); for ( index = 1; index < argc; index ++ ) { if ( !strcmp( argv[ index ], "-port" ) ) - dv_server_set_port( server, atoi( argv[ ++ index ] ) ); + miracle_server_set_port( server, atoi( argv[ ++ index ] ) ); else if ( !strcmp( argv[ index ], "-proxy" ) ) - dv_server_set_proxy( server, argv[ ++ index ] ); + miracle_server_set_proxy( server, argv[ ++ index ] ); else if ( !strcmp( argv[ index ], "-test" ) ) background = 0; else @@ -90,17 +92,17 @@ int main( int argc, char **argv ) if ( fork() ) return 0; setsid(); - dv1394d_log_init( log_syslog, LOG_INFO ); + miracle_log_init( log_syslog, LOG_INFO ); } else { - dv1394d_log_init( log_stderr, LOG_INFO ); + miracle_log_init( log_stderr, LOG_DEBUG ); } atexit( main_cleanup ); /* Execute the server */ - error = dv_server_execute( server ); + error = miracle_server_execute( server ); /* We need to wait until we're exited.. */ while ( !server->shutdown ) diff --git a/src/miracle/miracle_commands.c b/src/miracle/miracle_commands.c index 8a492d1a..4a23e439 100644 --- a/src/miracle/miracle_commands.c +++ b/src/miracle/miracle_commands.c @@ -18,10 +18,6 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifdef HAVE_CONFIG_H -#include -#endif - #include #include #include @@ -33,19 +29,17 @@ #include #include -#include "dvunit.h" -#include "global_commands.h" -#include "raw1394util.h" -#include -#include "log.h" +#include "miracle_unit.h" +#include "miracle_commands.h" +#include "miracle_log.h" -static dv_unit g_units[MAX_UNITS]; +static miracle_unit g_units[MAX_UNITS]; -/** Return the dv_unit given a numeric index. +/** Return the miracle_unit given a numeric index. */ -dv_unit dv1394d_get_unit( int n ) +miracle_unit miracle_get_unit( int n ) { if (n < MAX_UNITS) return g_units[n]; @@ -53,19 +47,19 @@ dv_unit dv1394d_get_unit( int n ) return NULL; } -/** Destroy the dv_unit given its numeric index. +/** Destroy the miracle_unit given its numeric index. */ -void dv1394d_delete_unit( int n ) +void miracle_delete_unit( int n ) { if (n < MAX_UNITS) { - dv_unit unit = dv1394d_get_unit(n); + miracle_unit unit = miracle_get_unit(n); if (unit != NULL) { - dv_unit_close( unit ); + miracle_unit_close( unit ); g_units[ n ] = NULL; - dv1394d_log( LOG_NOTICE, "Deleted unit U%d.", n ); + miracle_log( LOG_NOTICE, "Deleted unit U%d.", n ); } } } @@ -73,67 +67,36 @@ void dv1394d_delete_unit( int n ) /** Destroy all allocated units on the server. */ -void dv1394d_delete_all_units( void ) +void miracle_delete_all_units( void ) { int i; for (i = 0; i < MAX_UNITS; i++) - if ( dv1394d_get_unit(i) != NULL ) + { + if ( miracle_get_unit(i) != NULL ) { - dv_unit_close( dv1394d_get_unit(i) ); - dv1394d_log( LOG_NOTICE, "Deleted unit U%d.", i ); + miracle_unit_close( miracle_get_unit(i) ); + miracle_log( LOG_NOTICE, "Deleted unit U%d.", i ); } + } } /** Add a DV virtual vtr to the server. */ -response_codes dv1394d_add_unit( command_argument cmd_arg ) +response_codes miracle_add_unit( command_argument cmd_arg ) { - int i; - int channel = -1; - char *guid_str = (char*) cmd_arg->argument; - octlet_t guid; - uint32_t guid_hi; - uint32_t guid_lo; - - sscanf( guid_str, "%08x%08x", &guid_hi, &guid_lo ); - guid = (octlet_t)guid_hi << 32 | (octlet_t) guid_lo; + int i = 0; + for ( i = 0; i < MAX_UNITS; i ++ ) + if ( g_units[ i ] == NULL ) + break; - if ( dv_tokeniser_count( cmd_arg->tokeniser ) == 3 ) - channel = atoi( dv_tokeniser_get_string( cmd_arg->tokeniser, 2 ) ); - - /* make sure unit does not already exit */ - for (i = 0; i < MAX_UNITS; i++) + if ( i < MAX_UNITS ) { - if (g_units[i] != NULL) - if ( dv_unit_get_guid( g_units[i] ) == guid ) - { - dv_response_printf( cmd_arg->response, 1024, "a unit already exists for that node\n\n" ); - return RESPONSE_ERROR; - } + char *arg = cmd_arg->argument; + g_units[ i ] = miracle_unit_init( i, arg ); + if ( g_units[ i ] != NULL ) + miracle_unit_set_notifier( g_units[ i ], valerie_parser_get_notifier( cmd_arg->parser ), cmd_arg->root_dir ); + return g_units[ i ] != NULL ? RESPONSE_SUCCESS : RESPONSE_ERROR; } - - for (i = 0; i < MAX_UNITS; i++) - { - if (g_units[i] == NULL) - { - - g_units[ i ] = dv_unit_init( guid, channel ); - if ( g_units[ i ] == NULL ) - { - dv_response_printf( cmd_arg->response, 1024, "failed to allocate unit\n" ); - return RESPONSE_ERROR; - } - g_units[ i ]->unit = i; - dv_unit_set_notifier( g_units[ i ], dv_parser_get_notifier( cmd_arg->parser ), cmd_arg->root_dir ); - - dv1394d_log( LOG_NOTICE, "added unit %d to send to node %d over channel %d", - i, dv_unit_get_nodeid( g_units[i] ), dv_unit_get_channel( g_units[i] ) ); - dv_response_printf( cmd_arg->response, 10, "U%1d\n\n", i ); - return RESPONSE_SUCCESS_N; - } - } - - dv_response_printf( cmd_arg->response, 1024, "no more units can be created\n\n" ); return RESPONSE_ERROR; } @@ -141,79 +104,44 @@ response_codes dv1394d_add_unit( command_argument cmd_arg ) /** List all AV/C nodes on the bus. */ -response_codes dv1394d_list_nodes( command_argument cmd_arg ) +response_codes miracle_list_nodes( command_argument cmd_arg ) { response_codes error = RESPONSE_SUCCESS_N; - raw1394handle_t handle; - int i, j; - char line[1024]; - octlet_t guid; - rom1394_directory dir; - - for ( j = 0; j < raw1394_get_num_ports(); j++ ) - { - handle = raw1394_open(j); - for ( i = 0; i < raw1394_get_nodecount(handle); ++i ) - { - rom1394_get_directory( handle, i, &dir); - if ( (rom1394_get_node_type(&dir) == ROM1394_NODE_TYPE_AVC) ) - { - guid = rom1394_get_guid(handle, i); - if (dir.label != NULL) - { - snprintf( line, 1023, "%02d %08x%08x \"%s\"\n", i, - (quadlet_t) (guid>>32), (quadlet_t) (guid & 0xffffffff), dir.label ); - } else { - snprintf( line, 1023, "%02d %08x%08x \"Unlabeled Node %d\"\n", i, - (quadlet_t) (guid>>32), (quadlet_t) (guid & 0xffffffff), i ); - } - dv_response_write( cmd_arg->response, line, strlen(line) ); - rom1394_free_directory( &dir); - } - } - raw1394_close( handle ); - } - dv_response_write( cmd_arg->response, "\n", 1 ); return error; } /** List units already added to server. */ -response_codes dv1394d_list_units( command_argument cmd_arg ) +response_codes miracle_list_units( command_argument cmd_arg ) { response_codes error = RESPONSE_SUCCESS_N; - char line[1024]; - int i; - - for (i = 0; i < MAX_UNITS; i++) + int i = 0; + + for ( i = 0; i < MAX_UNITS; i ++ ) { - if (dv1394d_get_unit(i) != NULL) + miracle_unit unit = miracle_get_unit( i ); + if ( unit != NULL ) { - snprintf( line, 1023, "U%d %02d %08x%08x %d\n", i, dv_unit_get_nodeid(g_units[i]), - (quadlet_t) (dv_unit_get_guid(g_units[i]) >> 32), - (quadlet_t) (dv_unit_get_guid(g_units[i]) & 0xffffffff), - !dv_unit_is_offline( g_units[i] ) ); - dv_response_write( cmd_arg->response, line, strlen(line) ); + mlt_properties properties = unit->properties; + char *constructor = mlt_properties_get( properties, "constructor" ); + int node = mlt_properties_get_int( properties, "node" ); + int online = !mlt_properties_get_int( properties, "offline" ); + valerie_response_printf( cmd_arg->response, 1024, "U%d %02d %s %d\n", i, node, constructor, online ); } } - dv_response_write( cmd_arg->response, "\n", 1 ); return error; } -static int -filter_files( const struct dirent *de ) +static int filter_files( const struct dirent *de ) { - if ( de->d_name[ 0 ] != '.' ) - return 1; - else - return 0; + return de->d_name[ 0 ] != '.'; } /** List clips in a directory. */ -response_codes dv1394d_list_clips( command_argument cmd_arg ) +response_codes miracle_list_clips( command_argument cmd_arg ) { response_codes error = RESPONSE_BAD_FILE; const char *dir_name = (const char*) cmd_arg->argument; @@ -233,19 +161,19 @@ response_codes dv1394d_list_clips( command_argument cmd_arg ) { snprintf( fullname, 1023, "%s%s/%s", cmd_arg->root_dir, dir_name, de[i]->d_name ); if ( stat( fullname, &info ) == 0 && S_ISDIR( info.st_mode ) ) - dv_response_printf( cmd_arg->response, 1024, "\"%s/\"\n", de[i]->d_name ); + valerie_response_printf( cmd_arg->response, 1024, "\"%s/\"\n", de[i]->d_name ); } for (i = 0; i < n; i++ ) { snprintf( fullname, 1023, "%s%s/%s", cmd_arg->root_dir, dir_name, de[i]->d_name ); if ( lstat( fullname, &info ) == 0 && ( S_ISREG( info.st_mode ) || ( strstr( fullname, ".clip" ) && info.st_mode | S_IXUSR ) ) ) - dv_response_printf( cmd_arg->response, 1024, "\"%s\" %llu\n", de[i]->d_name, (unsigned long long) info.st_size ); + valerie_response_printf( cmd_arg->response, 1024, "\"%s\" %llu\n", de[i]->d_name, (unsigned long long) info.st_size ); free( de[ i ] ); } free( de ); closedir( dir ); - dv_response_write( cmd_arg->response, "\n", 1 ); + valerie_response_write( cmd_arg->response, "\n", 1 ); } return error; @@ -254,7 +182,7 @@ response_codes dv1394d_list_clips( command_argument cmd_arg ) /** Set a server configuration property. */ -response_codes dv1394d_set_global_property( command_argument cmd_arg ) +response_codes miracle_set_global_property( command_argument cmd_arg ) { char *key = (char*) cmd_arg->argument; char *value = NULL; @@ -264,7 +192,7 @@ response_codes dv1394d_set_global_property( command_argument cmd_arg ) return RESPONSE_OUT_OF_RANGE; *value = 0; value++; - dv1394d_log( LOG_DEBUG, "SET %s = %s", key, value ); + miracle_log( LOG_DEBUG, "SET %s = %s", key, value ); if ( strncasecmp( key, "root", 1024) == 0 ) { @@ -275,7 +203,7 @@ response_codes dv1394d_set_global_property( command_argument cmd_arg ) for (i = 0; i < MAX_UNITS; i++) { if (g_units[i] != NULL) - dv_unit_terminate( g_units[i] ); + miracle_unit_terminate( g_units[i] ); } /* set the property */ @@ -297,13 +225,13 @@ response_codes dv1394d_set_global_property( command_argument cmd_arg ) /** Get a server configuration property. */ -response_codes dv1394d_get_global_property( command_argument cmd_arg ) +response_codes miracle_get_global_property( command_argument cmd_arg ) { char *key = (char*) cmd_arg->argument; if ( strncasecmp( key, "root", 1024) == 0 ) { - dv_response_write( cmd_arg->response, cmd_arg->root_dir, strlen(cmd_arg->root_dir) ); + valerie_response_write( cmd_arg->response, cmd_arg->root_dir, strlen(cmd_arg->root_dir) ); return RESPONSE_SUCCESS_1; } else @@ -312,142 +240,4 @@ response_codes dv1394d_get_global_property( command_argument cmd_arg ) return RESPONSE_SUCCESS; } -/** IEEE 1394 Bus Reset handler - - This is included here for now due to all the unit management involved. -*/ - -static int reset_handler( raw1394handle_t h, unsigned int generation ) -{ - int i, j, count, retry = 3; - int port = (int) raw1394_get_userdata( h ); - - raw1394_update_generation( h, generation ); - dv1394d_log( LOG_NOTICE, "bus reset on port %d", port ); - - while ( retry-- > 0 ) - { - raw1394handle_t handle = raw1394_open( port ); - count = raw1394_get_nodecount( handle ); - - if ( count > 0 ) - { - dv1394d_log( LOG_DEBUG, "bus reset, checking units" ); - - /* suspend all units on this port */ - for ( j = MAX_UNITS; j > 0; j-- ) - { - if ( g_units[ j-1 ] != NULL && dv_unit_get_port( g_units[ j-1 ] ) == port ) - dv_unit_suspend( g_units[ j-1 ] ); - } - dv1394d_log( LOG_DEBUG, "All units are now stopped" ); - - /* restore units with known guid, take others offline */ - for ( j = 0; j < MAX_UNITS; j++ ) - { - if ( g_units[j] != NULL && - ( dv_unit_get_port( g_units[ j ] ) == port || dv_unit_get_port( g_units[ j ] ) == -1 ) ) - { - int found = 0; - for ( i = 0; i < count; i++ ) - { - octlet_t guid; - dv1394d_log( LOG_DEBUG, "attempting to get guid for node %d", i ); - guid = rom1394_get_guid( handle, i ); - if ( guid == g_units[ j ]->guid ) - { - dv1394d_log( LOG_NOTICE, "unit with GUID %08x%08x found", - (quadlet_t) (g_units[j]->guid>>32), (quadlet_t) (g_units[j]->guid & 0xffffffff)); - if ( dv_unit_is_offline( g_units[ j ] ) ) - dv_unit_online( g_units[ j ] ); - else - dv_unit_restore( g_units[ j ] ); - found = 1; - break; - } - } - if ( found == 0 ) - dv_unit_offline( g_units[ j ] ); - } - } - dv1394d_log( LOG_DEBUG, "completed bus reset handler"); - raw1394_close( handle ); - return 0; - } - raw1394_close( handle ); - } - dv1394d_log( LOG_CRIT, "raw1394 reported zero nodes on the bus!" ); - return 0; -} - - -/** One pthread per IEEE 1394 port -*/ - -static pthread_t raw1394service_thread[4]; - -/** One raw1394 handle for each pthread/port -*/ - -static raw1394handle_t raw1394service_handle[4]; - -/** The service thread that polls raw1394 for new events. -*/ - -static void* raw1394_service( void *arg ) -{ - raw1394handle_t handle = (raw1394handle_t) arg; - struct pollfd raw1394_poll; - raw1394_poll.fd = raw1394_get_fd( handle ); - raw1394_poll.events = POLLIN; - raw1394_poll.revents = 0; - while ( 1 ) - { - if ( poll( &raw1394_poll, 1, 200) > 0 ) - { - if ( (raw1394_poll.revents & POLLIN) - || (raw1394_poll.revents & POLLPRI) ) - raw1394_loop_iterate( handle ); - } - pthread_testcancel(); - } - -} - - -/** Start the raw1394 service threads for handling bus reset. - - One thread is launched per port on the system. -*/ - -void raw1394_start_service_threads( void ) -{ - int port; - for ( port = 0; port < raw1394_get_num_ports(); port++ ) - { - raw1394service_handle[port] = raw1394_open( port ); - raw1394_set_bus_reset_handler( raw1394service_handle[port], reset_handler ); - pthread_create( &(raw1394service_thread[port]), NULL, raw1394_service, raw1394service_handle[port] ); - } - for ( ; port < 4; port++ ) - raw1394service_handle[port] = NULL; -} - -/** Shutdown all the raw1394 service threads. -*/ - -void raw1394_stop_service_threads( void ) -{ - int i; - for ( i = 0; i < 4; i++ ) - { - if ( raw1394service_handle[i] != NULL ) - { - pthread_cancel( raw1394service_thread[i] ); - pthread_join( raw1394service_thread[i], NULL ); - raw1394_close( raw1394service_handle[i] ); - } - } -} - diff --git a/src/miracle/miracle_commands.h b/src/miracle/miracle_commands.h index 6c60d7da..9d79683c 100644 --- a/src/miracle/miracle_commands.h +++ b/src/miracle/miracle_commands.h @@ -22,28 +22,28 @@ #ifndef _GLOBAL_COMMANDS_H_ #define _GLOBAL_COMMANDS_H_ -#include -#include "dvunit.h" -#include "dvconnection.h" +#include +#include "miracle_unit.h" +#include "miracle_connection.h" #ifdef __cplusplus extern "C" { #endif -dv_unit dv1394d_get_unit( int ); -void dv1394d_delete_unit( int ); -void dv1394d_delete_all_units( void ); -int dv1394d_unit_status( int n, dv1394_status status, int root_offset ); -void raw1394_start_service_threads( void ); -void raw1394_stop_service_threads( void ); - -extern response_codes dv1394d_add_unit( command_argument ); -extern response_codes dv1394d_list_nodes( command_argument ); -extern response_codes dv1394d_list_units( command_argument ); -extern response_codes dv1394d_list_clips( command_argument ); -extern response_codes dv1394d_set_global_property( command_argument ); -extern response_codes dv1394d_get_global_property( command_argument ); +extern miracle_unit miracle_get_unit( int ); +extern void miracle_delete_unit( int ); +extern void miracle_delete_all_units( void ); +extern int miracle_unit_status( int n, valerie_status status, int root_offset ); +//extern void raw1394_start_service_threads( void ); +//extern void raw1394_stop_service_threads( void ); + +extern response_codes miracle_add_unit( command_argument ); +extern response_codes miracle_list_nodes( command_argument ); +extern response_codes miracle_list_units( command_argument ); +extern response_codes miracle_list_clips( command_argument ); +extern response_codes miracle_set_global_property( command_argument ); +extern response_codes miracle_get_global_property( command_argument ); #ifdef __cplusplus } diff --git a/src/miracle/miracle_connection.c b/src/miracle/miracle_connection.c index 6c65e351..563a769a 100644 --- a/src/miracle/miracle_connection.c +++ b/src/miracle/miracle_connection.c @@ -1,5 +1,5 @@ /* - * dvconnection.c -- DV Connection Handler + * miracle_connection.c -- DV Connection Handler * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Charles Yates * @@ -34,12 +34,13 @@ #include #include +#include + /* Application header files */ -#include "global_commands.h" -#include "dvconnection.h" -#include "dvsocket.h" -#include "dvserver.h" -#include "log.h" +#include "miracle_commands.h" +#include "miracle_connection.h" +#include "miracle_server.h" +#include "miracle_log.h" /** This is a generic replacement for fgets which operates on a file descriptor. Unlike fgets, we can also specify a line terminator. Maximum @@ -80,46 +81,46 @@ int fdgetline( int fd, char *buf, int max, char line_terminator, int *eof_chk ) } static int connection_initiate( int ); -static int connection_send( int, dv_response ); +static int connection_send( int, valerie_response ); static int connection_read( int, char *, int ); static void connection_close( int ); static int connection_initiate( int fd ) { int error = 0; - dv_response response = dv_response_init( ); - dv_response_set_error( response, 100, "VTR Ready" ); + valerie_response response = valerie_response_init( ); + valerie_response_set_error( response, 100, "VTR Ready" ); error = connection_send( fd, response ); - dv_response_close( response ); + valerie_response_close( response ); return error; } -static int connection_send( int fd, dv_response response ) +static int connection_send( int fd, valerie_response response ) { int error = 0; int index = 0; - int code = dv_response_get_error_code( response ); + int code = valerie_response_get_error_code( response ); if ( code != -1 ) { - int items = dv_response_count( response ); + int items = valerie_response_count( response ); if ( items == 0 ) - dv_response_set_error( response, 500, "Unknown error" ); + valerie_response_set_error( response, 500, "Unknown error" ); if ( code == 200 && items > 2 ) - dv_response_set_error( response, 201, "OK" ); + valerie_response_set_error( response, 201, "OK" ); else if ( code == 200 && items > 1 ) - dv_response_set_error( response, 202, "OK" ); + valerie_response_set_error( response, 202, "OK" ); - code = dv_response_get_error_code( response ); - items = dv_response_count( response ); + code = valerie_response_get_error_code( response ); + items = valerie_response_count( response ); for ( index = 0; !error && index < items; index ++ ) { - char *line = dv_response_get_line( response, index ); + char *line = valerie_response_get_line( response, index ); int length = strlen( line ); - if ( length == 0 && index != dv_response_count( response ) - 1 && write( fd, " ", 1 ) != 1 ) + if ( length == 0 && index != valerie_response_count( response ) - 1 && write( fd, " ", 1 ) != 1 ) error = -1; else if ( length > 0 && write( fd, line, length ) != length ) error = -1; @@ -127,7 +128,7 @@ static int connection_send( int fd, dv_response response ) error = -1; } - if ( ( code == 201 || code == 500 ) && strcmp( dv_response_get_line( response, items - 1 ), "" ) ) + if ( ( code == 201 || code == 500 ) && strcmp( valerie_response_get_line( response, items - 1 ), "" ) ) write( fd, "\r\n", 2 ); } else @@ -151,27 +152,27 @@ static int connection_read( int fd, char *command, int length ) return nchars; } -int connection_status( int fd, dv1394_notifier notifier ) +int connection_status( int fd, valerie_notifier notifier ) { int error = 0; int index = 0; - dv1394_status_t status; + valerie_status_t status; char text[ 10240 ]; - dv_socket socket = dv_socket_init_fd( fd ); + valerie_socket socket = valerie_socket_init_fd( fd ); for ( index = 0; !error && index < MAX_UNITS; index ++ ) { - dv1394_notifier_get( notifier, &status, index ); - dv1394_status_serialise( &status, text, sizeof( text ) ); - error = dv_socket_write_data( socket, text, strlen( text ) ) != strlen( text ); + valerie_notifier_get( notifier, &status, index ); + valerie_status_serialise( &status, text, sizeof( text ) ); + error = valerie_socket_write_data( socket, text, strlen( text ) ) != strlen( text ); } while ( !error ) { - if ( dv1394_notifier_wait( notifier, &status ) == 0 ) + if ( valerie_notifier_wait( notifier, &status ) == 0 ) { - dv1394_status_serialise( &status, text, sizeof( text ) ); - error = dv_socket_write_data( socket, text, strlen( text ) ) != strlen( text ); + valerie_status_serialise( &status, text, sizeof( text ) ); + error = valerie_socket_write_data( socket, text, strlen( text ) ) != strlen( text ); } else { @@ -186,7 +187,7 @@ int connection_status( int fd, dv1394_notifier notifier ) } } - dv_socket_close( socket ); + valerie_socket_close( socket ); return error; } @@ -203,11 +204,8 @@ void *parser_thread( void *arg ) char address[ 512 ]; char command[ 1024 ]; int fd = connection->fd; - dv_parser parser = connection->parser; - dv_response response = NULL; - - /* We definitely want to ignore broken pipes. */ - signal( SIGPIPE, SIG_IGN ); + valerie_parser parser = connection->parser; + valerie_response response = NULL; /* Get the connecting clients ip information */ he = gethostbyaddr( (char *) &( connection->sin.sin_addr.s_addr ), sizeof(u_int32_t), AF_INET); @@ -216,7 +214,7 @@ void *parser_thread( void *arg ) else inet_ntop( AF_INET, &( connection->sin.sin_addr.s_addr), address, 32 ); - dv1394d_log( LOG_NOTICE, "Connection established with %s (%d)", address, fd ); + miracle_log( LOG_NOTICE, "Connection established with %s (%d)", address, fd ); /* Execute the commands received. */ if ( connection_initiate( fd ) == 0 ) @@ -227,14 +225,14 @@ void *parser_thread( void *arg ) { if ( strncmp( command, "STATUS", 6 ) ) { - response = dv_parser_execute( parser, command ); - dv1394d_log( LOG_INFO, "%s \"%s\" %d", address, command, dv_response_get_error_code( response ) ); + response = valerie_parser_execute( parser, command ); + miracle_log( LOG_INFO, "%s \"%s\" %d", address, command, valerie_response_get_error_code( response ) ); error = connection_send( fd, response ); - dv_response_close( response ); + valerie_response_close( response ); } else { - error = connection_status( fd, dv_parser_get_notifier( parser ) ); + error = connection_status( fd, valerie_parser_get_notifier( parser ) ); } } } @@ -242,7 +240,7 @@ void *parser_thread( void *arg ) /* Free the resources associated with this connection. */ connection_close( fd ); - dv1394d_log( LOG_NOTICE, "Connection with %s (%d) closed", address, fd ); + miracle_log( LOG_NOTICE, "Connection with %s (%d) closed", address, fd ); free( connection ); diff --git a/src/miracle/miracle_connection.h b/src/miracle/miracle_connection.h index 1c5d00b0..ce19115f 100644 --- a/src/miracle/miracle_connection.h +++ b/src/miracle/miracle_connection.h @@ -1,5 +1,5 @@ /* - * dvconnection.h -- DV Connection Handler + * miracle_connection.h -- DV Connection Handler * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Charles Yates * @@ -25,8 +25,8 @@ #include #include -#include -#include +#include +#include #ifdef __cplusplus extern "C" @@ -40,7 +40,7 @@ typedef struct { int fd; struct sockaddr_in sin; - dv_parser parser; + valerie_parser parser; } connection_t; @@ -68,9 +68,9 @@ response_codes; typedef struct { - dv_parser parser; - dv_response response; - dv_tokeniser tokeniser; + valerie_parser parser; + valerie_response response; + valerie_tokeniser tokeniser; char *command; int unit; void *argument; diff --git a/src/miracle/miracle_local.c b/src/miracle/miracle_local.c index fce4ab22..ac6c7578 100644 --- a/src/miracle/miracle_local.c +++ b/src/miracle/miracle_local.c @@ -1,5 +1,5 @@ /* - * dvlocal.c -- Local dv1394d Parser + * miracle_local.c -- Local Miracle Parser * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Charles Yates * @@ -27,59 +27,59 @@ #include #include -/* Library header files */ -#include +/* Valerie header files */ +#include + +/* MLT header files. */ +#include /* Application header files */ -#include -#include -#include "dvlocal.h" -#include "dvconnection.h" -#include "global_commands.h" -#include "unit_commands.h" -#include "log.h" -#include "raw1394util.h" - -/** Private dv_local structure. +#include "miracle_local.h" +#include "miracle_connection.h" +#include "miracle_commands.h" +#include "miracle_unit_commands.h" +#include "miracle_log.h" + +/** Private miracle_local structure. */ typedef struct { - dv_parser parser; + valerie_parser parser; char root_dir[1024]; } -*dv_local, dv_local_t; +*miracle_local, miracle_local_t; /** Forward declarations. */ -static dv_response dv_local_connect( dv_local ); -static dv_response dv_local_execute( dv_local, char * ); -static void dv_local_close( dv_local ); -response_codes print_help( command_argument arg ); -response_codes dv1394d_run( command_argument arg ); -response_codes dv1394d_shutdown( command_argument arg ); +static valerie_response miracle_local_connect( miracle_local ); +static valerie_response miracle_local_execute( miracle_local, char * ); +static void miracle_local_close( miracle_local ); +response_codes miracle_help( command_argument arg ); +response_codes miracle_run( command_argument arg ); +response_codes miracle_shutdown( command_argument arg ); /** DV Parser constructor. */ -dv_parser dv_parser_init_local( ) +valerie_parser miracle_parser_init_local( ) { - dv_parser parser = malloc( sizeof( dv_parser_t ) ); - dv_local local = malloc( sizeof( dv_local_t ) ); + valerie_parser parser = malloc( sizeof( valerie_parser_t ) ); + miracle_local local = malloc( sizeof( miracle_local_t ) ); if ( parser != NULL ) { - memset( parser, 0, sizeof( dv_parser_t ) ); + memset( parser, 0, sizeof( valerie_parser_t ) ); - parser->connect = (parser_connect)dv_local_connect; - parser->execute = (parser_execute)dv_local_execute; - parser->close = (parser_close)dv_local_close; + parser->connect = (parser_connect)miracle_local_connect; + parser->execute = (parser_execute)miracle_local_execute; + parser->close = (parser_close)miracle_local_close; parser->real = local; if ( local != NULL ) { - memset( local, 0, sizeof( dv_local_t ) ); + memset( local, 0, sizeof( miracle_local_t ) ); local->parser = parser; local->root_dir[0] = '/'; } @@ -156,35 +156,35 @@ command_t; static command_t vocabulary[] = { {"BYE", NULL, 0, ATYPE_NONE, "Terminates the session. Units are not removed and task queue is not flushed."}, - {"HELP", print_help, 0, ATYPE_NONE, "Display this information!"}, - {"NLS", dv1394d_list_nodes, 0, ATYPE_NONE, "List the AV/C nodes on the 1394 bus."}, - {"UADD", dv1394d_add_unit, 0, ATYPE_STRING, "Create a new DV unit (virtual VTR) to transmit to receiver specified in GUID argument."}, - {"ULS", dv1394d_list_units, 0, ATYPE_NONE, "Lists the units that have already been added to the server."}, - {"CLS", dv1394d_list_clips, 0, ATYPE_STRING, "Lists the clips at directory name argument."}, - {"SET", dv1394d_set_global_property, 0, ATYPE_STRING, "Set a server configuration property."}, - {"GET", dv1394d_get_global_property, 0, ATYPE_STRING, "Get a server configuration property."}, - {"RUN", dv1394d_run, 0, ATYPE_STRING, "Run a batch file." }, - {"LIST", dv1394d_list, 1, ATYPE_NONE, "List the playlist associated to a unit."}, - {"LOAD", dv1394d_load, 1, ATYPE_STRING, "Load clip specified in absolute filename argument."}, - {"INSERT", dv1394d_insert, 1, ATYPE_STRING, "Insert a clip at the given clip index."}, - {"REMOVE", dv1394d_remove, 1, ATYPE_NONE, "Remove a clip at the given clip index."}, - {"CLEAN", dv1394d_clean, 1, ATYPE_NONE, "Clean a unit by removing all but the currently playing clip."}, - {"MOVE", dv1394d_move, 1, ATYPE_INT, "Move a clip to another clip index."}, - {"APND", dv1394d_append, 1, ATYPE_STRING, "Append a clip specified in absolute filename argument."}, - {"PLAY", dv1394d_play, 1, ATYPE_NONE, "Play a loaded clip at speed -2000 to 2000 where 1000 = normal forward speed."}, - {"STOP", dv1394d_stop, 1, ATYPE_NONE, "Stop a loaded and playing clip."}, - {"PAUSE", dv1394d_pause, 1, ATYPE_NONE, "Pause a playing clip."}, - {"REW", dv1394d_rewind, 1, ATYPE_NONE, "Rewind a unit. If stopped, seek to beginning of clip. If playing, play fast backwards."}, - {"FF", dv1394d_ff, 1, ATYPE_NONE, "Fast forward a unit. If stopped, seek to beginning of clip. If playing, play fast forwards."}, - {"STEP", dv1394d_step, 1, ATYPE_INT, "Step argument number of frames forward or backward."}, - {"GOTO", dv1394d_goto, 1, ATYPE_INT, "Jump to frame number supplied as argument."}, - {"SIN", dv1394d_set_in_point, 1, ATYPE_INT, "Set the IN point of the loaded clip to frame number argument. -1 = reset in point to 0"}, - {"SOUT", dv1394d_set_out_point, 1, ATYPE_INT, "Set the OUT point of the loaded clip to frame number argument. -1 = reset out point to maximum."}, - {"USTA", dv1394d_get_unit_status, 1, ATYPE_NONE, "Report information about the unit."}, - {"USET", dv1394d_set_unit_property, 1, ATYPE_STRING, "Set a unit configuration property."}, - {"UGET", dv1394d_get_unit_property, 1, ATYPE_STRING, "Get a unit configuration property."}, - {"XFER", dv1394d_transfer, 1, ATYPE_STRING, "Transfer the unit's clip to another unit specified as argument."}, - {"SHUTDOWN", dv1394d_shutdown, 0, ATYPE_NONE, "Shutdown the server."}, + {"HELP", miracle_help, 0, ATYPE_NONE, "Display this information!"}, + {"NLS", miracle_list_nodes, 0, ATYPE_NONE, "List the AV/C nodes on the 1394 bus."}, + {"UADD", miracle_add_unit, 0, ATYPE_STRING, "Create a new DV unit (virtual VTR) to transmit to receiver specified in GUID argument."}, + {"ULS", miracle_list_units, 0, ATYPE_NONE, "Lists the units that have already been added to the server."}, + {"CLS", miracle_list_clips, 0, ATYPE_STRING, "Lists the clips at directory name argument."}, + {"SET", miracle_set_global_property, 0, ATYPE_STRING, "Set a server configuration property."}, + {"GET", miracle_get_global_property, 0, ATYPE_STRING, "Get a server configuration property."}, + {"RUN", miracle_run, 0, ATYPE_STRING, "Run a batch file." }, + {"LIST", miracle_list, 1, ATYPE_NONE, "List the playlist associated to a unit."}, + {"LOAD", miracle_load, 1, ATYPE_STRING, "Load clip specified in absolute filename argument."}, + {"INSERT", miracle_insert, 1, ATYPE_STRING, "Insert a clip at the given clip index."}, + {"REMOVE", miracle_remove, 1, ATYPE_NONE, "Remove a clip at the given clip index."}, + {"CLEAN", miracle_clean, 1, ATYPE_NONE, "Clean a unit by removing all but the currently playing clip."}, + {"MOVE", miracle_move, 1, ATYPE_INT, "Move a clip to another clip index."}, + {"APND", miracle_append, 1, ATYPE_STRING, "Append a clip specified in absolute filename argument."}, + {"PLAY", miracle_play, 1, ATYPE_NONE, "Play a loaded clip at speed -2000 to 2000 where 1000 = normal forward speed."}, + {"STOP", miracle_stop, 1, ATYPE_NONE, "Stop a loaded and playing clip."}, + {"PAUSE", miracle_pause, 1, ATYPE_NONE, "Pause a playing clip."}, + {"REW", miracle_rewind, 1, ATYPE_NONE, "Rewind a unit. If stopped, seek to beginning of clip. If playing, play fast backwards."}, + {"FF", miracle_ff, 1, ATYPE_NONE, "Fast forward a unit. If stopped, seek to beginning of clip. If playing, play fast forwards."}, + {"STEP", miracle_step, 1, ATYPE_INT, "Step argument number of frames forward or backward."}, + {"GOTO", miracle_goto, 1, ATYPE_INT, "Jump to frame number supplied as argument."}, + {"SIN", miracle_set_in_point, 1, ATYPE_INT, "Set the IN point of the loaded clip to frame number argument. -1 = reset in point to 0"}, + {"SOUT", miracle_set_out_point, 1, ATYPE_INT, "Set the OUT point of the loaded clip to frame number argument. -1 = reset out point to maximum."}, + {"USTA", miracle_get_unit_status, 1, ATYPE_NONE, "Report information about the unit."}, + {"USET", miracle_set_unit_property, 1, ATYPE_STRING, "Set a unit configuration property."}, + {"UGET", miracle_get_unit_property, 1, ATYPE_STRING, "Get a unit configuration property."}, + {"XFER", miracle_transfer, 1, ATYPE_STRING, "Transfer the unit's clip to another unit specified as argument."}, + {"SHUTDOWN", miracle_shutdown, 0, ATYPE_NONE, "Shutdown the server."}, {NULL, NULL, 0, ATYPE_NONE, NULL} }; @@ -192,7 +192,7 @@ static command_t vocabulary[] = */ static char helpstr [] = - "dv1394d -- A DV over IEEE 1394 TCP Server\n" + "Miracle -- A Multimedia Playout Server\n" " Copyright (C) 2002-2003 Ushodaya Enterprises Limited\n" " Authors:\n" " Dan Dennedy \n" @@ -209,22 +209,22 @@ inline char *get_response_msg( int code ) return responses[ i ].message; } -/** Tell the user the dv1394d command set +/** Tell the user the miracle command set */ -response_codes print_help( command_argument cmd_arg ) +response_codes miracle_help( command_argument cmd_arg ) { int i = 0; - dv_response_printf( cmd_arg->response, 10240, "%s", helpstr ); + valerie_response_printf( cmd_arg->response, 10240, "%s", helpstr ); for ( i = 0; vocabulary[ i ].command != NULL; i ++ ) - dv_response_printf( cmd_arg->response, 1024, + valerie_response_printf( cmd_arg->response, 1024, "%-10.10s%s\n", vocabulary[ i ].command, vocabulary[ i ].help ); - dv_response_printf( cmd_arg->response, 2, "\n" ); + valerie_response_printf( cmd_arg->response, 2, "\n" ); return RESPONSE_SUCCESS_N; } @@ -232,28 +232,28 @@ response_codes print_help( command_argument cmd_arg ) /** Execute a batch file. */ -response_codes dv1394d_run( command_argument cmd_arg ) +response_codes miracle_run( command_argument cmd_arg ) { - dv_response temp = dv_parser_run( cmd_arg->parser, (char *)cmd_arg->argument ); + valerie_response temp = valerie_parser_run( cmd_arg->parser, (char *)cmd_arg->argument ); if ( temp != NULL ) { int index = 0; - dv_response_set_error( cmd_arg->response, - dv_response_get_error_code( temp ), - dv_response_get_error_string( temp ) ); + valerie_response_set_error( cmd_arg->response, + valerie_response_get_error_code( temp ), + valerie_response_get_error_string( temp ) ); - for ( index = 1; index < dv_response_count( temp ); index ++ ) - dv_response_printf( cmd_arg->response, 10240, "%s\n", dv_response_get_line( temp, index ) ); + for ( index = 1; index < valerie_response_count( temp ); index ++ ) + valerie_response_printf( cmd_arg->response, 10240, "%s\n", valerie_response_get_line( temp, index ) ); - dv_response_close( temp ); + valerie_response_close( temp ); } - return dv_response_get_error_code( cmd_arg->response ); + return valerie_response_get_error_code( cmd_arg->response ); } -response_codes dv1394d_shutdown( command_argument cmd_arg ) +response_codes miracle_shutdown( command_argument cmd_arg ) { exit( 0 ); return RESPONSE_SUCCESS; @@ -274,9 +274,9 @@ void signal_handler( int sig ) { #ifdef _GNU_SOURCE - dv1394d_log( LOG_DEBUG, "Received %s - shutting down.", strsignal(sig) ); + miracle_log( LOG_DEBUG, "Received %s - shutting down.", strsignal(sig) ); #else - dv1394d_log( LOG_DEBUG, "Received signal %i - shutting down.", sig ); + miracle_log( LOG_DEBUG, "Received signal %i - shutting down.", sig ); #endif exit(EXIT_SUCCESS); @@ -286,23 +286,21 @@ void signal_handler( int sig ) /** Local 'connect' function. */ -static dv_response dv_local_connect( dv_local local ) +static valerie_response miracle_local_connect( miracle_local local ) { - dv_response response = dv_response_init( ); + valerie_response response = valerie_response_init( ); self = pthread_self( ); - dv_response_set_error( response, 100, "VTR Ready" ); + valerie_response_set_error( response, 100, "VTR Ready" ); signal( SIGHUP, signal_handler ); signal( SIGINT, signal_handler ); - signal( SIGTERM, signal_handler ); + signal( SIGTERM, SIG_DFL ); signal( SIGSTOP, signal_handler ); + signal( SIGPIPE, signal_handler ); + signal( SIGALRM, signal_handler ); signal( SIGCHLD, SIG_IGN ); - - raw1394_reconcile_bus(); - /* Start the raw1394 service threads for handling bus resets */ - raw1394_start_service_threads(); return response; } @@ -310,18 +308,18 @@ static dv_response dv_local_connect( dv_local local ) /** Set the error and determine the message associated to this command. */ -void dv_command_set_error( command_argument cmd, response_codes code ) +void miracle_command_set_error( command_argument cmd, response_codes code ) { - dv_response_set_error( cmd->response, code, get_response_msg( code ) ); + valerie_response_set_error( cmd->response, code, get_response_msg( code ) ); } /** Parse the unit argument. */ -int dv_command_parse_unit( command_argument cmd, int argument ) +int miracle_command_parse_unit( command_argument cmd, int argument ) { int unit = -1; - char *string = dv_tokeniser_get_string( cmd->tokeniser, argument ); + char *string = valerie_tokeniser_get_string( cmd->tokeniser, argument ); if ( string != NULL && ( string[ 0 ] == 'U' || string[ 0 ] == 'u' ) && strlen( string ) > 1 ) unit = atoi( string + 1 ); return unit; @@ -330,10 +328,10 @@ int dv_command_parse_unit( command_argument cmd, int argument ) /** Parse a normal argument. */ -void *dv_command_parse_argument( command_argument cmd, int argument, arguments_types type ) +void *miracle_command_parse_argument( command_argument cmd, int argument, arguments_types type ) { void *ret = NULL; - char *value = dv_tokeniser_get_string( cmd->tokeniser, argument ); + char *value = valerie_tokeniser_get_string( cmd->tokeniser, argument ); if ( value != NULL ) { @@ -366,9 +364,9 @@ void *dv_command_parse_argument( command_argument cmd, int argument, arguments_t /** Get the error code - note that we simply the success return. */ -response_codes dv_command_get_error( command_argument cmd ) +response_codes miracle_command_get_error( command_argument cmd ) { - response_codes ret = dv_response_get_error_code( cmd->response ); + response_codes ret = valerie_response_get_error_code( cmd->response ); if ( ret == RESPONSE_SUCCESS_N || ret == RESPONSE_SUCCESS_1 ) ret = RESPONSE_SUCCESS; return ret; @@ -377,30 +375,30 @@ response_codes dv_command_get_error( command_argument cmd ) /** Execute the command. */ -static dv_response dv_local_execute( dv_local local, char *command ) +static valerie_response miracle_local_execute( miracle_local local, char *command ) { command_argument_t cmd; cmd.parser = local->parser; - cmd.response = dv_response_init( ); - cmd.tokeniser = dv_tokeniser_init( ); + cmd.response = valerie_response_init( ); + cmd.tokeniser = valerie_tokeniser_init( ); cmd.command = command; cmd.unit = -1; cmd.argument = NULL; cmd.root_dir = local->root_dir; /* Set the default error */ - dv_command_set_error( &cmd, RESPONSE_UNKNOWN_COMMAND ); + miracle_command_set_error( &cmd, RESPONSE_UNKNOWN_COMMAND ); /* Parse the command */ - if ( dv_tokeniser_parse_new( cmd.tokeniser, command, " " ) > 0 ) + if ( valerie_tokeniser_parse_new( cmd.tokeniser, command, " " ) > 0 ) { int index = 0; - char *value = dv_tokeniser_get_string( cmd.tokeniser, 0 ); + char *value = valerie_tokeniser_get_string( cmd.tokeniser, 0 ); int found = 0; /* Strip quotes from all tokens */ - for ( index = 0; index < dv_tokeniser_count( cmd.tokeniser ); index ++ ) - dv_util_strip( dv_tokeniser_get_string( cmd.tokeniser, index ), '\"' ); + for ( index = 0; index < valerie_tokeniser_count( cmd.tokeniser ); index ++ ) + valerie_util_strip( valerie_tokeniser_get_string( cmd.tokeniser, index ), '\"' ); /* Search the vocabulary array for value */ for ( index = 1; !found && vocabulary[ index ].command != NULL; index ++ ) @@ -412,35 +410,35 @@ static dv_response dv_local_execute( dv_local local, char *command ) { int position = 1; - dv_command_set_error( &cmd, RESPONSE_SUCCESS ); + miracle_command_set_error( &cmd, RESPONSE_SUCCESS ); if ( vocabulary[ index ].is_unit ) { - cmd.unit = dv_command_parse_unit( &cmd, position ); + cmd.unit = miracle_command_parse_unit( &cmd, position ); if ( cmd.unit == -1 ) - dv_command_set_error( &cmd, RESPONSE_MISSING_ARG ); + miracle_command_set_error( &cmd, RESPONSE_MISSING_ARG ); position ++; } - if ( dv_command_get_error( &cmd ) == RESPONSE_SUCCESS ) + if ( miracle_command_get_error( &cmd ) == RESPONSE_SUCCESS ) { - cmd.argument = dv_command_parse_argument( &cmd, position, vocabulary[ index ].type ); + cmd.argument = miracle_command_parse_argument( &cmd, position, vocabulary[ index ].type ); if ( cmd.argument == NULL && vocabulary[ index ].type != ATYPE_NONE ) - dv_command_set_error( &cmd, RESPONSE_MISSING_ARG ); + miracle_command_set_error( &cmd, RESPONSE_MISSING_ARG ); position ++; } - if ( dv_command_get_error( &cmd ) == RESPONSE_SUCCESS ) + if ( miracle_command_get_error( &cmd ) == RESPONSE_SUCCESS ) { response_codes error = vocabulary[ index ].operation( &cmd ); - dv_command_set_error( &cmd, error ); + miracle_command_set_error( &cmd, error ); } free( cmd.argument ); } } - dv_tokeniser_close( cmd.tokeniser ); + valerie_tokeniser_close( cmd.tokeniser ); return cmd.response; } @@ -448,13 +446,10 @@ static dv_response dv_local_execute( dv_local local, char *command ) /** Close the parser. */ -static void dv_local_close( dv_local local ) +static void miracle_local_close( miracle_local local ) { - raw1394_stop_service_threads(); - dv1394d_delete_all_units(); + miracle_delete_all_units(); pthread_kill_other_threads_np(); - dv1394d_log( LOG_DEBUG, "Clean shutdown." ); + miracle_log( LOG_DEBUG, "Clean shutdown." ); free( local ); - dv_clip_factory_close( ); - dv_frame_pool_close( ); } diff --git a/src/miracle/miracle_local.h b/src/miracle/miracle_local.h index fbbe4447..6baf0350 100644 --- a/src/miracle/miracle_local.h +++ b/src/miracle/miracle_local.h @@ -1,5 +1,5 @@ /* - * dvlocal.h -- Local dv1394d Parser + * miracle_local.h -- Local dv1394d Parser * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Charles Yates * @@ -18,11 +18,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef _DV_LOCAL_H_ -#define _DV_LOCAL_H_ +#ifndef _MIRACLE_LOCAL_H_ +#define _MIRACLE_LOCAL_H_ /* Application header files */ -#include +#include #ifdef __cplusplus extern "C" @@ -32,7 +32,7 @@ extern "C" /** Local parser API. */ -extern dv_parser dv_parser_init_local( ); +extern valerie_parser miracle_parser_init_local( ); #ifdef __cplusplus } diff --git a/src/miracle/miracle_log.c b/src/miracle/miracle_log.c index cdb5d82f..adfc5467 100644 --- a/src/miracle/miracle_log.c +++ b/src/miracle/miracle_log.c @@ -1,5 +1,5 @@ /* - * log.h -- logging facility implementation + * miracle_log.c -- logging facility implementation * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Dan Dennedy * @@ -18,21 +18,16 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifdef HAVE_CONFIG_H -#include -#endif - #include #include #include -#include "log.h" +#include "miracle_log.h" static int log_output = log_stderr; static int threshold = LOG_DEBUG; -void -dv1394d_log_init( enum log_output method, int new_threshold ) +void miracle_log_init( enum log_output method, int new_threshold ) { log_output = method; threshold = new_threshold; @@ -41,8 +36,7 @@ dv1394d_log_init( enum log_output method, int new_threshold ) } -void -dv1394d_log( int priority, char *format, ... ) +void miracle_log( int priority, char *format, ... ) { va_list list; va_start( list, format ); diff --git a/src/miracle/miracle_log.h b/src/miracle/miracle_log.h index 04505e97..3788ee52 100644 --- a/src/miracle/miracle_log.h +++ b/src/miracle/miracle_log.h @@ -1,5 +1,5 @@ /* - * log.h -- logging facility header + * miracle_log.h -- logging facility header * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Dan Dennedy * @@ -33,8 +33,8 @@ enum log_output { log_syslog }; -void dv1394d_log_init( enum log_output method, int threshold ); -void dv1394d_log( int priority, char *format, ... ); +void miracle_log_init( enum log_output method, int threshold ); +void miracle_log( int priority, char *format, ... ); #ifdef __cplusplus } diff --git a/src/miracle/miracle_server.c b/src/miracle/miracle_server.c index d4f886b9..3c82c338 100644 --- a/src/miracle/miracle_server.c +++ b/src/miracle/miracle_server.c @@ -1,5 +1,5 @@ /* - * dvserver.c -- DV Server + * miracle_server.c -- DV Server * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Charles Yates * @@ -18,10 +18,6 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifdef HAVE_CONFIG_H -#include -#endif - /* System header files */ #include #include @@ -36,28 +32,29 @@ #include #include -#include "log.h" #include #include #include /* Application header files */ -#include "dvserver.h" -#include "dvconnection.h" -#include "dvlocal.h" -#include "log.h" -#include -#include +#include "miracle_server.h" +#include "miracle_connection.h" +#include "miracle_local.h" +#include "miracle_log.h" +#include +#include + +#define VERSION "0.0.1" /** Initialise a server structure. */ -dv_server dv_server_init( char *id ) +miracle_server miracle_server_init( char *id ) { - dv_server server = malloc( sizeof( dv_server_t ) ); + miracle_server server = malloc( sizeof( miracle_server_t ) ); if ( server != NULL ) { - memset( server, 0, sizeof( dv_server_t ) ); + memset( server, 0, sizeof( miracle_server_t ) ); server->id = id; server->port = DEFAULT_TCP_PORT; server->socket = -1; @@ -68,27 +65,27 @@ dv_server dv_server_init( char *id ) /** Set the port of the server. */ -void dv_server_set_port( dv_server server, int port ) +void miracle_server_set_port( miracle_server server, int port ) { server->port = port; } -void dv_server_set_proxy( dv_server server, char *proxy ) +void miracle_server_set_proxy( miracle_server server, char *proxy ) { - dv_tokeniser tokeniser = dv_tokeniser_init( ); + valerie_tokeniser tokeniser = valerie_tokeniser_init( ); server->proxy = 1; server->remote_port = DEFAULT_TCP_PORT; - dv_tokeniser_parse_new( tokeniser, proxy, ":" ); - strcpy( server->remote_server, dv_tokeniser_get_string( tokeniser, 0 ) ); - if ( dv_tokeniser_count( tokeniser ) == 2 ) - server->remote_port = atoi( dv_tokeniser_get_string( tokeniser, 1 ) ); - dv_tokeniser_close( tokeniser ); + valerie_tokeniser_parse_new( tokeniser, proxy, ":" ); + strcpy( server->remote_server, valerie_tokeniser_get_string( tokeniser, 0 ) ); + if ( valerie_tokeniser_count( tokeniser ) == 2 ) + server->remote_port = atoi( valerie_tokeniser_get_string( tokeniser, 1 ) ); + valerie_tokeniser_close( tokeniser ); } /** Wait for a connection. */ -static int dv_server_wait_for_connect( dv_server server ) +static int miracle_server_wait_for_connect( miracle_server server ) { struct timeval tv; fd_set rfds; @@ -106,9 +103,9 @@ static int dv_server_wait_for_connect( dv_server server ) /** Run the server thread. */ -static void *dv_server_run( void *arg ) +static void *miracle_server_run( void *arg ) { - dv_server server = arg; + miracle_server server = arg; pthread_t cmd_parse_info; connection_t *tmp = NULL; pthread_attr_t thread_attributes; @@ -116,7 +113,7 @@ static void *dv_server_run( void *arg ) socksize = sizeof( struct sockaddr ); - dv1394d_log( LOG_NOTICE, "%s version %s listening on port %i", server->id, VERSION, server->port ); + miracle_log( LOG_NOTICE, "%s version %s listening on port %i", server->id, VERSION, server->port ); /* Create the initial thread. We want all threads to be created detached so their resources get freed automatically. (CY: ... hmmph...) */ @@ -129,7 +126,7 @@ static void *dv_server_run( void *arg ) while ( !server->shutdown ) { /* Wait for a new connection. */ - if ( dv_server_wait_for_connect( server ) ) + if ( miracle_server_wait_for_connect( server ) ) { /* Create a new block of data to hold a copy of the incoming connection for our server thread. The thread should free this when it terminates. */ @@ -144,7 +141,7 @@ static void *dv_server_run( void *arg ) } } - dv1394d_log( LOG_NOTICE, "%s version %s server terminated.", server->id, VERSION ); + miracle_log( LOG_NOTICE, "%s version %s server terminated.", server->id, VERSION ); return NULL; } @@ -152,10 +149,10 @@ static void *dv_server_run( void *arg ) /** Execute the server thread. */ -int dv_server_execute( dv_server server ) +int miracle_server_execute( miracle_server server ) { int error = 0; - dv_response response = NULL; + valerie_response response = NULL; int index = 0; struct sockaddr_in ServerAddr; int flag = 1; @@ -172,7 +169,7 @@ int dv_server_execute( dv_server server ) { server->shutdown = 1; perror( "socket" ); - dv1394d_log( LOG_ERR, "%s unable to create socket.", server->id ); + miracle_log( LOG_ERR, "%s unable to create socket.", server->id ); return -1; } @@ -182,7 +179,7 @@ int dv_server_execute( dv_server server ) { server->shutdown = 1; perror( "bind" ); - dv1394d_log( LOG_ERR, "%s unable to bind to port %d.", server->id, server->port ); + miracle_log( LOG_ERR, "%s unable to bind to port %d.", server->id, server->port ); return -1; } @@ -190,7 +187,7 @@ int dv_server_execute( dv_server server ) { server->shutdown = 1; perror( "listen" ); - dv1394d_log( LOG_ERR, "%s unable to listen on port %d.", server->id, server->port ); + miracle_log( LOG_ERR, "%s unable to listen on port %d.", server->id, server->port ); return -1; } @@ -198,31 +195,31 @@ int dv_server_execute( dv_server server ) if ( !server->proxy ) { - dv1394d_log( LOG_NOTICE, "Starting server on %d.", server->port ); - server->parser = dv_parser_init_local( ); + miracle_log( LOG_NOTICE, "Starting server on %d.", server->port ); + server->parser = miracle_parser_init_local( ); } else { - dv1394d_log( LOG_NOTICE, "Starting proxy for %s:%d on %d.", server->remote_server, server->remote_port, server->port ); - server->parser = dv_parser_init_remote( server->remote_server, server->remote_port ); + miracle_log( LOG_NOTICE, "Starting proxy for %s:%d on %d.", server->remote_server, server->remote_port, server->port ); + server->parser = valerie_parser_init_remote( server->remote_server, server->remote_port ); } - response = dv_parser_connect( server->parser ); + response = valerie_parser_connect( server->parser ); - if ( response != NULL && dv_response_get_error_code( response ) == 100 ) + if ( response != NULL && valerie_response_get_error_code( response ) == 100 ) { /* read configuration file */ if ( response != NULL && !server->proxy ) { - dv_response_close( response ); - response = dv_parser_run( server->parser, "/etc/dv1394d.conf" ); + valerie_response_close( response ); + response = valerie_parser_run( server->parser, "/etc/miracle.conf" ); - if ( dv_response_count( response ) > 1 ) + if ( valerie_response_count( response ) > 1 ) { - if ( dv_response_get_error_code( response ) > 299 ) - dv1394d_log( LOG_ERR, "Error evaluating server configuration. Processing stopped." ); - for ( index = 0; index < dv_response_count( response ); index ++ ) - dv1394d_log( LOG_DEBUG, "%4d: %s", index, dv_response_get_line( response, index ) ); + if ( valerie_response_get_error_code( response ) > 299 ) + miracle_log( LOG_ERR, "Error evaluating server configuration. Processing stopped." ); + for ( index = 0; index < valerie_response_count( response ); index ++ ) + miracle_log( LOG_DEBUG, "%4d: %s", index, valerie_response_get_line( response, index ) ); } } @@ -235,16 +232,16 @@ int dv_server_execute( dv_server server ) pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ); pthread_attr_setschedpolicy( &attr, SCHED_FIFO ); pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ); - dv_response_close( response ); - result = pthread_create( &server->thread, &attr, dv_server_run, server ); + valerie_response_close( response ); + result = pthread_create( &server->thread, &attr, miracle_server_run, server ); if ( result ) { - dv1394d_log( LOG_WARNING, "Failed to schedule realtime (%s)", strerror(errno) ); + miracle_log( LOG_WARNING, "Failed to schedule realtime (%s)", strerror(errno) ); pthread_attr_setschedpolicy( &attr, SCHED_OTHER ); - result = pthread_create( &server->thread, &attr, dv_server_run, server ); + result = pthread_create( &server->thread, &attr, miracle_server_run, server ); if ( result ) { - dv1394d_log( LOG_CRIT, "Failed to launch TCP listener thread" ); + miracle_log( LOG_CRIT, "Failed to launch TCP listener thread" ); error = -1; } } @@ -252,7 +249,7 @@ int dv_server_execute( dv_server server ) } else { - dv1394d_log( LOG_ERR, "Error connecting to parser. Processing stopped." ); + miracle_log( LOG_ERR, "Error connecting to parser. Processing stopped." ); server->shutdown = 1; error = -1; } @@ -263,13 +260,13 @@ int dv_server_execute( dv_server server ) /** Shutdown the server. */ -void dv_server_shutdown( dv_server server ) +void miracle_server_shutdown( miracle_server server ) { if ( server != NULL && !server->shutdown ) { server->shutdown = 1; pthread_join( server->thread, NULL ); - dv_parser_close( server->parser ); + valerie_parser_close( server->parser ); close( server->socket ); } } diff --git a/src/miracle/miracle_server.h b/src/miracle/miracle_server.h index 96b22cee..95dfb524 100644 --- a/src/miracle/miracle_server.h +++ b/src/miracle/miracle_server.h @@ -1,5 +1,5 @@ /* - * dvserver.h -- DV Server + * miracle_server.h -- DV Server * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Charles Yates * @@ -18,14 +18,14 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef _DV_SERVER_H_ -#define _DV_SERVER_H_ +#ifndef _MIRACLE_SERVER_H_ +#define _MIRACLE_SERVER_H_ /* System header files */ #include /* Application header files */ -#include +#include #ifdef __cplusplus extern "C" @@ -45,23 +45,23 @@ typedef struct char *id; int port; int socket; - dv_parser parser; + valerie_parser parser; pthread_t thread; int shutdown; int proxy; char remote_server[ 50 ]; int remote_port; } -*dv_server, dv_server_t; +*miracle_server, miracle_server_t; /** API for the server */ -extern dv_server dv_server_init( char * ); -extern void dv_server_set_port( dv_server, int ); -extern void dv_server_set_proxy( dv_server, char * ); -extern int dv_server_execute( dv_server ); -extern void dv_server_shutdown( dv_server ); +extern miracle_server miracle_server_init( char * ); +extern void miracle_server_set_port( miracle_server, int ); +extern void miracle_server_set_proxy( miracle_server, char * ); +extern int miracle_server_execute( miracle_server ); +extern void miracle_server_shutdown( miracle_server ); #ifdef __cplusplus } diff --git a/src/miracle/miracle_unit.c b/src/miracle/miracle_unit.c index bc8adcfb..31c01cf7 100644 --- a/src/miracle/miracle_unit.c +++ b/src/miracle/miracle_unit.c @@ -1,5 +1,5 @@ /* - * dvunit.c -- DV Transmission Unit Implementation + * miracle_unit.c -- DV Transmission Unit Implementation * Copyright (C) 2002-2003 Ushodaya Enterprises Limited * Author: Dan Dennedy * @@ -34,393 +34,306 @@ #include #include -#include -#include -#include #include -#include "dvunit.h" -#include "dvframe.h" -#include "dvframepool.h" -#include "dvqueue.h" -#include "dvpump.h" -#include "dverror.h" -#include "dvplayer.h" -#include "raw1394util.h" -#include "log.h" -#include "dvlocal.h" +#include "miracle_unit.h" +#include "miracle_log.h" +#include "miracle_local.h" + +#include /* Forward references */ -static void dv_unit_status_communicate( dv_unit ); +static void miracle_unit_status_communicate( miracle_unit ); + +/** Allocate a new DV transmission unit. + + \return A new miracle_unit handle. +*/ + +miracle_unit miracle_unit_init( int index, char *constructor ) +{ + miracle_unit this = NULL; + mlt_consumer consumer = NULL; + + char *id = strdup( constructor ); + char *arg = strchr( id, ':' ); + + if ( arg != NULL ) + *arg ++ = '\0'; -/** dv1394 device file names based upon devfs default names. */ + consumer = mlt_factory_consumer( id, arg ); -static char *devices[4][4] = { + if ( consumer != NULL ) { - "/dev/ieee1394/dv/host0/NTSC/in", - "/dev/ieee1394/dv/host0/NTSC/out", - "/dev/ieee1394/dv/host0/PAL/in", - "/dev/ieee1394/dv/host0/PAL/out", - },{ - "/dev/ieee1394/dv/host1/NTSC/in", - "/dev/ieee1394/dv/host1/NTSC/out", - "/dev/ieee1394/dv/host1/PAL/in", - "/dev/ieee1394/dv/host1/PAL/out" - },{ - "/dev/ieee1394/dv/host2/NTSC/in", - "/dev/ieee1394/dv/host2/NTSC/out", - "/dev/ieee1394/dv/host2/PAL/in", - "/dev/ieee1394/dv/host2/PAL/out" - },{ - "/dev/ieee1394/dv/host3/NTSC/in", - "/dev/ieee1394/dv/host3/NTSC/out", - "/dev/ieee1394/dv/host3/PAL/in", - "/dev/ieee1394/dv/host3/PAL/out" + mlt_playlist playlist = mlt_playlist_init( ); + this = calloc( sizeof( miracle_unit_t ), 1 ); + this->properties = mlt_properties_new( ); + this->producers = mlt_properties_new( ); + mlt_properties_init( this->properties, this ); + mlt_properties_set_int( this->properties, "unit", index ); + mlt_properties_set_int( this->properties, "generation", 0 ); + mlt_properties_set( this->properties, "constructor", constructor ); + mlt_properties_set( this->properties, "id", id ); + mlt_properties_set( this->properties, "arg", arg ); + mlt_properties_set_data( this->properties, "consumer", consumer, 0, ( mlt_destructor )mlt_consumer_close, NULL ); + mlt_properties_set_data( this->properties, "playlist", playlist, 0, ( mlt_destructor )mlt_playlist_close, NULL ); + mlt_consumer_connect( consumer, mlt_playlist_service( playlist ) ); } -}; -static int device_count[4] = {0,0,0,0}; - -/** Allocate a new DV transmission unit. + return this; +} - \param dv1394d_fd The file descriptor of a dv1394 device file to - use for transmission. - \param guid The node GUID of the receiving device. - \param channel The channel to use for transmission. - \return A new dv_unit handle. +/** Communicate the current status to all threads waiting on the notifier. */ -dv_unit dv_unit_init( octlet_t guid, int channel ) +static void miracle_unit_status_communicate( miracle_unit unit ) { - dv_unit unit = malloc( sizeof( dv_unit_t ) ); if ( unit != NULL ) { - int node_id; - - memset( unit, 0, sizeof( dv_unit_t ) ); - unit->guid = guid; - unit->buffer_size = 25; - unit->is_terminated = 1; - unit->channel = channel; - unit->dv1394_fd = -1; - unit->n_frames = DV1394_MAX_FRAMES / 2; - unit->n_fill = 1; - - /* get a raw1394 handle for plug control */ - if ( ( node_id = raw1394_find_node( &(unit->raw1394), guid ) ) != -1 ) - { - if ( dv_unit_online( unit ) == 1 ) - dv1394d_log( LOG_DEBUG, "Added online unit with GUID %08x%08x", - (quadlet_t) (unit->guid>>32), (quadlet_t) (unit->guid & 0xffffffff) ); - else - { - dv_unit_close( unit ); - unit = NULL; - } - } - else + mlt_properties properties = unit->properties; + char *root_dir = mlt_properties_get( properties, "root" ); + valerie_notifier notifier = mlt_properties_get_data( properties, "notifier", NULL ); + valerie_status_t status; + + if ( root_dir != NULL && notifier != NULL ) { - dv1394d_log( LOG_DEBUG, "Added offline unit with GUID %08x%08x", - (quadlet_t) (unit->guid>>32), (quadlet_t) (unit->guid & 0xffffffff) ); + if ( miracle_unit_get_status( unit, &status ) == 0 ) + /* if ( !( ( status.status == unit_playing || status.status == unit_paused ) && + strcmp( status.clip, "" ) && + !strcmp( status.tail_clip, "" ) && + status.position == 0 && + status.in == 0 && + status.out == 0 ) ) */ + valerie_notifier_put( notifier, &status ); } } - return unit; } -/** Allow stdin to feed the unit (redundant now that senddv has been dropped). +/** Set the notifier info */ -void dv_unit_allow_stdin( dv_unit unit, int flag ) +void miracle_unit_set_notifier( miracle_unit this, valerie_notifier notifier, char *root_dir ) { - unit->allow_stdin = flag; + mlt_properties properties = this->properties; + mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); + mlt_properties playlist_properties = mlt_playlist_properties( playlist ); + + mlt_properties_set( properties, "root", root_dir ); + mlt_properties_set_data( properties, "notifier", notifier, 0, NULL, NULL ); + mlt_properties_set_data( playlist_properties, "notifier_arg", this, 0, NULL, NULL ); + mlt_properties_set_data( playlist_properties, "notifier", miracle_unit_status_communicate, 0, NULL, NULL ); + + miracle_unit_status_communicate( this ); } -/** Override the default buffer/pump size - this must be done prior to the pumps - creation. +/** Create or locate a producer for the file specified. */ -void dv_unit_set_buffer_size( dv_unit unit, int size ) +static mlt_producer create_producer( miracle_unit unit, char *file ) { - if ( size > 0 ) + // Get the unit properties + mlt_properties properties = unit->producers; + + // Check if we already have loaded this file + mlt_producer result = mlt_properties_get_data( properties, file, NULL ); + + if ( result == NULL ) { - if ( unit->pump == NULL ) - unit->buffer_size = size; - else - unit->buffer_size = dv_pump_resize( unit->pump, size ); + // 1st Line preferences + if ( strstr( file, ".mpg" ) ) + result = mlt_factory_producer( "mcmpeg", file ); + else if ( strstr( file, ".mpeg" ) ) + result = mlt_factory_producer( "mcmpeg", file ); + else if ( strstr( file, ".dv" ) ) + result = mlt_factory_producer( "mcdv", file ); + else if ( strstr( file, ".dif" ) ) + result = mlt_factory_producer( "mcdv", file ); + else if ( strstr( file, ".jpg" ) ) + result = mlt_factory_producer( "pixbuf", file ); + else if ( strstr( file, ".JPG" ) ) + result = mlt_factory_producer( "pixbuf", file ); + else if ( strstr( file, ".jpeg" ) ) + result = mlt_factory_producer( "pixbuf", file ); + else if ( strstr( file, ".png" ) ) + result = mlt_factory_producer( "pixbuf", file ); + + // 2nd Line fallbacks + if ( result == NULL && strstr( file, ".dv" ) ) + result = mlt_factory_producer( "libdv", file ); + else if ( result == NULL && strstr( file, ".dif" ) ) + result = mlt_factory_producer( "libdv", file ); + + // 3rd line fallbacks + if ( result == NULL ) + result = mlt_factory_producer( "ffmpeg", file ); + + // Now store the result + mlt_properties_set_data( properties, file, result, 0, ( mlt_destructor )mlt_producer_close, NULL ); } -} -int dv_unit_get_buffer_size( dv_unit unit ) -{ - return unit->buffer_size; + return result; } -void dv_unit_set_n_frames( dv_unit unit, int size ) -{ - if ( size > 0 && size <= DV1394_MAX_FRAMES / 2 ) - unit->n_frames = size; -} +/** Update the generation count. +*/ -int dv_unit_get_n_frames( dv_unit unit ) +static void update_generation( miracle_unit unit ) { - return unit->n_frames; + mlt_properties properties = unit->properties; + int generation = mlt_properties_get_int( properties, "generation" ); + mlt_properties_set_int( properties, "generation", ++ generation ); } -void dv_unit_set_n_fill( dv_unit unit, int size ) +static void clear_unit( miracle_unit unit ) { - unit->n_fill = size; -} + mlt_properties properties = unit->properties; + mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); + mlt_producer producer = mlt_playlist_producer( playlist ); -int dv_unit_get_n_fill( dv_unit unit ) -{ - return unit->n_fill; -} + mlt_playlist_clear( playlist ); + mlt_producer_seek( producer, 0 ); -/** Set the notifier info -*/ + if ( unit->old_producers != NULL ) + mlt_properties_close( unit->old_producers ); + unit->old_producers = unit->producers; + unit->producers = mlt_properties_new( ); -void dv_unit_set_notifier( dv_unit this, dv1394_notifier notifier, char *root_dir ) -{ - this->notifier = notifier; - this->root_dir = root_dir; - dv_unit_status_communicate( this ); + update_generation( unit ); } -/** Communicate the current status to all threads waiting on the notifier. +/** Generate a report on all loaded clips. */ -static void dv_unit_status_communicate( dv_unit unit ) +void miracle_unit_report_list( miracle_unit unit, valerie_response response ) { - if ( unit != NULL && unit->notifier != NULL && unit->root_dir != NULL ) + int i; + mlt_properties properties = unit->properties; + int generation = mlt_properties_get_int( properties, "generation" ); + mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); + + valerie_response_printf( response, 1024, "%d\n", generation ); + + for ( i = 0; i < mlt_playlist_count( playlist ); i ++ ) { - dv1394_status_t status; - if ( dv_unit_get_status( unit, &status ) == 0 ) - if ( !( ( status.status == unit_playing || status.status == unit_paused ) && - strcmp( status.clip, "" ) && - !strcmp( status.tail_clip, "" ) && - status.position == 0 && - status.in == 0 && - status.out == 0 ) ) - dv1394_notifier_put( unit->notifier, &status ); + mlt_playlist_clip_info info; + mlt_playlist_get_clip_info( playlist , &info, i ); + valerie_response_printf( response, 10240, "%d \"%s\" %e %e %e %e %.2f\n", + i, info.resource, info.in, info.out, info.playtime, info.length, info.fps ); } } /** Load a clip into the unit clearing existing play list. \todo error handling - \param unit A dv_unit handle. + \param unit A miracle_unit handle. \param clip The absolute file name of the clip to load. \param in The starting frame (-1 for 0) \param out The ending frame (-1 for maximum) */ -dv_error_code dv_unit_load( dv_unit unit, const char *clip, long in, long out, int flush ) +valerie_error_code miracle_unit_load( miracle_unit unit, char *clip, double in, double out, int flush ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_error_code error = dv_player_get_error( player ); - if ( error == dv_pump_ok ) + // Have to clear the unit first + clear_unit( unit ); + + // Now try to create an producer + mlt_producer instance = create_producer( unit, clip ); + + if ( instance != NULL ) { - error = dv_player_replace_file( player, (char*) clip, in, out, flush ); - dv1394d_log( LOG_DEBUG, "loaded clip %s", clip ); - if ( unit->is_terminated ) - dv_unit_status_communicate( unit ); + mlt_properties properties = unit->properties; + mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); + mlt_playlist_append_io( playlist, instance, in, out ); + miracle_log( LOG_DEBUG, "loaded clip %s", clip ); + miracle_unit_status_communicate( unit ); + return valerie_ok; } - return error; + + return valerie_invalid_file; } -dv_error_code dv_unit_insert( dv_unit unit, const char *clip, int index, long in, long out ) +valerie_error_code miracle_unit_insert( miracle_unit unit, const char *clip, int index, double in, double out ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_error_code error = dv_player_get_error( player ); + /* + dv_player player = miracle_unit_get_dv_player( unit ); + valerie_error_code error = dv_player_get_error( player ); if ( error == dv_pump_ok ) { error = dv_player_insert_file( player, (char*) clip, index, in, out ); dv1394d_log( LOG_DEBUG, "inserted clip %s", clip ); if ( unit->is_terminated ) - dv_unit_status_communicate( unit ); + miracle_unit_status_communicate( unit ); } return error; + */ + return valerie_ok; } -dv_error_code dv_unit_remove( dv_unit unit, int index ) +valerie_error_code miracle_unit_remove( miracle_unit unit, int index ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_error_code error = dv_player_get_error( player ); + /* + dv_player player = miracle_unit_get_dv_player( unit ); + valerie_error_code error = dv_player_get_error( player ); if ( error == dv_pump_ok ) { error = dv_player_remove_clip( player, index ); dv1394d_log( LOG_DEBUG, "removed clip %d", index ); if ( unit->is_terminated ) - dv_unit_status_communicate( unit ); + miracle_unit_status_communicate( unit ); } return error; + */ + return valerie_ok; } -dv_error_code dv_unit_clean( dv_unit unit ) +valerie_error_code miracle_unit_clean( miracle_unit unit ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_error_code error = dv_player_get_error( player ); - if ( error == dv_pump_ok ) - { - error = dv_player_clean( player ); - dv1394d_log( LOG_DEBUG, "Cleaned playlist" ); - if ( unit->is_terminated ) - dv_unit_status_communicate( unit ); - } - return error; + clear_unit( unit ); + miracle_log( LOG_DEBUG, "Cleaned playlist" ); + return valerie_ok; } -dv_error_code dv_unit_move( dv_unit unit, int src, int dest ) +valerie_error_code miracle_unit_move( miracle_unit unit, int src, int dest ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_error_code error = dv_player_get_error( player ); + /* + dv_player player = miracle_unit_get_dv_player( unit ); + valerie_error_code error = dv_player_get_error( player ); if ( error == dv_pump_ok ) { error = dv_player_move_clip( player, src, dest ); dv1394d_log( LOG_DEBUG, "moved clip %d to %d", src, dest ); if ( unit->is_terminated ) - dv_unit_status_communicate( unit ); + miracle_unit_status_communicate( unit ); } return error; + */ + return valerie_ok; } /** Add a clip to the unit play list. \todo error handling - \param unit A dv_unit handle. + \param unit A miracle_unit handle. \param clip The absolute file name of the clip to load. \param in The starting frame (-1 for 0) \param out The ending frame (-1 for maximum) */ -dv_error_code dv_unit_append( dv_unit unit, const char *clip, long in, long out ) +valerie_error_code miracle_unit_append( miracle_unit unit, char *clip, double in, double out ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_error_code error = dv_player_add_file( player, (char*) clip, in, out ); - dv_unit_status_communicate( unit ); - return error; -} + mlt_producer instance = create_producer( unit, clip ); -void *output_cleanup( void *arg ) -{ - dv_unit unit = arg; - if ( unit != NULL && unit->mmap != NULL ) + if ( instance != NULL ) { - unit->is_terminated = 1; - dv_unit_status_communicate( unit ); - munmap( unit->mmap, unit->mmap_length ); - /* this actually stops transmission as opposed to allowing the - last frame to loop in the OHCI DMA context. */ - ioctl( unit->dv1394_fd, DV1394_SHUTDOWN, NULL ); + mlt_properties properties = unit->properties; + mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); + mlt_playlist_append_io( playlist, instance, in, out ); + miracle_log( LOG_DEBUG, "appended clip %s", clip ); + miracle_unit_status_communicate( unit ); + return valerie_ok; } - return NULL; -} - -/** The dv1394 transmission thread. - - \param arg A dv_unit handle. -*/ - -static void *output( void *arg ) -{ - dv_unit unit = arg; - dv_frame frames[ DV1394_MAX_FRAMES ]; - int frames_dropped = 0; /* count of total frames dropped (repeated) */ - struct dv1394_status status; - char errstr[64]; - int n_fill = unit->n_fill; - int n_frames = unit->n_frames; - - /* Determine the number of frames to wait for/fill on each iteration */ - if ( n_fill < 1 ) - n_fill = 1; - else if ( n_fill > unit->n_frames ) - n_fill = n_frames / 2; - - unit->mmap = mmap( NULL,unit->mmap_length,PROT_WRITE,MAP_SHARED,unit->dv1394_fd,0 ); - if ( unit->mmap == MAP_FAILED || unit->mmap == NULL ) - { - perror( "mmap" ); - return NULL; - } - - pthread_cleanup_push( output_cleanup, (void *)arg ); - - while ( dv_pump_get_available_output_count( unit->pump ) || - !( dv_unit_has_terminated( unit ) || dv_pump_has_terminated( unit->pump) ) ) - { - int available = 0; - - if ( ioctl( unit->dv1394_fd, DV1394_WAIT_FRAMES, n_fill ) < 0) - perror( "DV1394_WAIT_FRAMES" ); - - pthread_testcancel(); - - /* update the status for the next iteration and detect dropped frames */ - if ( ioctl( unit->dv1394_fd, DV1394_GET_STATUS, &status ) >= 0) - { - pthread_testcancel(); - - /* - printf( "dv1394 status: active=%02d, #clear=%02d, first clear=%02d\n", - status.active_frame, status.n_clear_frames, status.first_clear_frame); - */ - - /* report dropped frames */ - if( status.dropped_frames > 0 ) - { - frames_dropped += status.dropped_frames; - dv1394d_log( LOG_WARNING, "dv1394 repeated %d frames with %d available.", - status.dropped_frames, dv_pump_get_available_output_count( unit->pump ) ); - } - - available = dv_pump_get_output_block( unit->pump, (void **)frames, n_fill ); - - dv_unit_status_communicate( unit ); - - /* The only time we get 0 frames is when the unit is being stopped. */ - if ( available != 0 ) - { - int size = dv_frame_size( frames[ 0 ] ); - int pos = status.first_clear_frame; - int index = 0; - - for ( index = 0; index < available; index ++ ) - memcpy( unit->mmap + ( ( pos + index ) % n_frames ) * size, dv_frame_data( frames[ index ] ), size ); - - if ( ioctl( unit->dv1394_fd, DV1394_SUBMIT_FRAMES, available ) >= 0) - { - for ( index = 0; index < available - 1; index ++ ) - { - dv_frame_clear_error( frames[ index ] ); - dv_frame_id_clear( dv_frame_get_id( frames[ index ] ) ); - } - dv_pump_return_output_block( unit->pump ); - pthread_testcancel(); - } - else - { - dv1394d_log( LOG_ERR, "failed to write frames to dv1394: %s.", strerror_r( errno, errstr, 63 ) ); - dv_pump_terminate( unit->pump ); - dv_pump_flush( unit->pump ); - pthread_testcancel(); - } - } - } - else - { - dv1394d_log( LOG_ERR, "failed to get dv1394 status: %s.", strerror_r( errno, errstr, 63 ) ); - dv_pump_return_used_output( unit->pump ); - } - } - - if ( frames_dropped > 0 ) - dv1394d_log( LOG_WARNING, "dv1394 repeated %d frames total during this transmission.", frames_dropped ); - - pthread_cleanup_pop( 1 ); - - return NULL; + return valerie_invalid_file; } /** Start playing the clip. @@ -428,317 +341,92 @@ static void *output( void *arg ) Start a dv-pump and commence dv1394 transmission. \todo error handling - \param unit A dv_unit handle. + \param unit A miracle_unit handle. \param speed An integer that specifies the playback rate as a percentage multiplied by 100. */ -void dv_unit_play( dv_unit_t *unit, int speed ) +void miracle_unit_play( miracle_unit_t *unit, int speed ) { - dv_player player = dv_unit_get_dv_player( unit ); - - if ( unit->is_terminated == 1 && ( dv_player_get_total_frames( player ) > 0 || unit->allow_stdin ) ) - { - int retval; - dv_frame frame = NULL; - struct dv1394_init setup = - { - api_version: DV1394_API_VERSION, - channel: unit->channel, - /* this only sets the *requested* size of the ringbuffer, - in frames */ - n_frames: unit->n_frames, - /* we set the format later */ - cip_n: unit->dv1394_cip_n, - cip_d: unit->dv1394_cip_d, - syt_offset: unit->dv1394_syt_offset - }; - pthread_attr_t attr; - - if ( unit->in == NULL ) - { - if ( !unit->allow_stdin || dv_player_get_total_frames( player ) != 0 ) - unit->in = dv_player_get_dv_input( player ); - else - unit->in = dv_input_init( unit->pump ); - } - else - { - dv_input_join_thread( unit->in ); - pthread_join( unit->out, NULL ); - } - - unit->is_terminated = 0; - dv_pump_restart( unit->pump ); - dv_input_start_thread( unit->in ); - dv_player_set_speed( player, (double) speed/1000.0 ); - - /* first we read a little data to see if this is PAL or NTSC - so we can initialize dv1394 properly */ - frame = dv_pump_get_available_output( unit->pump ); - - /* initialize dv1394 */ - setup.format = dv_frame_is_pal(frame) ? DV1394_PAL : DV1394_NTSC; - - retval = ioctl( unit->dv1394_fd, DV1394_INIT, &setup ); - if (retval < 0) - { - perror( "DV1394_INIT" ); - return; - } - - unit->mmap_length = unit->n_frames * dv_frame_size( frame ); - - pthread_attr_init( &attr ); - pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); - pthread_attr_setinheritsched( &attr, PTHREAD_INHERIT_SCHED ); - pthread_create( &unit->out, &attr, output, unit ); - } - else - { - dv_player_set_speed( player, (double) speed/1000.0 ); - } - dv_unit_status_communicate( unit ); + mlt_properties properties = unit->properties; + mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); + mlt_producer producer = mlt_playlist_producer( playlist ); + mlt_producer_set_speed( producer, ( double )speed / 1000 ); + miracle_unit_status_communicate( unit ); } /** Stop playback. Terminates the dv_pump and halts dv1394 transmission. - \param unit A dv_unit handle. + \param unit A miracle_unit handle. */ -void dv_unit_terminate( dv_unit unit ) +void miracle_unit_terminate( miracle_unit unit ) { - unit->is_terminated = 1; - if ( unit->pump != NULL ) - { - dv_pump_terminate( unit->pump ); - dv_pump_flush( unit->pump ); - } } /** Query the status of unit playback. - \param unit A dv_unit handle. + \param unit A miracle_unit handle. \return 1 if the unit is not playing, 0 if playing. */ -int dv_unit_has_terminated( dv_unit unit ) +int miracle_unit_has_terminated( miracle_unit unit ) { - return unit->is_terminated; -} - -/** Get the dv_player from the dv_unit. - - \param unit A dv_unit handle. - \return A dv_player handle. -*/ - -dv_player dv_unit_get_dv_player( dv_unit unit ) -{ - if ( unit != NULL ) - { - if ( unit->pump == NULL ) - { - unit->pump = dv_pump_init( unit->buffer_size ); - if ( unit->pump != NULL ) - unit->player = dv_player_init( unit->pump ); - } - return unit->player; - } - return NULL; + return 0; } - /** Transfer the currently loaded clip to another unit */ -int dv_unit_transfer( dv_unit dest_unit, dv_unit src_unit ) +int miracle_unit_transfer( miracle_unit dest_unit, miracle_unit src_unit ) { - dv_player src_player = dv_unit_get_dv_player( src_unit ); - dv_player dest_player = dv_unit_get_dv_player( dest_unit ); - - if( dest_player != NULL && src_player != NULL ) - dv_player_replace_player( dest_player, src_player ); - return 0; } -/** Get the guid associated to this unit. -*/ - -octlet_t dv_unit_get_guid( dv_unit unit ) -{ - return unit->guid; -} - -/** Get the node id associated to this unit. -*/ - -int dv_unit_get_nodeid( dv_unit unit ) -{ - return (unit->node_id & 0x3f); -} - -/** Get the channel associated to this unit. -*/ - -int dv_unit_get_channel( dv_unit unit ) -{ - return (unit->channel); -} - -/** Turn unit online. -*/ - -int dv_unit_online( dv_unit unit ) -{ - int result = 0; - int port, node_id; - - if ( unit->raw1394 != NULL ) - raw1394_close( unit->raw1394 ); - - node_id = raw1394_find_node( &(unit->raw1394), unit->guid ); - if ( node_id != -1 ) - { - unit->node_id = 0xffc0 | node_id; - port = dv_unit_get_port( unit ); - - unit->dv1394_fd = open( devices[ port ][ device_count[port] ], O_RDWR ); - if ( unit->dv1394_fd < 0 ) - { - dv1394d_log( LOG_ERR, "failed to open dv1394 device - %s\n", devices[ port ][ device_count[port] ] ); - dv_unit_close( unit ); - } - else - { - device_count[ port ] ++; - if ( establish_p2p_connection( unit->raw1394, unit->node_id, (unsigned int *) &(unit->channel) ) ) - { - avc1394_vcr_record( unit->raw1394, unit->node_id ); - unit->online = 1; - dv_unit_status_communicate( unit ); - result = 1; - } - } - } - - return result; -} - -/** Turn unit offline. -*/ - -void dv_unit_offline( dv_unit unit ) -{ - if ( unit->online == 1 ) - { - if ( unit->is_terminated == 0 ) - dv_unit_terminate( unit ); - unit->online = 0; - if ( unit->raw1394 != NULL ) - { - avc1394_vcr_stop( unit->raw1394, unit->node_id ); - break_p2p_connection( unit->raw1394, unit->node_id, unit->channel ); - } - if ( unit->dv1394_fd > -1 ) - { - close( unit->dv1394_fd ); - device_count[ dv_unit_get_port( unit ) ] --; - } - dv_unit_status_communicate( unit ); - dv1394d_log( LOG_DEBUG, "Unit with GUID %08x%08x is now offline.", - (quadlet_t) (unit->guid>>32), (quadlet_t) (unit->guid & 0xffffffff) ); - } -} - /** Determine if unit is offline. */ -int dv_unit_is_offline( dv_unit unit ) +int miracle_unit_is_offline( miracle_unit unit ) { - return (unit->online == 0); + return 0; } /** Obtain the status for a given unit */ -int dv_unit_get_status( dv_unit unit, dv1394_status status ) +int miracle_unit_get_status( miracle_unit unit, valerie_status status ) { - int error = -1; + int error = unit == NULL; - memset( status, 0, sizeof( dv1394_status_t ) ); + memset( status, 0, sizeof( valerie_status_t ) ); - if ( unit != NULL ) + if ( !error ) { - dv_player player = dv_unit_get_dv_player( unit ); + mlt_properties properties = unit->properties; + mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); + mlt_producer producer = mlt_playlist_producer( playlist ); + mlt_producer clip = mlt_playlist_current( playlist ); - error = 0; + mlt_playlist_clip_info info; + int clip_index = mlt_playlist_current_clip( playlist ); + mlt_playlist_get_clip_info( playlist, &info, clip_index ); - if ( player != NULL ) + if ( info.resource != NULL && strcmp( info.resource, "" ) ) { - dv_frame head = dv_pump_get_head( player->pump ); - dv_frame tail = dv_pump_get_tail( player->pump ); - - status->speed = (int)( dv_player_get_speed( player ) * 1000.0 ); - status->fps = dv_player_frames_per_second( player, 0 ); - - if ( head != NULL ) - { - dv_frame_id id = dv_frame_get_id( head ); - if ( id->resource != NULL ) - { - const char *resource = id->resource; - if ( resource != NULL && unit->root_dir != NULL ) - resource += strlen( unit->root_dir ) - ( unit->root_dir[ strlen( unit->root_dir ) - 1 ] == '/' ); - strncpy( status->clip, resource, sizeof( status->clip ) ); - } - else - { - char *title = dv_player_get_name( player, dv_player_get_clip_containing( player, 0 ), unit->root_dir ); - if ( title != NULL ) - strncpy( status->clip, title, sizeof( status->clip ) ); - } - - status->position = id->relative; - status->in = id->in; - status->out = id->out; - status->length = id->length; - status->seek_flag = id->seek_flag; - } - else - { - char *title = dv_player_get_name( player, dv_player_get_clip_containing( player, 0 ), unit->root_dir ); - if ( title != NULL ) - strncpy( status->clip, title, sizeof( status->clip ) ); - } - - if ( tail != NULL ) - { - dv_frame_id id = dv_frame_get_id( tail ); - const char *resource = id->resource; - if ( resource != NULL && unit->root_dir != NULL ) - resource += strlen( unit->root_dir ) - ( unit->root_dir[ strlen( unit->root_dir ) - 1 ] == '/' ); - if ( resource != NULL ) - strncpy( status->tail_clip, resource, sizeof( status->clip ) ); - status->tail_position = id->relative; - status->tail_in = id->in; - status->tail_out = id->out; - status->tail_length = id->length; - } - - status->generation = player->generation; - status->clip_index = dv_unit_get_current_clip( unit ); + strncpy( status->clip, info.resource, sizeof( status->clip ) ); + status->speed = (int)( mlt_producer_get_speed( producer ) * 1000.0 ); + status->fps = mlt_producer_get_fps( producer ); + status->in = info.in; + status->out = info.in + info.playtime; + status->position = mlt_producer_position( clip ); + status->length = mlt_producer_get_length( clip ); + status->seek_flag = 1; } - if ( dv_unit_is_offline( unit ) ) - status->status = unit_offline; - else if ( !strcmp( status->clip, "" ) ) + if ( !strcmp( status->clip, "" ) ) status->status = unit_not_loaded; - else if ( dv_unit_has_terminated( unit ) ) - status->status = unit_stopped; else if ( status->speed == 0 ) status->status = unit_paused; else @@ -749,7 +437,7 @@ int dv_unit_get_status( dv_unit unit, dv1394_status status ) status->status = unit_undefined; } - status->unit = unit->unit; + status->unit = mlt_properties_get_int( unit->properties, "unit" ); return error; } @@ -757,344 +445,104 @@ int dv_unit_get_status( dv_unit unit, dv1394_status status ) /** Change position in the playlist. */ -void dv_unit_change_position( dv_unit unit, int clip, long position ) +void miracle_unit_change_position( miracle_unit unit, int clip, double position ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_player_set_clip_position( player, clip, position ); - dv_unit_status_communicate( unit ); + miracle_unit_status_communicate( unit ); } /** Change speed. */ -void dv_unit_change_speed( dv_unit unit, int speed ) +void miracle_unit_change_speed( miracle_unit unit, int speed ) { - if ( dv_unit_has_terminated( unit ) ) - dv_unit_change_position( unit, 0, 0 ); - else - dv_unit_play( unit, speed ); } -int dv_unit_get_current_clip( dv_unit unit ) +int miracle_unit_get_current_clip( miracle_unit unit ) { - dv_player player = dv_unit_get_dv_player( unit ); - unsigned long position = dv_player_get_position( player ); - return dv_player_get_clip_containing( player, position ); + return 0; } /** Set a clip's in point */ -int dv_unit_set_clip_in( dv_unit unit, int index, long position ) +int miracle_unit_set_clip_in( miracle_unit unit, int index, double position ) { int error = 0; - dv_player player = dv_unit_get_dv_player( unit ); - - if ( player != NULL ) - { - dv_unit_change_speed( unit, 0 ); - if ( dv_player_set_in_point( player, index, (unsigned long) position ) == position ) - dv_player_set_clip_position( player, index, position ); - else - error = -2; - } - else - { - error = -1; - } - - dv_unit_status_communicate( unit ); - return error; - } /** Set a clip's out point. */ -int dv_unit_set_clip_out( dv_unit unit, int index, long position ) +int miracle_unit_set_clip_out( miracle_unit unit, int index, double position ) { int error = 0; - dv_player player = dv_unit_get_dv_player( unit ); - - if ( player != NULL ) - { - dv_unit_change_speed( unit, 0 ); - if ( dv_player_set_out_point( player, index, position ) == position ) - dv_player_set_clip_position( player, index, position ); - else - error = -2; - } - else - { - error = -1; - } - - dv_unit_status_communicate( unit ); - return error; } /** Step by specified position. */ -void dv_unit_step( dv_unit unit, int offset ) +void miracle_unit_step( miracle_unit unit, double offset ) { - dv_player player = dv_unit_get_dv_player( unit ); - dv_player_change_position( player, dv_seek_relative, offset ); } /** Set the unit's clip mode regarding in and out points. */ -void dv_unit_set_mode( dv_unit unit, dv_player_clip_mode mode ) -{ - dv_player player = dv_unit_get_dv_player( unit ); - if ( player != NULL ) - dv_player_set_clip_mode( player, mode ); - dv_unit_status_communicate( unit ); -} +//void miracle_unit_set_mode( miracle_unit unit, dv_player_clip_mode mode ) +//{ + //dv_player player = miracle_unit_get_dv_player( unit ); + //if ( player != NULL ) + //dv_player_set_clip_mode( player, mode ); + //miracle_unit_status_communicate( unit ); +//} /** Get the unit's clip mode regarding in and out points. */ -dv_player_clip_mode dv_unit_get_mode( dv_unit unit ) -{ - dv_player player = dv_unit_get_dv_player( unit ); - return dv_player_get_clip_mode( player ); -} +//dv_player_clip_mode miracle_unit_get_mode( miracle_unit unit ) +//{ + //dv_player player = miracle_unit_get_dv_player( unit ); + //return dv_player_get_clip_mode( player ); +//} /** Set the unit's clip mode regarding eof handling. */ -void dv_unit_set_eof_action( dv_unit unit, dv_player_eof_action action ) -{ - dv_player player = dv_unit_get_dv_player( unit ); - dv_player_set_eof_action( player, action ); - dv_unit_status_communicate( unit ); -} +//void miracle_unit_set_eof_action( miracle_unit unit, dv_player_eof_action action ) +//{ + //dv_player player = miracle_unit_get_dv_player( unit ); + //dv_player_set_eof_action( player, action ); + //miracle_unit_status_communicate( unit ); +//} /** Get the unit's clip mode regarding eof handling. */ -dv_player_eof_action dv_unit_get_eof_action( dv_unit unit ) -{ - dv_player player = dv_unit_get_dv_player( unit ); - return dv_player_get_eof_action( player ); -} +//dv_player_eof_action miracle_unit_get_eof_action( miracle_unit unit ) +//{ + //dv_player player = miracle_unit_get_dv_player( unit ); + //return dv_player_get_eof_action( player ); +//} /** Release the unit \todo error handling - \param unit A dv_unit handle. + \param unit A miracle_unit handle. */ -void dv_unit_close( dv_unit unit ) +void miracle_unit_close( miracle_unit unit ) { if ( unit != NULL ) { - dv1394d_log( LOG_DEBUG, "closing unit..." ); - dv_unit_offline( unit ); - if ( unit->pump != NULL ) - { - dv_pump_terminate( unit->pump ); - dv_pump_flush( unit->pump ); - dv_pump_return_used_output( unit->pump ); - dv_input_join_thread( unit->in ); - if ( !unit->is_terminated ) - pthread_join( unit->out, NULL ); - dv_pump_close( unit->pump ); - unit->pump = NULL; - } - raw1394_close( unit->raw1394 ); + miracle_log( LOG_DEBUG, "closing unit..." ); + if ( unit->old_producers != NULL ) + mlt_properties_close( unit->old_producers ); + mlt_properties_close( unit->properties ); + mlt_properties_close( unit->producers ); free( unit ); - dv1394d_log( LOG_DEBUG, "... unit closed." ); - } -} - -/** Get the raw1394 port associated to this unit. -*/ - -int dv_unit_get_port( dv_unit unit ) -{ - if ( unit->raw1394 != NULL ) - return (int) raw1394_get_userdata( unit->raw1394 ); - else - return -1; -} - -/** Set the dv1394 file descriptor for the unit. -*/ - -void dv_unit_set_dv1394_fd( dv_unit unit, int fd ) -{ - unit->dv1394_fd = fd; -} - -/** Get the dv1394 syt_offset (timestamp latency) property. -*/ - -unsigned int dv_unit_get_syt_offset( dv_unit unit ) -{ - return unit->dv1394_syt_offset; -} - -/** Get the dv1394 cip_n (timing numerator) property. -*/ - -unsigned int dv_unit_get_cip_n( dv_unit unit ) -{ - return unit->dv1394_cip_n; -} - -/** Get the dv1394 cip_d (timing denominator) property. -*/ - -unsigned int dv_unit_get_cip_d( dv_unit unit ) -{ - return unit->dv1394_cip_d; -} - -/** Set the dv1394 syt_offset (timestamp latency) property. - - Stops and restarts the unit if playing. -*/ - -void dv_unit_set_syt_offset( dv_unit unit, unsigned int syt_offset ) -{ - int restart = !unit->is_terminated; - int speed = (int)( dv_player_get_speed( dv_unit_get_dv_player(unit) ) * 1000.0 ); - - dv_unit_terminate( unit ); - unit->dv1394_syt_offset = syt_offset; - if ( restart ) - dv_unit_play( unit, speed ); -} - -/** Set the dv1394 cip_n (timing numerator) property. - - Stops and restarts the unit if playing. -*/ - -void dv_unit_set_cip_n( dv_unit unit, unsigned int cip_n ) -{ - int restart = !unit->is_terminated; - int speed = (int)( dv_player_get_speed( dv_unit_get_dv_player(unit) ) * 1000.0 ); - - dv_unit_terminate( unit ); - unit->dv1394_cip_n = cip_n; - if ( restart ) - dv_unit_play( unit, speed ); -} - -/** Set the dv1394 cip_d (timing denominator) property. - - Stops and restarts the unit if playing. -*/ - -void dv_unit_set_cip_d( dv_unit unit, unsigned int cip_d ) -{ - int restart = !unit->is_terminated; - int speed = (int)( dv_player_get_speed( dv_unit_get_dv_player(unit) ) * 1000.0 ); - - dv_unit_terminate( unit ); - unit->dv1394_cip_d = cip_d; - if ( restart ) - dv_unit_play( unit, speed ); -} - -/** Terminate, but only the output thread and close dv1394. -*/ - -void dv_unit_suspend( dv_unit unit ) -{ - if ( unit->is_terminated == 0 ) - { - unit->is_terminated = 1; - unit->is_suspended = 1; - dv_pump_terminate( unit->pump ); - dv_pump_flush( unit->pump ); - pthread_cancel( unit->out ); - } - if ( unit->dv1394_fd > -1 ) - { - close( unit->dv1394_fd ); - device_count[ dv_unit_get_port( unit ) ] --; + miracle_log( LOG_DEBUG, "... unit closed." ); } - unit->dv1394_fd = -1; - dv_unit_status_communicate( unit ); } - -/** Restore unit on the bus, re-open dv1394, start playback if pump is running. -*/ - -void dv_unit_restore( dv_unit unit ) -{ - int result = 0; - int port, node_id; - - if ( unit->raw1394 != NULL ) - raw1394_close( unit->raw1394 ); - - node_id = raw1394_find_node( &(unit->raw1394), unit->guid ); - if ( node_id != -1 ) - { - unit->node_id = 0xffc0 | node_id; - port = dv_unit_get_port( unit ); - - unit->dv1394_fd = open( devices[ port ][ device_count[port] ], O_RDWR ); - if ( unit->dv1394_fd < 0 ) - { - dv1394d_log( LOG_ERR, "failed to open dv1394 device - %s\n", devices[ port ][ device_count[port] ] ); - dv_unit_close( unit ); - } - else - { - device_count[ port ] ++; - break_p2p_connection( unit->raw1394, unit->node_id, unit->channel ); - if ( establish_p2p_connection( unit->raw1394, unit->node_id, (unsigned int *) &(unit->channel) ) ) - { - avc1394_vcr_record( unit->raw1394, unit->node_id ); - unit->online = 1; - result = 1; - } - } - } - if ( unit->is_suspended == 1 ) - { - int retval; - dv_frame frame = dv_pump_get_available_output( unit->pump ); - struct dv1394_init setup = - { - api_version: DV1394_API_VERSION, - channel: unit->channel, - /* this only sets the *requested* size of the ringbuffer, - in frames */ - n_frames: unit->n_frames, - format: dv_frame_is_pal(frame) ? DV1394_PAL : DV1394_NTSC, - cip_n: unit->dv1394_cip_n, - cip_d: unit->dv1394_cip_d, - syt_offset: unit->dv1394_syt_offset - }; - pthread_attr_t attr; - - dv_input_join_thread( unit->in ); - unit->is_terminated = 0; - unit->is_suspended = 0; - dv_pump_restart( unit->pump ); - dv_input_start_thread( unit->in ); - - /* initialize dv1394 */ - retval = ioctl( unit->dv1394_fd, DV1394_INIT, &setup ); - if ( retval < 0 ) - return; - - pthread_attr_init( &attr ); - pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); - pthread_attr_setinheritsched( &attr, PTHREAD_INHERIT_SCHED ); - /* pthread_attr_setschedpolicy( &attr, SCHED_RR ); */ - pthread_create( &unit->out, &attr, output, unit ); - } - dv_unit_status_communicate( unit ); -} diff --git a/src/miracle/miracle_unit.h b/src/miracle/miracle_unit.h index 54338182..fabfe5a8 100644 --- a/src/miracle/miracle_unit.h +++ b/src/miracle/miracle_unit.h @@ -22,14 +22,9 @@ #define _DV_UNIT_H_ #include -#include -#include -#include -#include -#include -#include -#include +#include +#include #ifdef __cplusplus extern "C" @@ -38,81 +33,43 @@ extern "C" typedef struct { - int unit; - dv_pump pump; - dv_player player; - dv_input in; - int dv1394_fd; - int is_terminated; - int is_suspended; - pthread_t out; - int channel; - nodeid_t node_id; - octlet_t guid; - raw1394handle_t raw1394; - int allow_stdin; - int buffer_size; - int online; - dv1394_notifier notifier; - char *root_dir; - unsigned int dv1394_syt_offset; - unsigned int dv1394_cip_n; - unsigned int dv1394_cip_d; - unsigned int n_frames; - unsigned int n_fill; - uint8_t *mmap; - int mmap_pos; - int mmap_length; -} dv_unit_t, *dv_unit; + mlt_properties properties; + mlt_properties producers; + mlt_properties old_producers; +} +miracle_unit_t, *miracle_unit; -extern dv_unit dv_unit_init( octlet_t guid, int channel ); -extern void dv_unit_allow_stdin( dv_unit unit, int flag ); -extern void dv_unit_set_buffer_size( dv_unit unit, int size ); -extern int dv_unit_get_buffer_size( dv_unit unit ); -extern void dv_unit_set_n_frames( dv_unit unit, int size ); -extern int dv_unit_get_n_frames( dv_unit unit ); -extern void dv_unit_set_n_fill( dv_unit unit, int size ); -extern int dv_unit_get_n_fill( dv_unit unit ); -extern dv_error_code dv_unit_load( dv_unit unit, const char *clip, long in, long out, int flush ); -extern dv_error_code dv_unit_insert( dv_unit unit, const char *clip, int index, long in, long out ); -extern dv_error_code dv_unit_append( dv_unit unit, const char *clip, long in, long out ); -extern dv_error_code dv_unit_remove( dv_unit unit, int index ); -extern dv_error_code dv_unit_clean( dv_unit unit ); -extern dv_error_code dv_unit_move( dv_unit unit, int src, int dest ); -extern int dv_unit_transfer( dv_unit dest_unit, dv_unit src_unit ); -extern void dv_unit_play( dv_unit_t *unit, int speed ); -extern void dv_unit_terminate( dv_unit ); -extern int dv_unit_has_terminated( dv_unit ); -extern octlet_t dv_unit_get_guid( dv_unit unit ); -extern int dv_unit_get_nodeid( dv_unit unit ); -extern int dv_unit_get_channel( dv_unit unit ); -extern int dv_unit_online( dv_unit unit ); -extern void dv_unit_offline( dv_unit unit ); -extern int dv_unit_is_offline( dv_unit unit ); -extern void dv_unit_set_notifier( dv_unit, dv1394_notifier, char * ); -extern int dv_unit_get_status( dv_unit, dv1394_status ); -extern void dv_unit_change_position( dv_unit, int, long position ); -extern void dv_unit_change_speed( dv_unit unit, int speed ); -extern int dv_unit_set_clip_in( dv_unit unit, int index, long position ); -extern int dv_unit_set_clip_out( dv_unit unit, int index, long position ); -extern void dv_unit_set_mode( dv_unit unit, dv_player_clip_mode mode ); -extern dv_player_clip_mode dv_unit_get_mode( dv_unit unit ); -extern void dv_unit_set_eof_action( dv_unit unit, dv_player_eof_action mode ); -extern dv_player_eof_action dv_unit_get_eof_action( dv_unit unit ); -extern void dv_unit_step( dv_unit unit, int offset ); -extern void dv_unit_close( dv_unit unit ); -extern int dv_unit_get_port( dv_unit unit ); -extern void dv_unit_set_dv1394_fd( dv_unit unit, int fd ); -extern unsigned int dv_unit_get_syt_offset( dv_unit unit ); -extern unsigned int dv_unit_get_cip_n( dv_unit unit ); -extern unsigned int dv_unit_get_cip_d( dv_unit unit ); -extern void dv_unit_set_syt_offset( dv_unit unit, unsigned int ); -extern void dv_unit_set_cip_n( dv_unit unit, unsigned int ); -extern void dv_unit_set_cip_d( dv_unit unit, unsigned int ); -extern void dv_unit_suspend( dv_unit ); -extern void dv_unit_restore( dv_unit ); -extern dv_player dv_unit_get_dv_player( dv_unit ); -extern int dv_unit_get_current_clip( dv_unit ); +extern miracle_unit miracle_unit_init( int index, char *arg ); +extern void miracle_unit_report_list( miracle_unit unit, valerie_response response ); +extern void miracle_unit_allow_stdin( miracle_unit unit, int flag ); +extern valerie_error_code miracle_unit_load( miracle_unit unit, char *clip, double in, double out, int flush ); +extern valerie_error_code miracle_unit_insert( miracle_unit unit, const char *clip, int index, double in, double out ); +extern valerie_error_code miracle_unit_append( miracle_unit unit, char *clip, double in, double out ); +extern valerie_error_code miracle_unit_remove( miracle_unit unit, int index ); +extern valerie_error_code miracle_unit_clean( miracle_unit unit ); +extern valerie_error_code miracle_unit_move( miracle_unit unit, int src, int dest ); +extern int miracle_unit_transfer( miracle_unit dest_unit, miracle_unit src_unit ); +extern void miracle_unit_play( miracle_unit_t *unit, int speed ); +extern void miracle_unit_terminate( miracle_unit ); +extern int miracle_unit_has_terminated( miracle_unit ); +extern int miracle_unit_get_nodeid( miracle_unit unit ); +extern int miracle_unit_get_channel( miracle_unit unit ); +extern int miracle_unit_is_offline( miracle_unit unit ); +extern void miracle_unit_set_notifier( miracle_unit, valerie_notifier, char * ); +extern int miracle_unit_get_status( miracle_unit, valerie_status ); +extern void miracle_unit_change_position( miracle_unit, int, double position ); +extern void miracle_unit_change_speed( miracle_unit unit, int speed ); +extern int miracle_unit_set_clip_in( miracle_unit unit, int index, double position ); +extern int miracle_unit_set_clip_out( miracle_unit unit, int index, double position ); +//extern void miracle_unit_set_mode( miracle_unit unit, dv_player_clip_mode mode ); +//extern dv_player_clip_mode miracle_unit_get_mode( miracle_unit unit ); +//extern void miracle_unit_set_eof_action( miracle_unit unit, dv_player_eof_action mode ); +//extern dv_player_eof_action miracle_unit_get_eof_action( miracle_unit unit ); +extern void miracle_unit_step( miracle_unit unit, double offset ); +extern void miracle_unit_close( miracle_unit unit ); +extern void miracle_unit_suspend( miracle_unit ); +extern void miracle_unit_restore( miracle_unit ); +extern int miracle_unit_get_current_clip( miracle_unit ); #ifdef __cplusplus diff --git a/src/miracle/miracle_unit_commands.c b/src/miracle/miracle_unit_commands.c index b12f2c72..a630422b 100644 --- a/src/miracle/miracle_unit_commands.c +++ b/src/miracle/miracle_unit_commands.c @@ -28,16 +28,15 @@ #include #include #include +#include -#include "dvunit.h" -#include "global_commands.h" -#include "dverror.h" -#include "dvframepool.h" -#include "log.h" +#include "miracle_unit.h" +#include "miracle_commands.h" +#include "miracle_log.h" -int dv1394d_load( command_argument cmd_arg ) +int miracle_load( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + miracle_unit unit = miracle_get_unit(cmd_arg->unit); char *filename = (char*) cmd_arg->argument; char fullname[1024]; int flush = 1; @@ -57,53 +56,34 @@ int dv1394d_load( command_argument cmd_arg ) return RESPONSE_INVALID_UNIT; else { - long in = -1, out = -1; - if ( dv_tokeniser_count( cmd_arg->tokeniser ) == 5 ) + double in = -1, out = -1; + if ( valerie_tokeniser_count( cmd_arg->tokeniser ) == 5 ) { - in = atoi( dv_tokeniser_get_string( cmd_arg->tokeniser, 3 ) ); - out = atoi( dv_tokeniser_get_string( cmd_arg->tokeniser, 4 ) ); + in = atof( valerie_tokeniser_get_string( cmd_arg->tokeniser, 3 ) ); + out = atof( valerie_tokeniser_get_string( cmd_arg->tokeniser, 4 ) ); } - if ( dv_unit_load( unit, fullname, in, out, flush ) != dv_pump_ok ) + if ( miracle_unit_load( unit, fullname, in, out, flush ) != valerie_ok ) return RESPONSE_BAD_FILE; } return RESPONSE_SUCCESS; } -int dv1394d_list( command_argument cmd_arg ) +int miracle_list( command_argument cmd_arg ) { - int i = 0; - dv_unit unit = dv1394d_get_unit( cmd_arg->unit ); - dv_player player = dv_unit_get_dv_player( unit ); - - if ( player != NULL ) + miracle_unit unit = miracle_get_unit( cmd_arg->unit ); + + if ( unit != NULL ) { - dv_response_printf( cmd_arg->response, 1024, "%d\n", player->generation ); - - for ( i = 0; i < dv_player_get_clip_count( player ); i ++ ) - { - dv_clip clip = dv_player_get_clip( player, i ); - - dv_response_printf( cmd_arg->response, 10240, - "%d \"%s\" %d %d %d %d %.2f\n", - i, - dv_clip_get_resource( clip, cmd_arg->root_dir ), - dv_clip_get_in( clip ), - ( !dv_clip_is_seekable( clip ) && clip->out_frame == -1 ? -1 : dv_clip_get_out( clip ) ), - dv_clip_get_max_frames( clip ), - ( !dv_clip_is_seekable( clip ) && clip->out_frame == -1 ? -1 : dv_player_get_length_of_clip( player, i ) ), - dv_clip_frames_per_second( clip ) ); - } - - dv_response_printf( cmd_arg->response, 2, "\n" ); - + miracle_unit_report_list( unit, cmd_arg->response ); return RESPONSE_SUCCESS; } + return RESPONSE_INVALID_UNIT; } - +/* static int parse_clip( command_argument cmd_arg, int arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + dv_unit unit = miracle_get_unit(cmd_arg->unit); int clip = dv_unit_get_current_clip( unit ); if ( dv_tokeniser_count( cmd_arg->tokeniser ) > arg ) @@ -124,10 +104,12 @@ static int parse_clip( command_argument cmd_arg, int arg ) return clip; } +*/ -int dv1394d_insert( command_argument cmd_arg ) +int miracle_insert( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); char *filename = (char*) cmd_arg->argument; char fullname[1024]; @@ -159,12 +141,14 @@ int dv1394d_insert( command_argument cmd_arg ) return RESPONSE_BAD_FILE; } } + */ return RESPONSE_SUCCESS; } -int dv1394d_remove( command_argument cmd_arg ) +int miracle_remove( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); if (unit == NULL) return RESPONSE_INVALID_UNIT; @@ -175,12 +159,14 @@ int dv1394d_remove( command_argument cmd_arg ) if ( dv_unit_remove( unit, index ) != dv_pump_ok ) return RESPONSE_BAD_FILE; } + */ return RESPONSE_SUCCESS; } -int dv1394d_clean( command_argument cmd_arg ) +int miracle_clean( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); if (unit == NULL) return RESPONSE_INVALID_UNIT; @@ -189,12 +175,14 @@ int dv1394d_clean( command_argument cmd_arg ) if ( dv_unit_clean( unit ) != dv_pump_ok ) return RESPONSE_BAD_FILE; } + */ return RESPONSE_SUCCESS; } -int dv1394d_move( command_argument cmd_arg ) +int miracle_move( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); if ( unit != NULL ) { @@ -215,36 +203,36 @@ int dv1394d_move( command_argument cmd_arg ) { return RESPONSE_INVALID_UNIT; } - + */ + return RESPONSE_SUCCESS; } -int dv1394d_append( command_argument cmd_arg ) +int miracle_append( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + miracle_unit unit = miracle_get_unit(cmd_arg->unit); char *filename = (char*) cmd_arg->argument; char fullname[1024]; if ( filename[0] == '/' ) filename++; + snprintf( fullname, 1023, "%s%s", cmd_arg->root_dir, filename ); if (unit == NULL) return RESPONSE_INVALID_UNIT; else { - long in = -1, out = -1; - if ( dv_tokeniser_count( cmd_arg->tokeniser ) == 5 ) + double in = -1, out = -1; + if ( valerie_tokeniser_count( cmd_arg->tokeniser ) == 5 ) { - in = atoi( dv_tokeniser_get_string( cmd_arg->tokeniser, 3 ) ); - out = atoi( dv_tokeniser_get_string( cmd_arg->tokeniser, 4 ) ); + in = atof( valerie_tokeniser_get_string( cmd_arg->tokeniser, 3 ) ); + out = atof( valerie_tokeniser_get_string( cmd_arg->tokeniser, 4 ) ); } - switch ( dv_unit_append( unit, fullname, in, out ) ) + switch ( miracle_unit_append( unit, fullname, in, out ) ) { - case dv_pump_ok: + case valerie_ok: return RESPONSE_SUCCESS; - case dv_pump_too_many_files_open: - return RESPONSE_TOO_MANY_FILES; default: return RESPONSE_BAD_FILE; } @@ -252,62 +240,59 @@ int dv1394d_append( command_argument cmd_arg ) return RESPONSE_SUCCESS; } -int dv1394d_play( command_argument cmd_arg ) +int miracle_play( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + miracle_unit unit = miracle_get_unit(cmd_arg->unit); - if (unit == NULL || dv_unit_is_offline(unit)) + if ( unit == NULL ) + { return RESPONSE_INVALID_UNIT; + } else { int speed = 1000; - if ( dv_tokeniser_count( cmd_arg->tokeniser ) == 3 ) - speed = atoi( dv_tokeniser_get_string( cmd_arg->tokeniser, 2 ) ); - dv_unit_play( unit, speed ); + if ( valerie_tokeniser_count( cmd_arg->tokeniser ) == 3 ) + speed = atoi( valerie_tokeniser_get_string( cmd_arg->tokeniser, 2 ) ); + miracle_unit_play( unit, speed ); } - + return RESPONSE_SUCCESS; } -int dv1394d_stop( command_argument cmd_arg ) +int miracle_stop( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); - - if (unit == NULL || dv_unit_is_offline(unit)) + miracle_unit unit = miracle_get_unit(cmd_arg->unit); + if ( unit == NULL ) return RESPONSE_INVALID_UNIT; - else - dv_unit_terminate( unit ); - + else + miracle_unit_play( unit, 0 ); return RESPONSE_SUCCESS; } -int dv1394d_pause( command_argument cmd_arg ) +int miracle_pause( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); - - if (unit == NULL || dv_unit_is_offline(unit)) + miracle_unit unit = miracle_get_unit(cmd_arg->unit); + if ( unit == NULL ) return RESPONSE_INVALID_UNIT; else - dv_unit_play( unit, 0 ); - + miracle_unit_play( unit, 0 ); return RESPONSE_SUCCESS; } -int dv1394d_rewind( command_argument cmd_arg ) +int miracle_rewind( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); - - if (unit == NULL || dv_unit_is_offline(unit)) + miracle_unit unit = miracle_get_unit(cmd_arg->unit); + if ( unit == NULL ) return RESPONSE_INVALID_UNIT; - else - dv_unit_change_speed( unit, -2000 ); - + else + miracle_unit_play( unit, -2000 ); return RESPONSE_SUCCESS; } -int dv1394d_step( command_argument cmd_arg ) +int miracle_step( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); if (unit == NULL || dv_unit_is_offline(unit)) return RESPONSE_INVALID_UNIT; @@ -316,38 +301,38 @@ int dv1394d_step( command_argument cmd_arg ) dv_unit_play( unit, 0 ); dv_unit_step( unit, *(int*) cmd_arg->argument ); } - + */ return RESPONSE_SUCCESS; } -int dv1394d_goto( command_argument cmd_arg ) +int miracle_goto( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); int clip = parse_clip( cmd_arg, 3 ); if (unit == NULL || dv_unit_is_offline(unit)) return RESPONSE_INVALID_UNIT; else dv_unit_change_position( unit, clip, *(int*) cmd_arg->argument ); - + */ return RESPONSE_SUCCESS; } -int dv1394d_ff( command_argument cmd_arg ) +int miracle_ff( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); - - if (unit == NULL || dv_unit_is_offline(unit)) + miracle_unit unit = miracle_get_unit(cmd_arg->unit); + if ( unit == NULL ) return RESPONSE_INVALID_UNIT; - else - dv_unit_change_speed( unit, 2000 ); - + else + miracle_unit_play( unit, 2000 ); return RESPONSE_SUCCESS; } -int dv1394d_set_in_point( command_argument cmd_arg ) +int miracle_set_in_point( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); int clip = parse_clip( cmd_arg, 3 ); if (unit == NULL || dv_unit_is_offline(unit)) @@ -364,13 +349,14 @@ int dv1394d_set_in_point( command_argument cmd_arg ) return RESPONSE_OUT_OF_RANGE; } } - + */ return RESPONSE_SUCCESS; } -int dv1394d_set_out_point( command_argument cmd_arg ) +int miracle_set_out_point( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); int clip = parse_clip( cmd_arg, 3 ); if (unit == NULL || dv_unit_is_offline(unit)) @@ -387,35 +373,31 @@ int dv1394d_set_out_point( command_argument cmd_arg ) return RESPONSE_OUT_OF_RANGE; } } - + */ return RESPONSE_SUCCESS; } -int dv1394d_get_unit_status( command_argument cmd_arg ) +int miracle_get_unit_status( command_argument cmd_arg ) { - dv1394_status_t status; - int error = dv_unit_get_status( dv1394d_get_unit( cmd_arg->unit ), &status ); + valerie_status_t status; + int error = miracle_unit_get_status( miracle_get_unit( cmd_arg->unit ), &status ); if ( error == -1 ) return RESPONSE_INVALID_UNIT; else { char text[ 10240 ]; - - dv_response_printf( cmd_arg->response, - sizeof( text ), - dv1394_status_serialise( &status, text, sizeof( text ) ) ); - + valerie_response_printf( cmd_arg->response, sizeof( text ), valerie_status_serialise( &status, text, sizeof( text ) ) ); return RESPONSE_SUCCESS_1; } - return 0; } -int dv1394d_set_unit_property( command_argument cmd_arg ) +int miracle_set_unit_property( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); if (unit == NULL) return RESPONSE_INVALID_UNIT; @@ -429,7 +411,7 @@ int dv1394d_set_unit_property( command_argument cmd_arg ) return RESPONSE_OUT_OF_RANGE; value[0] = 0; value++; - dv1394d_log( LOG_DEBUG, "USET %s = %s", key, value ); + miracle_log( LOG_DEBUG, "USET %s = %s", key, value ); if ( strncasecmp( key, "eof", 1024) == 0 ) { if ( strncasecmp( value, "pause", 1024) == 0) @@ -479,13 +461,14 @@ int dv1394d_set_unit_property( command_argument cmd_arg ) else return RESPONSE_OUT_OF_RANGE; } - + */ return RESPONSE_SUCCESS; } -int dv1394d_get_unit_property( command_argument cmd_arg ) +int miracle_get_unit_property( command_argument cmd_arg ) { - dv_unit unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit unit = miracle_get_unit(cmd_arg->unit); if (unit == NULL) return RESPONSE_INVALID_UNIT; @@ -585,14 +568,15 @@ int dv1394d_get_unit_property( command_argument cmd_arg ) dv_response_printf( cmd_arg->response, 1024, "n_fill=%d\n", dv_unit_get_n_fill( unit ) ); } } - + */ return RESPONSE_SUCCESS; } -int dv1394d_transfer( command_argument cmd_arg ) +int miracle_transfer( command_argument cmd_arg ) { - dv_unit src_unit = dv1394d_get_unit(cmd_arg->unit); + /* + dv_unit src_unit = miracle_get_unit(cmd_arg->unit); int dest_unit_id = -1; char *string = (char*) cmd_arg->argument; if ( string != NULL && ( string[ 0 ] == 'U' || string[ 0 ] == 'u' ) && strlen( string ) > 1 ) @@ -600,13 +584,13 @@ int dv1394d_transfer( command_argument cmd_arg ) if ( src_unit != NULL && dest_unit_id != -1 ) { - dv_unit dest_unit = dv1394d_get_unit( dest_unit_id ); + dv_unit dest_unit = miracle_get_unit( dest_unit_id ); if ( dest_unit != NULL && !dv_unit_is_offline(dest_unit) && dest_unit != src_unit ) { dv_unit_transfer( dest_unit, src_unit ); return RESPONSE_SUCCESS; } } - + */ return RESPONSE_INVALID_UNIT; } diff --git a/src/miracle/miracle_unit_commands.h b/src/miracle/miracle_unit_commands.h index a7163bdc..575ff1be 100644 --- a/src/miracle/miracle_unit_commands.h +++ b/src/miracle/miracle_unit_commands.h @@ -22,33 +22,33 @@ #ifndef _UNIT_COMMANDS_H_ #define _UNIT_COMMANDS_H_ -#include "dvconnection.h" +#include "miracle_connection.h" #ifdef __cplusplus extern "C" { #endif -extern response_codes dv1394d_list( command_argument ); -extern response_codes dv1394d_load( command_argument ); -extern response_codes dv1394d_insert( command_argument ); -extern response_codes dv1394d_remove( command_argument ); -extern response_codes dv1394d_clean( command_argument ); -extern response_codes dv1394d_move( command_argument ); -extern response_codes dv1394d_append( command_argument ); -extern response_codes dv1394d_play( command_argument ); -extern response_codes dv1394d_stop( command_argument ); -extern response_codes dv1394d_pause( command_argument ); -extern response_codes dv1394d_rewind( command_argument ); -extern response_codes dv1394d_step( command_argument ); -extern response_codes dv1394d_goto( command_argument ); -extern response_codes dv1394d_ff( command_argument ); -extern response_codes dv1394d_set_in_point( command_argument ); -extern response_codes dv1394d_set_out_point( command_argument ); -extern response_codes dv1394d_get_unit_status( command_argument ); -extern response_codes dv1394d_set_unit_property( command_argument ); -extern response_codes dv1394d_get_unit_property( command_argument ); -extern response_codes dv1394d_transfer( command_argument ); +extern response_codes miracle_list( command_argument ); +extern response_codes miracle_load( command_argument ); +extern response_codes miracle_insert( command_argument ); +extern response_codes miracle_remove( command_argument ); +extern response_codes miracle_clean( command_argument ); +extern response_codes miracle_move( command_argument ); +extern response_codes miracle_append( command_argument ); +extern response_codes miracle_play( command_argument ); +extern response_codes miracle_stop( command_argument ); +extern response_codes miracle_pause( command_argument ); +extern response_codes miracle_rewind( command_argument ); +extern response_codes miracle_step( command_argument ); +extern response_codes miracle_goto( command_argument ); +extern response_codes miracle_ff( command_argument ); +extern response_codes miracle_set_in_point( command_argument ); +extern response_codes miracle_set_out_point( command_argument ); +extern response_codes miracle_get_unit_status( command_argument ); +extern response_codes miracle_set_unit_property( command_argument ); +extern response_codes miracle_get_unit_property( command_argument ); +extern response_codes miracle_transfer( command_argument ); #ifdef __cplusplus } diff --git a/src/modules/core/producer_ppm.c b/src/modules/core/producer_ppm.c index 3d3f5839..b508654b 100644 --- a/src/modules/core/producer_ppm.c +++ b/src/modules/core/producer_ppm.c @@ -43,12 +43,20 @@ mlt_producer producer_ppm_init( void *command ) if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) { mlt_producer producer = &this->parent; + mlt_properties properties = mlt_producer_properties( producer ); producer->get_frame = producer_get_frame; producer->close = producer_close; if ( command != NULL ) + { + mlt_properties_set( properties, "resource", command ); this->command = strdup( command ); + } + else + { + mlt_properties_set( properties, "resource", "ppm test" ); + } return producer; } diff --git a/src/modules/dv/producer_libdv.c b/src/modules/dv/producer_libdv.c index 05218cf3..c2921e3d 100644 --- a/src/modules/dv/producer_libdv.c +++ b/src/modules/dv/producer_libdv.c @@ -51,9 +51,10 @@ mlt_producer producer_libdv_init( char *filename ) { producer_libdv this = calloc( sizeof( struct producer_libdv_s ), 1 ); - if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) + if ( filename != NULL && this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) { mlt_producer producer = &this->parent; + mlt_properties properties = mlt_producer_properties( producer ); // Register transport implementation with the producer producer->close = producer_close; @@ -68,11 +69,11 @@ mlt_producer producer_libdv_init( char *filename ) dv_set_audio_correction( this->dv_decoder, DV_AUDIO_CORRECT_AVERAGE ); // Open the file if specified - if ( filename != NULL ) - { - this->fd = open( filename, O_RDONLY ); - producer_collect_info( this ); - } + this->fd = open( filename, O_RDONLY ); + producer_collect_info( this ); + + // Set the resource property (required for all producers) + mlt_properties_set( properties, "resource", filename ); // Return the producer return producer; diff --git a/src/modules/ffmpeg/audio.sh b/src/modules/ffmpeg/audio.sh index 3c7475a2..2d6aeda3 100755 --- a/src/modules/ffmpeg/audio.sh +++ b/src/modules/ffmpeg/audio.sh @@ -1,5 +1,7 @@ #!/bin/bash +trap exit + audio_type="$1" audio_file="$2" audio_position=$3 @@ -8,7 +10,7 @@ audio_channels=$5 audio_track=$5 if [ "$audio_type" == "dsp" ] -then ffmpeg -ad "$audio_file" -f s16le -ar $audio_frequency -ac $audio_channels - -else ffmpeg -i "$audio_file" -ss $audio_position -f s16le -ar $audio_frequency -ac $audio_channels - +then ffmpeg -ad "$audio_file" -f s16le -ar $audio_frequency -ac $audio_channels - +else ffmpeg -i "$audio_file" -ss $audio_position -f s16le -ar $audio_frequency -ac $audio_channels - fi diff --git a/src/modules/ffmpeg/producer_ffmpeg.c b/src/modules/ffmpeg/producer_ffmpeg.c index 8777fb11..2af9de37 100644 --- a/src/modules/ffmpeg/producer_ffmpeg.c +++ b/src/modules/ffmpeg/producer_ffmpeg.c @@ -26,12 +26,118 @@ #include #include #include +#include +#include +#include +#include typedef struct producer_ffmpeg_s *producer_ffmpeg; +/** Bi-directional pipe structure. +*/ + +typedef struct rwpipe +{ + int pid; + FILE *reader; + FILE *writer; +} +rwpipe; + +/** Create a bidirectional pipe for the given command. +*/ + +rwpipe *rwpipe_open( char *command ) +{ + rwpipe *this = malloc( sizeof( rwpipe ) ); + + if ( this != NULL ) + { + int input[ 2 ]; + int output[ 2 ]; + + pipe( input ); + pipe( output ); + + this->pid = fork(); + + if ( this->pid == 0 ) + { + signal( SIGPIPE, SIG_DFL ); + signal( SIGHUP, SIG_DFL ); + signal( SIGINT, SIG_DFL ); + signal( SIGTERM, SIG_DFL ); + signal( SIGSTOP, SIG_DFL ); + signal( SIGCHLD, SIG_DFL ); + + dup2( output[ 0 ], STDIN_FILENO ); + dup2( input[ 1 ], STDOUT_FILENO ); + + close( input[ 0 ] ); + close( input[ 1 ] ); + close( output[ 0 ] ); + close( output[ 1 ] ); + + execl( "/bin/sh", "sh", "-c", command, NULL ); + exit( 255 ); + } + else + { + setpgid( this->pid, this->pid ); + + close( input[ 1 ] ); + close( output[ 0 ] ); + + this->reader = fdopen( input[ 0 ], "r" ); + this->writer = fdopen( output[ 1 ], "w" ); + } + } + + return this; +} + +/** Read data from the pipe. +*/ + +FILE *rwpipe_reader( rwpipe *this ) +{ + if ( this != NULL ) + return this->reader; + else + return NULL; +} + +/** Write data to the pipe. +*/ + +FILE *rwpipe_writer( rwpipe *this ) +{ + if ( this != NULL ) + return this->writer; + else + return NULL; +} + +/** Close the pipe and process. +*/ + +void rwpipe_close( rwpipe *this ) +{ + if ( this != NULL ) + { + fclose( this->reader ); + fclose( this->writer ); + kill( - this->pid, SIGKILL ); + waitpid( - this->pid, NULL, 0 ); + free( this ); + } +} + struct producer_ffmpeg_s { struct mlt_producer_s parent; + rwpipe *video_pipe; + rwpipe *audio_pipe; FILE *video; FILE *audio; uint64_t expected; @@ -52,7 +158,7 @@ static void producer_close( mlt_producer parent ); mlt_producer producer_ffmpeg_init( char *file ) { producer_ffmpeg this = calloc( sizeof( struct producer_ffmpeg_s ), 1 ); - if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) + if ( file != NULL && this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) { // Get the producer mlt_producer producer = &this->parent; @@ -67,7 +173,7 @@ mlt_producer producer_ffmpeg_init( char *file ) // Set the properties mlt_properties_set( properties, "mlt_type", "producer_ffmpeg" ); - if ( file != NULL && !strcmp( file, "v4l" ) ) + if ( !strcmp( file, "v4l" ) ) { mlt_properties_set( properties, "video_type", "v4l" ); mlt_properties_set( properties, "video_file", "/dev/video0" ); @@ -89,6 +195,7 @@ mlt_producer producer_ffmpeg_init( char *file ) mlt_properties_set_int( properties, "audio_track", 0 ); mlt_properties_set( properties, "log_id", file ); + mlt_properties_set( properties, "resource", file ); this->buffer = malloc( 1024 * 1024 * 2 ); @@ -151,7 +258,8 @@ FILE *producer_ffmpeg_run_video( producer_ffmpeg this, mlt_timecode position ) video_rate, ( float )position ); - this->video = popen( command, "r" ); + this->video_pipe = rwpipe_open( command ); + this->video = rwpipe_reader( this->video_pipe ); } } return this->video; @@ -188,7 +296,8 @@ FILE *producer_ffmpeg_run_audio( producer_ffmpeg this, mlt_timecode position ) channels, track ); - this->audio = popen( command, "r" ); + this->audio_pipe = rwpipe_open( command ); + this->audio = rwpipe_reader( this->audio_pipe ); } } return this->audio; @@ -207,12 +316,12 @@ static void producer_ffmpeg_position( producer_ffmpeg this, uint64_t requested, { // Close the video pipe if ( this->video != NULL ) - pclose( this->video ); + rwpipe_close( this->video_pipe ); this->video = NULL; // Close the audio pipe if ( this->audio != NULL ) - pclose( this->audio ); + rwpipe_close( this->audio_pipe ); this->audio = NULL; // We should not be open now @@ -309,7 +418,7 @@ static int producer_get_audio( mlt_frame this, int16_t **buffer, mlt_audio_forma *samples = sample_calculator( fps, *frequency, target - skip ); if ( fread( *buffer, *samples * *channels * 2, 1, producer->audio ) != 1 ) { - pclose( producer->audio ); + rwpipe_close( producer->audio_pipe ); producer->audio = NULL; producer->end_of_audio = 1; } @@ -423,7 +532,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i // Inform caller that end of clip is reached this->end_of_video = !video_loop; - pclose( this->video ); + rwpipe_close( this->video_pipe ); this->video = NULL; } @@ -472,9 +581,9 @@ static void producer_close( mlt_producer parent ) { producer_ffmpeg this = parent->child; if ( this->video ) - pclose( this->video ); + rwpipe_close( this->video_pipe ); if ( this->audio ) - pclose( this->audio ); + rwpipe_close( this->audio_pipe ); parent->close = NULL; mlt_producer_close( parent ); free( this->buffer ); diff --git a/src/modules/ffmpeg/video.sh b/src/modules/ffmpeg/video.sh index 481718cc..f8689fe7 100755 --- a/src/modules/ffmpeg/video.sh +++ b/src/modules/ffmpeg/video.sh @@ -1,5 +1,7 @@ #!/bin/bash +trap exit + video_type="$1" video_file="$2" video_size="$3" diff --git a/src/modules/gtk2/producer_pango.c b/src/modules/gtk2/producer_pango.c index 5877d524..c1bf1d3f 100644 --- a/src/modules/gtk2/producer_pango.c +++ b/src/modules/gtk2/producer_pango.c @@ -84,6 +84,8 @@ mlt_producer producer_pango_init( const char *markup ) mlt_properties_set_int( properties, "y", 0 ); mlt_properties_set_double( properties, "mix", 1.0 ); + mlt_properties_set( properties, "resource", "pango" ); + return producer; } free( this ); diff --git a/src/modules/gtk2/producer_pixbuf.c b/src/modules/gtk2/producer_pixbuf.c index 7114979a..f1f1f45f 100644 --- a/src/modules/gtk2/producer_pixbuf.c +++ b/src/modules/gtk2/producer_pixbuf.c @@ -49,10 +49,10 @@ static int filter_files( const struct dirent *de ) } -mlt_producer producer_pixbuf_init( const char *filename ) +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 ) + if ( filename != NULL && this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) { mlt_producer producer = &this->parent; @@ -63,6 +63,7 @@ mlt_producer producer_pixbuf_init( const char *filename ) mlt_properties properties = mlt_producer_properties( &this->parent ); // Set the default properties + mlt_properties_set( properties, "resource", filename ); mlt_properties_set_int( properties, "video_standard", mlt_video_standard_pal ); mlt_properties_set_double( properties, "ttl", 5 ); diff --git a/src/modules/gtk2/producer_pixbuf.h b/src/modules/gtk2/producer_pixbuf.h index 346a6544..74b8f7a3 100644 --- a/src/modules/gtk2/producer_pixbuf.h +++ b/src/modules/gtk2/producer_pixbuf.h @@ -40,6 +40,6 @@ struct producer_pixbuf_s uint8_t *alpha; }; -extern mlt_producer producer_pixbuf_init( const char *filename ); +extern mlt_producer producer_pixbuf_init( char *filename ); #endif diff --git a/src/modules/sdl/consumer_sdl.c b/src/modules/sdl/consumer_sdl.c index 714fc66f..85852d57 100644 --- a/src/modules/sdl/consumer_sdl.c +++ b/src/modules/sdl/consumer_sdl.c @@ -232,13 +232,10 @@ static int consumer_play_audio( consumer_sdl this, mlt_frame frame, int init_aud fprintf( stderr, "SDL failed to open audio: %s\n", SDL_GetError() ); init_audio = 2; } - else + else if ( got.size != 0 ) { - if ( got.size != 0 ) - { - SDL_PauseAudio( 0 ); - init_audio = 0; - } + SDL_PauseAudio( 0 ); + init_audio = 0; } } diff --git a/src/valerie/Makefile b/src/valerie/Makefile index 908c432f..6afae187 100644 --- a/src/valerie/Makefile +++ b/src/valerie/Makefile @@ -1,5 +1,5 @@ -AR = ar +TARGET = libvalerie.so OBJS = valerie.o \ valerie_notifier.o \ @@ -17,11 +17,10 @@ CFLAGS=-Wall -g -D_FILE_OFFSET_BITS=64 -pthread LDFLAGS=-ldv -lpthread -all: libvalerie.a +all: $(TARGET) -libvalerie.a: $(OBJS) - $(AR) rvu $@ $(OBJS) - ranlib $@ +$(TARGET): $(OBJS) + $(CC) -shared -o $@ $(OBJS) $(LDFLAGS) depend: $(SRCS) $(CC) -MM $(CFLAGS) $^ 1>.depend @@ -30,7 +29,7 @@ dist-clean: clean rm -f .depend clean: - rm -f $(OBJS) libvalerie.a + rm -f $(OBJS) $(TARGET) ifneq ($(wildcard .depend),) include .depend diff --git a/src/valerie/valerie.c b/src/valerie/valerie.c index 2e1f2895..4157284b 100644 --- a/src/valerie/valerie.c +++ b/src/valerie/valerie.c @@ -311,9 +311,9 @@ valerie_error_code valerie_unit_play( valerie this, int unit ) /** Play the unit at specified speed. */ -valerie_error_code valerie_unit_play_at_speed( valerie this, int unit, double speed ) +valerie_error_code valerie_unit_play_at_speed( valerie this, int unit, int speed ) { - return valerie_execute( this, 10240, "PLAY U%d %e", unit, speed ); + return valerie_execute( this, 10240, "PLAY U%d %d", unit, speed ); } /** Stop playback on the specified unit. diff --git a/src/valerie/valerie.h b/src/valerie/valerie.h index 91c09878..fc3b059b 100644 --- a/src/valerie/valerie.h +++ b/src/valerie/valerie.h @@ -100,7 +100,7 @@ extern valerie_error_code valerie_unit_clip_remove( valerie, int, valerie_clip_o extern valerie_error_code valerie_unit_remove_current_clip( valerie, int ); extern valerie_error_code valerie_unit_clip_insert( valerie, int, valerie_clip_offset, int, char *, double, double ); extern valerie_error_code valerie_unit_play( valerie, int ); -extern valerie_error_code valerie_unit_play_at_speed( valerie, int, double ); +extern valerie_error_code valerie_unit_play_at_speed( valerie, int, int ); extern valerie_error_code valerie_unit_stop( valerie, int ); extern valerie_error_code valerie_unit_pause( valerie, int ); extern valerie_error_code valerie_unit_rewind( valerie, int ); @@ -227,7 +227,7 @@ typedef struct { int unit; int node; - char guid[ 17 ]; + char guid[ 512 ]; int online; } *valerie_unit_entry, valerie_unit_entry_t;