diff -up vlc-3.0.21/modules/codec/avcodec/video.c.orig vlc-3.0.21/modules/codec/avcodec/video.c
--- vlc-3.0.21/modules/codec/avcodec/video.c.orig	2024-06-05 17:56:07.000000000 +0200
+++ vlc-3.0.21/modules/codec/avcodec/video.c	2025-09-29 18:11:31.100313450 +0200
@@ -204,8 +205,7 @@ static int lavc_GetVideoFormat(decoder_t
     else if (ctx->time_base.num > 0 && ctx->time_base.den > 0)
     {
         fmt->i_frame_rate = ctx->time_base.den;
-        fmt->i_frame_rate_base = ctx->time_base.num
-                                 * __MAX(ctx->ticks_per_frame, 1);
+        fmt->i_frame_rate_base = ctx->time_base.num;
     }
 
     /* FIXME we should only set the known values and let the core decide
@@ -327,12 +327,10 @@ static int lavc_UpdateVideoFormat(decode
 
     /* always have date in fields/ticks units */
     if(dec->p_sys->pts.i_divider_num)
-        date_Change(&dec->p_sys->pts, fmt_out.i_frame_rate *
-                                      __MAX(ctx->ticks_per_frame, 1),
+        date_Change(&dec->p_sys->pts, fmt_out.i_frame_rate,
                                       fmt_out.i_frame_rate_base);
     else
-        date_Init(&dec->p_sys->pts, fmt_out.i_frame_rate *
-                                    __MAX(ctx->ticks_per_frame, 1),
+        date_Init(&dec->p_sys->pts, fmt_out.i_frame_rate,
                                     fmt_out.i_frame_rate_base);
 
     fmt_out.p_palette = dec->fmt_out.video.p_palette;
@@ -945,9 +943,11 @@ static vlc_tick_t interpolate_next_pts(
         p_sys->pts.i_divider_num == 0 )
         return VLC_TICK_INVALID;
 
+#if LIBAVCODEC_VERSION_CHECK( 60, 12, 100, 0, 0 )
+    int i_tick = p_context->codec_descriptor->props & AV_CODEC_PROP_FIELDS ? 2 : 1;
+#else
     int i_tick = p_context->ticks_per_frame;
-    if( i_tick <= 0 )
-        i_tick = 1;
+#endif
 
     /* interpolate the next PTS */
     return date_Increment( &p_sys->pts, i_tick + frame->repeat_pict );
@@ -1429,8 +1429,13 @@ static picture_t *DecodeBlock( decoder_t
         /* Hack to force display of still pictures */
         p_pic->b_force = p_sys->b_first_frame;
         p_pic->i_nb_fields = 2 + frame->repeat_pict;
+#if LIBAVUTIL_VERSION_CHECK( 58, 7, 100, 0, 0 )
+        p_pic->b_progressive = !(frame->flags & AV_FRAME_FLAG_INTERLACED);
+        p_pic->b_top_field_first = !!(frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST);
+#else
         p_pic->b_progressive = !frame->interlaced_frame;
         p_pic->b_top_field_first = frame->top_field_first;
+#endif
 
         if (DecodeSidedata(p_dec, frame, p_pic))
             i_pts = VLC_TICK_INVALID;
diff -up vlc-3.0.21/modules/codec/avcodec/avcommon_compat.h.orig vlc-3.0.21/modules/codec/avcodec/avcommon_compat.h
--- vlc-3.0.21/modules/codec/avcodec/avcommon_compat.h.orig	2025-09-29 18:15:41.268452578 +0200
+++ vlc-3.0.21/modules/codec/avcodec/avcommon_compat.h	2025-09-29 20:44:02.254440841 +0200
@@ -75,9 +75,12 @@
 #ifndef AV_CODEC_CAP_SMALL_LAST_FRAME
 # define AV_CODEC_CAP_SMALL_LAST_FRAME CODEC_CAP_SMALL_LAST_FRAME
 #endif
-#ifndef AV_INPUT_BUFFER_MIN_SIZE
+#if !defined(AV_INPUT_BUFFER_MIN_SIZE) && defined(FF_MIN_BUFFER_SIZE)
 # define AV_INPUT_BUFFER_MIN_SIZE FF_MIN_BUFFER_SIZE
 #endif
+#ifndef AV_INPUT_BUFFER_MIN_SIZE
+# define AV_INPUT_BUFFER_MIN_SIZE 16384
+#endif
 #ifndef  FF_MAX_B_FRAMES
 # define  FF_MAX_B_FRAMES 16 // FIXME: remove this
 #endif
@@ -87,6 +87,48 @@
 #ifndef FF_API_STRUCT_VAAPI_CONTEXT
 # define FF_API_STRUCT_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59)
 #endif
+#ifndef FF_PROFILE_UNKNOWN // removed in ffmpeg 8
+# define FF_PROFILE_UNKNOWN AV_PROFILE_UNKNOWN
+#endif
+#ifndef FF_LEVEL_UNKNOWN
+# define FF_LEVEL_UNKNOWN AV_LEVEL_UNKNOWN
+#endif
+#ifndef FF_PROFILE_HEVC_MAIN
+# define FF_PROFILE_HEVC_MAIN AV_PROFILE_HEVC_MAIN
+#endif
+#ifndef FF_PROFILE_HEVC_MAIN_10
+# define FF_PROFILE_HEVC_MAIN_10 AV_PROFILE_HEVC_MAIN_10
+#endif
+#ifndef FF_PROFILE_VP9_0
+# define FF_PROFILE_VP9_0 AV_PROFILE_VP9_0
+#endif
+#ifndef FF_PROFILE_VP9_2
+# define FF_PROFILE_VP9_2 AV_PROFILE_VP9_2
+#endif
+#ifndef FF_PROFILE_AAC_LOW
+# define FF_PROFILE_AAC_LOW AV_PROFILE_AAC_LOW
+#endif
+#ifndef FF_PROFILE_AAC_MAIN
+# define FF_PROFILE_AAC_MAIN AV_PROFILE_AAC_MAIN
+#endif
+#ifndef FF_PROFILE_AAC_SSR
+# define FF_PROFILE_AAC_SSR AV_PROFILE_AAC_SSR
+#endif
+#ifndef FF_PROFILE_AAC_LTP
+# define FF_PROFILE_AAC_LTP AV_PROFILE_AAC_LTP
+#endif
+#ifndef FF_PROFILE_AAC_HE_V2
+# define FF_PROFILE_AAC_HE_V2 AV_PROFILE_AAC_HE_V2
+#endif
+#ifndef FF_PROFILE_AAC_HE
+# define FF_PROFILE_AAC_HE AV_PROFILE_AAC_HE
+#endif
+#ifndef FF_PROFILE_AAC_LD
+# define FF_PROFILE_AAC_LD AV_PROFILE_AAC_LD
+#endif
+#ifndef FF_PROFILE_AAC_ELD
+# define FF_PROFILE_AAC_ELD AV_PROFILE_AAC_ELD
+#endif
 
 #endif /* HAVE_LIBAVCODEC_AVCODEC_H */
 
diff -up vlc-3.0.21/modules/codec/avcodec/encoder.c.orig vlc-3.0.21/modules/codec/avcodec/encoder.c
--- vlc-3.0.21/modules/codec/avcodec/encoder.c.orig	2025-09-29 20:57:24.899649420 +0200
+++ vlc-3.0.21/modules/codec/avcodec/encoder.c	2025-09-29 21:06:09.272715899 +0200
@@ -258,19 +258,29 @@ static void probe_video_frame_rate( enco
                                   ( p_enc->fmt_out.i_codec == VLC_CODEC_MP4V ? 25 : CLOCK_FREQ );
 
     msg_Dbg( p_enc, "Time base for probing set to %d/%d", p_context->time_base.num, p_context->time_base.den );
-    if( p_codec->supported_framerates )
+
+    const AVRational *supported_framerates;
+#if LIBAVCODEC_VERSION_CHECK( 61, 13, 100, 0, 0 )
+    if (avcodec_get_supported_config(p_context, p_codec, AV_CODEC_CONFIG_FRAME_RATE, 0,
+                                     (const void **)&supported_framerates, NULL) < 0)
+        supported_framerates = NULL;
+#else
+    supported_framerates = p_codec->supported_framerates;
+#endif
+
+    if( supported_framerates )
     {
         /* We are finding fps values so 1/time_base */
         AVRational target = {
             .num = p_context->time_base.den,
             .den = p_context->time_base.num
         };
-        int idx = av_find_nearest_q_idx(target, p_codec->supported_framerates);
+        int idx = av_find_nearest_q_idx(target, supported_framerates);
 
-        p_context->time_base.num = p_codec->supported_framerates[idx].den ?
-                                    p_codec->supported_framerates[idx].den : 1;
-        p_context->time_base.den = p_codec->supported_framerates[idx].den ?
-                                    p_codec->supported_framerates[idx].num : CLOCK_FREQ;
+        p_context->time_base.num = supported_framerates[idx].den ?
+                                    supported_framerates[idx].den : 1;
+        p_context->time_base.den = supported_framerates[idx].den ?
+                                    supported_framerates[idx].num : CLOCK_FREQ;
 
         /* If we have something reasonable on supported framerates, use that*/
         if( p_context->time_base.den && p_context->time_base.den < CLOCK_FREQ )
@@ -559,7 +569,16 @@ int InitVideoEnc( vlc_object_t *p_this )
         p_enc->fmt_in.video.i_chroma = p_enc->fmt_in.i_codec;
         GetFfmpegChroma( &p_context->pix_fmt, &p_enc->fmt_in.video );
 
-        if( p_codec->pix_fmts )
+        const enum AVPixelFormat *pix_fmts;
+#if LIBAVCODEC_VERSION_CHECK( 61, 13, 100, 0, 0 )
+        if (avcodec_get_supported_config(p_context, p_codec, AV_CODEC_CONFIG_PIX_FORMAT, 0,
+                                        (const void **)&pix_fmts, NULL) < 0)
+            pix_fmts = NULL;
+#else
+        pix_fmts = p_codec->pix_fmts;
+#endif
+
+        if( pix_fmts )
         {
             static const enum AVPixelFormat vlc_pix_fmts[] = {
                 AV_PIX_FMT_YUV420P,
@@ -567,8 +586,8 @@ int InitVideoEnc( vlc_object_t *p_this )
                 AV_PIX_FMT_RGB24,
             };
             bool found = false;
-            const enum PixelFormat *p = p_codec->pix_fmts;
-            for( ; !found && *p != -1; p++ )
+            const enum AVPixelFormat *p = pix_fmts;
+            for( ; !found && *p != AV_PIX_FMT_NONE; p++ )
             {
                 for( size_t i = 0; i < ARRAY_SIZE(vlc_pix_fmts); ++i )
                 {
@@ -580,7 +599,7 @@ int InitVideoEnc( vlc_object_t *p_this )
                     }
                 }
             }
-            if (!found) p_context->pix_fmt = p_codec->pix_fmts[0];
+            if (!found) p_context->pix_fmt = pix_fmts[0];
             GetVlcChroma( &p_enc->fmt_in.video, p_context->pix_fmt );
             p_enc->fmt_in.i_codec = p_enc->fmt_in.video.i_chroma;
         }
@@ -705,22 +724,29 @@ int InitVideoEnc( vlc_object_t *p_this )
     }
     else if( p_enc->fmt_in.i_cat == AUDIO_ES )
     {
+        const enum AVSampleFormat *sample_fmts;
+#if LIBAVCODEC_VERSION_CHECK( 61, 13, 100, 0, 0 )
+        if (avcodec_get_supported_config(p_context, p_codec, AV_CODEC_CONFIG_SAMPLE_FORMAT, 0,
+                                        (const void **)&sample_fmts, NULL) < 0)
+            sample_fmts = NULL;
+#else
+        sample_fmts = p_codec->sample_fmts;
+#endif
+
         p_context->codec_type  = AVMEDIA_TYPE_AUDIO;
-        p_context->sample_fmt  = p_codec->sample_fmts ?
-                                    p_codec->sample_fmts[0] :
-                                    AV_SAMPLE_FMT_S16;
+        p_context->sample_fmt  = sample_fmts ? sample_fmts[0] : AV_SAMPLE_FMT_S16;
 
         /* Try to match avcodec input format to vlc format so we could avoid one
            format conversion */
         if( GetVlcAudioFormat( p_context->sample_fmt ) != p_enc->fmt_in.i_codec
-            && p_codec->sample_fmts )
+            && sample_fmts )
         {
             msg_Dbg( p_enc, "Trying to find more suitable sample format instead of %s", av_get_sample_fmt_name( p_context->sample_fmt ) );
-            for( unsigned int i=0; p_codec->sample_fmts[i] != -1; i++ )
+            for( unsigned int i=0; sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++ )
             {
-                if( GetVlcAudioFormat( p_codec->sample_fmts[i] ) == p_enc->fmt_in.i_codec )
+                if( GetVlcAudioFormat( sample_fmts[i] ) == p_enc->fmt_in.i_codec )
                 {
-                    p_context->sample_fmt = p_codec->sample_fmts[i];
+                    p_context->sample_fmt = sample_fmts[i];
                     msg_Dbg( p_enc, "Using %s as new sample format", av_get_sample_fmt_name( p_context->sample_fmt ) );
                     break;
                 }
@@ -729,14 +755,14 @@ int InitVideoEnc( vlc_object_t *p_this )
         p_sys->b_planar = av_sample_fmt_is_planar( p_context->sample_fmt );
         // Try if we can use interleaved format for codec input as VLC doesn't really do planar audio yet
         // FIXME: Remove when planar/interleaved audio in vlc is equally supported
-        if( p_sys->b_planar && p_codec->sample_fmts )
+        if( p_sys->b_planar && sample_fmts )
         {
             msg_Dbg( p_enc, "Trying to find packet sample format instead of planar %s", av_get_sample_fmt_name( p_context->sample_fmt ) );
-            for( unsigned int i=0; p_codec->sample_fmts[i] != -1; i++ )
+            for( unsigned int i=0; sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++ )
             {
-                if( !av_sample_fmt_is_planar( p_codec->sample_fmts[i] ) )
+                if( !av_sample_fmt_is_planar( sample_fmts[i] ) )
                 {
-                    p_context->sample_fmt = p_codec->sample_fmts[i];
+                    p_context->sample_fmt = sample_fmts[i];
                     msg_Dbg( p_enc, "Changing to packet format %s as new sample format", av_get_sample_fmt_name( p_context->sample_fmt ) );
                     break;
                 }
@@ -1227,8 +1253,19 @@ static block_t *EncodeVideo( encoder_t *
         frame->pict_type = 0;
 
         frame->repeat_pict = p_pict->i_nb_fields - 2;
+#if LIBAVUTIL_VERSION_CHECK( 58, 7, 100, 0, 0 )
+        if (p_pict->b_progressive)
+            frame->flags &= ~AV_FRAME_FLAG_INTERLACED;
+        else
+            frame->flags |= AV_FRAME_FLAG_INTERLACED;
+        if (p_pict->b_top_field_first)
+            frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
+        else
+            frame->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
+#else
         frame->interlaced_frame = !p_pict->b_progressive;
         frame->top_field_first = !!p_pict->b_top_field_first;
+#endif
 
         frame->format = p_sys->p_context->pix_fmt;
         frame->width = p_sys->p_context->width;
@@ -1483,9 +1520,8 @@ void EndVideoEnc( vlc_object_t *p_this )
     av_frame_free( &p_sys->frame );
 
     vlc_avcodec_lock();
-    avcodec_close( p_sys->p_context );
-    vlc_avcodec_unlock();
     avcodec_free_context( &p_sys->p_context );
+    vlc_avcodec_unlock();
 
 
     av_free( p_sys->p_interleave_buf );
diff -up vlc-3.0.21/modules/demux/avformat/demux.c.orig vlc-3.0.21/modules/demux/avformat/demux.c
--- vlc-3.0.21/modules/demux/avformat/demux.c.orig	2025-09-29 21:22:51.285995366 +0200
+++ vlc-3.0.21/modules/demux/avformat/demux.c	2025-09-29 21:38:04.883772120 +0200
@@ -111,6 +111,19 @@ static vlc_fourcc_t CodecTagToFourcc( ui
 #endif
 }
 
+
+static inline void* GetStreamSideData(const AVStream *s, enum AVPacketSideDataType type)
+{
+#if LIBAVCODEC_VERSION_CHECK( 60, 29, 100, 0, 0 )
+    const AVCodecParameters *cp = s->codecpar;
+    const AVPacketSideData *psd =
+        av_packet_side_data_get(cp->coded_side_data, cp->nb_coded_side_data, type);
+    return psd ? psd->data : NULL;
+#else
+    return av_stream_get_side_data(s, type, NULL);
+#endif
+}
+
 /*****************************************************************************
  * Open
  *****************************************************************************/
@@ -137,7 +150,7 @@ static void get_rotation(es_format_t *fm
         else
             fmt->video.orientation = ORIENT_NORMAL;
     }
-    int32_t *matrix = (int32_t *)av_stream_get_side_data(s, AV_PKT_DATA_DISPLAYMATRIX, NULL);
+    int32_t *matrix = GetStreamSideData(s, AV_PKT_DATA_DISPLAYMATRIX);
     if( matrix ) {
         angle = lround(av_display_rotation_get(matrix));
 
