+static enum PixelFormat pick_pix_fmt( mlt_image_format img_fmt )
+{
+ switch ( img_fmt )
+ {
+ case mlt_image_rgb24:
+ return PIX_FMT_RGB24;
+ case mlt_image_rgb24a:
+ return PIX_FMT_RGBA;
+ case mlt_image_yuv420p:
+ return PIX_FMT_YUV420P;
+ default:
+ return PIX_FMT_YUYV422;
+ }
+}
+
+static int get_mlt_audio_format( int av_sample_fmt )
+{
+ switch ( av_sample_fmt )
+ {
+ case AV_SAMPLE_FMT_U8:
+ return mlt_audio_u8;
+ case AV_SAMPLE_FMT_S32:
+ return mlt_audio_s32le;
+ case AV_SAMPLE_FMT_FLT:
+ return mlt_audio_f32le;
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(17<<8)+0)
+ case AV_SAMPLE_FMT_U8P:
+ return mlt_audio_u8;
+ case AV_SAMPLE_FMT_S32P:
+ return mlt_audio_s32le;
+ case AV_SAMPLE_FMT_FLTP:
+ return mlt_audio_f32le;
+#endif
+ default:
+ return mlt_audio_s16;
+ }
+}
+
+static int pick_sample_fmt( mlt_properties properties, AVCodec *codec )
+{
+ int sample_fmt = AV_SAMPLE_FMT_S16;
+ const char *format = mlt_properties_get( properties, "mlt_audio_format" );
+ const int *p = codec->sample_fmts;
+
+ // get default av_sample_fmt from mlt_audio_format
+ if ( format )
+ {
+ if ( !strcmp( format, "s32le" ) )
+ sample_fmt = AV_SAMPLE_FMT_S32;
+ else if ( !strcmp( format, "f32le" ) )
+ sample_fmt = AV_SAMPLE_FMT_FLT;
+ else if ( !strcmp( format, "u8" ) )
+ sample_fmt = AV_SAMPLE_FMT_U8;
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(17<<8)+0)
+ else if ( !strcmp( format, "s32" ) )
+ sample_fmt = AV_SAMPLE_FMT_S32P;
+ else if ( !strcmp( format, "float" ) )
+ sample_fmt = AV_SAMPLE_FMT_FLTP;
+#endif
+ }
+ // check if codec supports our mlt_audio_format
+ for ( ; *p != -1; p++ )
+ {
+ if ( *p == sample_fmt )
+ return sample_fmt;
+ }
+ // no match - pick first one we support
+ for ( p = codec->sample_fmts; *p != -1; p++ )
+ {
+ switch (*p)
+ {
+ case AV_SAMPLE_FMT_U8:
+ case AV_SAMPLE_FMT_S16:
+ case AV_SAMPLE_FMT_S32:
+ case AV_SAMPLE_FMT_FLT:
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(17<<8)+0)
+ case AV_SAMPLE_FMT_U8P:
+ case AV_SAMPLE_FMT_S16P:
+ case AV_SAMPLE_FMT_S32P:
+ case AV_SAMPLE_FMT_FLTP:
+#endif
+ return *p;
+ default:
+ break;
+ }
+ }
+ mlt_log_error( properties, "audio codec sample_fmt not compatible" );
+
+ return AV_SAMPLE_FMT_NONE;
+}
+
+static uint8_t* interleaved_to_planar( int samples, int channels, uint8_t* audio, int bytes_per_sample )
+{
+ uint8_t *buffer = mlt_pool_alloc( AUDIO_ENCODE_BUFFER_SIZE );
+ uint8_t *p = buffer;
+ int c;
+
+ memset( buffer, 0, AUDIO_ENCODE_BUFFER_SIZE );
+ for ( c = 0; c < channels; c++ )
+ {
+ uint8_t *q = audio + c * bytes_per_sample;
+ int i = samples + 1;
+ while ( --i )
+ {
+ memcpy( p, q, bytes_per_sample );
+ p += bytes_per_sample;
+ q += channels * bytes_per_sample;
+ }
+ }
+ return buffer;
+}
+