Removed unecessary locks in avformat
[melted] / src / modules / avformat / producer_avformat.c
index 582171e..4f83e41 100644 (file)
@@ -25,7 +25,7 @@
 #include <framework/mlt_frame.h>
 
 // ffmpeg Header files
-#include <ffmpeg/avformat.h>
+#include <avformat.h>
 
 // System header files
 #include <stdlib.h>
@@ -270,6 +270,12 @@ static int producer_open( mlt_producer this, char *file )
                        // Find default audio and video streams
                        find_default_streams( context, &audio_index, &video_index );
 
+                       // Check if we're seekable (something funny about mpeg here :-/)
+                       if ( strstr( file, ".mpg" ) == NULL && strstr( file, ".mpeg" ) == NULL )
+                               mlt_properties_set_int( properties, "seekable", av_seek_frame( context, -1, context->start_time ) >= 0 );
+                       else
+                               mlt_properties_set_int( properties, "seekable", 1 );
+
                        // 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 );
@@ -388,9 +394,6 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        mlt_properties_set_int( frame_properties, "width", *width );
        mlt_properties_set_int( frame_properties, "height", *height );
 
-       // Lock the mutex now
-       avformat_lock( );
-
        // Construct an AVFrame for YUV422 conversion
        if ( output == NULL )
        {
@@ -418,7 +421,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                else
                {
                        // Set to the real timecode
-                       av_seek_frame( context, -1, real_timecode * 1000000.0 );
+                       av_seek_frame( context, -1, context->start_time + real_timecode * 1000000.0 );
        
                        // Remove the cached info relating to the previous position
                        mlt_properties_set_double( properties, "current_time", real_timecode );
@@ -469,7 +472,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;
@@ -483,6 +486,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 );
                                }
                        }
 
@@ -571,13 +575,14 @@ 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
-       avformat_unlock( );
-
        return 0;
 }
 
@@ -598,9 +603,6 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame )
        // Get the frame properties
        mlt_properties frame_properties = mlt_frame_properties( frame );
 
-       // Lock the mutex now
-       avformat_lock( );
-
        if ( context != NULL && index != -1 )
        {
                // Get the video stream
@@ -667,9 +669,6 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame )
        {
                mlt_properties_set_int( frame_properties, "test_image", 1 );
        }
-
-       // Unlock the mutex now
-       avformat_unlock( );
 }
 
 /** Get the audio from a frame.
@@ -695,6 +694,9 @@ static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form
        // Get the audio_index
        int index = mlt_properties_get_int( properties, "audio_index" );
 
+       // Get the seekable status
+       int seekable = mlt_properties_get_int( properties, "seekable" );
+
        // Obtain the expected frame numer
        mlt_position expected = mlt_properties_get_position( properties, "audio_expected" );
 
@@ -724,10 +726,6 @@ static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form
 
        // Flag for paused (silence) 
        int paused = 0;
-       int locked = 0;
-
-       // Lock the mutex now
-       avformat_lock( );
 
        // Check for resample and create if necessary
        if ( resample == NULL && codec_context->channels <= 2 )
@@ -770,12 +768,11 @@ static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form
                else
                {
                        // Set to the real timecode
-                       av_seek_frame( context, -1, real_timecode * 1000000.0 );
+                       if ( !seekable || av_seek_frame( context, -1, context->start_time + real_timecode * 1000000.0 ) != 0 )
+                               paused = 1;
 
                        // Clear the usage in the audio buffer
                        audio_used = 0;
-
-                       locked = 1;
                }
        }
 
@@ -860,7 +857,7 @@ static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form
                                        mlt_properties_set_double( properties, "discrepancy", discrepancy );
                                }
 
-                               if ( !ignore && discrepancy * current_pts <= ( real_timecode - 0.02 ) )
+                               if ( seekable && ( !ignore && discrepancy * current_pts <= ( real_timecode - 0.02 ) ) )
                                        ignore = 1;
                        }
 
@@ -896,11 +893,9 @@ static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form
                mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
        }
 
-       // Regardless of speed, we expect to get the next frame (cos we ain't too bright)
-       mlt_properties_set_position( properties, "audio_expected", position + 1 );
-
-       // Unlock the mutex now
-       avformat_unlock( );
+       // Regardless of speed (other than paused), we expect to get the next frame
+       if ( !paused )
+               mlt_properties_set_position( properties, "audio_expected", position + 1 );
 
        return 0;
 }
@@ -919,9 +914,6 @@ static void producer_set_up_audio( mlt_producer this, mlt_frame frame )
        // Get the audio_index
        int index = mlt_properties_get_int( properties, "audio_index" );
 
-       // Lock the mutex now
-       avformat_lock( );
-
        // Deal with audio context
        if ( context != NULL && index != -1 )
        {
@@ -964,9 +956,6 @@ static void producer_set_up_audio( mlt_producer this, mlt_frame frame )
                        mlt_properties_set_data( frame_properties, "avformat_producer", this, 0, NULL, NULL );
                }
        }
-
-       // Unlock the mutex now
-       avformat_unlock( );
 }
 
 /** Our get frame implementation.
@@ -981,7 +970,7 @@ static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index
        mlt_frame_set_position( *frame, mlt_producer_position( this ) );
 
        // Set the position of this producer
-       mlt_properties_set_position( mlt_frame_properties( *frame ), "avformat_position", mlt_producer_get_in( this ) + mlt_producer_position( this ) );
+       mlt_properties_set_position( mlt_frame_properties( *frame ), "avformat_position", mlt_producer_position( this ) );
 
        // Set up the video
        producer_set_up_video( this, *frame );