summarylogtreecommitdiffstats
path: root/ffmpeg5.patch
blob: 3727b18e0b601bcf902af7d3b5e15249b232646f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
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...