// ffmpeg Header files
#include <avformat.h>
+#include <opt.h>
#ifdef SWSCALE
# include <swscale.h>
#endif
/** Find the default streams.
*/
-static void find_default_streams( AVFormatContext *context, int *audio_index, int *video_index )
+static mlt_properties find_default_streams( mlt_properties meta_media, AVFormatContext *context, int *audio_index, int *video_index )
{
int i;
+ char key[200];
+
+ mlt_properties_set_int( meta_media, "meta.media.nb_streams", context->nb_streams );
// Allow for multiple audio and video streams in the file and select first of each (if available)
for( i = 0; i < context->nb_streams; i++ )
{
// Get the codec context
- AVCodecContext *codec_context = context->streams[ i ]->codec;
+ AVStream *stream = context->streams[ i ];
+ if ( ! stream ) continue;
+ AVCodecContext *codec_context = stream->codec;
+ if ( ! codec_context ) continue;
+ AVCodec *codec = avcodec_find_decoder( codec_context->codec_id );
+ if ( ! codec ) continue;
- if ( avcodec_find_decoder( codec_context->codec_id ) == NULL )
- continue;
+ snprintf( key, sizeof(key), "meta.media.%d.stream.type", i );
// Determine the type and obtain the first index of each type
- switch( codec_context->codec_type )
+ switch( codec_context->codec_type )
{
case CODEC_TYPE_VIDEO:
if ( *video_index < 0 )
*video_index = i;
+ mlt_properties_set( meta_media, key, "video" );
+ snprintf( key, sizeof(key), "meta.media.%d.stream.frame_rate", i );
+ mlt_properties_set_double( meta_media, key, av_q2d( context->streams[ i ]->r_frame_rate ) );
+ snprintf( key, sizeof(key), "meta.media.%d.stream.sample_aspect_ratio", i );
+ mlt_properties_set_double( meta_media, key, av_q2d( context->streams[ i ]->sample_aspect_ratio ) );
+ snprintf( key, sizeof(key), "meta.media.%d.codec.pix_fmt", i );
+ mlt_properties_set( meta_media, key, avcodec_get_pix_fmt_name( codec_context->pix_fmt ) );
+ snprintf( key, sizeof(key), "meta.media.%d.codec.sample_aspect_ratio", i );
+ mlt_properties_set_double( meta_media, key, av_q2d( codec_context->sample_aspect_ratio ) );
break;
case CODEC_TYPE_AUDIO:
if ( *audio_index < 0 )
*audio_index = i;
+ mlt_properties_set( meta_media, key, "audio" );
+ snprintf( key, sizeof(key), "meta.media.%d.codec.sample_fmt", i );
+ mlt_properties_set( meta_media, key, avcodec_get_sample_fmt_name( codec_context->sample_fmt ) );
+ snprintf( key, sizeof(key), "meta.media.%d.codec.sample_rate", i );
+ mlt_properties_set_int( meta_media, key, codec_context->sample_rate );
+ snprintf( key, sizeof(key), "meta.media.%d.codec.channels", i );
+ mlt_properties_set_int( meta_media, key, codec_context->channels );
break;
default:
break;
}
+// snprintf( key, sizeof(key), "meta.media.%d.stream.time_base", i );
+// 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 );
+ snprintf( key, sizeof(key), "meta.media.%d.codec.long_name", i );
+ mlt_properties_set( meta_media, key, codec->long_name );
+ 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 );
+// mlt_properties_set_double( meta_media, key, av_q2d( codec_context->time_base ) );
+ snprintf( key, sizeof(key), "meta.media.%d.codec.profile", i );
+ mlt_properties_set_int( meta_media, key, codec_context->profile );
+ snprintf( key, sizeof(key), "meta.media.%d.codec.level", i );
+ mlt_properties_set_int( meta_media, key, codec_context->level );
}
+
+ return meta_media;
}
/** Producer file destructor.
}
// Find default audio and video streams
- find_default_streams( context, &audio_index, &video_index );
+ find_default_streams( properties, context, &audio_index, &video_index );
if ( context->start_time != AV_NOPTS_VALUE )
mlt_properties_set_double( properties, "_start_time", context->start_time );
// Construct an AVFrame for YUV422 conversion
if ( av_frame == NULL )
- {
av_frame = avcodec_alloc_frame( );
- mlt_properties_set_data( properties, "av_frame", av_frame, 0, av_free, NULL );
- }
while( ret >= 0 && !got_picture )
{
mlt_properties_set_int( properties, "top_field_first", av_frame->top_field_first );
mlt_properties_set_int( properties, "_current_position", int_position );
mlt_properties_set_int( properties, "_got_picture", 1 );
+ mlt_properties_set_data( properties, "av_frame", av_frame, 0, av_free, NULL );
}
else
{
return 0;
}
+/** Process properties as AVOptions and apply to AV context obj
+*/
+
+static void apply_properties( void *obj, mlt_properties properties, int flags )
+{
+ int i;
+ int count = mlt_properties_count( properties );
+ for ( i = 0; i < count; i++ )
+ {
+ const char *opt_name = mlt_properties_get_name( properties, i );
+ const AVOption *opt = av_find_opt( obj, opt_name, NULL, flags, flags );
+ if ( opt != NULL )
+#if LIBAVCODEC_VERSION_INT >= ((51<<16)+(59<<8)+0)
+ av_set_string2( obj, opt_name, mlt_properties_get( properties, opt_name), 0 );
+#else
+ av_set_string( obj, opt_name, mlt_properties_get( properties, opt_name) );
+#endif
+ }
+}
+
/** Set up video handling.
*/
context = mlt_properties_get_data( properties, "video_context", NULL );
mlt_properties_set_data( properties, "dummy_context", NULL, 0, NULL, NULL );
mlt_events_unblock( properties, this );
+
+ // Process properties as AVOptions
+ apply_properties( context, properties, AV_OPT_FLAG_DECODING_PARAM );
}
// Exception handling for video_index
index = -1;
}
avformat_unlock( );
+
+ // Process properties as AVOptions
+ apply_properties( codec_context, properties, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM );
}
// No codec, no show...
index = -1;
}
avformat_unlock( );
+
+ // Process properties as AVOptions
+ apply_properties( codec_context, properties, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM );
}
// No codec, no show...