// AV option (0 = both, 1 = video, 2 = audio)
int av = 0;
+ // Setting lowest log level
+ av_log_set_level( -1 );
+
// Only if there is not a protocol specification that avformat can handle
if ( mrl && !url_exist( file ) )
{
// We will default to the first audio and video streams found
int audio_index = -1;
int video_index = -1;
+ int av_bypass = 0;
// Now set properties where we can (use default unknowns if required)
if ( context->duration != AV_NOPTS_VALUE )
mlt_properties_set_double( properties, "start_time", context->start_time );
// Check if we're seekable (something funny about mpeg here :-/)
- if ( strcmp( file, "pipe:" ) )
- mlt_properties_set_int( properties, "seekable", av_seek_frame( context, -1, mlt_properties_get_double( properties, "start_time" ) ) >= 0 );
+ if ( strcmp( file, "pipe:" ) && strncmp( file, "http://", 6 ) )
+ mlt_properties_set_int( properties, "seekable", av_seek_frame( context, -1, mlt_properties_get_double( properties, "start_time" ), AVSEEK_FLAG_BACKWARD ) >= 0 );
+ else
+ av_bypass = 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 );
// We're going to cheat here - for a/v files, we will have two contexts (reasoning will be clear later)
- if ( av == 0 && strcmp( file, "pipe:" ) && audio_index != -1 && video_index != -1 )
+ if ( av == 0 && !av_bypass && audio_index != -1 && video_index != -1 )
{
// We'll use the open one as our video_context
mlt_properties_set_data( properties, "video_context", context, 0, producer_file_close, NULL );
// Something has gone wrong
error = -1;
}
+
+ mlt_properties_set_int( properties, "av_bypass", av_bypass );
}
}
pict.linesize[2] = width >> 1;
img_convert( &pict, PIX_FMT_YUV420P, (AVPicture *)frame, pix_fmt, width, height );
}
+ else if ( format == mlt_image_rgb24 )
+ {
+ AVPicture output;
+ avpicture_fill( &output, buffer, PIX_FMT_RGB24, width, height );
+ img_convert( &output, PIX_FMT_RGB24, (AVPicture *)frame, pix_fmt, width, height );
+ }
else
{
AVPicture output;
// Generate the size in bytes
int size = 0;
+ // Hopefully provide better support for streams...
+ int av_bypass = mlt_properties_get_int( properties, "av_bypass" );
+
// Set the result arguments that we know here (only *buffer is now required)
- if ( *format != mlt_image_yuv422 && *format != mlt_image_yuv420p )
- *format = mlt_image_yuv422;
*width = codec_context->width;
*height = codec_context->height;
- size = *width * ( *height + 1 ) * 2;
+ switch ( *format )
+ {
+ case mlt_image_yuv420p:
+ size = *width * 3 * ( *height + 1 ) / 2;
+ break;
+ case mlt_image_rgb24:
+ size = *width * ( *height + 1 ) * 3;
+ break;
+ default:
+ *format = mlt_image_yuv422;
+ size = *width * ( *height + 1 ) * 2;
+ break;
+ }
// Set this on the frame properties
mlt_properties_set_int( frame_properties, "width", *width );
// Fast forward - seeking is inefficient for small distances - just ignore following frames
ignore = position - expected;
}
- else if ( codec_context->gop_size == 0 || ( position < expected || position - expected >= 12 ) )
+ else if ( seekable && ( position < expected || position - expected >= 12 ) )
{
// Set to the real timecode
- av_seek_frame( context, -1, mlt_properties_get_double( properties, "start_time" ) + real_timecode * 1000000.0 );
+ av_seek_frame( context, -1, mlt_properties_get_double( properties, "start_time" ) + real_timecode * 1000000.0, AVSEEK_FLAG_BACKWARD );
// Remove the cached info relating to the previous position
mlt_properties_set_double( properties, "current_time", real_timecode );
// Duplicate the last image if necessary
if ( av_frame != NULL && ( paused || mlt_properties_get_double( properties, "current_time" ) >= real_timecode ) &&
- strcmp( mlt_properties_get( properties, "resource" ), "pipe:" ) )
+ av_bypass == 0 )
{
// Duplicate it
convert_image( av_frame, *buffer, codec_context->pix_fmt, *format, *width, *height );
{
int ret = 0;
int got_picture = 0;
+ int must_decode = 1;
+
+ // Temporary hack to improve intra frame only
+ if ( !strcmp( codec_context->codec->name, "mjpeg" ) )
+ must_decode = 0;
memset( &pkt, 0, sizeof( pkt ) );
{
av_frame = calloc( 1, sizeof( AVFrame ) );
mlt_properties_set_data( properties, "av_frame", av_frame, 0, free, NULL );
- paused = 0;
}
while( ret >= 0 && !got_picture )
// We only deal with video from the selected video_index
if ( ret >= 0 && pkt.stream_index == index && pkt.size > 0 )
{
+ // Determine time code of the packet
+ if ( pkt.pts != AV_NOPTS_VALUE )
+ current_time = ( double )pkt.pts / 1000000.0;
+ else
+ current_time = real_timecode;
+
// Decode the image
- ret = avcodec_decode_video( codec_context, av_frame, &got_picture, pkt.data, pkt.size );
+ if ( must_decode || current_time >= real_timecode )
+ ret = avcodec_decode_video( codec_context, av_frame, &got_picture, pkt.data, pkt.size );
if ( got_picture )
{
- if ( pkt.pts != AV_NOPTS_VALUE )
- current_time = ( double )pkt.pts / 1000000.0;
- else
- current_time = real_timecode;
-
// Handle ignore
if ( ( int )( current_time * 100 ) < ( int )( real_timecode * 100 ) - 7 )
{
}
else if ( current_time >= real_timecode )
{
- //current_time = real_timecode;
ignore = 0;
}
else if ( ignore -- )
if ( codec != NULL )
{
double source_fps = 0;
+ int norm_aspect_ratio = mlt_properties_get_int( properties, "norm_aspect_ratio" );
// XXX: We won't know the real aspect ratio until an image is decoded
// but we do need it now (to satisfy filter_resize) - take a guess based
// on pal/ntsc
- if ( codec_context->sample_aspect_ratio.num > 0 )
+ if ( !norm_aspect_ratio && codec_context->sample_aspect_ratio.num > 0 )
{
mlt_properties_set_double( properties, "aspect_ratio", av_q2d( codec_context->sample_aspect_ratio ) );
}
else if ( position < expected || position - expected >= 12 )
{
// Set to the real timecode
- if ( av_seek_frame( context, -1, mlt_properties_get_double( properties, "start_time" ) + real_timecode * 1000000.0 ) != 0 )
+ if ( av_seek_frame( context, -1, mlt_properties_get_double( properties, "start_time" ) + real_timecode * 1000000.0, AVSEEK_FLAG_BACKWARD ) != 0 )
paused = 1;
// Clear the usage in the audio buffer
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_position( this ) );
+ mlt_properties_set_position( mlt_frame_properties( *frame ), "avformat_position", mlt_producer_frame( this ) );
// Set up the video
producer_set_up_video( this, *frame );