]> git.sesse.net Git - mlt/commitdiff
vorbis producer added, clean up on clip handling in multitrack
authorlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Tue, 27 Jan 2004 15:36:31 +0000 (15:36 +0000)
committerlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Tue, 27 Jan 2004 15:36:31 +0000 (15:36 +0000)
git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@97 d19143bc-622f-0410-bfdd-b5b2a6649095

12 files changed:
README
docs/services.txt
src/framework/mlt_multitrack.c
src/miracle/miracle_unit.c
src/modules/Makefile
src/modules/avformat/producer_avformat.c
src/modules/inigo/producer_inigo.c
src/modules/vorbis/Makefile [new file with mode: 0644]
src/modules/vorbis/configure [new file with mode: 0755]
src/modules/vorbis/factory.c [new file with mode: 0644]
src/modules/vorbis/producer_vorbis.c [new file with mode: 0644]
src/modules/vorbis/producer_vorbis.h [new file with mode: 0644]

diff --git a/README b/README
index 8e1631301327307a5ca88c6d2e8397c7c9a4e4ec..4fc7dad71161bbcf3d4936230353d91d7efa7351 100644 (file)
--- a/README
+++ b/README
@@ -19,6 +19,7 @@ Directories
                        + dv                    - libdv dependent services
                        + ffmpeg                - ffmpeg dependent services
                        + avformat              - libavformat dependent services
+                       + vorbis                - vorbis dependenent services
                        + sdl                   - SDL dependent services
                        + resample              - libresample dependent services
                        + gtk2                  - pango and pixbuf dependent services
index 390d05d6d8f1e0fa8f3b519215faebb776ef0c94..8cbed80ff102fd468353060416936c4be7991356 100644 (file)
@@ -313,6 +313,34 @@ Producers
 
                        Since it uses pipes, it is not compatible with bluefish.
 
+       vorbis
+
+               Description
+
+                       OGG Vorbis file reader.
+
+               Constructor Argument
+
+                       'file' - file to use (only .ogg supported at the moment)
+
+               Initialisation Properties
+
+                       int in - in point
+                       int out - out point
+
+               Read Only Properties
+
+                       double fps - this is fixed at 25 for PAL currently
+
+               Dependencies
+
+                       libvorbisfile
+
+               Known Bugs
+
+                       Fixed frame size (PAL audio chunks).
+                       Doesn't cover ogg files with multiple, differing sections.
+
 
 Filters
 -------
index 2faaf69ae5dfe698aaed07adcb2861ff94ffbe3c..ef7a1bed65732feaa505924ba47978dc32fc73fb 100644 (file)
@@ -210,6 +210,21 @@ mlt_producer mlt_multitrack_track( mlt_multitrack this, int track )
        return producer;
 }
 
+static int position_compare( const void *p1, const void *p2 )
+{
+       return *( int64_t * )p1 - *( int64_t * )p2;
+}
+
+static int add_unique( mlt_position *array, int size, mlt_position position )
+{
+       int i = 0;
+       for ( i = 0; i < size; i ++ )
+               if ( array[ i ] == position )
+                       break;
+       if ( i == size )
+               array[ size ++ ] = position;
+       return size;
+}
 
 /** Determine the clip point.
 
@@ -233,11 +248,12 @@ mlt_producer mlt_multitrack_track( mlt_multitrack this, int track )
 
 mlt_position mlt_multitrack_clip( mlt_multitrack this, mlt_whence whence, int index )
 {
-       int first = 1;
        mlt_position position = 0;
        int i = 0;
+       int j = 0;
+       int64_t *map = malloc( 1000 * sizeof( mlt_position ) );
+       int count = 0;
 
-       // Loop through each of the tracks
        for ( i = 0; i < this->count; i ++ )
        {
                // Get the producer for this track
@@ -252,35 +268,59 @@ mlt_position mlt_multitrack_clip( mlt_multitrack this, mlt_whence whence, int in
                        // Determine if it's a playlist
                        mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL );
 
-                       // We only consider playlists
+                       // Special case consideration of playlists
                        if ( playlist != NULL )
                        {
-                               // Locate the smallest position
-                               if ( first )
-                               {
-                                       // First position found
-                                       position = mlt_playlist_clip( playlist, whence, index );
-       
-                                       // We're no longer first
-                                       first = 0;
-                               }
-                               else
-                               {
-                                       // Obtain the clip position in this playlist
-                                       //mlt_position position2 = mlt_playlist_clip( playlist, whence, index );
-
-                                       // If this position is prior to the first, then use it
-                                       //if ( position2 < position )
-                                               //position = position2;
-                               }
+                               for ( j = 0; j < mlt_playlist_count( playlist ); j ++ )
+                                       count = add_unique( map, count, mlt_playlist_clip( playlist, mlt_whence_relative_start, j ) );
+                               count = add_unique( map, count, mlt_producer_get_out( producer ) + 1 );
                        }
                        else
                        {
-                               fprintf( stderr, "track %d isn't a playlist\n", index );
+                               count = add_unique( map, count, 0 );
+                               count = add_unique( map, count, mlt_producer_get_out( producer ) + 1 );
                        }
                }
        }
 
+       // Now sort the map
+       qsort( map, count, sizeof( int64_t ), position_compare );
+
+       // Now locate the requested index
+       switch( whence )
+       {
+               case mlt_whence_relative_start:
+                       if ( index < count )
+                               position = map[ index ];
+                       else
+                               position = map[ count - 1 ];
+                       break;
+
+               case mlt_whence_relative_current:
+                       position = mlt_producer_position( mlt_multitrack_producer( this ) );
+                       for ( i = 0; i < count - 2; i ++ ) 
+                               if ( position >= map[ i ] && position < map[ i + 1 ] )
+                                       break;
+                       index += i;
+                       if ( index >= 0 && index < count )
+                               position = map[ index ];
+                       else if ( index < 0 )
+                               position = map[ 0 ];
+                       else
+                               position = map[ count - 1 ];
+                       break;
+
+               case mlt_whence_relative_end:
+                       if ( index < count )
+                               position = map[ count - index - 1 ];
+                       else
+                               position = map[ 0 ];
+                       break;
+       }
+
+       // Free the map
+       free( map );
+
        return position;
 }
 
index 2f7391792013f6cc945bbea990eab43cf8c91ccf..b194e7c225a341e286072cad5d64b8c032dd05e0 100644 (file)
@@ -146,6 +146,8 @@ static mlt_producer create_producer( miracle_unit unit, char *file )
                        char *args[ 2 ] = { file, NULL };
                        result = mlt_factory_producer( "inigo", args );
                }
+               else if ( strstr( file, ".westley" ) )
+                       result = mlt_factory_producer( "westley", file );
                else if ( strstr( file, ".mpg" ) )
                        result = mlt_factory_producer( "mcmpeg", file );
                else if ( strstr( file, ".mpeg" ) )
@@ -166,7 +168,9 @@ static mlt_producer create_producer( miracle_unit unit, char *file )
                        result = mlt_factory_producer( "pixbuf", file );
                else if ( strstr( file, ".txt" ) )
                        result = mlt_factory_producer( "pango", file );
-       
+               else if ( strstr( file, ".ogg" ) )
+                       result = mlt_factory_producer( "vorbis", file );
+
                // 2nd Line fallbacks
                if ( result == NULL && strstr( file, ".dv" ) )
                        result = mlt_factory_producer( "libdv", file );
@@ -177,6 +181,10 @@ static mlt_producer create_producer( miracle_unit unit, char *file )
                if ( result == NULL )
                        result = mlt_factory_producer( "avformat", file );
 
+               // 4th 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 );
        }
index 8a14a7fbec6097da965499f79f4b879f6742c601..4691b5e6d4ca35557240c24ad715b40b5a84d982 100644 (file)
@@ -1,4 +1,4 @@
-SUBDIRS = core gtk2 dv sdl mainconcept bluefish ffmpeg resample inigo avformat westley
+SUBDIRS = core gtk2 dv sdl mainconcept bluefish ffmpeg resample inigo avformat vorbis westley
 
 all clean depend install:
        list='$(SUBDIRS)'; \
index 943b8476d12f8722c04ad40d6c0c3159d34f1107..d19c165989eaea8775a9f6f45d6928f11acefe47 100644 (file)
@@ -92,7 +92,7 @@ mlt_producer producer_avformat_init( char *file )
 /** Find the default streams.
 */
 
-void find_default_streams( AVFormatContext *context, int *audio_index, int *video_index )
+static void find_default_streams( AVFormatContext *context, int *audio_index, int *video_index )
 {
        int i;
 
@@ -122,7 +122,7 @@ void find_default_streams( AVFormatContext *context, int *audio_index, int *vide
 /** Producer file destructor.
 */
 
-void producer_file_close( void *context )
+static void producer_file_close( void *context )
 {
        if ( context != NULL )
        {
@@ -140,7 +140,7 @@ void producer_file_close( void *context )
 /** Producer file destructor.
 */
 
-void producer_codec_close( void *codec )
+static void producer_codec_close( void *codec )
 {
        if ( codec != NULL )
        {
index ed20ea3b1a2e3d340e0a01ec21464110bde5aa45..313e8d59782e3e5ac4f89475d04fbde61908e22f 100644 (file)
@@ -48,7 +48,9 @@ static mlt_producer parse_inigo( char *file )
        if ( result != NULL )
        {
                mlt_properties properties = mlt_producer_properties( result );
+               fprintf( stderr, "resource = %s\n", mlt_properties_get( properties, "resource" ) );
                mlt_properties_set( properties, "resource", file );
+               fprintf( stderr, "resource = %s\n", mlt_properties_get( properties, "resource" ) );
        }
 
        while( count -- )
@@ -85,6 +87,8 @@ static mlt_producer create_producer( char *file )
                result = mlt_factory_producer( "pango", file );
        else if ( strstr( file, ".westley" ) )
                result = mlt_factory_producer( "westley", file );
+       else if ( strstr( file, ".ogg" ) )
+               result = mlt_factory_producer( "vorbis", file );
 
        // 2nd Line fallbacks
        if ( result == NULL && strstr( file, ".dv" ) )
@@ -96,6 +100,10 @@ static mlt_producer create_producer( char *file )
        if ( result == NULL )
                result = mlt_factory_producer( "avformat", file );
 
+       // 4th line fallbacks 
+       if ( result == NULL )
+               result = mlt_factory_producer( "ffmpeg", file );
+
        return result;
 }
 
diff --git a/src/modules/vorbis/Makefile b/src/modules/vorbis/Makefile
new file mode 100644 (file)
index 0000000..ac457c0
--- /dev/null
@@ -0,0 +1,29 @@
+
+TARGET = ../libmltvorbis.so
+
+OBJS = factory.o \
+          producer_vorbis.o
+
+CFLAGS = -I../../ -Wall -g -D_FILE_OFFSET_BITS=64
+
+LDFLAGS = -lvorbisfile
+
+SRCS := $(OBJS:.o=.c)
+
+all:   $(TARGET)
+
+$(TARGET): $(OBJS)
+               $(CC) -shared -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/modules/vorbis/configure b/src/modules/vorbis/configure
new file mode 100755 (executable)
index 0000000..77f3155
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+if [ "$help" != "1" ]
+then
+
+cat << EOF >> ../producers.dat
+vorbis         libmltvorbis.so
+EOF
+
+fi
+
diff --git a/src/modules/vorbis/factory.c b/src/modules/vorbis/factory.c
new file mode 100644 (file)
index 0000000..2ca9309
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * factory.c -- the factory method interfaces
+ * Copyright (C) 2003-2004 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.
+ */
+
+#include <string.h>
+
+#include "producer_vorbis.h"
+
+void *mlt_create_producer( char *id, void *arg )
+{
+       if ( !strcmp( id, "vorbis" ) )
+               return producer_vorbis_init( arg );
+       return NULL;
+}
+
+void *mlt_create_filter( char *id, void *arg )
+{
+       return NULL;
+}
+
+void *mlt_create_transition( char *id, void *arg )
+{
+       return NULL;
+}
+
+void *mlt_create_consumer( char *id, void *arg )
+{
+       return NULL;
+}
+
diff --git a/src/modules/vorbis/producer_vorbis.c b/src/modules/vorbis/producer_vorbis.c
new file mode 100644 (file)
index 0000000..9d3b849
--- /dev/null
@@ -0,0 +1,339 @@
+/*
+ * producer_vorbis.c -- vorbis producer
+ * Copyright (C) 2003-2004 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.
+ */
+
+// Local header files
+#include "producer_vorbis.h"
+
+// MLT Header files
+#include <framework/mlt_frame.h>
+
+// vorbis Header files
+#include <vorbis/codec.h>
+#include <vorbis/vorbisfile.h>
+
+// System header files
+#include <stdlib.h>
+#include <string.h>
+
+// Forward references.
+static int producer_open( mlt_producer this, char *file );
+static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index );
+
+/** Constructor for libvorbis.
+*/
+
+mlt_producer producer_vorbis_init( char *file )
+{
+       mlt_producer this = NULL;
+
+       // Check that we have a non-NULL argument
+       if ( file != NULL )
+       {
+               // Construct the producer
+               this = calloc( 1, sizeof( struct mlt_producer_s ) );
+
+               // Initialise it
+               if ( mlt_producer_init( this, NULL ) == 0 )
+               {
+                       // Get the properties
+                       mlt_properties properties = mlt_producer_properties( this );
+
+                       // Set the resource property (required for all producers)
+                       mlt_properties_set( properties, "resource", file );
+
+                       // Register our get_frame implementation
+                       this->get_frame = producer_get_frame;
+
+                       // Open the file
+                       if ( producer_open( this, file ) != 0 )
+                       {
+                               // Clean up
+                               mlt_producer_close( this );
+                               this = NULL;
+                       }
+               }
+       }
+
+       return this;
+}
+
+/** Destuctor for ogg files.
+*/
+
+static void producer_file_close( void *file )
+{
+       if ( file != NULL )
+       {
+               // Close the ogg vorbis structure
+               ov_clear( file );
+
+               // Free the memory
+               free( file );
+       }
+}
+
+/** Open the file.
+*/
+
+static int producer_open( mlt_producer this, char *file )
+{
+       // FILE pointer for file
+       FILE *input = fopen( file, "r" );
+
+       // Error code to return
+       int error = input == NULL;
+
+       // Continue if file is open
+       if ( error == 0 )
+       {
+               // OggVorbis file structure
+               OggVorbis_File *ov = calloc( 1, sizeof( OggVorbis_File ) );
+
+               // Attempt to open the stream
+               error = ov == NULL || ov_open( input, ov, NULL, 0 ) != 0;
+
+               // Assign to producer properties if successful
+               if ( error == 0 )
+               {
+                       // Get the properties
+                       mlt_properties properties = mlt_producer_properties( this );
+
+                       // Assign the ov structure
+                       mlt_properties_set_data( properties, "ogg_vorbis_file", ov, 0, producer_file_close, NULL );
+
+                       if ( ov_seekable( ov ) )
+                       {
+                               // Get the length of the file
+                       double length = ov_time_total( ov, -1 );
+
+                               // We will treat everything with the producer fps
+                               double fps = mlt_properties_get_double( properties, "fps" );
+
+                               // Set out and length of file
+                               mlt_properties_set_position( properties, "out", ( length * fps ) - 1 );
+                               mlt_properties_set_position( properties, "length", ( length * fps ) );
+                       }
+               }
+               else
+               {
+                       // Clean up
+                       free( ov );
+
+                       // Must close input file when open fails
+                       fclose( input );
+               }
+       }
+
+       return error;
+}
+
+/** Convert a frame position to a time code.
+*/
+
+static double producer_time_of_frame( mlt_producer this, mlt_position position )
+{
+       // Get the properties
+       mlt_properties properties = mlt_producer_properties( this );
+
+       // Obtain the fps
+       double fps = mlt_properties_get_double( properties, "fps" );
+
+       // Do the calc
+       return ( double )position / fps;
+}
+
+/** Get the audio from a frame.
+*/
+
+static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
+{
+       // Get the properties from the frame
+       mlt_properties frame_properties = mlt_frame_properties( frame );
+
+       // Obtain the frame number of this frame
+       mlt_position position = mlt_properties_get_position( frame_properties, "vorbis_position" );
+
+       // Get the producer 
+       mlt_producer this = mlt_properties_get_data( frame_properties, "vorbis_producer", NULL );
+
+       // Get the producer properties
+       mlt_properties properties = mlt_producer_properties( this );
+
+       // Get the ogg vorbis file
+       OggVorbis_File *ov = mlt_properties_get_data( properties, "ogg_vorbis_file", NULL );
+
+       // Obtain the expected frame numer
+       mlt_position expected = mlt_properties_get_position( properties, "audio_expected" );
+
+       // Get the fps for this producer
+       double fps = mlt_properties_get_double( properties, "fps" );
+
+       // Get the vorbis info
+       vorbis_info *vi = ov_info( ov, -1 );
+
+       // Obtain the audio buffer
+       int16_t *audio_buffer = mlt_properties_get_data( properties, "audio_buffer", NULL );
+
+       // Get amount of audio used
+       int audio_used =  mlt_properties_get_int( properties, "audio_used" );
+
+       // Number of frames to ignore (for ffwd)
+       int ignore = 0;
+
+       // Flag for paused (silence) 
+       int paused = 0;
+
+       // Check for audio buffer and create if necessary
+       if ( audio_buffer == NULL )
+       {
+               // Allocate the audio buffer
+               audio_buffer = malloc( 131072 * sizeof( int16_t ) );
+
+               // And store it on properties for reuse
+               mlt_properties_set_data( properties, "audio_buffer", audio_buffer, 0, free, NULL );
+       }
+
+       // Seek if necessary
+       if ( position != expected )
+       {
+               if ( position + 1 == expected )
+               {
+                       // We're paused - silence required
+                       paused = 1;
+               }
+               else if ( position > expected && ( position - expected ) < 250 )
+               {
+                       // Fast forward - seeking is inefficient for small distances - just ignore following frames
+                       ignore = position - expected;
+               }
+               else
+               {
+                       // Seek to the required position
+                       ov_time_seek( ov, producer_time_of_frame( this, position ) );
+                       expected = position;
+                       audio_used = 0;
+               }
+       }
+
+       // Return info in frame
+       *frequency = vi->rate;
+       *channels = vi->channels;
+
+       // Get the audio if required
+       if ( !paused )
+       {
+               // Bitstream section
+               int current_section;
+
+               // Get the number of samples for the current frame
+               *samples = mlt_sample_calculator( fps, *frequency, expected ++ );
+
+               while( *samples > audio_used  )
+               {
+                       // Read the samples
+                       int bytes = ov_read( ov, ( char * )( &audio_buffer[ audio_used * 2 ] ), 4096, 0, 2, 1, &current_section );
+
+                       // Break if error or eof
+                       if ( bytes <= 0 )
+                               break;
+
+                       // Increment number of samples used
+                       audio_used += bytes / ( sizeof( int16_t ) * *channels );
+
+                       // Handle ignore
+                       while ( ignore && audio_used >= *samples )
+                       {
+                               ignore --;
+                               audio_used -= *samples;
+                               memmove( audio_buffer, &audio_buffer[ *samples * *channels ], audio_used * sizeof( int16_t ) );
+                               *samples = mlt_sample_calculator( fps, *frequency, expected ++ );
+                       }
+               }
+
+               // Now handle the audio if we have enough
+               if ( audio_used >= *samples )
+               {
+                       *buffer = malloc( *samples * *channels * sizeof( int16_t ) );
+                       memcpy( *buffer, audio_buffer, *samples * *channels * sizeof( int16_t ) );
+                       audio_used -= *samples;
+                       memmove( audio_buffer, &audio_buffer[ *samples * *channels ], audio_used * *channels * sizeof( int16_t ) );
+                       mlt_properties_set_data( frame_properties, "audio", *buffer, 0, free, NULL );
+               }
+               else
+               {
+                       frame->get_audio = NULL;
+                       mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
+                       audio_used = 0;
+               }
+               
+               // Store the number of audio samples still available
+               mlt_properties_set_int( properties, "audio_used", audio_used );
+       }
+       else
+       {
+               // Get silence and don't touch the context
+               frame->get_audio = NULL;
+               *samples = mlt_sample_calculator( fps, *frequency, position );
+               mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
+       }
+
+       // Regardless of speed, we expect to get the next frame (cos we ain't too bright)
+       mlt_properties_set_position( properties, "audio_expected", position + 1 );
+
+       return 0;
+}
+
+/** Set up audio handling.
+*/
+
+static void producer_set_up_audio( mlt_producer this, mlt_frame frame )
+{
+       // Get the properties
+       mlt_properties properties = mlt_frame_properties( frame );
+
+       // Set the audio method
+       frame->get_audio = producer_get_audio;
+
+       // Set the producer on the frame
+       mlt_properties_set_data( properties, "vorbis_producer", this, 0, NULL, NULL );
+}
+
+/** Our get frame implementation.
+*/
+
+static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index )
+{
+       // Create an empty frame
+       *frame = mlt_frame_init( );
+
+       // Update timecode on the frame we're creating
+       mlt_frame_set_position( *frame, mlt_producer_position( this ) );
+
+       // Set the position of this producer
+       mlt_properties_set_position( mlt_frame_properties( *frame ), "vorbis_position", mlt_producer_get_in( this ) + mlt_producer_position( this ) );
+
+       // Set up the audio
+       producer_set_up_audio( this, *frame );
+
+       // Calculate the next timecode
+       mlt_producer_prepare_next( this );
+
+       return 0;
+}
diff --git a/src/modules/vorbis/producer_vorbis.h b/src/modules/vorbis/producer_vorbis.h
new file mode 100644 (file)
index 0000000..6aaf404
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * producer_vorbis.h -- vorbis producer
+ * Copyright (C) 2003-2004 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 _PRODUCER_VORBIS_H_
+#define _PRODUCER_VORBIS_H_
+
+#include <framework/mlt_producer.h>
+
+extern mlt_producer producer_vorbis_init( char *file );
+
+#endif