From: ddennedy Date: Wed, 17 Mar 2004 21:36:59 +0000 (+0000) Subject: added filter_channelcopy. X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=0d368e962076c3b96040b86cd5d87a1bbfe0a594;p=mlt added filter_channelcopy. 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 --- diff --git a/docs/services.txt b/docs/services.txt index 10d25a03..74672b9f 100644 --- a/docs/services.txt +++ b/docs/services.txt @@ -518,6 +518,31 @@ Filters 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 @@ -754,7 +779,9 @@ Filters 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. @@ -777,7 +804,8 @@ Filters Known Bugs - none + Assumes 2 channels during libsamplerate initialisation. Untested + with >2 channels. rescale diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index 773632ab..6ebd5683 100644 --- a/src/modules/avformat/producer_avformat.c +++ b/src/modules/avformat/producer_avformat.c @@ -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; +#if 0 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 ); } +#endif /** 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 ); - + // 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 ) { diff --git a/src/modules/core/Makefile b/src/modules/core/Makefile index fd7d0dff..ac79e0a8 100644 --- a/src/modules/core/Makefile +++ b/src/modules/core/Makefile @@ -4,6 +4,7 @@ TARGET = ../libmltcore.so OBJS = factory.o \ producer_ppm.o \ filter_brightness.o \ + filter_channelcopy.o \ filter_greyscale.o \ filter_gamma.o \ filter_luma.o \ diff --git a/src/modules/core/configure b/src/modules/core/configure index 4660916f..ee29e184 100755 --- a/src/modules/core/configure +++ b/src/modules/core/configure @@ -10,6 +10,7 @@ EOF cat << EOF >> ../filters.dat brightness libmltcore.so +channelcopy libmltcore.so gamma libmltcore.so greyscale libmltcore.so luma libmltcore.so @@ -28,4 +29,3 @@ region libmltcore.so EOF fi - diff --git a/src/modules/core/factory.c b/src/modules/core/factory.c index 1d037a06..43f45913 100644 --- a/src/modules/core/factory.c +++ b/src/modules/core/factory.c @@ -22,6 +22,7 @@ #include "producer_ppm.h" #include "filter_brightness.h" +#include "filter_channelcopy.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, "channelcopy" ) ) + return filter_channelcopy_init( arg ); 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; } - diff --git a/src/modules/core/filter_channelcopy.c b/src/modules/core/filter_channelcopy.c new file mode 100644 index 00000000..fd49d12f --- /dev/null +++ b/src/modules/core/filter_channelcopy.c @@ -0,0 +1,103 @@ +/* + * filter_channelcopy.c -- copy one audio channel to another + * Copyright (C) 2003-2004 Ushodaya Enterprises Limited + * Author: Dan Dennedy + * + * 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 + +#include +#include +#define __USE_ISOC99 1 +#include + +/** 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 index 00000000..c958583e --- /dev/null +++ b/src/modules/core/filter_channelcopy.h @@ -0,0 +1,28 @@ +/* + * filter_channelcopy.h -- copy audio channel from one to another + * Copyright (C) 2003-2004 Ushodaya Enterprises Limited + * Author: Dan Dennedy + * + * 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 + +extern mlt_filter filter_channelcopy_init( char *arg ); + +#endif diff --git a/src/modules/resample/filter_resample.c b/src/modules/resample/filter_resample.c index b8da7605..57f9aadc 100644 --- a/src/modules/resample/filter_resample.c +++ b/src/modules/resample/filter_resample.c @@ -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 ); + int channels_avail = *channels; 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 - 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 ) @@ -158,4 +181,3 @@ mlt_filter filter_resample_init( char *arg ) } return this; } -