summarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.SRCINFO61
-rw-r--r--PKGBUILD76
-rw-r--r--ffmpeg5.patch890
3 files changed, 1027 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..820ce87903b0
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,61 @@
+pkgbase = mlt6
+ pkgdesc = An open source multimedia framework
+ pkgver = 6.26.1
+ pkgrel = 11
+ url = https://www.mltframework.org
+ arch = x86_64
+ license = GPL
+ makedepends = cmake
+ makedepends = ladspa
+ makedepends = frei0r-plugins
+ makedepends = libdv
+ makedepends = sdl_image
+ makedepends = libsamplerate
+ makedepends = sox
+ makedepends = ffmpeg
+ makedepends = vid.stab
+ makedepends = qt5-svg
+ makedepends = jack
+ makedepends = libexif
+ makedepends = python
+ makedepends = swig
+ makedepends = movit
+ makedepends = eigen
+ makedepends = opencv
+ makedepends = rubberband
+ makedepends = gdk-pixbuf2
+ makedepends = pango
+ makedepends = rtaudio
+ makedepends = imagemagick
+ depends = libebur128
+ optdepends = sdl_image: SDL1 plugin
+ optdepends = sdl2: SDL2 plugin
+ optdepends = libsamplerate: libavresample plugin
+ optdepends = sox: SOX (Audio Swiss Army Knife) plugin
+ optdepends = ffmpeg: ffmpeg plugin
+ optdepends = vid.stab: video stabilize plugin
+ optdepends = qt5-svg: Qt5 plugins
+ optdepends = jack: JACK sound output plugin
+ optdepends = ladspa: LADSPA plugins
+ optdepends = libexif: auto rotate plugin
+ optdepends = frei0r-plugins: for additional effects
+ optdepends = movit: opengl plugin
+ optdepends = opencv: openCV plugin
+ optdepends = rubberband: audio pitch plugin
+ optdepends = gdk-pixbuf2: gdk plugin
+ optdepends = pango: gdk plugin
+ optdepends = rtaudio: rtaudio plugin
+ optdepends = python: python bindings
+ provides = python-mlt
+ conflicts = python-mlt
+ replaces = python-mlt
+ source = mlt6-6.26.1.tar.gz::https://github.com/mltframework/mlt/archive/v6.26.1.tar.gz
+ source = https://github.com/mltframework/mlt/commit/7063e88e.patch
+ source = https://github.com/mltframework/mlt/commit/a87229bc.patch
+ source = ffmpeg5.patch
+ sha256sums = 8a484bbbf51f33e25312757531f3ad2ce20607149d20fcfcb40a3c1e60b20b4e
+ sha256sums = 8c2f537e46089ac165da12988aecf49e24d20ec33c1b88c6301f3d2640b8d8f3
+ sha256sums = fc08a5cefb9e164966d5a6514196866dc96bb33719b5b7c069e0b8910e8f8fa5
+ sha256sums = 7e21d494dbd5d5fe4627b82fbbfe63b52cbda316ad24ed995f8cbe60019566a0
+
+pkgname = mlt6
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..948bc7e0b9f3
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,76 @@
+# Maintainer:
+# Contributor: Antonio Rojas <arojas@archlinux.org>
+# Contributor: Sergej Pupykin <pupykin.s+arch@gmail.com>
+# Contributor: Fabian Schoelzel <myfirstname.mylastname@googlemail.com>
+# Contributor: funkyou <spamopfer@nickname.berlin.de>
+# Contributor: tardo <tardo@nagi-fanboi.net>
+# Contributor: Stefan Husmann <stefan-husmann@t-online.de>
+# Contributor: Gustavo Alvarez <sl1pkn07@gmail.com>
+
+pkgname=mlt6
+pkgver=6.26.1
+pkgrel=11
+pkgdesc="An open source multimedia framework"
+arch=(x86_64)
+url="https://www.mltframework.org"
+license=(GPL)
+depends=(libebur128)
+optdepends=('sdl_image: SDL1 plugin'
+ 'sdl2: SDL2 plugin'
+ 'libsamplerate: libavresample plugin'
+ 'sox: SOX (Audio Swiss Army Knife) plugin'
+ 'ffmpeg: ffmpeg plugin'
+ 'vid.stab: video stabilize plugin'
+ 'qt5-svg: Qt5 plugins'
+ 'jack: JACK sound output plugin'
+ 'ladspa: LADSPA plugins'
+ 'libexif: auto rotate plugin'
+ 'frei0r-plugins: for additional effects'
+ 'movit: opengl plugin'
+ 'opencv: openCV plugin'
+ 'rubberband: audio pitch plugin'
+ 'gdk-pixbuf2: gdk plugin'
+ 'pango: gdk plugin'
+ 'rtaudio: rtaudio plugin'
+ 'python: python bindings')
+makedepends=(cmake ladspa frei0r-plugins libdv sdl_image libsamplerate sox ffmpeg vid.stab qt5-svg
+ jack libexif python swig movit eigen opencv rubberband gdk-pixbuf2 pango rtaudio imagemagick)
+conflicts=(python-mlt)
+provides=(python-mlt)
+replaces=(python-mlt)
+source=($pkgname-$pkgver.tar.gz::https://github.com/mltframework/mlt/archive/v$pkgver.tar.gz
+ https://github.com/mltframework/mlt/commit/7063e88e.patch
+ https://github.com/mltframework/mlt/commit/a87229bc.patch
+ ffmpeg5.patch)
+sha256sums=('8a484bbbf51f33e25312757531f3ad2ce20607149d20fcfcb40a3c1e60b20b4e'
+ '8c2f537e46089ac165da12988aecf49e24d20ec33c1b88c6301f3d2640b8d8f3'
+ 'fc08a5cefb9e164966d5a6514196866dc96bb33719b5b7c069e0b8910e8f8fa5'
+ '7e21d494dbd5d5fe4627b82fbbfe63b52cbda316ad24ed995f8cbe60019566a0')
+
+prepare() {
+# Backport fixes for kdenlive crashes
+ patch -d mlt-$pkgver -p1 < 7063e88e.patch
+ patch -d mlt-$pkgver -p1 < a87229bc.patch
+# Fix build with FFmpeg 5
+ patch -d mlt-$pkgver -p1 < ffmpeg5.patch
+}
+
+build() {
+ cmake -B build -S mlt-$pkgver \
+ -DCMAKE_INSTALL_PREFIX=/usr \
+ -DMOD_OPENCV=ON \
+ -DMOD_GTK2=OFF \
+ -DSWIG_PYTHON=ON
+ cmake --build build
+}
+
+package() {
+ DESTDIR="$pkgdir" cmake --install build
+ mv "$pkgdir"/usr/bin/melt{,6} # Fix conflicts with mlt 7
+
+# Compress lumas
+ for pgm in "$pkgdir"/usr/share/mlt/lumas/*/*.pgm; do
+ convert $pgm{,.png}
+ rm -f $pgm
+ done
+}
diff --git a/ffmpeg5.patch b/ffmpeg5.patch
new file mode 100644
index 000000000000..3727b18e0b60
--- /dev/null
+++ b/ffmpeg5.patch
@@ -0,0 +1,890 @@
+From a426473bc8c5e477e305557d5cbd40eaecab33f0 Mon Sep 17 00:00:00 2001
+From: Dan Dennedy <dan@dennedy.org>
+Date: Wed, 1 Sep 2021 21:45:17 -0700
+Subject: [PATCH] fix build against FFmpeg master branch
+
+---
+ setenv | 6 +-
+ src/modules/avformat/consumer_avformat.c | 152 +++++++++++------------
+ src/modules/avformat/factory.c | 67 +++-------
+ src/modules/avformat/filter_avfilter.c | 32 ++---
+ src/modules/avformat/producer_avformat.c | 105 ++++++++++------
+ 5 files changed, 175 insertions(+), 187 deletions(-)
+
+diff --git a/src/modules/avformat/consumer_avformat.c b/src/modules/avformat/consumer_avformat.c
+index efd29b29e..cc4da13a6 100644
+--- a/src/modules/avformat/consumer_avformat.c
++++ b/src/modules/avformat/consumer_avformat.c
+@@ -34,9 +34,11 @@
+ #include <pthread.h>
+ #include <sys/time.h>
+ #include <unistd.h>
++#include <time.h>
+
+ // avformat header files
+ #include <libavformat/avformat.h>
++#include <libavcodec/avcodec.h>
+ #include <libavformat/avio.h>
+ #include <libswscale/swscale.h>
+ #include <libavutil/pixdesc.h>
+@@ -45,6 +47,7 @@
+ #include <libavutil/opt.h>
+ #include <libavutil/imgutils.h>
+ #include <libavutil/version.h>
++#include <libavutil/channel_layout.h>
+ #ifdef AVFILTER
+ #include <libavfilter/avfilter.h>
+ #include <libavfilter/buffersink.h>
+@@ -423,11 +426,12 @@ static int consumer_start( mlt_consumer consumer )
+ mlt_properties doc = mlt_properties_new();
+ mlt_properties formats = mlt_properties_new();
+ char key[20];
+- AVOutputFormat *format = NULL;
++ const AVOutputFormat *format = NULL;
++ void *iterator = NULL;
+
+ mlt_properties_set_data( properties, "f", formats, 0, (mlt_destructor) mlt_properties_close, NULL );
+ mlt_properties_set_data( doc, "formats", formats, 0, NULL, NULL );
+- while ( ( format = av_oformat_next( format ) ) )
++ while ( ( format = av_muxer_iterate( &iterator ) ) )
+ {
+ snprintf( key, sizeof(key), "%d", mlt_properties_count( formats ) );
+ mlt_properties_set( formats, key, format->name );
+@@ -444,11 +448,12 @@ static int consumer_start( mlt_consumer consumer )
+ mlt_properties doc = mlt_properties_new();
+ mlt_properties codecs = mlt_properties_new();
+ char key[20];
+- AVCodec *codec = NULL;
++ const AVCodec *codec = NULL;
+
+ mlt_properties_set_data( properties, "acodec", codecs, 0, (mlt_destructor) mlt_properties_close, NULL );
+ mlt_properties_set_data( doc, "audio_codecs", codecs, 0, NULL, NULL );
+- while ( ( codec = av_codec_next( codec ) ) )
++ void *iterator = NULL;
++ while ( ( codec = av_codec_iterate( &iterator ) ) )
+ #if LIBAVCODEC_VERSION_INT >= ((57<<16)+(37<<8)+0)
+ if ( av_codec_is_encoder(codec) && codec->type == AVMEDIA_TYPE_AUDIO )
+ #else
+@@ -470,11 +475,12 @@ static int consumer_start( mlt_consumer consumer )
+ mlt_properties doc = mlt_properties_new();
+ mlt_properties codecs = mlt_properties_new();
+ char key[20];
+- AVCodec *codec = NULL;
++ const AVCodec *codec = NULL;
++ void *iterator = NULL;
+
+ mlt_properties_set_data( properties, "vcodec", codecs, 0, (mlt_destructor) mlt_properties_close, NULL );
+ mlt_properties_set_data( doc, "video_codecs", codecs, 0, NULL, NULL );
+- while ( ( codec = av_codec_next( codec ) ) )
++ while ( ( codec = av_codec_iterate( &iterator ) ) )
+ #if LIBAVCODEC_VERSION_INT >= ((57<<16)+(37<<8)+0)
+ if ( av_codec_is_encoder(codec) && codec->type == AVMEDIA_TYPE_VIDEO )
+ #else
+@@ -616,7 +622,7 @@ static int get_mlt_audio_format( int av_sample_fmt )
+ }
+ }
+
+-static int pick_sample_fmt( mlt_properties properties, AVCodec *codec )
++static int pick_sample_fmt( mlt_properties properties, const AVCodec *codec )
+ {
+ int sample_fmt = AV_SAMPLE_FMT_S16;
+ const char *format = mlt_properties_get( properties, "mlt_audio_format" );
+@@ -693,7 +699,7 @@ static uint8_t* interleaved_to_planar( int samples, int channels, uint8_t* audio
+ /** Add an audio output stream
+ */
+
+-static AVStream *add_audio_stream( mlt_consumer consumer, AVFormatContext *oc, AVCodec *codec, int channels, int64_t channel_layout )
++static AVStream *add_audio_stream( mlt_consumer consumer, AVFormatContext *oc, const AVCodec *codec, AVCodecContext **codec_context, int channels, int64_t channel_layout )
+ {
+ // Get the properties
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
+@@ -704,10 +710,11 @@ static AVStream *add_audio_stream( mlt_consumer consumer, AVFormatContext *oc, A
+ // If created, then initialise from properties
+ if ( st != NULL )
+ {
+- AVCodecContext *c = st->codec;
+-
+- // Establish defaults from AVOptions
+- avcodec_get_context_defaults3( c, codec );
++ AVCodecContext *c = *codec_context = avcodec_alloc_context3(codec);
++ if (!c) {
++ mlt_log_fatal(MLT_CONSUMER_SERVICE(consumer), "Failed to allocate the audio encoder context\n");
++ return NULL;
++ }
+
+ c->codec_id = codec->id;
+ c->codec_type = AVMEDIA_TYPE_AUDIO;
+@@ -770,21 +777,11 @@ static AVStream *add_audio_stream( mlt_consumer consumer, AVFormatContext *oc, A
+ return st;
+ }
+
+-static int open_audio( mlt_properties properties, AVFormatContext *oc, AVStream *st, int audio_outbuf_size, const char *codec_name )
++static int open_audio( mlt_properties properties, AVFormatContext *oc, AVStream *st, const AVCodec *codec, AVCodecContext *c )
+ {
+ // We will return the audio input size from here
+ int audio_input_frame_size = 0;
+
+- // Get the context
+- AVCodecContext *c = st->codec;
+-
+- // Find the encoder
+- AVCodec *codec;
+- if ( codec_name )
+- codec = avcodec_find_encoder_by_name( codec_name );
+- else
+- codec = avcodec_find_encoder( c->codec_id );
+-
+ // Process properties as AVOptions on the AVCodec
+ if ( codec && codec->priv_class )
+ {
+@@ -807,6 +804,11 @@ static int open_audio( mlt_properties properties, AVFormatContext *oc, AVStream
+ // Continue if codec found and we can open it
+ if ( codec && avcodec_open2( c, codec, NULL ) >= 0 )
+ {
++ if (avcodec_parameters_from_context(st->codecpar, c) < 0) {
++ mlt_log_warning(NULL, "Failed to copy encoder parameters to output audio stream\n");
++ return 0;
++ }
++
+ // ugly hack for PCM codecs (will be removed ASAP with new PCM
+ // support to compute the input frame size in samples
+ if ( c->frame_size <= 1 )
+@@ -829,16 +831,10 @@ static int open_audio( mlt_properties properties, AVFormatContext *oc, AVStream
+ return audio_input_frame_size;
+ }
+
+-static void close_audio( AVFormatContext *oc, AVStream *st )
+-{
+- if ( st && st->codec )
+- avcodec_close( st->codec );
+-}
+-
+ /** Add a video output stream
+ */
+
+-static AVStream *add_video_stream( mlt_consumer consumer, AVFormatContext *oc, AVCodec *codec )
++static AVStream *add_video_stream( mlt_consumer consumer, AVFormatContext *oc, const AVCodec *codec, AVCodecContext **codec_context )
+ {
+ // Get the properties
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
+@@ -849,10 +845,12 @@ static AVStream *add_video_stream( mlt_consumer consumer, AVFormatContext *oc, A
+ if ( st != NULL )
+ {
+ char *pix_fmt = mlt_properties_get( properties, "pix_fmt" );
+- AVCodecContext *c = st->codec;
+
+- // Establish defaults from AVOptions
+- avcodec_get_context_defaults3( c, codec );
++ AVCodecContext *c = *codec_context = avcodec_alloc_context3(codec);
++ if (!c) {
++ mlt_log_fatal(MLT_CONSUMER_SERVICE(consumer), "Failed to allocate the video encoder context\n");
++ return NULL;
++ }
+
+ c->codec_id = codec->id;
+ c->codec_type = AVMEDIA_TYPE_VIDEO;
+@@ -1121,18 +1119,8 @@ static AVFrame *alloc_picture( int pix_fmt, int width, int height )
+ return picture;
+ }
+
+-static int open_video( mlt_properties properties, AVFormatContext *oc, AVStream *st, const char *codec_name )
++static int open_video( mlt_properties properties, AVFormatContext *oc, AVStream *st, const AVCodec *codec, AVCodecContext *video_enc )
+ {
+- // Get the codec
+- AVCodecContext *video_enc = st->codec;
+-
+- // find the video encoder
+- AVCodec *codec;
+- if ( codec_name )
+- codec = avcodec_find_encoder_by_name( codec_name );
+- else
+- codec = avcodec_find_encoder( video_enc->codec_id );
+-
+ // Process properties as AVOptions on the AVCodec
+ if ( codec && codec->priv_class )
+ {
+@@ -1166,21 +1154,22 @@ static int open_video( mlt_properties properties, AVFormatContext *oc, AVStream
+
+ const AVPixFmtDescriptor* srcDesc = av_pix_fmt_desc_get(video_enc->pix_fmt);
+ if (srcDesc->flags & AV_PIX_FMT_FLAG_RGB) {
+- st->codec->colorspace = AVCOL_SPC_RGB;
++ video_enc->colorspace = AVCOL_SPC_RGB;
+ }
+
+ int result = codec && avcodec_open2( video_enc, codec, NULL ) >= 0;
+-
+- return result;
+-}
+
+-void close_video(AVFormatContext *oc, AVStream *st)
+-{
+- if ( st && st->codec )
+- {
+- av_freep( &st->codec->stats_in );
+- avcodec_close(st->codec);
++ if (result >= 0) {
++ result = avcodec_parameters_from_context(st->codecpar, video_enc) >= 0;
++ if (!result) {
++ mlt_log_warning(NULL, "Failed to copy encoder parameters to output video stream\n");
++ }
++ } else {
++ mlt_log_warning( NULL, "%s: Unable to encode video - disabling video output.\n", __FILE__ );
+ }
++
++
++ return result;
+ }
+
+ static inline long time_difference( struct timeval *time1 )
+@@ -1219,7 +1208,9 @@ typedef struct encode_ctx_desc
+
+ AVFormatContext *oc;
+ AVStream *video_st;
++ AVCodecContext *vcodec_ctx;
+ AVStream *audio_st[ MAX_AUDIO_STREAMS ];
++ AVCodecContext *acodec_ctx[MAX_AUDIO_STREAMS];
+ int64_t sample_count[ MAX_AUDIO_STREAMS ];
+
+ // Used to store and override codec ids
+@@ -1279,7 +1270,7 @@ static int encode_audio(encode_ctx_t* ctx)
+ for ( i = 0; i < MAX_AUDIO_STREAMS && ctx->audio_st[i] && j < ctx->total_channels; i++ )
+ {
+ AVStream *stream = ctx->audio_st[i];
+- AVCodecContext *codec = stream->codec;
++ AVCodecContext *codec = ctx->acodec_ctx[i];
+ AVPacket pkt;
+
+ av_init_packet( &pkt );
+@@ -1452,7 +1443,7 @@ static int encode_audio(encode_ctx_t* ctx)
+
+ if ( i == 0 )
+ {
+- ctx->audio_pts = (double) ctx->sample_count[0] * av_q2d( stream->codec->time_base );
++ ctx->audio_pts = (double) ctx->sample_count[0] * av_q2d( codec->time_base );
+ }
+ }
+
+@@ -1531,14 +1522,13 @@ static void *consumer_thread( void *arg )
+ long int total_time = 0;
+
+ // Determine the format
+- AVOutputFormat *fmt = NULL;
++ const AVOutputFormat *fmt = NULL;
+ const char *filename = mlt_properties_get( properties, "target" );
+ char *format = mlt_properties_get( properties, "f" );
+ char *vcodec = mlt_properties_get( properties, "vcodec" );
+ char *acodec = mlt_properties_get( properties, "acodec" );
+- AVCodec *audio_codec = NULL;
+- AVCodec *video_codec = NULL;
+-
++ const AVCodec *audio_codec = NULL;
++ const AVCodec *video_codec = NULL;
+
+ // Misc
+ char key[27];
+@@ -1657,7 +1647,7 @@ static void *consumer_thread( void *arg )
+ // Add audio and video streams
+ if ( enc_ctx->video_codec_id != AV_CODEC_ID_NONE )
+ {
+- if ( ( enc_ctx->video_st = add_video_stream( consumer, enc_ctx->oc, video_codec ) ) )
++ if ( ( enc_ctx->video_st = add_video_stream( consumer, enc_ctx->oc, video_codec, &enc_ctx->vcodec_ctx ) ) )
+ {
+ const char* img_fmt_name = mlt_properties_get( properties, "mlt_image_format" );
+ if ( img_fmt_name )
+@@ -1670,7 +1660,7 @@ static void *consumer_thread( void *arg )
+ else
+ {
+ // Set the mlt_image_format from the selected pix_fmt.
+- const char *pix_fmt_name = av_get_pix_fmt_name( enc_ctx->video_st->codec->pix_fmt );
++ const char *pix_fmt_name = av_get_pix_fmt_name( enc_ctx->vcodec_ctx->pix_fmt );
+ if ( !strcmp( pix_fmt_name, "rgba" ) ||
+ !strcmp( pix_fmt_name, "argb" ) ||
+ !strcmp( pix_fmt_name, "bgra" ) ) {
+@@ -1698,7 +1688,7 @@ static void *consumer_thread( void *arg )
+ {
+ is_multi = 1;
+ enc_ctx->total_channels += j;
+- enc_ctx->audio_st[i] = add_audio_stream( consumer, enc_ctx->oc, audio_codec, j, av_get_default_channel_layout( j ) );
++ enc_ctx->audio_st[i] = add_audio_stream( consumer, enc_ctx->oc, audio_codec, &enc_ctx->acodec_ctx[i], j, av_get_default_channel_layout( j ) );
+ }
+ }
+ // single track
+@@ -1711,7 +1701,7 @@ static void *consumer_thread( void *arg )
+ {
+ layout = mlt_audio_channel_layout_default( enc_ctx->channels );
+ }
+- enc_ctx->audio_st[0] = add_audio_stream( consumer, enc_ctx->oc, audio_codec, enc_ctx->channels, mlt_to_av_channel_layout( layout ) );
++ enc_ctx->audio_st[0] = add_audio_stream( consumer, enc_ctx->oc, audio_codec, &enc_ctx->acodec_ctx[0], enc_ctx->channels, mlt_to_av_channel_layout( layout ) );
+ enc_ctx->total_channels = enc_ctx->channels;
+ }
+ }
+@@ -1720,7 +1710,7 @@ static void *consumer_thread( void *arg )
+ // Audio format is determined when adding the audio stream
+ mlt_audio_format aud_fmt = mlt_audio_none;
+ if ( enc_ctx->audio_st[0] )
+- aud_fmt = get_mlt_audio_format( enc_ctx->audio_st[0]->codec->sample_fmt );
++ aud_fmt = get_mlt_audio_format( enc_ctx->acodec_ctx[0]->sample_fmt );
+ enc_ctx->sample_bytes = mlt_audio_format_size( aud_fmt, 1, 1 );
+ enc_ctx->sample_bytes = enc_ctx->sample_bytes ? enc_ctx->sample_bytes : 1; // prevent divide by zero
+
+@@ -1744,16 +1734,15 @@ static void *consumer_thread( void *arg )
+ if ( enc_ctx->oc->oformat && enc_ctx->oc->oformat->priv_class && enc_ctx->oc->priv_data )
+ apply_properties( enc_ctx->oc->priv_data, properties, AV_OPT_FLAG_ENCODING_PARAM );
+
+- if ( enc_ctx->video_st && !open_video( properties, enc_ctx->oc, enc_ctx->video_st, vcodec? vcodec : NULL ) )
++ if ( enc_ctx->video_st && !open_video( properties, enc_ctx->oc, enc_ctx->video_st, video_codec, enc_ctx->vcodec_ctx ) )
+ enc_ctx->video_st = NULL;
+ for ( i = 0; i < MAX_AUDIO_STREAMS && enc_ctx->audio_st[i]; i++ )
+ {
+- enc_ctx->audio_input_frame_size = open_audio( properties, enc_ctx->oc, enc_ctx->audio_st[i], enc_ctx->audio_outbuf_size,
+- acodec? acodec : NULL );
++ enc_ctx->audio_input_frame_size = open_audio( properties, enc_ctx->oc, enc_ctx->audio_st[i], audio_codec, enc_ctx->acodec_ctx[i] );
+ if ( !enc_ctx->audio_input_frame_size )
+ {
+ // Remove the audio stream from the output context
+- int j;
++ unsigned int j;
+ for ( j = 0; j < enc_ctx->oc->nb_streams; j++ )
+ {
+ if ( enc_ctx->oc->streams[j] == enc_ctx->audio_st[i] )
+@@ -1808,10 +1797,10 @@ static void *consumer_thread( void *arg )
+ enum AVPixelFormat pix_fmt;
+ if ( enc_ctx->video_st ) {
+ #if defined(AVFILTER) && LIBAVUTIL_VERSION_MAJOR >= 56
+- pix_fmt = enc_ctx->video_st->codec->pix_fmt == AV_PIX_FMT_VAAPI ?
+- AV_PIX_FMT_NV12 : enc_ctx->video_st->codec->pix_fmt;
++ pix_fmt = enc_ctx->vcodec_ctx->pix_fmt == AV_PIX_FMT_VAAPI ?
++ AV_PIX_FMT_NV12 : enc_ctx->vcodec_ctx->pix_fmt;
+ #else
+- pix_fmt = enc_ctx->video_st->codec->pix_fmt;
++ pix_fmt = enc_ctx->vcodec_ctx->pix_fmt;
+ #endif
+ converted_avframe = alloc_picture( pix_fmt, width, height );
+ if ( !converted_avframe ) {
+@@ -1826,7 +1815,7 @@ static void *consumer_thread( void *arg )
+ {
+ enc_ctx->audio_avframe = av_frame_alloc();
+ if ( enc_ctx->audio_avframe ) {
+- AVCodecContext *c = enc_ctx->audio_st[0]->codec;
++ AVCodecContext *c = enc_ctx->acodec_ctx[0];
+ enc_ctx->audio_avframe->format = c->sample_fmt;
+ enc_ctx->audio_avframe->nb_samples = enc_ctx->audio_input_frame_size;
+ enc_ctx->audio_avframe->channel_layout = c->channel_layout;
+@@ -1957,7 +1946,7 @@ static void *consumer_thread( void *arg )
+ if ( mlt_deque_count( queue ) )
+ {
+ int ret = 0;
+- AVCodecContext *c = enc_ctx->video_st->codec;
++ AVCodecContext *c = enc_ctx->vcodec_ctx;
+
+ frame = mlt_deque_pop_front( queue );
+ frame_properties = MLT_FRAME_PROPERTIES( frame );
+@@ -2156,7 +2145,7 @@ static void *consumer_thread( void *arg )
+ }
+ }
+ enc_ctx->frame_count++;
+- enc_ctx->video_pts = (double) enc_ctx->frame_count * av_q2d( enc_ctx->video_st->codec->time_base );
++ enc_ctx->video_pts = (double) enc_ctx->frame_count * av_q2d( enc_ctx->vcodec_ctx->time_base );
+ if ( ret )
+ {
+ mlt_log_fatal( MLT_CONSUMER_SERVICE(consumer), "error writing video frame: %d\n", ret );
+@@ -2222,7 +2211,7 @@ static void *consumer_thread( void *arg )
+ if ( enc_ctx->video_st ) for (;;)
+ #endif
+ {
+- AVCodecContext *c = enc_ctx->video_st->codec;
++ AVCodecContext *c = enc_ctx->vcodec_ctx;
+ AVPacket pkt;
+ av_init_packet( &pkt );
+ if ( c->codec->id == AV_CODEC_ID_RAWVIDEO ) {
+@@ -2290,20 +2279,19 @@ static void *consumer_thread( void *arg )
+ av_free( converted_avframe->data[0] );
+ av_free( converted_avframe );
+ #if defined(AVFILTER) && LIBAVUTIL_VERSION_MAJOR >= 56
+- if (enc_ctx->video_st && enc_ctx->video_st->codec && AV_PIX_FMT_VAAPI == enc_ctx->video_st->codec->pix_fmt)
++ if (enc_ctx->video_st && enc_ctx->vcodec_ctx && AV_PIX_FMT_VAAPI == enc_ctx->vcodec_ctx->pix_fmt)
+ av_frame_free(&avframe);
+ #endif
+ av_free( video_outbuf );
+ av_free( enc_ctx->audio_avframe );
+
+ // close each codec
+- if ( enc_ctx->video_st )
+- close_video(enc_ctx->oc, enc_ctx->video_st);
+- for ( i = 0; i < MAX_AUDIO_STREAMS && enc_ctx->audio_st[i]; i++ )
+- close_audio( enc_ctx->oc, enc_ctx->audio_st[i] );
++ avcodec_free_context(&enc_ctx->vcodec_ctx);
++ for ( i = 0; i < MAX_AUDIO_STREAMS; i++ )
++ avcodec_free_context(&enc_ctx->acodec_ctx[i]);
+
+ // Free the streams
+- for ( i = 0; i < enc_ctx->oc->nb_streams; i++ )
++ for ( unsigned int i = 0; i < enc_ctx->oc->nb_streams; i++ )
+ av_freep( &enc_ctx->oc->streams[i] );
+
+ // Close the output file
+diff --git a/src/modules/avformat/factory.c b/src/modules/avformat/factory.c
+index cf80385a4..b142b6327 100644
+--- a/src/modules/avformat/factory.c
++++ b/src/modules/avformat/factory.c
+@@ -34,6 +34,7 @@ extern mlt_filter filter_avfilter_init( mlt_profile, mlt_service_type, const cha
+
+ // ffmpeg Header files
+ #include <libavformat/avformat.h>
++#include <libavcodec/avcodec.h>
+ #ifdef AVDEVICE
+ #include <libavdevice/avdevice.h>
+ #endif
+@@ -46,56 +47,19 @@ extern mlt_filter filter_avfilter_init( mlt_profile, mlt_service_type, const cha
+ // A static flag used to determine if avformat has been initialised
+ static int avformat_initialised = 0;
+
+-static int avformat_lockmgr(void **mutex, enum AVLockOp op)
+-{
+- pthread_mutex_t** pmutex = (pthread_mutex_t**) mutex;
+-
+- switch (op)
+- {
+- case AV_LOCK_CREATE:
+- *pmutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
+- if (!*pmutex) return -1;
+- pthread_mutex_init(*pmutex, NULL);
+- break;
+- case AV_LOCK_OBTAIN:
+- if (!*pmutex) return -1;
+- pthread_mutex_lock(*pmutex);
+- break;
+- case AV_LOCK_RELEASE:
+- if (!*pmutex) return -1;
+- pthread_mutex_unlock(*pmutex);
+- break;
+- case AV_LOCK_DESTROY:
+- if (!*pmutex) return -1;
+- pthread_mutex_destroy(*pmutex);
+- free(*pmutex);
+- *pmutex = NULL;
+- break;
+- }
+-
+- return 0;
+-}
+-
+-static void unregister_lockmgr( void *p )
+-{
+- av_lockmgr_register( NULL );
+-}
+-
+ static void avformat_init( )
+ {
+ // Initialise avformat if necessary
+ if ( avformat_initialised == 0 )
+ {
+ avformat_initialised = 1;
+- av_lockmgr_register( &avformat_lockmgr );
+- mlt_factory_register_for_clean_up( &avformat_lockmgr, unregister_lockmgr );
+- av_register_all( );
++// av_register_all( );
+ #ifdef AVDEVICE
+ avdevice_register_all();
+ #endif
+-#ifdef AVFILTER
+- avfilter_register_all();
+-#endif
++//#ifdef AVFILTER
++// avfilter_register_all();
++//#endif
+ avformat_network_init();
+ av_log_set_level( mlt_log_get_level() );
+ if ( getenv("MLT_AVFORMAT_PRODUCER_CACHE") )
+@@ -330,22 +294,25 @@ static mlt_properties avformat_metadata( mlt_service_type type, const char *id,
+ avformat_init();
+ if ( type == mlt_service_producer_type )
+ {
+- AVInputFormat *f = NULL;
+- while ( ( f = av_iformat_next( f ) ) )
++ const AVInputFormat *f = NULL;
++ void *iterator = NULL;
++ while ( ( f = av_demuxer_iterate( &iterator ) ) )
+ if ( f->priv_class )
+ add_parameters( params, &f->priv_class, flags, NULL, f->name, NULL );
+ }
+ else
+ {
+- AVOutputFormat *f = NULL;
+- while ( ( f = av_oformat_next( f ) ) )
++ const AVOutputFormat *f = NULL;
++ void *iterator = NULL;
++ while ( ( f = av_muxer_iterate( &iterator ) ) )
+ if ( f->priv_class )
+ add_parameters( params, &f->priv_class, flags, NULL, f->name, NULL );
+ }
+
+ add_parameters( params, avcodec, flags, NULL, NULL, NULL );
+- AVCodec *c = NULL;
+- while ( ( c = av_codec_next( c ) ) )
++ const AVCodec *c = NULL;
++ void *iterator = NULL;
++ while ( ( c = av_codec_iterate( &iterator ) ) )
+ if ( c->priv_class )
+ add_parameters( params, &c->priv_class, flags, NULL, c->name, NULL );
+
+@@ -452,9 +419,9 @@ MLT_REPOSITORY
+ mlt_properties_set_data(mlt_global_properties(), "avfilter.resolution_scale",
+ mlt_properties_parse_yaml(dirname), 0, (mlt_destructor) mlt_properties_close, NULL);
+
+- avfilter_register_all();
+- AVFilter *f = NULL;
+- while ( ( f = (AVFilter*)avfilter_next( f ) ) ) {
++ const AVFilter *f = NULL;
++ void *iterator = NULL;
++ while ( ( f = (AVFilter*) av_filter_iterate( &iterator ) ) ) {
+ // Support filters that have one input and one output of the same type.
+ if ( avfilter_pad_count( f->inputs ) == 1 &&
+ avfilter_pad_count( f->outputs ) == 1 &&
+diff --git a/src/modules/avformat/filter_avfilter.c b/src/modules/avformat/filter_avfilter.c
+index 12d37936f..f78b6c5f2 100644
+--- a/src/modules/avformat/filter_avfilter.c
++++ b/src/modules/avformat/filter_avfilter.c
+@@ -17,6 +17,11 @@
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
++#if !defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 700
++# undef _XOPEN_SOURCE
++# define _XOPEN_SOURCE 700
++#endif
++
+ #include "common.h"
+
+ #include <framework/mlt.h>
+@@ -148,8 +153,8 @@ static void set_avfilter_options( mlt_filter filter, double scale)
+ static void init_audio_filtergraph( mlt_filter filter, mlt_audio_format format, int frequency, int channels )
+ {
+ private_data* pdata = (private_data*)filter->child;
+- AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
+- AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
++ const AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
++ const AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
+ int sample_fmts[] = { -1, -1 };
+ int sample_rates[] = { -1, -1 };
+ int channel_counts[] = { -1, -1 };
+@@ -289,10 +294,10 @@ static void init_image_filtergraph( mlt_filter filter, mlt_image_format format,
+ {
+ private_data* pdata = (private_data*)filter->child;
+ mlt_profile profile = mlt_service_profile(MLT_FILTER_SERVICE(filter));
+- AVFilter *buffersrc = avfilter_get_by_name("buffer");
+- AVFilter *buffersink = avfilter_get_by_name("buffersink");
+- AVFilter *scale = avfilter_get_by_name("scale");
+- AVFilter *pad = avfilter_get_by_name("pad");
++ const AVFilter *buffersrc = avfilter_get_by_name("buffer");
++ const AVFilter *buffersink = avfilter_get_by_name("buffersink");
++ const AVFilter *scale = avfilter_get_by_name("scale");
++ const AVFilter *pad = avfilter_get_by_name("pad");
+ mlt_properties p = mlt_properties_new();
+ enum AVPixelFormat pixel_fmts[] = { -1, -1 };
+ AVRational sar = (AVRational){ profile->sample_aspect_num, profile->frame_rate_den };
+@@ -706,25 +711,24 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
+ pdata->avinframe->top_field_first = mlt_properties_get_int( frame_properties, "top_field_first" );
+ pdata->avinframe->color_primaries = mlt_properties_get_int( frame_properties, "color_primaries" );
+ pdata->avinframe->color_trc = mlt_properties_get_int( frame_properties, "color_trc" );
+- av_frame_set_color_range( pdata->avinframe,
+- mlt_properties_get_int( frame_properties, "full_luma" )? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG );
++ pdata->avinframe->color_range = mlt_properties_get_int( frame_properties, "full_luma" )? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
+
+ switch (mlt_properties_get_int( frame_properties, "colorspace" ))
+ {
+ case 240:
+- av_frame_set_colorspace( pdata->avinframe, AVCOL_SPC_SMPTE240M );
++ pdata->avinframe->colorspace = AVCOL_SPC_SMPTE240M;
+ break;
+ case 601:
+- av_frame_set_colorspace( pdata->avinframe, AVCOL_SPC_BT470BG );
++ pdata->avinframe->colorspace = AVCOL_SPC_BT470BG;
+ break;
+ case 709:
+- av_frame_set_colorspace( pdata->avinframe, AVCOL_SPC_BT709 );
++ pdata->avinframe->colorspace = AVCOL_SPC_BT709;
+ break;
+ case 2020:
+- av_frame_set_colorspace( pdata->avinframe, AVCOL_SPC_BT2020_NCL );
++ pdata->avinframe->colorspace = AVCOL_SPC_BT2020_NCL;
+ break;
+ case 2021:
+- av_frame_set_colorspace( pdata->avinframe, AVCOL_SPC_BT2020_CL );
++ pdata->avinframe->colorspace = AVCOL_SPC_BT2020_CL;
+ break;
+ }
+
+@@ -874,8 +878,6 @@ mlt_filter filter_avfilter_init( mlt_profile profile, mlt_service_type type, con
+ mlt_filter filter = mlt_filter_new();
+ private_data* pdata = (private_data*)calloc( 1, sizeof(private_data) );
+
+- avfilter_register_all();
+-
+ if( pdata && id )
+ {
+ id += 9; // Move past "avfilter."
+diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c
+index aee393dbc..8d2542114 100644
+--- a/src/modules/avformat/producer_avformat.c
++++ b/src/modules/avformat/producer_avformat.c
+@@ -40,6 +40,7 @@
+
+ // ffmpeg Header files
+ #include <libavformat/avformat.h>
++#include <libavcodec/avcodec.h>
+ #include <libswscale/swscale.h>
+ #include <libavutil/samplefmt.h>
+ #include <libavutil/pixdesc.h>
+@@ -382,10 +383,8 @@ static mlt_properties find_default_streams( producer_avformat self )
+ // Get the codec context
+ AVStream *stream = context->streams[ i ];
+ if ( ! stream ) continue;
+- AVCodecContext *codec_context = stream->codec;
+- if ( ! codec_context ) continue;
+ AVCodecParameters *codec_params = stream->codecpar;
+- AVCodec *codec = avcodec_find_decoder( codec_params->codec_id );
++ const AVCodec *codec = avcodec_find_decoder( codec_params->codec_id );
+ if ( ! codec ) continue;
+
+ snprintf( key, sizeof(key), "meta.media.%u.stream.type", i );
+@@ -421,9 +420,9 @@ static mlt_properties find_default_streams( producer_avformat self )
+ mlt_properties_set_int( meta_media, key, codec_params->height );
+ snprintf( key, sizeof(key), "meta.media.%u.codec.rotate", i );
+ mlt_properties_set_int( meta_media, key, get_rotation(context->streams[i]) );
+- snprintf( key, sizeof(key), "meta.media.%u.codec.frame_rate", i );
+- AVRational frame_rate = { codec_context->time_base.den, codec_context->time_base.num * codec_context->ticks_per_frame };
+- mlt_properties_set_double( meta_media, key, av_q2d( frame_rate ) );
++// snprintf( key, sizeof(key), "meta.media.%u.codec.frame_rate", i );
++// AVRational frame_rate = { codec_context->time_base.den, codec_context->time_base.num * codec_context->ticks_per_frame };
++// mlt_properties_set_double( meta_media, key, av_q2d( frame_rate ) );
+ snprintf( key, sizeof(key), "meta.media.%u.codec.pix_fmt", i );
+ mlt_properties_set( meta_media, key, av_get_pix_fmt_name( codec_params->format ) );
+ snprintf( key, sizeof(key), "meta.media.%u.codec.sample_aspect_ratio", i );
+@@ -447,7 +446,7 @@ static mlt_properties find_default_streams( producer_avformat self )
+ mlt_properties_set_int( meta_media, key, codec_params->width * codec_params->height > 750000 ? 709 : 601 );
+ break;
+ default:
+- mlt_properties_set_int( meta_media, key, codec_context->colorspace );
++// mlt_properties_set_int( meta_media, key, codec_context->colorspace );
+ break;
+ }
+ if ( codec_params->color_trc && codec_params->color_trc != AVCOL_TRC_UNSPECIFIED )
+@@ -474,8 +473,8 @@ static mlt_properties find_default_streams( producer_avformat self )
+ default:
+ break;
+ }
+-// snprintf( key, sizeof(key), "meta.media.%u.stream.time_base", i );
+-// mlt_properties_set_double( meta_media, key, av_q2d( context->streams[ i ]->time_base ) );
++// snprintf( key, sizeof(key), "meta.media.%u.stream.time_base", i );
++// mlt_properties_set_double( meta_media, key, av_q2d( context->streams[ i ]->time_base ) );
+ snprintf( key, sizeof(key), "meta.media.%u.codec.name", i );
+ mlt_properties_set( meta_media, key, codec->name );
+ snprintf( key, sizeof(key), "meta.media.%u.codec.long_name", i );
+@@ -532,7 +531,7 @@ static void get_aspect_ratio( mlt_properties properties, AVStream *stream, AVCod
+ mlt_properties_set_double( properties, "aspect_ratio", av_q2d( sar ) );
+ }
+
+-static char* parse_url( mlt_profile profile, const char* URL, AVInputFormat **format, AVDictionary **params )
++static char* parse_url( mlt_profile profile, const char* URL, const AVInputFormat **format, AVDictionary **params )
+ {
+ (void) profile; // unused
+ if ( !URL ) return NULL;
+@@ -817,7 +816,7 @@ static int producer_open(producer_avformat self, mlt_profile profile, const char
+ mlt_events_block( properties, self->parent );
+
+ // Parse URL
+- AVInputFormat *format = NULL;
++ const AVInputFormat *format = NULL;
+ AVDictionary *params = NULL;
+ char *filename = parse_url( profile, URL, &format, &params );
+
+@@ -1140,12 +1139,6 @@ static int seek_video( producer_avformat self, mlt_position position,
+ // Fetch the video format context
+ AVFormatContext *context = self->video_format;
+
+- // Get the video stream
+- AVStream *stream = context->streams[ self->video_index ];
+-
+- // Get codec context
+- AVCodecContext *codec_context = stream->codec;
+-
+ // We may want to use the source fps if available
+ double source_fps = mlt_properties_get_double( properties, "meta.media.frame_rate_num" ) /
+ mlt_properties_get_double( properties, "meta.media.frame_rate_den" );
+@@ -1176,11 +1169,11 @@ static int seek_video( producer_avformat self, mlt_position position,
+ timestamp, position, self->video_expected, self->last_position );
+
+ // Seek to the timestamp
+- codec_context->skip_loop_filter = AVDISCARD_NONREF;
++ self->video_codec->skip_loop_filter = AVDISCARD_NONREF;
+ av_seek_frame( context, self->video_index, timestamp, AVSEEK_FLAG_BACKWARD );
+
+ // flush any pictures still in decode buffer
+- avcodec_flush_buffers( codec_context );
++ avcodec_flush_buffers( self->video_codec );
+ self->video_send_result = 0;
+
+ // Remove the cached info relating to the previous position
+@@ -1216,11 +1209,23 @@ static void get_audio_streams_info( producer_avformat self )
+ if ( context->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO )
+ {
+ AVCodecParameters *codec_params = context->streams[i]->codecpar;
+- AVCodec *codec = avcodec_find_decoder( codec_params->codec_id );
++ const AVCodec *codec = avcodec_find_decoder( codec_params->codec_id );
++
++ // Setup the codec context
++ AVCodecContext *codec_context = avcodec_alloc_context3(codec);
++ if (!codec_context) {
++ mlt_log_info(MLT_PRODUCER_SERVICE(self->parent), "Failed to allocate the decoder context for stream #%d\n", i);
++ continue;
++ }
++ int ret = avcodec_parameters_to_context(codec_context, codec_params);
++ if (ret < 0) {
++ mlt_log_info(MLT_PRODUCER_SERVICE(self->parent), "Failed to copy decoder parameters to input decoder context for stream #%d\n", i);
++ continue;
++ }
+
+ // If we don't have a codec and we can't initialise it, we can't do much more...
+ pthread_mutex_lock( &self->open_mutex );
+- if ( codec && avcodec_open2( context->streams[i]->codec, codec, NULL ) >= 0 )
++ if ( codec && avcodec_open2( codec_context, codec, NULL ) >= 0 )
+ {
+ self->audio_streams++;
+ self->audio_max_stream = i;
+@@ -1229,7 +1234,7 @@ static void get_audio_streams_info( producer_avformat self )
+ self->max_channel = codec_params->channels;
+ if ( codec_params->sample_rate > self->max_frequency )
+ self->max_frequency = codec_params->sample_rate;
+- avcodec_close( context->streams[i]->codec );
++ avcodec_close( codec_context );
+ }
+ pthread_mutex_unlock( &self->open_mutex );
+ }
+@@ -1673,9 +1678,6 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
+
+ // Get the video stream
+ AVStream *stream = context->streams[ self->video_index ];
+-
+- // Get codec context
+- AVCodecContext *codec_context = stream->codec;
+ codec_params = stream->codecpar;
+
+ // Always use the image cache for album art.
+@@ -1746,13 +1748,12 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
+
+ // Seek if necessary
+ double speed = mlt_producer_get_speed(producer);
+- int preseek = must_decode && codec_context->has_b_frames && speed >= 0.0 && speed <= 1.0;
++ int preseek = must_decode && self->video_codec->has_b_frames && speed >= 0.0 && speed <= 1.0;
+ int paused = seek_video( self, position, req_position, preseek );
+
+ // Seek might have reopened the file
+ context = self->video_format;
+ stream = context->streams[ self->video_index ];
+- codec_context = stream->codec;
+ codec_params = stream->codecpar;
+ if ( *format == mlt_image_none || *format == mlt_image_movit ||
+ codec_params->format == AV_PIX_FMT_ARGB ||
+@@ -1897,10 +1898,10 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
+ // Decode the image
+ if ( must_decode || int_position >= req_position || !self->pkt.data )
+ {
+- codec_context->reordered_opaque = int_position;
++ self->video_codec->reordered_opaque = int_position;
+ if ( int_position >= req_position )
+- codec_context->skip_loop_filter = AVDISCARD_NONE;
+- self->video_send_result = avcodec_send_packet( codec_context, &self->pkt );
++ self->video_codec->skip_loop_filter = AVDISCARD_NONE;
++ self->video_send_result = avcodec_send_packet( self->video_codec, &self->pkt );
+ mlt_log_debug( MLT_PRODUCER_SERVICE( producer ), "decoded video packet with size %d => %d\n", self->pkt.size, self->video_send_result );
+ // Note: decode may fail at the beginning of MPEGfile (B-frames referencing before first I-frame), so allow a few errors.
+ if (!ignore_send_packet_result(self->video_send_result))
+@@ -1909,7 +1910,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
+ }
+ else
+ {
+- int error = avcodec_receive_frame( codec_context, self->video_frame );
++ int error = avcodec_receive_frame( self->video_codec, self->video_frame );
+ if ( error < 0 )
+ {
+ if ( error != AVERROR( EAGAIN ) && ++decode_errors > 10 )
+@@ -1969,7 +1970,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
+ if ( int_position < req_position )
+ got_picture = 0;
+ else if ( int_position >= req_position )
+- codec_context->skip_loop_filter = AVDISCARD_NONE;
++ self->video_codec->skip_loop_filter = AVDISCARD_NONE;
+ }
+ else if ( !self->pkt.data ) // draining decoder with null packets
+ {
+@@ -2137,11 +2138,10 @@ static int video_codec_init( producer_avformat self, int index, mlt_properties p
+ AVStream *stream = self->video_format->streams[ index ];
+
+ // Get codec context
+- AVCodecContext *codec_context = stream->codec;
+ AVCodecParameters *codec_params = stream->codecpar;
+
+ // Find the codec
+- AVCodec *codec = avcodec_find_decoder( codec_params->codec_id );
++ const AVCodec *codec = avcodec_find_decoder( codec_params->codec_id );
+ if ( mlt_properties_get( properties, "vcodec" ) ) {
+ if ( !( codec = avcodec_find_decoder_by_name( mlt_properties_get( properties, "vcodec" ) ) ) )
+ codec = avcodec_find_decoder( codec_params->codec_id );
+@@ -2153,6 +2153,20 @@ static int video_codec_init( producer_avformat self, int index, mlt_properties p
+ codec = avcodec_find_decoder( codec_params->codec_id );
+ }
+
++ // Setup the codec context
++ AVCodecContext *codec_context = avcodec_alloc_context3(codec);
++ if (!codec_context) {
++ mlt_log_error( MLT_PRODUCER_SERVICE( self->parent ), "Failed to allocate the decoder context for video stream #%d\n", index);
++ self->video_index = -1;
++ return 0;
++ }
++ int ret = avcodec_parameters_to_context(codec_context, codec_params);
++ if (ret < 0) {
++ mlt_log_error( MLT_PRODUCER_SERVICE( self->parent ), "Failed to copy decoder parameters to input decoder context for video stream #%d\n", index);
++ self->video_index = -1;
++ return 0;
++ }
++
+ // Initialise multi-threading
+ int thread_count = mlt_properties_get_int( properties, "threads" );
+ if ( thread_count == 0 && getenv( "MLT_AVFORMAT_THREADS" ) )
+@@ -2924,15 +2938,32 @@ static int audio_codec_init( producer_avformat self, int index, mlt_properties p
+ // Initialise the codec if necessary
+ if ( !self->audio_codec[ index ] )
+ {
++ // Get the video stream
++ AVStream *stream = self->audio_format->streams[ index ];
++
+ // Get codec context
+- AVCodecContext *codec_context = self->audio_format->streams[index]->codec;
++ AVCodecParameters *codec_params = stream->codecpar;
+
+ // Find the codec
+- AVCodec *codec = avcodec_find_decoder( codec_context->codec_id );
++ const AVCodec *codec = avcodec_find_decoder( codec_params->codec_id );
+ if ( mlt_properties_get( properties, "acodec" ) )
+ {
+ if ( !( codec = avcodec_find_decoder_by_name( mlt_properties_get( properties, "acodec" ) ) ) )
+- codec = avcodec_find_decoder( codec_context->codec_id );
++ codec = avcodec_find_decoder( codec_params->codec_id );
++ }
++
++ // Setup the codec context
++ AVCodecContext *codec_context = avcodec_alloc_context3(codec);
++ if (!codec_context) {
++ mlt_log_error( MLT_PRODUCER_SERVICE( self->parent ), "Failed to allocate the decoder context for audio stream #%d\n", index);
++ self->audio_index = -1;
++ return 0;
++ }
++ int ret = avcodec_parameters_to_context(codec_context, codec_params);
++ if (ret < 0) {
++ mlt_log_error( MLT_PRODUCER_SERVICE( self->parent ), "Failed to copy decoder parameters to input decoder context for audio stream #%d\n", index);
++ self->audio_index = -1;
++ return 0;
+ }
+
+ // If we don't have a codec and we can't initialise it, we can't do much more...