Backport https://github.com/mltframework/mlt/commit/ae83ceee72a0a39c063b02310f6ce928839712a2

Index: src/modules/avformat/producer_avformat.c
--- src/modules/avformat/producer_avformat.c.orig
+++ src/modules/avformat/producer_avformat.c
@@ -335,11 +335,20 @@ static int first_video_index(producer_avformat self)
 
 static const char *get_projection(AVStream *st)
 {
+#if LIBAVCODEC_VERSION_INT >= ((60 << 16) + (29 << 8) + 100)
+    const AVPacketSideData *psd = av_packet_side_data_get(st->codecpar->coded_side_data,
+                                                          st->codecpar->nb_coded_side_data,
+                                                          AV_PKT_DATA_SPHERICAL);
+    if (psd) {
+        const AVSphericalMapping *spherical = (const AVSphericalMapping *) psd->data;
+#else
     const AVSphericalMapping *spherical
         = (const AVSphericalMapping *) av_stream_get_side_data(st, AV_PKT_DATA_SPHERICAL, NULL);
 
-    if (spherical)
+    if (spherical) {
+#endif
         return av_spherical_projection_name(spherical->projection);
+    }
     return NULL;
 }
 
@@ -349,7 +358,16 @@ static double get_rotation(mlt_properties properties, 
 {
     AVDictionaryEntry *rotate_tag = av_dict_get(st->metadata, "rotate", NULL, 0);
     int has_rotate_metadata = rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0");
+#if LIBAVCODEC_VERSION_INT >= ((60 << 16) + (29 << 8) + 100)
+    int32_t *displaymatrix = NULL;
+    const AVPacketSideData *psd = av_packet_side_data_get(st->codecpar->coded_side_data,
+                                                          st->codecpar->nb_coded_side_data,
+                                                          AV_PKT_DATA_DISPLAYMATRIX);
+    if (psd)
+        displaymatrix = (int32_t *) psd->data;
+#else
     uint8_t *displaymatrix = av_stream_get_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
+#endif
     double theta = mlt_properties_get_double(properties, "rotate");
     int has_mlt_rotate = !!mlt_properties_get(properties, "rotate");
 
@@ -418,14 +436,7 @@ static AVRational guess_frame_rate(producer_avformat s
         frame_rate = av_d2q(av_q2d(stream->avg_frame_rate), 1024);
         fps = av_q2d(frame_rate);
     }
-    // XXX frame rates less than 1 fps are not considered sane
     if (isnan(fps) || isinf(fps) || fps < 1.0) {
-        // Get the frame rate from the codec.
-        frame_rate.num = self->video_codec->time_base.den;
-        frame_rate.den = self->video_codec->time_base.num * self->video_codec->ticks_per_frame;
-        fps = av_q2d(frame_rate);
-    }
-    if (isnan(fps) || isinf(fps) || fps < 1.0) {
         // Use the profile frame rate if all else fails.
         mlt_profile profile = mlt_service_profile(MLT_PRODUCER_SERVICE(self->parent));
         frame_rate.num = profile->frame_rate_num;
@@ -1580,7 +1591,7 @@ static void get_audio_streams_info(producer_avformat s
 #endif
                 if (codec_params->sample_rate > self->max_frequency)
                     self->max_frequency = codec_params->sample_rate;
-                avcodec_close(codec_context);
+                avcodec_free_context(&codec_context);
             }
             pthread_mutex_unlock(&self->open_mutex);
         }
@@ -1716,7 +1727,11 @@ static int sliced_h_pix_fmt_conv_proc(int id, int idx,
     struct SwsContext *sws;
     struct sliced_pix_fmt_conv_t *ctx = (struct sliced_pix_fmt_conv_t *) cookie;
 
+#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
+    interlaced = ctx->frame->flags & AV_FRAME_FLAG_INTERLACED;
+#else
     interlaced = ctx->frame->interlaced_frame;
+#endif
     field = (interlaced) ? (idx & 1) : 0;
     idx = (interlaced) ? (idx / 2) : idx;
     slices = (interlaced) ? (jobs / 2) : jobs;
@@ -1865,7 +1880,11 @@ static void convert_image_rgb(producer_avformat self,
     uint8_t *out_data[4];
     int out_stride[4];
 
+#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
+    if (src_pix_fmt == AV_PIX_FMT_YUV420P && (frame->flags & AV_FRAME_FLAG_INTERLACED)) {
+#else
     if (src_pix_fmt == AV_PIX_FMT_YUV420P && frame->interlaced_frame) {
+#endif
         // Perform field-aware conversion for 4:2:0
         int field_height = height / 2;
         const uint8_t *in_data[4];
@@ -2041,8 +2060,13 @@ static int convert_image(producer_avformat self,
 
         int sliced = !getenv("MLT_AVFORMAT_SLICED_PIXFMT_DISABLE") && src_pix_fmt != ctx.dst_format;
         if (sliced) {
+#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
+            ctx.slice_w = (width < 1000) ? (256 >> (frame->flags & AV_FRAME_FLAG_INTERLACED))
+                                         : (512 >> (frame->flags & AV_FRAME_FLAG_INTERLACED));
+#else
             ctx.slice_w = (width < 1000) ? (256 >> frame->interlaced_frame)
                                          : (512 >> frame->interlaced_frame);
+#endif
         } else {
             ctx.slice_w = width;
         }
@@ -2052,10 +2076,18 @@ static int convert_image(producer_avformat self,
 
         if (sliced && (last_slice_w % 8) == 0
             && !(ctx.src_format == AV_PIX_FMT_YUV422P && last_slice_w % 16)) {
+#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
+            c *= (frame->flags & AV_FRAME_FLAG_INTERLACED) ? 2 : 1;
+#else
             c *= frame->interlaced_frame ? 2 : 1;
+#endif
             mlt_slices_run_normal(c, sliced_h_pix_fmt_conv_proc, &ctx);
         } else {
+#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
+            c = (frame->flags & AV_FRAME_FLAG_INTERLACED) ? 2 : 1;
+#else
             c = frame->interlaced_frame ? 2 : 1;
+#endif
             ctx.slice_w = width;
             for (i = 0; i < c; i++)
                 sliced_h_pix_fmt_conv_proc(i, i, c, &ctx);
@@ -2524,7 +2556,11 @@ static int producer_get_image(mlt_frame frame,
                         // there are I frames, and find_first_pts() fails as a result.
                         // Try to set first_pts here after getting pict_type.
                         if (self->first_pts == AV_NOPTS_VALUE
+#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
+                            && ((self->video_frame->flags & AV_FRAME_FLAG_KEY)
+#else
                             && (self->video_frame->key_frame
+#endif
                                 || self->video_frame->pict_type == AV_PICTURE_TYPE_I))
                             self->first_pts = pts;
                         if (self->first_pts != AV_NOPTS_VALUE)
@@ -2558,22 +2594,45 @@ static int producer_get_image(mlt_frame frame,
                 if (mlt_properties_get(properties, "force_progressive")) {
                     self->progressive = !!mlt_properties_get_int(properties, "force_progressive");
                 } else if (self->video_frame && codec_params) {
+#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
+                    self->progressive = !(self->video_frame->flags & AV_FRAME_FLAG_INTERLACED)
+#else
                     self->progressive = !self->video_frame->interlaced_frame
+#endif
                                         && (codec_params->field_order == AV_FIELD_PROGRESSIVE
                                             || codec_params->field_order == AV_FIELD_UNKNOWN);
                 } else {
                     self->progressive = 0;
                 }
+#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
+                if (!self->progressive)
+                    self->video_frame->flags |= AV_FRAME_FLAG_INTERLACED;
+                else
+                    self->video_frame->flags &= ~AV_FRAME_FLAG_INTERLACED;
+#else
                 self->video_frame->interlaced_frame = !self->progressive;
+#endif
                 // Detect and correct field order
                 if (mlt_properties_get(properties, "force_tff")) {
                     self->top_field_first = !!mlt_properties_get_int(properties, "force_tff");
                 } else {
+#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
+                    self->top_field_first = (self->video_frame->flags
+                                             & AV_FRAME_FLAG_TOP_FIELD_FIRST)
+#else
                     self->top_field_first = self->video_frame->top_field_first
+#endif
                                             || codec_params->field_order == AV_FIELD_TT
                                             || codec_params->field_order == AV_FIELD_TB;
                 }
+#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
+                if (self->top_field_first)
+                    self->video_frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
+                else
+                    self->video_frame->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
+#else
                 self->video_frame->top_field_first = self->top_field_first;
+#endif
 #ifdef AVFILTER
                 if ((self->autorotate || mlt_properties_get(properties, "filtergraph"))
                     && !setup_filters(self) && self->vfilter_graph) {
@@ -3690,7 +3749,7 @@ static int audio_codec_init(producer_avformat self, in
         if (codec && avcodec_open2(codec_context, codec, NULL) >= 0) {
             // Now store the codec with its destructor
             if (self->audio_codec[index])
-                avcodec_close(self->audio_codec[index]);
+                avcodec_free_context(&self->audio_codec[index]);
             self->audio_codec[index] = codec_context;
             self->audio_index = index;
         } else {
