+static void reopen_video( producer_avformat self, mlt_producer producer )
+{
+ mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
+ mlt_service_lock( MLT_PRODUCER_SERVICE( producer ) );
+ pthread_mutex_lock( &self->audio_mutex );
+
+ if ( self->video_codec )
+ {
+ avformat_lock();
+ avcodec_close( self->video_codec );
+ avformat_unlock();
+ }
+ self->video_codec = NULL;
+ if ( self->dummy_context )
+ av_close_input_file( self->dummy_context );
+ self->dummy_context = NULL;
+ if ( self->video_format )
+ av_close_input_file( self->video_format );
+ self->video_format = NULL;
+
+ int audio_index = self->audio_index;
+ int video_index = self->video_index;
+
+ pthread_mutex_unlock( &self->audio_mutex );
+ pthread_mutex_unlock( &self->video_mutex );
+ producer_open( self, mlt_service_profile( MLT_PRODUCER_SERVICE(producer) ),
+ mlt_properties_get( properties, "resource" ) );
+ pthread_mutex_lock( &self->video_mutex );
+ pthread_mutex_lock( &self->audio_mutex );
+
+ self->audio_index = audio_index;
+ if ( self->video_format && video_index > -1 )
+ {
+ self->video_index = video_index;
+ video_codec_init( self, video_index, properties );
+ }
+
+ pthread_mutex_unlock( &self->audio_mutex );
+ mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) );
+}
+
+static int seek_video( producer_avformat self, mlt_position position,
+ int64_t req_position, int must_decode, int use_new_seek, int *ignore )
+{
+ mlt_producer producer = self->parent;
+ int paused = 0;
+
+ if ( self->seekable && ( position != self->video_expected || self->last_position < 0 ) )
+ {
+ mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
+
+ // Fetch the video format context
+ AVFormatContext *context = self->video_format;
+
+ // Get the video stream
+ AVStream *stream = context->streams[ self->video_index ];
+
+ // Get codec context
+ AVCodecContext *codec_context = stream->codec;
+
+ // We may want to use the source fps if available
+ double source_fps = mlt_properties_get_double( properties, "meta.media.frame_rate_num" ) /
+ mlt_properties_get_double( properties, "meta.media.frame_rate_den" );
+
+ if ( self->av_frame && position + 1 == self->video_expected )
+ {
+ // We're paused - use last image
+ paused = 1;
+ }
+ else if ( !self->seekable && position > self->video_expected && ( position - self->video_expected ) < 250 )
+ {
+ // Fast forward - seeking is inefficient for small distances - just ignore following frames
+ *ignore = ( int )( ( position - self->video_expected ) / mlt_producer_get_fps( producer ) * source_fps );
+ codec_context->skip_loop_filter = AVDISCARD_NONREF;
+ }
+ else if ( self->seekable && ( position < self->video_expected || position - self->video_expected >= 12 || self->last_position < 0 ) )
+ {
+ if ( use_new_seek && self->last_position == POSITION_INITIAL )