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: