]> git.sesse.net Git - mlt/commitdiff
added filter_channelcopy.
authorddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
Wed, 17 Mar 2004 21:36:59 +0000 (21:36 +0000)
committerddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
Wed, 17 Mar 2004 21:36:59 +0000 (21:36 +0000)
enhance filter_resample to reproduce channels when producer does not create as many as consumer requested.

git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@217 d19143bc-622f-0410-bfdd-b5b2a6649095

docs/services.txt
src/modules/avformat/producer_avformat.c
src/modules/core/Makefile
src/modules/core/configure
src/modules/core/factory.c
src/modules/core/filter_channelcopy.c [new file with mode: 0644]
src/modules/core/filter_channelcopy.h [new file with mode: 0644]
src/modules/resample/filter_resample.c

index 10d25a03ba63cdeafe2498f707c7252152e4d597..74672b9f9e770ccb51b66c53b0d2079d4fbea574 100644 (file)
@@ -518,6 +518,31 @@ Filters
                Known Bugs
                
                        Does not go completely to black or white.
                Known Bugs
                
                        Does not go completely to black or white.
+                       
+       
+       channelcopy
+       
+               Description
+               
+                       Copy audio from one channel to another channel.
+                       
+               Constructor Argument
+               
+                       to - the 0-indexed channel to copy into, default is 1.
+                       
+               Mutable Properties
+               
+                       int to - see above
+                       int from - the channel from which to copy, default is 0.
+                       
+               Dependencies
+               
+                       none
+                       
+               Known Bugs
+               
+                       none
+                       
 
 
        deinterlace
 
 
        deinterlace
@@ -754,7 +779,9 @@ Filters
 
                Description
 
 
                Description
 
-                       Adjust an audio stream's sampling rate.
+                       Adjust an audio stream's sampling rate, and duplicate channels if 
+                       producer provides less than consumer requested.
+                       
                        This filter is automatically invoked by Fezzik for the sake of
                        normalisation over inputs and with the consumer.
 
                        This filter is automatically invoked by Fezzik for the sake of
                        normalisation over inputs and with the consumer.
 
@@ -777,7 +804,8 @@ Filters
 
                Known Bugs
 
 
                Known Bugs
 
-                       none
+                       Assumes 2 channels during libsamplerate initialisation. Untested
+                       with >2 channels.
 
        rescale
 
 
        rescale
 
index 773632ab94523b9bff351d702c463b8fa5cd2d6a..6ebd5683a63de1cc609d07329631fb72b12926b8 100644 (file)
@@ -41,6 +41,7 @@ static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index
 static int avformat_initialised = 0;
 static pthread_mutex_t avformat_mutex;
 
 static int avformat_initialised = 0;
 static pthread_mutex_t avformat_mutex;
 
+#if 0
 void *av_malloc( unsigned int size )
 {
        return mlt_pool_alloc( size );
 void *av_malloc( unsigned int size )
 {
        return mlt_pool_alloc( size );
@@ -55,6 +56,7 @@ void av_free( void *ptr )
 {
        return mlt_pool_release( ptr );
 }
 {
        return mlt_pool_release( ptr );
 }
+#endif
 
 /** Constructor for libavformat.
 */
 
 /** Constructor for libavformat.
 */
@@ -297,7 +299,7 @@ static int producer_open( mlt_producer this, char *file )
                        // Store selected audio and video indexes on properties
                        mlt_properties_set_int( properties, "audio_index", audio_index );
                        mlt_properties_set_int( properties, "video_index", video_index );
                        // Store selected audio and video indexes on properties
                        mlt_properties_set_int( properties, "audio_index", audio_index );
                        mlt_properties_set_int( properties, "video_index", video_index );
-
+                       
                        // We're going to cheat here - for a/v files, we will have two contexts (reasoning will be clear later)
                        if ( audio_index != -1 && video_index != -1 )
                        {
                        // We're going to cheat here - for a/v files, we will have two contexts (reasoning will be clear later)
                        if ( audio_index != -1 && video_index != -1 )
                        {
index fd7d0dff91d3e13d6a3dfafe517083d902bf0521..ac79e0a89ddd5e163f1edbf902e27fba89079690 100644 (file)
@@ -4,6 +4,7 @@ TARGET = ../libmltcore.so
 OBJS = factory.o \
           producer_ppm.o \
           filter_brightness.o \
 OBJS = factory.o \
           producer_ppm.o \
           filter_brightness.o \
+          filter_channelcopy.o \
           filter_greyscale.o \
           filter_gamma.o \
           filter_luma.o \
           filter_greyscale.o \
           filter_gamma.o \
           filter_luma.o \
index 4660916f603ea012cc0b681915e8bb75fc29081a..ee29e18430aabcf8cdf69f7cbe385c84508cf4b5 100755 (executable)
@@ -10,6 +10,7 @@ EOF
 
 cat << EOF >> ../filters.dat
 brightness             libmltcore.so
 
 cat << EOF >> ../filters.dat
 brightness             libmltcore.so
+channelcopy            libmltcore.so
 gamma                  libmltcore.so
 greyscale              libmltcore.so
 luma                   libmltcore.so
 gamma                  libmltcore.so
 greyscale              libmltcore.so
 luma                   libmltcore.so
@@ -28,4 +29,3 @@ region                        libmltcore.so
 EOF
 
 fi
 EOF
 
 fi
-
index 1d037a0685f75237a381b273218080cd4a266bea..43f45913a212e802f75b6d546946e45a8a693e2d 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "producer_ppm.h"
 #include "filter_brightness.h"
 
 #include "producer_ppm.h"
 #include "filter_brightness.h"
+#include "filter_channelcopy.h"
 #include "filter_gamma.h"
 #include "filter_luma.h"
 #include "filter_greyscale.h"
 #include "filter_gamma.h"
 #include "filter_luma.h"
 #include "filter_greyscale.h"
@@ -49,6 +50,8 @@ void *mlt_create_filter( char *id, void *arg )
 {
        if ( !strcmp( id, "brightness" ) )
                return filter_brightness_init( arg );
 {
        if ( !strcmp( id, "brightness" ) )
                return filter_brightness_init( arg );
+       if ( !strcmp( id, "channelcopy" ) )
+               return filter_channelcopy_init( arg );
        if ( !strcmp( id, "gamma" ) )
                return filter_gamma_init( arg );
        if ( !strcmp( id, "greyscale" ) )
        if ( !strcmp( id, "gamma" ) )
                return filter_gamma_init( arg );
        if ( !strcmp( id, "greyscale" ) )
@@ -85,4 +88,3 @@ void *mlt_create_consumer( char *id, void *arg )
 {
        return NULL;
 }
 {
        return NULL;
 }
-
diff --git a/src/modules/core/filter_channelcopy.c b/src/modules/core/filter_channelcopy.c
new file mode 100644 (file)
index 0000000..fd49d12
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * filter_channelcopy.c -- copy one audio channel to another
+ * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
+ * Author: Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 "filter_channelcopy.h"
+
+#include <framework/mlt_frame.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#define __USE_ISOC99 1
+#include <math.h>
+
+/** Get the audio.
+*/
+
+static int filter_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
+{
+       // Get the properties of the a frame
+       mlt_properties properties = mlt_frame_properties( frame );
+       int i, j;
+       int from = mlt_properties_get_int( properties, "channelcopy.from" );
+       int to = mlt_properties_get_int( properties, "channelcopy.to" );
+
+       // Restore the original get_audio
+       frame->get_audio = mlt_properties_get_data( properties, "channelcopy.get_audio", NULL );
+
+       // Get the producer's audio
+       mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
+
+       // Duplicate channels as necessary
+       {
+               int size = *channels * *samples * 2;
+               int16_t *new_buffer = mlt_pool_alloc( size );
+               
+               mlt_properties_set_data( properties, "audio", new_buffer, size, ( mlt_destructor )mlt_pool_release, NULL );
+               
+               // Duplicate the existing channels
+               for ( i = 0; i < *samples; i++ )
+               {
+                       for ( j = 0; j < *channels; j++ )
+                       {
+                               new_buffer[ ( i * *channels ) + j ] = (*buffer)[ ( i * *channels ) + ( j == to ? from : j ) ];
+                       }
+               }
+               *buffer = new_buffer;
+       }
+       return 0;
+}
+
+/** Filter processing.
+*/
+
+static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
+{
+       mlt_properties properties = mlt_filter_properties( this );
+       mlt_properties frame_props = mlt_frame_properties( frame );
+
+       // Propogate the parameters
+       mlt_properties_set_int( frame_props, "channelcopy.to", mlt_properties_get_int( properties, "to" ) );
+       mlt_properties_set_int( frame_props, "channelcopy.from", mlt_properties_get_int( properties, "from" ) );
+
+       // Backup the original get_audio (it's still needed)
+       mlt_properties_set_data( frame_props, "channelcopy.get_audio", frame->get_audio, 0, NULL, NULL );
+
+       // Override the get_audio method
+       frame->get_audio = filter_get_audio;
+
+       return frame;
+}
+
+/** Constructor for the filter.
+*/
+
+mlt_filter filter_channelcopy_init( char *arg )
+{
+       mlt_filter this = mlt_filter_new( );
+       if ( this != NULL )
+       {
+               this->process = filter_process;
+               if ( arg != NULL )
+                       mlt_properties_set_int( mlt_filter_properties( this ), "to", atoi( arg ) );
+               else
+                       mlt_properties_set_int( mlt_filter_properties( this ), "to", 1 );
+       }
+       return this;
+}
diff --git a/src/modules/core/filter_channelcopy.h b/src/modules/core/filter_channelcopy.h
new file mode 100644 (file)
index 0000000..c958583
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * filter_channelcopy.h -- copy audio channel from one to another
+ * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
+ * Author: Dan Dennedy <dan@dennedy.org>
+ *
+ * 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 _FILTER_CHANNELCOPY_H_
+#define _FILTER_CHANNELCOPY_H_
+
+#include <framework/mlt_filter.h>
+
+extern mlt_filter filter_channelcopy_init( char *arg );
+
+#endif
index b8da7605d04672ffa1e639bb2e8f140a6c503bbd..57f9aadcc21304c470f9d597ede022f24107a66d 100644 (file)
@@ -43,6 +43,7 @@ static int resample_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form
        SRC_DATA data;
        float *input_buffer = mlt_properties_get_data( properties, "resample.input_buffer", NULL );
        float *output_buffer = mlt_properties_get_data( properties, "resample.output_buffer", NULL );
        SRC_DATA data;
        float *input_buffer = mlt_properties_get_data( properties, "resample.input_buffer", NULL );
        float *output_buffer = mlt_properties_get_data( properties, "resample.output_buffer", NULL );
+       int channels_avail = *channels;
        int i;
 
        if ( output_rate == 0 )
        int i;
 
        if ( output_rate == 0 )
@@ -52,7 +53,29 @@ static int resample_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form
        frame->get_audio = mlt_properties_get_data( properties, "resample.get_audio", NULL );
 
        // Get the producer's audio
        frame->get_audio = mlt_properties_get_data( properties, "resample.get_audio", NULL );
 
        // Get the producer's audio
-       mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
+       mlt_frame_get_audio( frame, buffer, format, frequency, &channels_avail, samples );
+
+       // Duplicate channels as necessary
+       if ( channels_avail < *channels )
+       {
+               int size = *channels * *samples * 2;
+               int16_t *new_buffer = mlt_pool_alloc( size );
+               
+               mlt_properties_set_data( properties, "audio", new_buffer, size, ( mlt_destructor )mlt_pool_release, NULL );
+               
+               // Duplicate the existing channels
+               for ( i = 0; i < *samples; i++ )
+               {
+                       int j, k = 0;
+                       for ( j = 0; j < *channels; j++ )
+                       {
+                               new_buffer[ ( i * *channels ) + j ] = (*buffer)[ ( i * channels_avail ) + k ];
+                               k = ( k + 1 ) % channels_avail;
+                       }
+               }
+               
+               *buffer = new_buffer;
+       }
 
        // Return now if now work to do
        if ( output_rate == *frequency )
 
        // Return now if now work to do
        if ( output_rate == *frequency )
@@ -158,4 +181,3 @@ mlt_filter filter_resample_init( char *arg )
        }
        return this;
 }
        }
        return this;
 }
-