]> git.sesse.net Git - mlt/blobdiff - src/modules/avformat/filter_avresample.c
fix QObject::connect of type QTextCursor errors
[mlt] / src / modules / avformat / filter_avresample.c
index f78dff87814a642da4cf37ce07ecbe6ce66ab174..65ea354e9ea6862d5c8aa99785a2f7b9ad8c0b16 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <framework/mlt_filter.h>
 #include <framework/mlt_frame.h>
+#include <framework/mlt_log.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 
 // ffmpeg Header files
 #include <libavformat/avformat.h>
+#if LIBAVUTIL_VERSION_INT >= ((50<<16)+(38<<8)+0)
+#  include <libavutil/samplefmt.h>
+#else
+#  define AV_SAMPLE_FMT_S16 SAMPLE_FMT_S16
+#endif
 
 /** Get the audio.
 */
 
 static int resample_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
 {
-       // Get the properties of the frame
-       mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
-
        // Get the filter service
        mlt_filter filter = mlt_frame_pop_audio( frame );
 
@@ -51,60 +54,13 @@ static int resample_get_audio( mlt_frame frame, void **buffer, mlt_audio_format
        // Obtain the resample context if it exists
        ReSampleContext *resample = mlt_properties_get_data( filter_properties, "audio_resample", NULL );
 
-       // Used to return number of channels in the source
-       int channels_avail = *channels;
-
-       // Loop variable
-       int i;
-
        // If no resample frequency is specified, default to requested value
        if ( output_rate == 0 )
                output_rate = *frequency;
 
        // Get the producer's audio
-       *format = mlt_audio_s16;
-       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 );
-               int j, k = 0;
-               
-               // Duplicate the existing channels
-               for ( i = 0; i < *samples; i++ )
-               {
-                       for ( j = 0; j < *channels; j++ )
-                       {
-                               new_buffer[ ( i * *channels ) + j ] = ((int16_t*)(*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 == 6 && *channels == 2 )
-       {
-               // 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 ] = ((int16_t*)(*buffer))[ ( i * channels_avail ) + 2 ];
-                       new_buffer[ ( i * *channels ) + 1 ] = ((int16_t*)(*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;
-       }
+       int error = mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
+       if ( error ) return error;
 
        // Return now if no work to do
        if ( output_rate != *frequency )
@@ -112,13 +68,23 @@ static int resample_get_audio( mlt_frame frame, void **buffer, mlt_audio_format
                // Will store number of samples created
                int used = 0;
 
+               mlt_log_debug( MLT_FILTER_SERVICE(filter), "channels %d samples %d frequency %d -> %d\n",
+                       *channels, *samples, *frequency, output_rate );
+
+               // Do not convert to s16 unless we need to change the rate
+               if ( *format != mlt_audio_s16 )
+               {
+                       *format = mlt_audio_s16;
+                       mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
+               }
+
                // Create a resampler if nececessary
                if ( resample == NULL || *frequency != mlt_properties_get_int( filter_properties, "last_frequency" ) )
                {
                        // Create the resampler
 #if (LIBAVCODEC_VERSION_INT >= ((52<<16)+(15<<8)+0))
                        resample = av_audio_resample_init( *channels, *channels, output_rate, *frequency,
-                               SAMPLE_FMT_S16, SAMPLE_FMT_S16, 16, 10, 0, 0.8 );
+                               AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16, 16, 10, 0, 0.8 );
 #else
                        resample = audio_resample_init( *channels, *channels, output_rate, *frequency );
 #endif
@@ -155,19 +121,19 @@ static int resample_get_audio( mlt_frame frame, void **buffer, mlt_audio_format
                mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );
        }
 
-       return 0;
+       return error;
 }
 
 /** Filter processing.
 */
 
-static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
+static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
 {
        // Only call this if we have a means to get audio
        if ( mlt_frame_is_test_audio( frame ) == 0 )
        {
                // Push the filter on to the stack
-               mlt_frame_push_audio( frame, this );
+               mlt_frame_push_audio( frame, filter );
 
                // Assign our get_audio method
                mlt_frame_push_audio( frame, resample_get_audio );
@@ -182,10 +148,10 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
 mlt_filter filter_avresample_init( char *arg )
 {
        // Create a filter
-       mlt_filter this = mlt_filter_new( );
+       mlt_filter filter = mlt_filter_new( );
 
        // Initialise if successful
-       if ( this != NULL )
+       if ( filter != NULL )
        {
                // Calculate size of the buffer
                int size = AVCODEC_MAX_AUDIO_FRAME_SIZE * sizeof( int16_t );
@@ -194,18 +160,18 @@ mlt_filter filter_avresample_init( char *arg )
                int16_t *buffer = mlt_pool_alloc( size );
 
                // Assign the process method
-               this->process = filter_process;
+               filter->process = filter_process;
 
                // Deal with argument
                if ( arg != NULL )
-                       mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "frequency", arg );
+                       mlt_properties_set( MLT_FILTER_PROPERTIES( filter ), "frequency", arg );
 
                // Default to 2 channel output
-               mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "channels", 2 );
+               mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "channels", 2 );
 
                // Store the buffer
-               mlt_properties_set_data( MLT_FILTER_PROPERTIES( this ), "buffer", buffer, size, mlt_pool_release, NULL );
+               mlt_properties_set_data( MLT_FILTER_PROPERTIES( filter ), "buffer", buffer, size, mlt_pool_release, NULL );
        }
 
-       return this;
+       return filter;
 }