return filter_avcolour_space_init( arg );
if ( !strcmp( id, "avdeinterlace" ) )
return filter_avdeinterlace_init( arg );
+#if LIBAVCODEC_VERSION_INT < ((54<<16)+(26<<8)+0)
if ( !strcmp( id, "avresample" ) )
return filter_avresample_init( arg );
+#endif
#ifdef SWSCALE
if ( !strcmp( id, "swscale" ) )
return filter_swscale_init( profile, arg );
MLT_REGISTER( filter_type, "avcolour_space", create_service );
MLT_REGISTER( filter_type, "avcolor_space", create_service );
MLT_REGISTER( filter_type, "avdeinterlace", create_service );
+#if LIBAVCODEC_VERSION_INT < ((54<<16)+(26<<8)+0)
MLT_REGISTER( filter_type, "avresample", create_service );
+#endif
#ifdef SWSCALE
MLT_REGISTER( filter_type, "swscale", create_service );
#endif
#endif
}
-static mlt_image_format pick_format( enum PixelFormat pix_fmt )
+static mlt_image_format pick_pix_format( enum PixelFormat pix_fmt )
{
switch ( pix_fmt )
{
}
}
+static mlt_audio_format pick_audio_format( enum AVSampleFormat sample_fmt )
+{
+ switch ( sample_fmt )
+ {
+ // interleaved
+ case AV_SAMPLE_FMT_S16:
+ return mlt_audio_s16;
+ case AV_SAMPLE_FMT_S32:
+ return mlt_audio_s32le;
+ case AV_SAMPLE_FMT_FLT:
+ return mlt_audio_f32le;
+ // planar - this producer converts planar to interleaved
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(17<<8)+0)
+ case AV_SAMPLE_FMT_S16P:
+ return mlt_audio_s16;
+ case AV_SAMPLE_FMT_S32P:
+ return mlt_audio_s32le;
+ case AV_SAMPLE_FMT_FLTP:
+ return mlt_audio_f32le;
+#endif
+ default:
+ return mlt_audio_none;
+ }
+}
+
static void convert_image( producer_avformat self, AVFrame *frame, uint8_t *buffer, int pix_fmt,
mlt_image_format *format, int width, int height, uint8_t **alpha )
{
codec_context->pix_fmt == PIX_FMT_RGBA ||
codec_context->pix_fmt == PIX_FMT_ABGR ||
codec_context->pix_fmt == PIX_FMT_BGRA )
- *format = pick_format( codec_context->pix_fmt );
+ *format = pick_pix_format( codec_context->pix_fmt );
// Duplicate the last image if necessary
if ( self->av_frame && self->av_frame->linesize[0]
#endif
}
+static void planar_to_interleaved( uint8_t *dest, uint8_t *src, int samples, int channels, int bytes_per_sample )
+{
+ int s, c;
+ for ( s = 0; s < samples; s++ )
+ {
+ for ( c = 0; c < channels; c++ )
+ {
+ memcpy( dest, src + ( c * samples + s ) * bytes_per_sample, bytes_per_sample );
+ dest += bytes_per_sample;
+ }
+ }
+}
+
static int decode_audio( producer_avformat self, int *ignore, AVPacket pkt, int channels, int samples, double timecode, double fps )
{
// Fetch the audio_format
}
else
{
- // Straight copy to audio buffer
- memcpy( &audio_buffer[ audio_used * codec_context->channels * sizeof_sample ], decode_buffer, data_size );
+ uint8_t *source = decode_buffer;
+ uint8_t *dest = &audio_buffer[ audio_used * codec_context->channels * sizeof_sample ];
+ switch ( codec_context->sample_fmt )
+ {
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(17<<8)+0)
+ case AV_SAMPLE_FMT_S16P:
+ case AV_SAMPLE_FMT_S32P:
+ case AV_SAMPLE_FMT_FLTP:
+ planar_to_interleaved( dest, source, convert_samples, codec_context->channels, sizeof_sample );
+ break;
+#endif
+ default:
+ // Straight copy to audio buffer
+ memcpy( dest, decode_buffer, data_size );
+ }
audio_used += convert_samples;
}
if ( codec_context && !self->audio_buffer[ index ] )
{
+#if LIBAVCODEC_VERSION_INT < ((54<<16)+(26<<8)+0)
// Check for resample and create if necessary
if ( codec_context->channels <= 2 )
{
#endif
}
else
+#endif
{
codec_context->request_channels = self->audio_index == INT_MAX ? codec_context->channels : *channels;
sizeof_sample = sample_bytes( codec_context );
index = self->audio_index;
*channels = self->audio_codec[ index ]->channels;
*frequency = self->audio_codec[ index ]->sample_rate;
- *format = self->audio_codec[ index ]->sample_fmt == AV_SAMPLE_FMT_S32 ? mlt_audio_s32le
- : self->audio_codec[ index ]->sample_fmt == AV_SAMPLE_FMT_FLT ? mlt_audio_f32le
- : mlt_audio_s16;
+ *format = pick_audio_format( self->audio_codec[ index ]->sample_fmt );
sizeof_sample = sample_bytes( self->audio_codec[ index ] );
}
else if ( self->audio_index == INT_MAX )
{
- // This only works if all audio tracks have the same sample format.
for ( index = 0; index < index_max; index++ )
if ( self->audio_codec[ index ] && !self->audio_resample[ index ] )
{
- *format = self->audio_codec[ index ]->sample_fmt == AV_SAMPLE_FMT_S32 ? mlt_audio_s32le
- : self->audio_codec[ index ]->sample_fmt == AV_SAMPLE_FMT_FLT ? mlt_audio_f32le
- : mlt_audio_s16;
+ // XXX: This only works if all audio tracks have the same sample format.
+ *format = pick_audio_format( self->audio_codec[ index ]->sample_fmt );
sizeof_sample = sample_bytes( self->audio_codec[ index ] );
break;
}