X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fmodules%2Fresample%2Ffilter_resample.c;h=2c848a8520b1273244399ca5ee2025c03d4ab038;hb=1d3ab5568258841b1741b8c2fc88ce4e958e6fc6;hp=c8fbf5fd924b591d5fc4e817dd03d572559322d7;hpb=3a63c2147254f4382a91f007c86680259b41f1be;p=melted diff --git a/src/modules/resample/filter_resample.c b/src/modules/resample/filter_resample.c index c8fbf5f..2c848a8 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,8 +53,55 @@ 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 * sizeof( int16_t ); + int16_t *new_buffer = mlt_pool_alloc( size ); + + // 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; + } + } + + // Update the audio buffer now - destroys the old + mlt_properties_set_data( properties, "audio", new_buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); + + *buffer = new_buffer; + } + else if ( channels_avail > *channels ) + { + // Nasty hack for ac3 5.1 audio - may be a cause of failure? + int size = *channels * *samples * sizeof( int16_t ); + int16_t *new_buffer = mlt_pool_alloc( size ); + + // Drop all but the first *channels + for ( i = 0; i < *samples; i++ ) + { + new_buffer[ ( i * *channels ) + 0 ] = (*buffer)[ ( i * channels_avail ) + 2 ]; + new_buffer[ ( i * *channels ) + 1 ] = (*buffer)[ ( i * channels_avail ) + 3 ]; + } + + // Update the audio buffer now - destroys the old + mlt_properties_set_data( properties, "audio", new_buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); + + *buffer = new_buffer; + } + + // Return now if no work to do + if ( output_rate == *frequency ) + return 0; + + //fprintf( stderr, "resample_get_audio: input_rate %d output_rate %d\n", *frequency, output_rate ); + // Convert to floating point for ( i = 0; i < *samples * *channels; ++i ) input_buffer[ i ] = ( float )( (*buffer)[ i ] ) / 32768; @@ -70,8 +118,8 @@ static int resample_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form { if ( data.output_frames_gen > *samples ) { - *buffer = (int16_t*) malloc( data.output_frames_gen * *channels * 2 ); - mlt_properties_set_data( properties, "audio", *buffer, *channels * data.output_frames_gen * 2, free, NULL ); + *buffer = mlt_pool_alloc( data.output_frames_gen * *channels * sizeof( int16_t ) ); + mlt_properties_set_data( properties, "audio", *buffer, *channels * data.output_frames_gen * 2, mlt_pool_release, NULL ); } *samples = data.output_frames_gen; *frequency = output_rate; @@ -101,24 +149,27 @@ static int resample_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form 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 frequency property if supplied - if ( mlt_properties_get( properties, "frequency" ) != NULL ) - mlt_properties_set_int( frame_props, "resample.frequency", mlt_properties_get_int( properties, "frequency" ) ); - - // Propogate the other properties - mlt_properties_set_int( frame_props, "resample.channels", mlt_properties_get_int( properties, "channels" ) ); - mlt_properties_set_data( frame_props, "resample.state", mlt_properties_get_data( properties, "state", NULL ), 0, NULL, NULL ); - mlt_properties_set_data( frame_props, "resample.input_buffer", mlt_properties_get_data( properties, "input_buffer", NULL ), 0, NULL, NULL ); - mlt_properties_set_data( frame_props, "resample.output_buffer", mlt_properties_get_data( properties, "output_buffer", NULL ), 0, NULL, NULL ); + if ( frame->get_audio != NULL ) + { + mlt_properties properties = mlt_filter_properties( this ); + mlt_properties frame_props = mlt_frame_properties( frame ); + + // Propogate the frequency property if supplied + if ( mlt_properties_get( properties, "frequency" ) != NULL ) + mlt_properties_set_int( frame_props, "resample.frequency", mlt_properties_get_int( properties, "frequency" ) ); + + // Propogate the other properties + mlt_properties_set_int( frame_props, "resample.channels", mlt_properties_get_int( properties, "channels" ) ); + mlt_properties_set_data( frame_props, "resample.state", mlt_properties_get_data( properties, "state", NULL ), 0, NULL, NULL ); + mlt_properties_set_data( frame_props, "resample.input_buffer", mlt_properties_get_data( properties, "input_buffer", NULL ), 0, NULL, NULL ); + mlt_properties_set_data( frame_props, "resample.output_buffer", mlt_properties_get_data( properties, "output_buffer", NULL ), 0, NULL, NULL ); - // Backup the original get_audio (it's still needed) - mlt_properties_set_data( frame_props, "resample.get_audio", frame->get_audio, 0, NULL, NULL ); + // Backup the original get_audio (it's still needed) + mlt_properties_set_data( frame_props, "resample.get_audio", frame->get_audio, 0, NULL, NULL ); - // Override the get_audio method - frame->get_audio = resample_get_audio; + // Override the get_audio method + frame->get_audio = resample_get_audio; + } return frame; } @@ -128,22 +179,22 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) mlt_filter filter_resample_init( char *arg ) { - mlt_filter this = calloc( sizeof( struct mlt_filter_s ), 1 ); - if ( this != NULL && mlt_filter_init( this, NULL ) == 0 ) + mlt_filter this = mlt_filter_new( ); + if ( this != NULL ) { int error; SRC_STATE *state = src_new( RESAMPLE_TYPE, 2 /* channels */, &error ); if ( error == 0 ) { + void *input_buffer = mlt_pool_alloc( BUFFER_LEN ); + void *output_buffer = mlt_pool_alloc( BUFFER_LEN ); this->process = filter_process; if ( arg != NULL ) mlt_properties_set_int( mlt_filter_properties( this ), "frequency", atoi( arg ) ); mlt_properties_set_int( mlt_filter_properties( this ), "channels", 2 ); mlt_properties_set_data( mlt_filter_properties( this ), "state", state, 0, (mlt_destructor)src_delete, NULL ); - mlt_properties_set_data( mlt_filter_properties( this ), "input_buffer", - malloc( BUFFER_LEN ), BUFFER_LEN, free, NULL ); - mlt_properties_set_data( mlt_filter_properties( this ), "output_buffer", - malloc( BUFFER_LEN ), BUFFER_LEN, free, NULL ); + mlt_properties_set_data( mlt_filter_properties( this ), "input_buffer", input_buffer, BUFFER_LEN, mlt_pool_release, NULL ); + mlt_properties_set_data( mlt_filter_properties( this ), "output_buffer", output_buffer, BUFFER_LEN, mlt_pool_release, NULL ); } else { @@ -152,4 +203,3 @@ mlt_filter filter_resample_init( char *arg ) } return this; } -