field order normalisation fix, add .vob to fezzik, field order detection for avformat
[melted] / src / modules / avformat / producer_avformat.c
index b5f7f62..ed7694d 100644 (file)
 #include <pthread.h>
 #include <math.h>
 
+void avformat_lock( );
+void avformat_unlock( );
+
 // 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 );
 
-// A static flag used to determine if avformat has been initialised
-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_realloc( void *ptr, unsigned int size )
-{
-       return mlt_pool_realloc( ptr, size );
-}
-
-void av_free( void *ptr )
-{
-       return mlt_pool_release( ptr );
-}
-#endif
-
 /** Constructor for libavformat.
 */
 
@@ -86,14 +68,6 @@ mlt_producer producer_avformat_init( char *file )
                        // Register our get_frame implementation
                        this->get_frame = producer_get_frame;
 
-                       // Initialise avformat if necessary
-                       if ( avformat_initialised == 0 )
-                       {
-                               avformat_initialised = 1;
-                               pthread_mutex_init( &avformat_mutex, NULL );
-                               av_register_all( );
-                       }
-
                        // Open the file
                        if ( producer_open( this, file ) != 0 )
                        {
@@ -145,13 +119,13 @@ static void producer_file_close( void *context )
        if ( context != NULL )
        {
                // Lock the mutex now
-               pthread_mutex_lock( &avformat_mutex );
+               avformat_lock( );
 
                // Close the file
                av_close_input_file( context );
 
                // Unlock the mutex now
-               pthread_mutex_unlock( &avformat_mutex );
+               avformat_unlock( );
        }
 }
 
@@ -163,13 +137,13 @@ static void producer_codec_close( void *codec )
        if ( codec != NULL )
        {
                // Lock the mutex now
-               pthread_mutex_lock( &avformat_mutex );
+               avformat_lock( );
 
                // Close the file
                avcodec_close( codec );
 
                // Unlock the mutex now
-               pthread_mutex_unlock( &avformat_mutex );
+               avformat_unlock( );
        }
 }
 
@@ -191,7 +165,7 @@ static int producer_open( mlt_producer this, char *file )
        double fps = mlt_properties_get_double( properties, "fps" );
 
        // Lock the mutex now
-       pthread_mutex_lock( &avformat_mutex );
+       avformat_lock( );
        
        // If "MRL", then create AVInputFormat
        AVInputFormat *format = NULL;
@@ -332,7 +306,7 @@ static int producer_open( mlt_producer this, char *file )
        }
 
        // Unlock the mutex now
-       pthread_mutex_unlock( &avformat_mutex );
+       avformat_unlock( );
 
        return error;
 }
@@ -415,16 +389,14 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        mlt_properties_set_int( frame_properties, "height", *height );
 
        // Lock the mutex now
-       pthread_mutex_lock( &avformat_mutex );
+       avformat_lock( );
 
        // Construct an AVFrame for YUV422 conversion
        if ( output == NULL )
        {
-               int size = avpicture_get_size( PIX_FMT_YUV422, *width, *height );
-               size += *width * 2;
+               int size = avpicture_get_size( PIX_FMT_YUV422, *width, *height + 1 );
                uint8_t *buf = mlt_pool_alloc( size );
                output = mlt_pool_alloc( sizeof( AVPicture ) );
-               //memset( output, 0, sizeof( AVPicture ) );
                avpicture_fill( output, buf, PIX_FMT_YUV422, *width, *height );
                mlt_properties_set_data( properties, "video_output_frame", output, 0, ( mlt_destructor )mlt_pool_release, NULL );
                mlt_properties_set_data( properties, "video_output_buffer", buf, 0, ( mlt_destructor )mlt_pool_release, NULL );
@@ -497,7 +469,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                                                current_time = real_timecode;
 
                                        // Handle ignore
-                                       if ( current_time < real_timecode )
+                                       if ( ( int )( current_time * 100 ) < ( int )( real_timecode * 100 ) - 7 )
                                        {
                                                ignore = 0;
                                                got_picture = 0;
@@ -511,6 +483,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                                        {
                                                got_picture = 0;
                                        }
+                                       mlt_properties_set_int( properties, "top_field_first", frame.top_field_first );
                                }
                        }
 
@@ -599,12 +572,16 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                        }
                }
        }
+       
+       // Set the field order property for this frame
+       mlt_properties_set_int( frame_properties, "top_field_first", 
+               mlt_properties_get_int( properties, "top_field_first" ) );
 
        // Regardless of speed, we expect to get the next frame (cos we ain't too bright)
        mlt_properties_set_position( properties, "video_expected", position + 1 );
 
        // Unlock the mutex now
-       pthread_mutex_unlock( &avformat_mutex );
+       avformat_unlock( );
 
        return 0;
 }
@@ -627,7 +604,7 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame )
        mlt_properties frame_properties = mlt_frame_properties( frame );
 
        // Lock the mutex now
-       pthread_mutex_lock( &avformat_mutex );
+       avformat_lock( );
 
        if ( context != NULL && index != -1 )
        {
@@ -697,7 +674,7 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame )
        }
 
        // Unlock the mutex now
-       pthread_mutex_unlock( &avformat_mutex );
+       avformat_unlock( );
 }
 
 /** Get the audio from a frame.
@@ -755,10 +732,10 @@ static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form
        int locked = 0;
 
        // Lock the mutex now
-       pthread_mutex_lock( &avformat_mutex );
+       avformat_lock( );
 
        // Check for resample and create if necessary
-       if ( resample == NULL )
+       if ( resample == NULL && codec_context->channels <= 2 )
        {
                // Create the resampler
                resample = audio_resample_init( *channels, codec_context->channels, *frequency, codec_context->sample_rate );
@@ -766,6 +743,11 @@ static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form
                // And store it on properties
                mlt_properties_set_data( properties, "audio_resample", resample, 0, ( mlt_destructor )audio_resample_close, NULL );
        }
+       else if ( resample == NULL )
+       {
+               *channels = codec_context->channels;
+               *frequency = codec_context->sample_rate;
+       }
 
        // Check for audio buffer and create if necessary
        if ( audio_buffer == NULL )
@@ -827,7 +809,7 @@ static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form
                uint8_t *ptr = pkt.data;
                        int data_size;
 
-                       // We only deal with video from the selected video_index
+                       // We only deal with audio from the selected audio_index
                        while ( ptr != NULL && ret >= 0 && pkt.stream_index == index && len > 0 )
                        {
                                // Decode the audio
@@ -844,9 +826,15 @@ static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form
 
                                if ( data_size > 0 )
                                {
-                                       int size_out = audio_resample( resample, &audio_buffer[ audio_used * *channels ], temp, data_size / ( codec_context->channels * sizeof( int16_t ) ) );
-
-                                       audio_used += size_out;
+                                       if ( resample != NULL )
+                                       {
+                                               audio_used += audio_resample( resample, &audio_buffer[ audio_used * *channels ], temp, data_size / ( codec_context->channels * sizeof( int16_t ) ) );
+                                       }
+                                       else
+                                       {
+                                               memcpy( &audio_buffer[ audio_used * *channels ], temp, data_size );
+                                               audio_used += data_size / ( codec_context->channels * sizeof( int16_t ) );
+                                       }
 
                                        // Handle ignore
                                        while ( ignore && audio_used > *samples )
@@ -917,7 +905,7 @@ static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form
        mlt_properties_set_position( properties, "audio_expected", position + 1 );
 
        // Unlock the mutex now
-       pthread_mutex_unlock( &avformat_mutex );
+       avformat_unlock( );
 
        return 0;
 }
@@ -937,7 +925,7 @@ static void producer_set_up_audio( mlt_producer this, mlt_frame frame )
        int index = mlt_properties_get_int( properties, "audio_index" );
 
        // Lock the mutex now
-       pthread_mutex_lock( &avformat_mutex );
+       avformat_lock( );
 
        // Deal with audio context
        if ( context != NULL && index != -1 )
@@ -983,7 +971,7 @@ static void producer_set_up_audio( mlt_producer this, mlt_frame frame )
        }
 
        // Unlock the mutex now
-       pthread_mutex_unlock( &avformat_mutex );
+       avformat_unlock( );
 }
 
 /** Our get frame implementation.