]> git.sesse.net Git - mlt/commitdiff
miracle part 1
authorlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Wed, 7 Jan 2004 14:58:21 +0000 (14:58 +0000)
committerlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Wed, 7 Jan 2004 14:58:21 +0000 (14:58 +0000)
git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@39 d19143bc-622f-0410-bfdd-b5b2a6649095

86 files changed:
Makefile
docs/services.txt
mlt/Makefile
mlt/docs/services.txt
mlt/setenv
mlt/src/framework/Makefile
mlt/src/framework/mlt_frame.c
mlt/src/framework/mlt_playlist.c
mlt/src/framework/mlt_playlist.h
mlt/src/framework/mlt_producer.c
mlt/src/humperdink/Makefile [new file with mode: 0644]
mlt/src/humperdink/client.c [new file with mode: 0644]
mlt/src/humperdink/client.h [new file with mode: 0644]
mlt/src/humperdink/io.c [new file with mode: 0644]
mlt/src/humperdink/io.h [new file with mode: 0644]
mlt/src/humperdink/remote.c [new file with mode: 0644]
mlt/src/inigo/inigo.c
mlt/src/miracle/Makefile [new file with mode: 0644]
mlt/src/miracle/miracle.c
mlt/src/miracle/miracle_commands.c
mlt/src/miracle/miracle_commands.h
mlt/src/miracle/miracle_connection.c
mlt/src/miracle/miracle_connection.h
mlt/src/miracle/miracle_local.c
mlt/src/miracle/miracle_local.h
mlt/src/miracle/miracle_log.c
mlt/src/miracle/miracle_log.h
mlt/src/miracle/miracle_server.c
mlt/src/miracle/miracle_server.h
mlt/src/miracle/miracle_unit.c
mlt/src/miracle/miracle_unit.h
mlt/src/miracle/miracle_unit_commands.c
mlt/src/miracle/miracle_unit_commands.h
mlt/src/modules/core/producer_ppm.c
mlt/src/modules/dv/producer_libdv.c
mlt/src/modules/ffmpeg/audio.sh
mlt/src/modules/ffmpeg/producer_ffmpeg.c
mlt/src/modules/ffmpeg/video.sh
mlt/src/modules/gtk2/producer_pango.c
mlt/src/modules/gtk2/producer_pixbuf.c
mlt/src/modules/gtk2/producer_pixbuf.h
mlt/src/modules/sdl/consumer_sdl.c
mlt/src/valerie/Makefile
mlt/src/valerie/valerie.c
mlt/src/valerie/valerie.h
setenv
src/framework/Makefile
src/framework/mlt_frame.c
src/framework/mlt_playlist.c
src/framework/mlt_playlist.h
src/framework/mlt_producer.c
src/humperdink/Makefile [new file with mode: 0644]
src/humperdink/client.c [new file with mode: 0644]
src/humperdink/client.h [new file with mode: 0644]
src/humperdink/io.c [new file with mode: 0644]
src/humperdink/io.h [new file with mode: 0644]
src/humperdink/remote.c [new file with mode: 0644]
src/inigo/inigo.c
src/miracle/Makefile [new file with mode: 0644]
src/miracle/miracle.c
src/miracle/miracle_commands.c
src/miracle/miracle_commands.h
src/miracle/miracle_connection.c
src/miracle/miracle_connection.h
src/miracle/miracle_local.c
src/miracle/miracle_local.h
src/miracle/miracle_log.c
src/miracle/miracle_log.h
src/miracle/miracle_server.c
src/miracle/miracle_server.h
src/miracle/miracle_unit.c
src/miracle/miracle_unit.h
src/miracle/miracle_unit_commands.c
src/miracle/miracle_unit_commands.h
src/modules/core/producer_ppm.c
src/modules/dv/producer_libdv.c
src/modules/ffmpeg/audio.sh
src/modules/ffmpeg/producer_ffmpeg.c
src/modules/ffmpeg/video.sh
src/modules/gtk2/producer_pango.c
src/modules/gtk2/producer_pixbuf.c
src/modules/gtk2/producer_pixbuf.h
src/modules/sdl/consumer_sdl.c
src/valerie/Makefile
src/valerie/valerie.c
src/valerie/valerie.h

index ef2180983bb68ddfeac7c414c28fd1d162d0ba8e..fe7ee8e41ae22627adc0e9f70df65a0e4b153826 100644 (file)
--- 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)'; \
index d56ef2c6e535445abc9104d996488334b08b7b34..8118894f98d71e932cd17f98ca892d09e772857f 100644 (file)
@@ -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
index ef2180983bb68ddfeac7c414c28fd1d162d0ba8e..fe7ee8e41ae22627adc0e9f70df65a0e4b153826 100644 (file)
@@ -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)'; \
index d56ef2c6e535445abc9104d996488334b08b7b34..8118894f98d71e932cd17f98ca892d09e772857f 100644 (file)
@@ -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
index 01363eb6a2c3683fef1c477cc5783e2fa30ed504..9d665ed09103968986162cc4a5724556a5ab8136 100644 (file)
@@ -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
 
index d01ee34749f54d0f98e649b32e3279f32fe1a044..6d804016796e32b2236811a4aea6125612edae11 100644 (file)
@@ -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
index 16d51f89adc78e9c96d8c4efc90cbb1c350316a1..dd179837a149001ed6ac8e25790efce5972083d1 100644 (file)
@@ -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 ++;
                }
index 7a2ad658a01e5323faf42087d986a3148ecc555b..d11f9562ddbab8a55443ece34d4ebddeccb32a9c 100644 (file)
@@ -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 ) );
 
index c6013860e73f32944614e60dfe42b3506ac59cca..3e30ba6be8425966bcb7560522d823326c17c4b0 100644 (file)
 
 #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
index 87c2f0899faf3e4bc557fab4552aa2c4ae69267c..751e19a9e3066309fd03efd267743c15325a6e97 100644 (file)
@@ -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 (file)
index 0000000..53f2f96
--- /dev/null
@@ -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 (file)
index 0000000..1f0ff3d
--- /dev/null
@@ -0,0 +1,1026 @@
+/*
+ * client.c -- dv1394d client demo
+ * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* 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 (file)
index 0000000..9490360
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * client.h -- dv1394d client demo
+ * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * 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 <stdio.h>
+#include <pthread.h>
+#include <valerie/valerie.h>
+
+/** 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 (file)
index 0000000..b9e92f2
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * io.c -- dv1394d client demo input/output
+ * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <termios.h>
+#include <unistd.h>
+
+/* 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 (file)
index 0000000..6c4b609
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * io.h -- dv1394d client demo input/output
+ * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * 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 (file)
index 0000000..18ac5a5
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * remote.c -- Remote dv1394d client demo
+ * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * 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 <stdio.h>
+
+/* dv1394d header files */
+#include <valerie/valerie_remote.h>
+
+/* 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;
+}
index bc087ba30d5b5e62841b07351f613023a0601ab2..8b84043869aacf828a0dd9528659419eeefd1679 100644 (file)
@@ -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 (file)
index 0000000..6568199
--- /dev/null
@@ -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
index 47a645ab958048aa3a6440996fc3064b3609be55..8d1294d033055210b02679097b27f5115192b470 100644 (file)
@@ -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:
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 /* System header files */
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <time.h>
 
+#include <framework/mlt.h>
+
 /* 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 )
index 8a492d1ae9e20b1845ed1c391a9abffeadde1970..4a23e439c2c6a7599f66e85efc62df4906667b03 100644 (file)
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <dirent.h>
 #include <pthread.h>
 
-#include "dvunit.h"
-#include "global_commands.h"
-#include "raw1394util.h"
-#include <libavc1394/rom1394.h>
-#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] );
-               }
-       }
-}
-
 
index 6c60d7dab426d7d23b2ab5cb4c72e49b39502715..9d79683c04b0d05ac3e9fc737f274f34c07ecd04 100644 (file)
 #ifndef _GLOBAL_COMMANDS_H_
 #define _GLOBAL_COMMANDS_H_
 
-#include <dv1394status.h>
-#include "dvunit.h"
-#include "dvconnection.h"
+#include <valerie/valerie_status.h>
+#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
 }
index 6c65e3517b07bb2504dcfbe67f82c0228eb19df9..563a769a0a5be6e26876113514b9ff1f40f0c85a 100644 (file)
@@ -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 <charles.yates@pandora.be>
  *
 #include <sys/socket.h> 
 #include <arpa/inet.h>
 
+#include <valerie/valerie_socket.h>
+
 /* 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 );
 
index 1c5d00b0c1ea11039afa06ca1ea9fa4903605170..ce19115f79962d66e81bedbad1f59057416655ad 100644 (file)
@@ -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 <charles.yates@pandora.be>
  *
@@ -25,8 +25,8 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 
-#include <dvparser.h>
-#include <dvtokeniser.h>
+#include <valerie/valerie_parser.h>
+#include <valerie/valerie_tokeniser.h>
 
 #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;
index fce4ab2214f1f07f58b5d49198b99781669762b4..ac6c7578e1fde98786ec0a8050d08371fe9012f1 100644 (file)
@@ -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 <charles.yates@pandora.be>
  *
 #include <string.h>
 #include <signal.h>
 
-/* Library header files */
-#include <dvutil.h>
+/* Valerie header files */
+#include <valerie/valerie_util.h>
+
+/* MLT header files. */
+#include <framework/mlt_factory.h>
 
 /* Application header files */
-#include <dvclipfactory.h>
-#include <dvframepool.h>
-#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 <dan@dennedy.org>\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( );
 }
index fbbe44471499d4513cd3af35c1facbfa64b830f6..6baf0350bc838bf4016965b93719b6224a980f44 100644 (file)
@@ -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 <charles.yates@pandora.be>
  *
  * 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 <dvparser.h>
+#include <valerie/valerie_parser.h>
 
 #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
 }
index cdb5d82f79359a61de313ea2af583311283c8e47..adfc54672f8203c17ba3160721dd622c10080aa4 100644 (file)
@@ -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 <dan@dennedy.org>
  *
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #include <stdarg.h>
 #include <syslog.h>
 #include <stdio.h>
 
-#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 );
index 04505e97c9d1bdb057eae4aecd28a09a3b225a94..3788ee52b1407bce61e07030821487c50be0626a 100644 (file)
@@ -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 <dan@dennedy.org>
  *
@@ -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
 }
index d4f886b9b2cd65d06ed95276b928e3c3527cf098..3c82c3387af4f49bf473a26f59f6a8af54ec5c37 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * dvserver.c -- DV Server
+ * miracle_server.c -- DV Server
  * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
  * Author: Charles Yates <charles.yates@pandora.be>
  *
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 /* System header files */
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <string.h>
 #include <netinet/in.h>
-#include "log.h"
 #include <netdb.h>
 #include <errno.h>
 #include <arpa/inet.h>
 
 /* Application header files */
-#include "dvserver.h"
-#include "dvconnection.h"
-#include "dvlocal.h"
-#include "log.h"
-#include <dvremote.h>
-#include <dvtokeniser.h>
+#include "miracle_server.h"
+#include "miracle_connection.h"
+#include "miracle_local.h"
+#include "miracle_log.h"
+#include <valerie/valerie_remote.h>
+#include <valerie/valerie_tokeniser.h>
+
+#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 );
        }
 }
index 96b22cee828f394159a288b4b55fcd0d56bf0ab1..95dfb5241c35ec1df745f8da569de40aeb8b6676 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * dvserver.h -- DV Server
+ * miracle_server.h -- DV Server
  * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
  * Author: Charles Yates <charles.yates@pandora.be>
  *
  * 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 <pthread.h>
 
 /* Application header files */
-#include <dvparser.h>
+#include <valerie/valerie_parser.h>
 
 #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
 }
index bc8adcfb13b26d4e72c1d76e4aa5817eff1b72dd..31c01cf7cdb869a7be8a787a3caf5f2e0978e217 100644 (file)
@@ -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 <dan@dennedy.org>
  *
 #include <errno.h>
 #include <signal.h>
 
-#include <libdv/dv1394.h>
-#include <libraw1394/raw1394.h>
-#include <libavc1394/avc1394_vcr.h>
 #include <sys/mman.h>
 
-#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 <framework/mlt.h>
 
 /* 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 );
-}
index 54338182babc10dbe8856186eeb4aafe15f6402e..fabfe5a84915dd9165b298ee484cc5ac3d744755 100644 (file)
 #define _DV_UNIT_H_
 
 #include <pthread.h>
-#include <libraw1394/raw1394.h>
 
-#include <dv1394notifier.h>
-#include <dv1394status.h>
-#include <dvpump.h>
-#include <dvplayer.h>
-#include <dvinput.h>
-#include <dverror.h>
+#include <framework/mlt_properties.h>
+#include <valerie/valerie.h>
 
 #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
index b12f2c72bb167eff4717ca9d8a0c7c0b7ab6bf6f..a630422bb95ab0f052d175b0911abd54d3e7b816 100644 (file)
 #include <unistd.h>
 #include <string.h>
 #include <stdlib.h>
+#include <stdio.h>
 
-#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;
 }
index a7163bdcc1ad4fa6e77d9bafa976ee7e95e6e17c..575ff1beec00c1a4929bc78655be8c944a4a9a7a 100644 (file)
 #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
 }
index 3d3f5839d847fceeccedc3c0406a0e7f71df4ccd..b508654bc09af3b29979562020bf87b51704c684 100644 (file)
@@ -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;
        }
index 05218cf3fe6d29445ff0af57bbac969e48070116..c2921e3de955c792ae4d12cfdd93db3563f27ab7 100644 (file)
@@ -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;
index 3c7475a2abcebe7c96e318d9458c142779fa506b..2d6aeda3778ee252ca71cccb385a68c9162aa8da 100755 (executable)
@@ -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
 
index 8777fb1173e8e1a69ff7209e225ba0a26f50ed6a..2af9de37aa6ef844daf065bd5a56a26adec184f6 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
 
 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 );
index 481718cc83ed664f3220d4f007eacc9143b0b7f1..f8689fe75ef908feb6d4587081a105435b51617a 100755 (executable)
@@ -1,5 +1,7 @@
 #!/bin/bash
 
+trap exit
+
 video_type="$1"
 video_file="$2"
 video_size="$3"
index 5877d52402da1fa0a962329b237697e269317e76..c1bf1d3f467ac4f8d42e1f5e3597731cdde9da8f 100644 (file)
@@ -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 );
index 7114979ae3538a7633a2d1aa03bf8776e7f60e10..f1f1f45fe10d38cfce0342d7fe6e6a249e535acf 100644 (file)
@@ -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 );
                
index 346a65441b31142445767c5059632d75f2cf0cd6..74b8f7a3fdf23eb6472c14f0378a4cdaa399924e 100644 (file)
@@ -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
index 714fc66f5a6351512192b8b14b781d74601415ac..85852d5703bbcff886966b1d060a475994964b85 100644 (file)
@@ -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;
                }
        }
 
index 908c432f8f7a763afc5cc638340d3f419ca4e39b..6afae18766a263acfcbc238f8bdf11571cb44a69 100644 (file)
@@ -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
index 2e1f28951b6bb686de6ca46f7cff60b48e9df600..4157284b8006ab45645c1158075caf04d27cab6b 100644 (file)
@@ -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.
index 91c098785fab33010b1e7db4f57f1bd645c1ecc7..fc3b059bc60caaa5bdb18cb7e48226bfbef8440e 100644 (file)
@@ -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 01363eb6a2c3683fef1c477cc5783e2fa30ed504..9d665ed09103968986162cc4a5724556a5ab8136 100644 (file)
--- 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
 
index d01ee34749f54d0f98e649b32e3279f32fe1a044..6d804016796e32b2236811a4aea6125612edae11 100644 (file)
@@ -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
index 16d51f89adc78e9c96d8c4efc90cbb1c350316a1..dd179837a149001ed6ac8e25790efce5972083d1 100644 (file)
@@ -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 ++;
                }
index 7a2ad658a01e5323faf42087d986a3148ecc555b..d11f9562ddbab8a55443ece34d4ebddeccb32a9c 100644 (file)
@@ -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 ) );
 
index c6013860e73f32944614e60dfe42b3506ac59cca..3e30ba6be8425966bcb7560522d823326c17c4b0 100644 (file)
 
 #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
index 87c2f0899faf3e4bc557fab4552aa2c4ae69267c..751e19a9e3066309fd03efd267743c15325a6e97 100644 (file)
@@ -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 (file)
index 0000000..53f2f96
--- /dev/null
@@ -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 (file)
index 0000000..1f0ff3d
--- /dev/null
@@ -0,0 +1,1026 @@
+/*
+ * client.c -- dv1394d client demo
+ * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* 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 (file)
index 0000000..9490360
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * client.h -- dv1394d client demo
+ * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * 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 <stdio.h>
+#include <pthread.h>
+#include <valerie/valerie.h>
+
+/** 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 (file)
index 0000000..b9e92f2
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * io.c -- dv1394d client demo input/output
+ * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <termios.h>
+#include <unistd.h>
+
+/* 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 (file)
index 0000000..6c4b609
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * io.h -- dv1394d client demo input/output
+ * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * 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 (file)
index 0000000..18ac5a5
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * remote.c -- Remote dv1394d client demo
+ * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * 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 <stdio.h>
+
+/* dv1394d header files */
+#include <valerie/valerie_remote.h>
+
+/* 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;
+}
index bc087ba30d5b5e62841b07351f613023a0601ab2..8b84043869aacf828a0dd9528659419eeefd1679 100644 (file)
@@ -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 (file)
index 0000000..6568199
--- /dev/null
@@ -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
index 47a645ab958048aa3a6440996fc3064b3609be55..8d1294d033055210b02679097b27f5115192b470 100644 (file)
@@ -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:
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 /* System header files */
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <time.h>
 
+#include <framework/mlt.h>
+
 /* 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 )
index 8a492d1ae9e20b1845ed1c391a9abffeadde1970..4a23e439c2c6a7599f66e85efc62df4906667b03 100644 (file)
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <dirent.h>
 #include <pthread.h>
 
-#include "dvunit.h"
-#include "global_commands.h"
-#include "raw1394util.h"
-#include <libavc1394/rom1394.h>
-#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] );
-               }
-       }
-}
-
 
index 6c60d7dab426d7d23b2ab5cb4c72e49b39502715..9d79683c04b0d05ac3e9fc737f274f34c07ecd04 100644 (file)
 #ifndef _GLOBAL_COMMANDS_H_
 #define _GLOBAL_COMMANDS_H_
 
-#include <dv1394status.h>
-#include "dvunit.h"
-#include "dvconnection.h"
+#include <valerie/valerie_status.h>
+#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
 }
index 6c65e3517b07bb2504dcfbe67f82c0228eb19df9..563a769a0a5be6e26876113514b9ff1f40f0c85a 100644 (file)
@@ -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 <charles.yates@pandora.be>
  *
 #include <sys/socket.h> 
 #include <arpa/inet.h>
 
+#include <valerie/valerie_socket.h>
+
 /* 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 );
 
index 1c5d00b0c1ea11039afa06ca1ea9fa4903605170..ce19115f79962d66e81bedbad1f59057416655ad 100644 (file)
@@ -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 <charles.yates@pandora.be>
  *
@@ -25,8 +25,8 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 
-#include <dvparser.h>
-#include <dvtokeniser.h>
+#include <valerie/valerie_parser.h>
+#include <valerie/valerie_tokeniser.h>
 
 #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;
index fce4ab2214f1f07f58b5d49198b99781669762b4..ac6c7578e1fde98786ec0a8050d08371fe9012f1 100644 (file)
@@ -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 <charles.yates@pandora.be>
  *
 #include <string.h>
 #include <signal.h>
 
-/* Library header files */
-#include <dvutil.h>
+/* Valerie header files */
+#include <valerie/valerie_util.h>
+
+/* MLT header files. */
+#include <framework/mlt_factory.h>
 
 /* Application header files */
-#include <dvclipfactory.h>
-#include <dvframepool.h>
-#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 <dan@dennedy.org>\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( );
 }
index fbbe44471499d4513cd3af35c1facbfa64b830f6..6baf0350bc838bf4016965b93719b6224a980f44 100644 (file)
@@ -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 <charles.yates@pandora.be>
  *
  * 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 <dvparser.h>
+#include <valerie/valerie_parser.h>
 
 #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
 }
index cdb5d82f79359a61de313ea2af583311283c8e47..adfc54672f8203c17ba3160721dd622c10080aa4 100644 (file)
@@ -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 <dan@dennedy.org>
  *
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #include <stdarg.h>
 #include <syslog.h>
 #include <stdio.h>
 
-#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 );
index 04505e97c9d1bdb057eae4aecd28a09a3b225a94..3788ee52b1407bce61e07030821487c50be0626a 100644 (file)
@@ -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 <dan@dennedy.org>
  *
@@ -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
 }
index d4f886b9b2cd65d06ed95276b928e3c3527cf098..3c82c3387af4f49bf473a26f59f6a8af54ec5c37 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * dvserver.c -- DV Server
+ * miracle_server.c -- DV Server
  * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
  * Author: Charles Yates <charles.yates@pandora.be>
  *
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 /* System header files */
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <string.h>
 #include <netinet/in.h>
-#include "log.h"
 #include <netdb.h>
 #include <errno.h>
 #include <arpa/inet.h>
 
 /* Application header files */
-#include "dvserver.h"
-#include "dvconnection.h"
-#include "dvlocal.h"
-#include "log.h"
-#include <dvremote.h>
-#include <dvtokeniser.h>
+#include "miracle_server.h"
+#include "miracle_connection.h"
+#include "miracle_local.h"
+#include "miracle_log.h"
+#include <valerie/valerie_remote.h>
+#include <valerie/valerie_tokeniser.h>
+
+#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 );
        }
 }
index 96b22cee828f394159a288b4b55fcd0d56bf0ab1..95dfb5241c35ec1df745f8da569de40aeb8b6676 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * dvserver.h -- DV Server
+ * miracle_server.h -- DV Server
  * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
  * Author: Charles Yates <charles.yates@pandora.be>
  *
  * 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 <pthread.h>
 
 /* Application header files */
-#include <dvparser.h>
+#include <valerie/valerie_parser.h>
 
 #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
 }
index bc8adcfb13b26d4e72c1d76e4aa5817eff1b72dd..31c01cf7cdb869a7be8a787a3caf5f2e0978e217 100644 (file)
@@ -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 <dan@dennedy.org>
  *
 #include <errno.h>
 #include <signal.h>
 
-#include <libdv/dv1394.h>
-#include <libraw1394/raw1394.h>
-#include <libavc1394/avc1394_vcr.h>
 #include <sys/mman.h>
 
-#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 <framework/mlt.h>
 
 /* 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 );
-}
index 54338182babc10dbe8856186eeb4aafe15f6402e..fabfe5a84915dd9165b298ee484cc5ac3d744755 100644 (file)
 #define _DV_UNIT_H_
 
 #include <pthread.h>
-#include <libraw1394/raw1394.h>
 
-#include <dv1394notifier.h>
-#include <dv1394status.h>
-#include <dvpump.h>
-#include <dvplayer.h>
-#include <dvinput.h>
-#include <dverror.h>
+#include <framework/mlt_properties.h>
+#include <valerie/valerie.h>
 
 #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
index b12f2c72bb167eff4717ca9d8a0c7c0b7ab6bf6f..a630422bb95ab0f052d175b0911abd54d3e7b816 100644 (file)
 #include <unistd.h>
 #include <string.h>
 #include <stdlib.h>
+#include <stdio.h>
 
-#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;
 }
index a7163bdcc1ad4fa6e77d9bafa976ee7e95e6e17c..575ff1beec00c1a4929bc78655be8c944a4a9a7a 100644 (file)
 #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
 }
index 3d3f5839d847fceeccedc3c0406a0e7f71df4ccd..b508654bc09af3b29979562020bf87b51704c684 100644 (file)
@@ -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;
        }
index 05218cf3fe6d29445ff0af57bbac969e48070116..c2921e3de955c792ae4d12cfdd93db3563f27ab7 100644 (file)
@@ -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;
index 3c7475a2abcebe7c96e318d9458c142779fa506b..2d6aeda3778ee252ca71cccb385a68c9162aa8da 100755 (executable)
@@ -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
 
index 8777fb1173e8e1a69ff7209e225ba0a26f50ed6a..2af9de37aa6ef844daf065bd5a56a26adec184f6 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
 
 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 );
index 481718cc83ed664f3220d4f007eacc9143b0b7f1..f8689fe75ef908feb6d4587081a105435b51617a 100755 (executable)
@@ -1,5 +1,7 @@
 #!/bin/bash
 
+trap exit
+
 video_type="$1"
 video_file="$2"
 video_size="$3"
index 5877d52402da1fa0a962329b237697e269317e76..c1bf1d3f467ac4f8d42e1f5e3597731cdde9da8f 100644 (file)
@@ -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 );
index 7114979ae3538a7633a2d1aa03bf8776e7f60e10..f1f1f45fe10d38cfce0342d7fe6e6a249e535acf 100644 (file)
@@ -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 );
                
index 346a65441b31142445767c5059632d75f2cf0cd6..74b8f7a3fdf23eb6472c14f0378a4cdaa399924e 100644 (file)
@@ -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
index 714fc66f5a6351512192b8b14b781d74601415ac..85852d5703bbcff886966b1d060a475994964b85 100644 (file)
@@ -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;
                }
        }
 
index 908c432f8f7a763afc5cc638340d3f419ca4e39b..6afae18766a263acfcbc238f8bdf11571cb44a69 100644 (file)
@@ -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
index 2e1f28951b6bb686de6ca46f7cff60b48e9df600..4157284b8006ab45645c1158075caf04d27cab6b 100644 (file)
@@ -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.
index 91c098785fab33010b1e7db4f57f1bd645c1ecc7..fc3b059bc60caaa5bdb18cb7e48226bfbef8440e 100644 (file)
@@ -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;