// MLT Header files
#include <framework/mlt_producer.h>
#include <framework/mlt_frame.h>
+#include <framework/mlt_profile.h>
// ffmpeg Header files
#include <avformat.h>
#include <pthread.h>
#include <math.h>
+#if LIBAVUTIL_VERSION_INT < (50<<16)
+#define PIX_FMT_YUYV422 PIX_FMT_YUV422
+#endif
+
void avformat_lock( );
void avformat_unlock( );
mlt_producer producer_avformat_init( mlt_profile profile, char *file )
{
+ int error = 0;
+
+ // Report information about available demuxers and codecs as YAML Tiny
+ if ( file && strstr( file, "f-list" ) )
+ {
+ fprintf( stderr, "---\nformats:\n" );
+ AVInputFormat *format = NULL;
+ while ( ( format = av_iformat_next( format ) ) )
+ fprintf( stderr, " - %s\n", format->name );
+ fprintf( stderr, "...\n" );
+ error = 1;
+ }
+ if ( file && strstr( file, "acodec-list" ) )
+ {
+ fprintf( stderr, "---\naudio_codecs:\n" );
+ AVCodec *codec = NULL;
+ while ( ( codec = av_codec_next( codec ) ) )
+ if ( codec->decode && codec->type == CODEC_TYPE_AUDIO )
+ fprintf( stderr, " - %s\n", codec->name );
+ fprintf( stderr, "...\n" );
+ error = 1;
+ }
+ if ( file && strstr( file, "vcodec-list" ) )
+ {
+ fprintf( stderr, "---\nvideo_codecs:\n" );
+ AVCodec *codec = NULL;
+ while ( ( codec = av_codec_next( codec ) ) )
+ if ( codec->decode && codec->type == CODEC_TYPE_VIDEO )
+ fprintf( stderr, " - %s\n", codec->name );
+ fprintf( stderr, "...\n" );
+ error = 1;
+ }
+ if ( error )
+ return NULL;
+
mlt_producer this = NULL;
// Check that we have a non-NULL argument
// mlt_properties_set_double( meta_media, key, av_q2d( context->streams[ i ]->time_base ) );
snprintf( key, sizeof(key), "meta.media.%d.codec.name", i );
mlt_properties_set( meta_media, key, codec->name );
+#if (LIBAVCODEC_VERSION_INT >= ((51<<16)+(55<<8)+0))
snprintf( key, sizeof(key), "meta.media.%d.codec.long_name", i );
mlt_properties_set( meta_media, key, codec->long_name );
+#endif
snprintf( key, sizeof(key), "meta.media.%d.codec.bit_rate", i );
mlt_properties_set_int( meta_media, key, codec_context->bit_rate );
// snprintf( key, sizeof(key), "meta.media.%d.codec.time_base", i );
else
{
AVPicture output;
- avpicture_fill( &output, buffer, PIX_FMT_YUV422, width, height );
- img_convert( &output, PIX_FMT_YUV422, (AVPicture *)frame, pix_fmt, width, height );
+ avpicture_fill( &output, buffer, PIX_FMT_YUYV422, width, height );
+ img_convert( &output, PIX_FMT_YUYV422, (AVPicture *)frame, pix_fmt, width, height );
}
#endif
}
}
else if ( position < expected || position - expected >= 12 )
{
+ int64_t timestamp = ( int64_t )( real_timecode * AV_TIME_BASE + 0.5 );
+ if ( context->start_time != AV_NOPTS_VALUE )
+ timestamp += context->start_time;
+ if ( timestamp < 0 )
+ timestamp = 0;
+
// Set to the real timecode
- if ( av_seek_frame( context, -1, mlt_properties_get_double( properties, "_start_time" ) + real_timecode * 1000000.0, AVSEEK_FLAG_BACKWARD ) != 0 )
+ if ( av_seek_frame( context, -1, timestamp, AVSEEK_FLAG_BACKWARD ) != 0 )
paused = 1;
// Clear the usage in the audio buffer
// If we're behind, ignore this packet
if ( pkt.pts >= 0 )
{
- float current_pts = av_q2d( stream->time_base ) * pkt.pts;
- if ( seekable && ( !ignore && current_pts <= ( real_timecode - 0.02 ) ) )
+ double current_pts = av_q2d( stream->time_base ) * pkt.pts;
+ double source_fps = mlt_properties_get_double( properties, "source_fps" );
+ int req_position = ( int )( real_timecode * source_fps + 0.5 );
+ int int_position = ( int )( current_pts * source_fps + 0.5 );
+
+ if ( context->start_time != AV_NOPTS_VALUE )
+ int_position -= ( int )( context->start_time * source_fps / AV_TIME_BASE + 0.5 );
+ if ( seekable && !ignore && int_position < req_position )
ignore = 1;
}
}