Dear Maintainer,

I backported the work done by upstream around ffmpeg 5.  Please see attached.
This was sufficient to address the FTBFS both for Sid and Ubuntu Kinetic.

-Dan
Subject:     Backport ffmpeg 5 fixes
Author:      Dan Bungert <daniel.bung...@canonical.com>
Origin:      https://github.com/Xpra-org/xpra
Bug:         https://github.com/Xpra-org/xpra/pull/3242
Bug-Ubuntu:  https://bugs.launchpad.net/bugs/1982418
Bug-Debian:  https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1004797
Forwarded:   not-needed
Last-Update: 2022-07-20

Backport fixes from Antoine Martin upstream:
* b66a358fc31852ad246a9956dfa5f09a0f2b5274
* 5058864909fdf76652d20c3d555bd91667762f88
* f70e01d6e66245b689c11433abef9c51d345452e
* 19060163bc0a0174dafce40ee7c176e8c7fbb9df
--- a/xpra/codecs/enc_ffmpeg/encoder.pyx
+++ b/xpra/codecs/enc_ffmpeg/encoder.pyx
@@ -203,7 +203,7 @@
         int width
         int height
         AVPixelFormat pix_fmt
-        int thread_safe_callbacks
+        #int thread_safe_callbacks
         int thread_count
         int thread_type
         int flags
@@ -286,7 +286,7 @@
     AVCodecID AV_CODEC_ID_AAC
 
     #init and free:
-    AVCodec *avcodec_find_encoder(AVCodecID id)
+    const AVCodec *avcodec_find_encoder(AVCodecID id)
     AVCodecContext *avcodec_alloc_context3(const AVCodec *codec)
     int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
     int avcodec_send_frame(AVCodecContext *avctx,const AVFrame *frame) nogil
@@ -367,10 +367,8 @@
     int AVFMT_FLAG_DISCARD_CORRUPT  #Discard frames marked corrupted
     int AVFMT_FLAG_FLUSH_PACKETS    #Flush the AVIOContext every packet
     int AVFMT_FLAG_BITEXACT
-    int AVFMT_FLAG_MP4A_LATM        #Enable RTP MP4A-LATM payload
     int AVFMT_FLAG_SORT_DTS         #try to interleave outputted packets by dts (using this flag can slow demuxing down)
     int AVFMT_FLAG_PRIV_OPT         #Enable use of private options by delaying codec open (this could be made default once all code is converted)
-    int AVFMT_FLAG_KEEP_SIDE_DATA   #Don't merge side data but keep it separate.
     int AVFMT_FLAG_FAST_SEEK        #Enable fast, but inaccurate seeks for some formats
 
     int AVFMT_NOFILE                #Demuxer will use avio_open, no opened file should be provided by the caller
@@ -509,10 +507,8 @@
     AVFMT_FLAG_DISCARD_CORRUPT : "DISCARD_CORRUPT",
     AVFMT_FLAG_FLUSH_PACKETS   : "FLUSH_PACKETS",
     AVFMT_FLAG_BITEXACT        : "BITEXACT",
-    AVFMT_FLAG_MP4A_LATM       : "MP4A_LATM",
     AVFMT_FLAG_SORT_DTS        : "SORT_DTS",
     AVFMT_FLAG_PRIV_OPT        : "PRIV_OPT",
-    AVFMT_FLAG_KEEP_SIDE_DATA  : "KEEP_SIDE_DATA",
     AVFMT_FLAG_FAST_SEEK       : "FAST_SEEK",
     }
 
@@ -747,7 +743,7 @@
     cdef object muxer_format
     cdef object file
     #video:
-    cdef AVCodec *video_codec
+    cdef const AVCodec *video_codec
     cdef AVStream *video_stream
     cdef AVCodecContext *video_ctx
     cdef AVPixelFormat pix_fmt
@@ -759,7 +755,7 @@
     cdef object encoding
     cdef object profile
     #audio:
-    cdef AVCodec *audio_codec
+    cdef const AVCodec *audio_codec
     cdef AVStream *audio_stream
     cdef AVCodecContext *audio_ctx
     cdef uint8_t ready
@@ -902,7 +898,7 @@
         self.video_ctx.height = self.height
         self.video_ctx.bit_rate = max(200000, self.width*self.height*4) #4 bits per pixel
         self.video_ctx.pix_fmt = self.pix_fmt
-        self.video_ctx.thread_safe_callbacks = 1
+        #self.video_ctx.thread_safe_callbacks = 1
         #if oformat.flags & AVFMT_GLOBALHEADER:
         if self.encoding not in ("mpeg1", "mpeg2"):
             self.video_ctx.thread_type = THREAD_TYPE
--- a/xpra/codecs/dec_avcodec2/decoder.pyx
+++ b/xpra/codecs/dec_avcodec2/decoder.pyx
@@ -71,7 +71,7 @@
         int width
         int height
         AVPixelFormat pix_fmt
-        int thread_safe_callbacks
+        #int thread_safe_callbacks
         int thread_count
         int thread_type
         int flags
@@ -87,7 +87,7 @@
     AVCodecID AV_CODEC_ID_MPEG2VIDEO
 
     #init and free:
-    AVCodec *avcodec_find_decoder(AVCodecID id)
+    const AVCodec *avcodec_find_decoder(AVCodecID id)
     AVCodecContext *avcodec_alloc_context3(const AVCodec *codec)
     int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
     AVFrame* av_frame_alloc()
@@ -95,7 +95,8 @@
     int avcodec_close(AVCodecContext *avctx)
 
     #actual decoding:
-    void av_init_packet(AVPacket *pkt) nogil
+    AVPacket *av_packet_alloc() nogil
+    void av_packet_free(AVPacket **avpkt)
     void avcodec_get_frame_defaults(AVFrame *frame) nogil
     int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt) nogil
     int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) nogil
@@ -293,7 +294,7 @@
         It also handles reconstructing a single ImageWrapper
         constructed from 3-pass decoding (see plane_sizes).
     """
-    cdef AVCodec *codec
+    cdef const AVCodec *codec
     cdef AVCodecContext *codec_ctx
     cdef AVPixelFormat pix_fmt
     cdef AVPixelFormat actual_pix_fmt
@@ -367,7 +368,7 @@
         self.codec_ctx.pix_fmt = self.pix_fmt
         #self.codec_ctx.get_buffer2 = avcodec_get_buffer2
         #self.codec_ctx.release_buffer = avcodec_release_buffer
-        self.codec_ctx.thread_safe_callbacks = 1
+        #self.codec_ctx.thread_safe_callbacks = 1
         self.codec_ctx.thread_type = 2      #FF_THREAD_SLICE: allow more than one thread per frame
         self.codec_ctx.thread_count = 0     #auto
         self.codec_ctx.flags2 |= AV_CODEC_FLAG2_FAST    #may cause "no deblock across slices" - which should be fine
@@ -491,7 +492,6 @@
         cdef int size
         cdef int ret = 0
         cdef int nplanes
-        cdef AVPacket avpkt
         cdef AVFrameWrapper framewrapper
         cdef AVFrame *av_frame
         cdef object img
@@ -519,13 +519,15 @@
 
         #ensure we can detect if the frame buffer got allocated:
         clear_frame(av_frame)
+        cdef AVPacket *avpkt = NULL
         #now safe to run without gil:
         with nogil:
-            av_init_packet(&avpkt)
+            avpkt = av_packet_alloc()
             avpkt.data = <uint8_t *> (padded_buf)
             avpkt.size = buf_len
-            ret = avcodec_send_packet(self.codec_ctx, &avpkt)
+            ret = avcodec_send_packet(self.codec_ctx, avpkt)
         if ret!=0:
+            av_packet_free(&avpkt)
             free(padded_buf)
             log("%s.decompress_image(%s:%s, %s) avcodec_send_packet failure: %s", self, type(input), buf_len, options, av_error_str(ret))
             self.log_av_error(buf_len, ret, options)
@@ -533,6 +535,7 @@
         with nogil:
             ret = avcodec_receive_frame(self.codec_ctx, av_frame)
         free(padded_buf)
+        av_packet_free(&avpkt)
         if ret==-errno.EAGAIN:
             d = options.intget("delayed", 0)
             if d>0:

Reply via email to