diff options
Diffstat (limited to 'gnu/packages')
-rw-r--r-- | gnu/packages/jami.scm | 266 | ||||
-rw-r--r-- | gnu/packages/patches/ffmpeg-jami-change-RTCP-ratio.patch | 27 | ||||
-rw-r--r-- | gnu/packages/patches/ffmpeg-jami-libopusdec-enable-FEC.patch | 127 | ||||
-rw-r--r-- | gnu/packages/patches/ffmpeg-jami-libopusenc-enable-FEC.patch | 50 | ||||
-rw-r--r-- | gnu/packages/patches/ffmpeg-jami-libopusenc-reload-packet-loss-at-encode.patch | 44 | ||||
-rw-r--r-- | gnu/packages/patches/ffmpeg-jami-remove-mjpeg-log.patch | 26 | ||||
-rw-r--r-- | gnu/packages/patches/ffmpeg-jami-rtp_ext_abs_send_time.patch | 71 | ||||
-rw-r--r-- | gnu/packages/patches/ffmpeg-jami-screen-sharing-x11-fix.patch | 302 | ||||
-rw-r--r-- | gnu/packages/video.scm | 248 |
9 files changed, 894 insertions, 267 deletions
diff --git a/gnu/packages/jami.scm b/gnu/packages/jami.scm index 3037d090d3..c035a966c7 100644 --- a/gnu/packages/jami.scm +++ b/gnu/packages/jami.scm @@ -89,272 +89,6 @@ (patches (search-patches "jami-disable-integration-tests.patch" "jami-libjami-headers-search.patch")))) -;; Jami maintains a set of patches for some key dependencies (currently -;; pjproject and ffmpeg) of Jami that haven't yet been integrated upstream. -;; This procedure simplifies the process of applying them. -(define jami-apply-custom-patches - #~(lambda* (#:key dep-name patches) - (let ((patches-directory "patches")) - (mkdir-p patches-directory) - (invoke "tar" "-xvf" #$%jami-sources - "-C" patches-directory - "--strip-components=5" - "--wildcards" - (string-append "jami-*/daemon/contrib/src/" dep-name)) - (for-each (lambda (f) - (invoke "patch" "--force" "--ignore-whitespace" "-p1" "-i" - (string-append patches-directory "/" f ".patch"))) - patches)))) - -;; The following variables are configure flags used by ffmpeg-jami. They're -;; from the jami/daemon/contrib/src/ffmpeg/rules.mak file. We try to keep it -;; as close to the official Jami package as possible, to provide all the -;; codecs and extra features that are expected (see: -;; https://review.jami.net/plugins/gitiles/jami-daemon/+/refs/heads/master/contrib/src/ffmpeg/rules.mak). -;; An exception are the ffnvcodec-related switches, which is not packaged in -;; Guix and would not work with Mesa. -(define %ffmpeg-default-configure-flags - '("--disable-everything" - "--enable-zlib" - "--enable-gpl" - "--enable-swscale" - "--enable-bsfs" - "--disable-filters" - "--disable-programs" - "--disable-postproc" - "--disable-protocols" - "--enable-protocol=crypto" - "--enable-protocol=file" - "--enable-protocol=rtp" - "--enable-protocol=srtp" - "--enable-protocol=tcp" - "--enable-protocol=udp" - "--enable-protocol=unix" - "--enable-protocol=pipe" - - ;; Enable muxers/demuxers. - "--disable-demuxers" - "--disable-muxers" - "--enable-muxer=rtp" - "--enable-muxer=g722" - "--enable-muxer=g726" - "--enable-muxer=g726le" - "--enable-muxer=h263" - "--enable-muxer=h264" - "--enable-muxer=hevc" - "--enable-muxer=matroska" - "--enable-muxer=wav" - "--enable-muxer=webm" - "--enable-muxer=ogg" - "--enable-muxer=pcm_s16be" - "--enable-muxer=pcm_s16le" - "--enable-demuxer=rtp" - "--enable-demuxer=mjpeg" - "--enable-demuxer=mjpeg_2000" - "--enable-demuxer=mpegvideo" - "--enable-demuxer=gif" - "--enable-demuxer=image_jpeg_pipe" - "--enable-demuxer=image_png_pipe" - "--enable-demuxer=image_webp_pipe" - "--enable-demuxer=matroska" - "--enable-demuxer=m4v" - "--enable-demuxer=mp3" - "--enable-demuxer=ogg" - "--enable-demuxer=flac" - "--enable-demuxer=wav" - "--enable-demuxer=ac3" - "--enable-demuxer=g722" - "--enable-demuxer=g723_1" - "--enable-demuxer=g726" - "--enable-demuxer=g726le" - "--enable-demuxer=pcm_mulaw" - "--enable-demuxer=pcm_alaw" - "--enable-demuxer=pcm_s16be" - "--enable-demuxer=pcm_s16le" - "--enable-demuxer=h263" - "--enable-demuxer=h264" - "--enable-demuxer=hevc" - - ;; Enable parsers. - "--enable-parser=h263" - "--enable-parser=h264" - "--enable-parser=hevc" - "--enable-parser=mpeg4video" - "--enable-parser=vp8" - "--enable-parser=vp9" - "--enable-parser=opus" - - ;; Encoders/decoders. - "--enable-encoder=adpcm_g722" - "--enable-decoder=adpcm_g722" - "--enable-encoder=adpcm_g726" - "--enable-decoder=adpcm_g726" - "--enable-encoder=adpcm_g726le" - "--enable-decoder=adpcm_g726le" - "--enable-decoder=g729" - "--enable-encoder=g723_1" - "--enable-decoder=g723_1" - "--enable-encoder=rawvideo" - "--enable-decoder=rawvideo" - "--enable-encoder=libx264" - "--enable-decoder=h264" - "--enable-encoder=pcm_alaw" - "--enable-decoder=pcm_alaw" - "--enable-encoder=pcm_mulaw" - "--enable-decoder=pcm_mulaw" - "--enable-encoder=mpeg4" - "--enable-decoder=mpeg4" - "--enable-encoder=libvpx_vp8" - "--enable-decoder=vp8" - "--enable-decoder=vp9" - "--enable-encoder=h263" - "--enable-encoder=h263p" - "--enable-decoder=h263" - "--enable-encoder=mjpeg" - "--enable-decoder=mjpeg" - "--enable-decoder=mjpegb" - "--enable-libspeex" - "--enable-libopus" - "--enable-libvpx" - "--enable-libx264" - "--enable-encoder=libspeex" - "--enable-decoder=libspeex" - "--enable-encoder=libopus" - "--enable-decoder=libopus" - - ;; Encoders/decoders for ringtones and audio streaming. - "--enable-decoder=flac" - "--enable-decoder=vorbis" - "--enable-decoder=aac" - "--enable-decoder=ac3" - "--enable-decoder=eac3" - "--enable-decoder=mp3" - "--enable-decoder=pcm_u24le" - "--enable-decoder=pcm_u32le" - "--enable-decoder=pcm_u8" - "--enable-decoder=pcm_f16le" - "--enable-decoder=pcm_f32le" - "--enable-decoder=pcm_f64le" - "--enable-decoder=pcm_s16le" - "--enable-decoder=pcm_s24le" - "--enable-decoder=pcm_s32le" - "--enable-decoder=pcm_s64le" - "--enable-decoder=pcm_u16le" - "--enable-encoder=pcm_u8" - "--enable-encoder=pcm_f32le" - "--enable-encoder=pcm_f64le" - "--enable-encoder=pcm_s16le" - "--enable-encoder=pcm_s32le" - "--enable-encoder=pcm_s64le" - - "--enable-decoder=pcm_s16be" - "--enable-decoder=pcm_s16be_planar" - "--enable-decoder=pcm_s16le_planar" - "--enable-decoder=pcm_s24be" - "--enable-decoder=pcm_s24le_planar" - "--enable-decoder=pcm_s32be" - "--enable-decoder=pcm_s32le_planar" - "--enable-decoder=pcm_s64be" - "--enable-decoder=pcm_s8" - "--enable-decoder=pcm_s8_planar" - "--enable-decoder=pcm_u16be" - - ;; Encoders/decoders for images. - "--enable-encoder=gif" - "--enable-decoder=gif" - "--enable-encoder=jpegls" - "--enable-decoder=jpegls" - "--enable-encoder=ljpeg" - "--enable-decoder=jpeg2000" - "--enable-encoder=png" - "--enable-decoder=png" - "--enable-encoder=bmp" - "--enable-decoder=bmp" - "--enable-encoder=tiff" - "--enable-decoder=tiff" - - ;; Filters. - "--enable-filter=scale" - "--enable-filter=overlay" - "--enable-filter=amix" - "--enable-filter=amerge" - "--enable-filter=aresample" - "--enable-filter=format" - "--enable-filter=aformat" - "--enable-filter=fps" - "--enable-filter=transpose" - "--enable-filter=pad" - - "--enable-filter=afir" - "--enable-filter=split" - "--enable-filter=drawbox" - "--enable-filter=drawtext" - "--enable-filter=rotate" - "--enable-filter=loop" - "--enable-filter=setpts" - "--enable-filter=movie" - "--enable-filter=alphamerge" - "--enable-filter=boxblur" - "--enable-filter=lut" - "--enable-filter=negate" - "--enable-filter=colorkey" - "--enable-filter=transpose")) - -(define %ffmpeg-linux-configure-flags - '("--enable-pic" - "--extra-cxxflags=-fPIC" - "--extra-cflags=-fPIC" - "--target-os=linux" - "--enable-indev=v4l2" - "--enable-indev=xcbgrab" - "--enable-vdpau" - "--enable-hwaccel=h264_vdpau" - "--enable-hwaccel=mpeg4_vdpau" - "--enable-vaapi" - "--enable-hwaccel=h264_vaapi" - "--enable-hwaccel=mpeg4_vaapi" - "--enable-hwaccel=h263_vaapi" - "--enable-hwaccel=vp8_vaapi" - "--enable-hwaccel=mjpeg_vaapi" - "--enable-hwaccel=hevc_vaapi" - "--enable-encoder=h264_vaapi" - "--enable-encoder=vp8_vaapi" - "--enable-encoder=mjpeg_vaapi" - "--enable-encoder=hevc_vaapi")) - -(define (ffmpeg-compose-configure-flags) - "Compose the configure flag lists of ffmpeg-jami." - #~(append '#$%ffmpeg-default-configure-flags - (if (string-contains #$(%current-system) "linux") - '#$%ffmpeg-linux-configure-flags - '()))) - -(define-public ffmpeg-jami - (package - (inherit ffmpeg) - (name "ffmpeg-jami") - (arguments - (substitute-keyword-arguments (package-arguments ffmpeg) - ((#:configure-flags _ '()) - #~(cons* "--disable-static" - "--enable-shared" - "--disable-stripping" - #$(ffmpeg-compose-configure-flags))) - ((#:phases phases) - #~(modify-phases #$phases - (add-after 'unpack 'apply-patches - (lambda _ - ;; These patches come from: - ;; "jami-project/daemon/contrib/src/ffmpeg/rules.mak". - (#$jami-apply-custom-patches - #:dep-name "ffmpeg" - #:patches '("remove-mjpeg-log" - "change-RTCP-ratio" - "rtp_ext_abs_send_time" - "libopusdec-enable-FEC" - "libopusenc-reload-packet-loss-at-encode" - "screen-sharing-x11-fix")))))))))) - (define-public libjami (package (name "libjami") diff --git a/gnu/packages/patches/ffmpeg-jami-change-RTCP-ratio.patch b/gnu/packages/patches/ffmpeg-jami-change-RTCP-ratio.patch new file mode 100644 index 0000000000..6248165d8c --- /dev/null +++ b/gnu/packages/patches/ffmpeg-jami-change-RTCP-ratio.patch @@ -0,0 +1,27 @@ +From a884b62c9e6f23b9f4369d724e25db2f42dad28d Mon Sep 17 00:00:00 2001 +From: Pierre LESPAGNOL <pierre.lespagnol@savoirfairelinux.com> +Date: Tue, 28 May 2019 16:18:20 -0400 +Subject: [PATCH] Changement du ratio de 0.5% a 5% + +--- + libavformat/rtp.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libavformat/rtp.h b/libavformat/rtp.h +index 54512c6f71..16916ff86a 100644 +--- a/libavformat/rtp.h ++++ b/libavformat/rtp.h +@@ -78,8 +78,8 @@ enum AVCodecID ff_rtp_codec_id(const char *buf, enum AVMediaType codec_type); + #define RTP_VERSION 2 + #define RTP_MAX_SDES 256 /**< maximum text length for SDES */ + +-/* RTCP packets use 0.5% of the bandwidth */ +-#define RTCP_TX_RATIO_NUM 5 ++/* RTCP packets use 2.5% of the bandwidth */ ++#define RTCP_TX_RATIO_NUM 25 + #define RTCP_TX_RATIO_DEN 1000 + + /* An arbitrary id value for RTP Xiph streams - only relevant to indicate +-- +2.17.1 + diff --git a/gnu/packages/patches/ffmpeg-jami-libopusdec-enable-FEC.patch b/gnu/packages/patches/ffmpeg-jami-libopusdec-enable-FEC.patch new file mode 100644 index 0000000000..fb9466a4fc --- /dev/null +++ b/gnu/packages/patches/ffmpeg-jami-libopusdec-enable-FEC.patch @@ -0,0 +1,127 @@ +diff --git a/libavcodec/libopusdec.c b/libavcodec/libopusdec.c +index 9b9a610343..8ec5bfc1ad 100644 +--- a/libavcodec/libopusdec.c ++++ b/libavcodec/libopusdec.c +@@ -45,6 +45,8 @@ struct libopus_context { + #ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST + int apply_phase_inv; + #endif ++ int decode_fec; ++ int64_t expected_next_pts; + }; + + #define OPUS_HEAD_SIZE 19 +@@ -141,6 +143,8 @@ static av_cold int libopus_decode_init(AVCodecContext *avc) + /* Decoder delay (in samples) at 48kHz */ + avc->delay = avc->internal->skip_samples = opus->pre_skip; + ++ opus->expected_next_pts = AV_NOPTS_VALUE; ++ + return 0; + } + +@@ -161,27 +165,82 @@ static int libopus_decode(AVCodecContext *avc, AVFrame *frame, + int *got_frame_ptr, AVPacket *pkt) + { + struct libopus_context *opus = avc->priv_data; +- int ret, nb_samples; ++ uint8_t *outptr; ++ int ret, nb_samples = 0, nb_lost_samples = 0, nb_samples_left; ++ ++ // If FEC is enabled, calculate number of lost samples ++ if (opus->decode_fec && ++ opus->expected_next_pts != AV_NOPTS_VALUE && ++ pkt->pts != AV_NOPTS_VALUE && ++ pkt->pts != opus->expected_next_pts) { ++ // Cap at recovering 120 ms of lost audio. ++ nb_lost_samples = pkt->pts - opus->expected_next_pts; ++ nb_lost_samples = FFMIN(nb_lost_samples, MAX_FRAME_SIZE); ++ } + +- frame->nb_samples = MAX_FRAME_SIZE; ++ frame->nb_samples = MAX_FRAME_SIZE + nb_lost_samples; + if ((ret = ff_get_buffer(avc, frame, 0)) < 0) + return ret; + ++ outptr = frame->data[0]; ++ nb_samples_left = frame->nb_samples; ++ ++ if (opus->decode_fec && nb_lost_samples) { ++ // Try to recover the lost samples with FEC data from this one. ++ // If there's no FEC data, the decoder will do loss concealment instead. ++ if (avc->sample_fmt == AV_SAMPLE_FMT_S16) ++ nb_samples = opus_multistream_decode(opus->dec, pkt->data, pkt->size, ++ (opus_int16 *)outptr, ++ nb_lost_samples, 1); ++ else ++ nb_samples = opus_multistream_decode_float(opus->dec, pkt->data, pkt->size, ++ (float *)outptr, ++ nb_lost_samples, 1); ++ ++ if (nb_samples < 0) { ++ av_log(avc, AV_LOG_ERROR, "Decoding error: %s\n", ++ opus_strerror(nb_samples)); ++ return ff_opus_error_to_averror(nb_samples); ++ } ++ ++ av_log(avc, AV_LOG_WARNING, "Recovered %d samples with FEC/PLC\n", ++ nb_samples); ++ ++ outptr += nb_samples * avc->channels * av_get_bytes_per_sample(avc->sample_fmt); ++ nb_samples_left -= nb_samples; ++ if (pkt->pts != AV_NOPTS_VALUE) { ++ pkt->pts -= nb_samples; ++ frame->pts = pkt->pts; ++ } ++ } ++ ++ // Decode the actual, non-lost data. + if (avc->sample_fmt == AV_SAMPLE_FMT_S16) +- nb_samples = opus_multistream_decode(opus->dec, pkt->data, pkt->size, +- (opus_int16 *)frame->data[0], +- frame->nb_samples, 0); ++ ret = opus_multistream_decode(opus->dec, pkt->data, pkt->size, ++ (opus_int16 *)outptr, ++ nb_samples_left, 0); + else +- nb_samples = opus_multistream_decode_float(opus->dec, pkt->data, pkt->size, +- (float *)frame->data[0], +- frame->nb_samples, 0); ++ ret = opus_multistream_decode_float(opus->dec, pkt->data, pkt->size, ++ (float *)outptr, ++ nb_samples_left, 0); + +- if (nb_samples < 0) { ++ if (ret < 0) { + av_log(avc, AV_LOG_ERROR, "Decoding error: %s\n", +- opus_strerror(nb_samples)); +- return ff_opus_error_to_averror(nb_samples); ++ opus_strerror(ret)); ++ return ff_opus_error_to_averror(ret); + } + ++ nb_samples += ret; ++ ++ if (opus->decode_fec) ++ { ++ // Calculate the next expected pts ++ if (pkt->pts == AV_NOPTS_VALUE) { ++ opus->expected_next_pts = AV_NOPTS_VALUE; ++ } else { ++ opus->expected_next_pts = pkt->pts + nb_samples; ++ } ++ } + #ifndef OPUS_SET_GAIN + { + int i = avc->ch_layout.nb_channels * nb_samples; +@@ -220,6 +279,7 @@ static const AVOption libopusdec_options[] = { + #ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST + { "apply_phase_inv", "Apply intensity stereo phase inversion", OFFSET(apply_phase_inv), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS }, + #endif ++ { "decode_fec", "Decode FEC data or use PLC", OFFSET(decode_fec), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, + { NULL }, + }; + +-- +2.34.1 + diff --git a/gnu/packages/patches/ffmpeg-jami-libopusenc-enable-FEC.patch b/gnu/packages/patches/ffmpeg-jami-libopusenc-enable-FEC.patch new file mode 100644 index 0000000000..43b786c567 --- /dev/null +++ b/gnu/packages/patches/ffmpeg-jami-libopusenc-enable-FEC.patch @@ -0,0 +1,50 @@ +diff --git a/libavcodec/libopusencc.c b/libavcodec/libopusencc.c +index 2a97811d18..40ee7b8fec 100644 +--- a/libavcodec/libopusenc.c ++++ b/libavcodec/libopusenc.c +@@ -33,6 +33,7 @@ + typedef struct LibopusEncOpts { + int vbr; + int application; ++ int enable_fec; + int packet_loss; + int complexity; + float frame_duration; +@@ -143,6 +144,13 @@ + "Unable to set constrained VBR: %s\n", opus_strerror(ret)); + + ret = opus_multistream_encoder_ctl(enc, ++ OPUS_SET_INBAND_FEC(opts->enable_fec)); ++ if (ret != OPUS_OK) ++ av_log(avctx, AV_LOG_WARNING, ++ "Unable to set enable FEC flag percentage: %s\n", ++ opus_strerror(ret)); ++ ++ ret = opus_multistream_encoder_ctl(enc, + OPUS_SET_PACKET_LOSS_PERC(opts->packet_loss)); + if (ret != OPUS_OK) + av_log(avctx, AV_LOG_WARNING, +@@ -452,6 +460,15 @@ + int ret; + int discard_padding; + ++ // Reload packet loss setting ++ ret = opus_multistream_encoder_ctl(opus->enc, ++ OPUS_SET_PACKET_LOSS_PERC(opus->opts.packet_loss)); ++ if (ret != OPUS_OK) ++ av_log(avctx, AV_LOG_WARNING, ++ "Unable to set expected packet loss percentage: %s\n", ++ opus_strerror(ret)); ++ ++ + if (frame) { + ret = ff_af_queue_add(&opus->afq, frame); + if (ret < 0) +@@ -543,6 +560,7 @@ + { "audio", "Favor faithfulness to the input", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_AUDIO }, 0, 0, FLAGS, "application" }, + { "lowdelay", "Restrict to only the lowest delay modes", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_RESTRICTED_LOWDELAY }, 0, 0, FLAGS, "application" }, + { "frame_duration", "Duration of a frame in milliseconds", OFFSET(frame_duration), AV_OPT_TYPE_FLOAT, { .dbl = 20.0 }, 2.5, 120.0, FLAGS }, ++ { "enable_fec", "Enable forward error correction", OFFSET(enable_fec), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, + { "packet_loss", "Expected packet loss percentage", OFFSET(packet_loss), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, FLAGS }, + { "vbr", "Variable bit rate mode", OFFSET(vbr), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 2, FLAGS, "vbr" }, + { "off", "Use constant bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "vbr" }, diff --git a/gnu/packages/patches/ffmpeg-jami-libopusenc-reload-packet-loss-at-encode.patch b/gnu/packages/patches/ffmpeg-jami-libopusenc-reload-packet-loss-at-encode.patch new file mode 100644 index 0000000000..5c4bd4d3eb --- /dev/null +++ b/gnu/packages/patches/ffmpeg-jami-libopusenc-reload-packet-loss-at-encode.patch @@ -0,0 +1,44 @@ +From dba13d03bc8e827fededc20b0ab1f574a1500f2a Mon Sep 17 00:00:00 2001 +From: Philip-Dylan Gleonec <philip-dylan.gleonec@savoirfairelinux.com> +Date: Thu, 11 Feb 2021 12:25:14 +0100 +Subject: [PATCH 2/2] avcodec/libopusenc: reload packet loss at encode + +An estimation of packet loss is required by libopus to compute its FEC +data. Currently, this estimation is constant, and can not be changed +after configuration. This means an application using libopus through +ffmpeg can not adapt the packet loss estimation when the network +quality degrades. + +This patch makes the encoder reload the packet_loss AVOption before +encoding samples, if fec is enabled. This way an application can modify +the packet loss estimation by changing the AVOption. Typical use-case +is a RTP stream, where packet loss can be estimated from RTCP packets. + +Signed-off-by: Philip-Dylan Gleonec <philip-dylan.gleonec@savoirfairelinux.com> +--- + libavcodec/libopusenc.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c +index 70d17f802b..c18e8ae7fa 100644 +--- a/libavcodec/libopusenc.c ++++ b/libavcodec/libopusenc.c +@@ -460,6 +460,15 @@ static int libopus_encode(AVCodecContext *avctx, AVPacket *avpkt, + int ret; + int discard_padding; + ++ if (opus->opts.fec) { ++ ret = opus_multistream_encoder_ctl(opus->enc, ++ OPUS_SET_PACKET_LOSS_PERC(opus->opts.packet_loss)); ++ if (ret != OPUS_OK) ++ av_log(avctx, AV_LOG_WARNING, ++ "Unable to set expected packet loss percentage: %s\n", ++ opus_strerror(ret)); ++ } ++ + if (frame) { + ret = ff_af_queue_add(&opus->afq, frame); + if (ret < 0) +-- +2.25.1 + diff --git a/gnu/packages/patches/ffmpeg-jami-remove-mjpeg-log.patch b/gnu/packages/patches/ffmpeg-jami-remove-mjpeg-log.patch new file mode 100644 index 0000000000..595baea9c9 --- /dev/null +++ b/gnu/packages/patches/ffmpeg-jami-remove-mjpeg-log.patch @@ -0,0 +1,26 @@ +From c557a6211f5a29d89fc2ab561e0fb3d8878fb6ad Mon Sep 17 00:00:00 2001 +From: philippegorley <gorley.philippe@gmail.com> +Date: Mon, 17 Dec 2018 15:27:57 -0500 +Subject: [PATCH] remove mjpeg log + +--- + libavcodec/mjpegdec.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c +index d1dca84d36..4a26c23cd4 100644 +--- a/libavcodec/mjpegdec.c ++++ b/libavcodec/mjpegdec.c +@@ -2294,9 +2294,7 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, + "restart marker: %d\n", start_code & 0x0f); + /* APP fields */ + } else if (start_code >= APP0 && start_code <= APP15) { +- if ((ret = mjpeg_decode_app(s)) < 0) +- av_log(avctx, AV_LOG_ERROR, "unable to decode APP fields: %s\n", +- av_err2str(ret)); ++ ret = mjpeg_decode_app(s); + /* Comment */ + } else if (start_code == COM) { + ret = mjpeg_decode_com(s); +-- +2.17.1 diff --git a/gnu/packages/patches/ffmpeg-jami-rtp_ext_abs_send_time.patch b/gnu/packages/patches/ffmpeg-jami-rtp_ext_abs_send_time.patch new file mode 100644 index 0000000000..cf52cf972a --- /dev/null +++ b/gnu/packages/patches/ffmpeg-jami-rtp_ext_abs_send_time.patch @@ -0,0 +1,71 @@ +diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c +index 63047beccc..d59ec3dc8c 100644 +--- a/libavformat/rtpenc.c ++++ b/libavformat/rtpenc.c +@@ -28,6 +28,8 @@ + + #include "rtpenc.h" + ++#define EXT_ABS_SEND_TIME ++ + static const AVOption options[] = { + FF_RTP_FLAG_OPTS(RTPMuxContext, flags), + { "payload_type", "Specify RTP payload type", offsetof(RTPMuxContext, payload_type), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 127, AV_OPT_FLAG_ENCODING_PARAM }, +@@ -146,7 +148,11 @@ static int rtp_write_header(AVFormatContext *s1) + s1->pb->max_packet_size); + } else + s1->packet_size = s1->pb->max_packet_size; ++#ifdef EXT_ABS_SEND_TIME ++ if (s1->packet_size <= 20) { ++#else + if (s1->packet_size <= 12) { ++#endif + av_log(s1, AV_LOG_ERROR, "Max packet size %u too low\n", s1->packet_size); + return AVERROR(EIO); + } +@@ -154,7 +160,11 @@ static int rtp_write_header(AVFormatContext *s1) + if (!s->buf) { + return AVERROR(ENOMEM); + } ++#ifdef EXT_ABS_SEND_TIME ++ s->max_payload_size = s1->packet_size - 20; ++#else + s->max_payload_size = s1->packet_size - 12; ++#endif + + if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { + avpriv_set_pts_info(st, 32, 1, st->codecpar->sample_rate); +@@ -332,16 +342,34 @@ static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time, int bye) + void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m) + { + RTPMuxContext *s = s1->priv_data; ++ uint64_t ntp64_time; ++ uint32_t absoluteSendTime; + + av_log(s1, AV_LOG_TRACE, "rtp_send_data size=%d\n", len); + + /* build the RTP header */ ++#ifdef EXT_ABS_SEND_TIME ++ avio_w8(s1->pb, RTP_VERSION << 6 | 0x10); // extention bit ++#else + avio_w8(s1->pb, RTP_VERSION << 6); ++#endif + avio_w8(s1->pb, (s->payload_type & 0x7f) | ((m & 0x01) << 7)); + avio_wb16(s1->pb, s->seq); + avio_wb32(s1->pb, s->timestamp); + avio_wb32(s1->pb, s->ssrc); + ++#ifdef EXT_ABS_SEND_TIME ++ avio_wb16(s1->pb, 0xBEDE); // magic word ++ avio_wb16(s1->pb, 0x0001); // length=1 ++ avio_w8(s1->pb, 0x32); // ID=3 and lenght=2 ++ ntp64_time = ff_get_formatted_ntp_time(ff_ntp_time()); ++ absoluteSendTime = (uint32_t)((ntp64_time>> 14) & 0x00ffffff); ++ av_log(s1, AV_LOG_TRACE, "ntp64:%lu, abs_time:%u\n", ntp64_time, absoluteSendTime); ++ avio_w8(s1->pb, (uint8_t)(absoluteSendTime >> 16)); ++ avio_w8(s1->pb, (uint8_t)(absoluteSendTime >> 8 & 0xff)); ++ avio_w8(s1->pb, (uint8_t)(absoluteSendTime & 0xff)); ++#endif ++ + avio_write(s1->pb, buf1, len); + avio_flush(s1->pb); diff --git a/gnu/packages/patches/ffmpeg-jami-screen-sharing-x11-fix.patch b/gnu/packages/patches/ffmpeg-jami-screen-sharing-x11-fix.patch new file mode 100644 index 0000000000..e54a346706 --- /dev/null +++ b/gnu/packages/patches/ffmpeg-jami-screen-sharing-x11-fix.patch @@ -0,0 +1,302 @@ +From c1b210534b15188c964b31dc47e172f8ed4aca55 Mon Sep 17 00:00:00 2001 +From: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com> +Date: Tue, 19 Jul 2022 13:35:19 -0300 +Subject: [PATCH] Screen sharing x11 fixes + ++ We can now have a single stream in the x11grab, which can be updated to follow window resizing ++ Due to stream reinit, shm may cause memory issues and was removed ++ Adds one option (is_area) that defines if we are grabing a region of the display/window or the hole screen/window. + +note: This is a custom patch for later rebase +--- + libavdevice/xcbgrab.c | 186 ++++++++++-------------------------------- + 1 file changed, 45 insertions(+), 141 deletions(-) + +diff --git a/libavdevice/xcbgrab.c b/libavdevice/xcbgrab.c +index 64a68ba497..76e654b424 100644 +--- a/libavdevice/xcbgrab.c ++++ b/libavdevice/xcbgrab.c +@@ -29,11 +29,6 @@ + #include <xcb/xfixes.h> + #endif + +-#if CONFIG_LIBXCB_SHM +-#include <sys/shm.h> +-#include <xcb/shm.h> +-#endif +- + #if CONFIG_LIBXCB_SHAPE + #include <xcb/shape.h> + #endif +@@ -53,9 +48,6 @@ typedef struct XCBGrabContext { + xcb_connection_t *conn; + xcb_screen_t *screen; + xcb_window_t window; +-#if CONFIG_LIBXCB_SHM +- AVBufferPool *shm_pool; +-#endif + int64_t time_frame; + AVRational time_base; + int64_t frame_duration; +@@ -72,10 +64,9 @@ typedef struct XCBGrabContext { + int region_border; + int centered; + int select_region; ++ int is_area; + + const char *framerate; +- +- int has_shm; + } XCBGrabContext; + + #define FOLLOW_CENTER -1 +@@ -97,6 +88,7 @@ static const AVOption options[] = { + { "show_region", "Show the grabbing region.", OFFSET(show_region), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D }, + { "region_border", "Set the region border thickness.", OFFSET(region_border), AV_OPT_TYPE_INT, { .i64 = 3 }, 1, 128, D }, + { "select_region", "Select the grabbing region graphically using the pointer.", OFFSET(select_region), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, D }, ++ { "is_area", "Define if we are grabing a region of the display/window.", OFFSET(is_area), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, D }, + { NULL }, + }; + +@@ -216,99 +208,6 @@ static int64_t wait_frame(AVFormatContext *s, AVPacket *pkt) + return curtime; + } + +-#if CONFIG_LIBXCB_SHM +-static int check_shm(xcb_connection_t *conn) +-{ +- xcb_shm_query_version_cookie_t cookie = xcb_shm_query_version(conn); +- xcb_shm_query_version_reply_t *reply; +- +- reply = xcb_shm_query_version_reply(conn, cookie, NULL); +- if (reply) { +- free(reply); +- return 1; +- } +- +- return 0; +-} +- +-static void free_shm_buffer(void *opaque, uint8_t *data) +-{ +- shmdt(data); +-} +- +-static AVBufferRef *allocate_shm_buffer(void *opaque, size_t size) +-{ +- xcb_connection_t *conn = opaque; +- xcb_shm_seg_t segment; +- AVBufferRef *ref; +- uint8_t *data; +- int id; +- +- id = shmget(IPC_PRIVATE, size, IPC_CREAT | 0777); +- if (id == -1) +- return NULL; +- +- segment = xcb_generate_id(conn); +- xcb_shm_attach(conn, segment, id, 0); +- data = shmat(id, NULL, 0); +- shmctl(id, IPC_RMID, 0); +- if ((intptr_t)data == -1 || !data) +- return NULL; +- +- ref = av_buffer_create(data, size, free_shm_buffer, (void *)(ptrdiff_t)segment, 0); +- if (!ref) +- shmdt(data); +- +- return ref; +-} +- +-static int xcbgrab_frame_shm(AVFormatContext *s, AVPacket *pkt) +-{ +- XCBGrabContext *c = s->priv_data; +- xcb_shm_get_image_cookie_t iq; +- xcb_shm_get_image_reply_t *img; +- xcb_drawable_t drawable = c->window_id; +- xcb_generic_error_t *e = NULL; +- AVBufferRef *buf; +- xcb_shm_seg_t segment; +- +- buf = av_buffer_pool_get(c->shm_pool); +- if (!buf) { +- av_log(s, AV_LOG_ERROR, "Could not get shared memory buffer.\n"); +- return AVERROR(ENOMEM); +- } +- segment = (xcb_shm_seg_t)(uintptr_t)av_buffer_pool_buffer_get_opaque(buf); +- +- iq = xcb_shm_get_image(c->conn, drawable, +- c->x, c->y, c->width, c->height, ~0, +- XCB_IMAGE_FORMAT_Z_PIXMAP, segment, 0); +- img = xcb_shm_get_image_reply(c->conn, iq, &e); +- +- xcb_flush(c->conn); +- +- if (e) { +- av_log(s, AV_LOG_ERROR, +- "Cannot get the image data " +- "event_error: response_type:%u error_code:%u " +- "sequence:%u resource_id:%u minor_code:%u major_code:%u.\n", +- e->response_type, e->error_code, +- e->sequence, e->resource_id, e->minor_code, e->major_code); +- +- free(e); +- av_buffer_unref(&buf); +- return AVERROR(EACCES); +- } +- +- free(img); +- +- pkt->buf = buf; +- pkt->data = buf->data; +- pkt->size = c->frame_size; +- +- return 0; +-} +-#endif /* CONFIG_LIBXCB_SHM */ +- + #if CONFIG_LIBXCB_XFIXES + static int check_xfixes(xcb_connection_t *conn) + { +@@ -462,14 +361,7 @@ static int xcbgrab_read_packet(AVFormatContext *s, AVPacket *pkt) + if (c->show_region) + xcbgrab_update_region(s, win_x, win_y); + +-#if CONFIG_LIBXCB_SHM +- if (c->has_shm && xcbgrab_frame_shm(s, pkt) < 0) { +- av_log(s, AV_LOG_WARNING, "Continuing without shared memory.\n"); +- c->has_shm = 0; +- } +-#endif +- if (!c->has_shm) +- ret = xcbgrab_frame(s, pkt); ++ ret = xcbgrab_frame(s, pkt); + pkt->dts = pkt->pts = pts; + pkt->duration = c->frame_duration; + +@@ -488,11 +380,8 @@ static av_cold int xcbgrab_read_close(AVFormatContext *s) + { + XCBGrabContext *ctx = s->priv_data; + +-#if CONFIG_LIBXCB_SHM +- av_buffer_pool_uninit(&ctx->shm_pool); +-#endif +- + xcb_disconnect(ctx->conn); ++ ctx->conn = NULL; + + return 0; + } +@@ -572,7 +461,15 @@ static int pixfmt_from_pixmap_format(AVFormatContext *s, int depth, + static int create_stream(AVFormatContext *s) + { + XCBGrabContext *c = s->priv_data; +- AVStream *st = avformat_new_stream(s, NULL); ++ ++ // If we try to open another stream to x11grab, there is no reason ++ // to keep more than one stream in the context. ++ AVStream *st; ++ if (!s->nb_streams) { ++ st = avformat_new_stream(s, NULL); ++ } else { ++ st = s->streams[0]; ++ } + xcb_get_geometry_cookie_t gc; + xcb_get_geometry_reply_t *geo; + int64_t frame_size_bits; +@@ -594,11 +491,26 @@ static int create_stream(AVFormatContext *s) + return AVERROR_EXTERNAL; + } + ++ // av_log(s, AV_LOG_ERROR, "Capture is_area %d\n", c->is_area); ++ // Width and Height are not 0 only when we set a window area to share ++ // This if may be valid only in the first call to create_stream + if (!c->width || !c->height) { ++ // av_log(s, AV_LOG_ERROR, "Capture area!\n"); ++ c->is_area = 0; ++ c->width = geo->width; ++ c->height = geo->height; ++ } ++ // If not a predefined area, then we should follow geometry changes ++ // This can be valid only on the second call onwards ++ if (!c->is_area && (c->width != geo->width || c->height != geo->height)) { + c->width = geo->width; + c->height = geo->height; + } + ++ // av_log(s, AV_LOG_ERROR, "Capture area %dx%d at position %d.%d\n", ++ // c->width, c->height, ++ // c->x, c->y); ++ + if (c->x + c->width > geo->width || + c->y + c->height > geo->height) { + av_log(s, AV_LOG_ERROR, +@@ -628,13 +540,6 @@ static int create_stream(AVFormatContext *s) + } + c->frame_size = frame_size_bits / 8; + +-#if CONFIG_LIBXCB_SHM +- c->shm_pool = av_buffer_pool_init2(c->frame_size + AV_INPUT_BUFFER_PADDING_SIZE, +- c->conn, allocate_shm_buffer, NULL); +- if (!c->shm_pool) +- return AVERROR(ENOMEM); +-#endif +- + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO; + st->codecpar->width = c->width; +@@ -829,23 +734,26 @@ static av_cold int xcbgrab_read_header(AVFormatContext *s) + sscanf(s->url, "+%d,%d", &c->x, &c->y); + } + +- c->conn = xcb_connect(display_name[0] ? display_name : NULL, &screen_num); +- av_freep(&display_name); ++ if (!c->conn || !c->screen) { ++ xcbgrab_read_close(s); ++ c->conn = xcb_connect(display_name[0] ? display_name : NULL, &screen_num); ++ av_freep(&display_name); + +- if ((ret = xcb_connection_has_error(c->conn))) { +- av_log(s, AV_LOG_ERROR, "Cannot open display %s, error %d.\n", +- s->url[0] ? s->url : "default", ret); +- return AVERROR(EIO); +- } ++ if ((ret = xcb_connection_has_error(c->conn))) { ++ av_log(s, AV_LOG_ERROR, "Cannot open display %s, error %d.\n", ++ s->url[0] ? s->url : "default", ret); ++ return AVERROR(EIO); ++ } + +- setup = xcb_get_setup(c->conn); ++ setup = xcb_get_setup(c->conn); + +- c->screen = get_screen(setup, screen_num); +- if (!c->screen) { +- av_log(s, AV_LOG_ERROR, "The screen %d does not exist.\n", +- screen_num); +- xcbgrab_read_close(s); +- return AVERROR(EIO); ++ c->screen = get_screen(setup, screen_num); ++ if (!c->screen) { ++ av_log(s, AV_LOG_ERROR, "The screen %d does not exist.\n", ++ screen_num); ++ xcbgrab_read_close(s); ++ return AVERROR(EIO); ++ } + } + + if (c->window_id == XCB_NONE) +@@ -876,10 +784,6 @@ static av_cold int xcbgrab_read_header(AVFormatContext *s) + return ret; + } + +-#if CONFIG_LIBXCB_SHM +- c->has_shm = check_shm(c->conn); +-#endif +- + #if CONFIG_LIBXCB_XFIXES + if (c->draw_mouse) { + if (!(c->draw_mouse = check_xfixes(c->conn))) { +-- +2.34.1 + diff --git a/gnu/packages/video.scm b/gnu/packages/video.scm index de812ac762..d751442561 100644 --- a/gnu/packages/video.scm +++ b/gnu/packages/video.scm @@ -50,7 +50,7 @@ ;;; Copyright © 2021 Alexey Abramov <levenson@mmer.org> ;;; Copyright © 2021, 2022, 2023 Andrew Tropin <andrew@trop.in> ;;; Copyright © 2021 David Wilson <david@daviwil.com> -;;; Copyright © 2021, 2022, 2023 Maxim Cournoyer <maxim.cournoyer@gmail.com> +;;; Copyright © 2021, 2022, 2023, 2024 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; Copyright © 2020 Hartmut Goebel <h.goebel@crazy-compilers.com> ;;; Copyright © 2021 Raghav Gururajan <rg@raghavgururajan.name> ;;; Copyright © 2021 Thiago Jung Bauermann <bauermann@kolabnow.com> @@ -2000,6 +2000,252 @@ audio/video codec library.") "--enable-static")))) (inputs '())))) +;;; Custom ffmpeg package used by Jami, which incorporates custom patches. +(define-public ffmpeg-jami + (package + (inherit ffmpeg) + (name "ffmpeg-jami") + (source (let ((ffmpeg-origin (package-source ffmpeg))) + (origin + (inherit ffmpeg-origin) + ;; These patches originate come from + ;; <https://review.jami.net/plugins/gitiles/jami-daemon/+/refs/heads/master/contrib/src/ffmpeg/>. + ;; Make sure to keep them update and/or register any new ones + ;; here. + (patches + (append + (origin-patches ffmpeg-origin) + (search-patches + "ffmpeg-jami-remove-mjpeg-log.patch" + "ffmpeg-jami-change-RTCP-ratio.patch" + "ffmpeg-jami-rtp_ext_abs_send_time.patch" + "ffmpeg-jami-libopusdec-enable-FEC.patch" + "ffmpeg-jami-libopusenc-reload-packet-loss-at-encode.patch" + "ffmpeg-jami-screen-sharing-x11-fix.patch")))))) + (arguments + (substitute-keyword-arguments (package-arguments ffmpeg) + ((#:configure-flags _ '()) + #~(list "--disable-static" + "--enable-shared" + "--disable-stripping" + ;; The following variables are configure flags used by + ;; ffmpeg-jami. They're from the + ;; jami/daemon/contrib/src/ffmpeg/rules.mak file. We try to + ;; keep it as close to the official Jami package as possible, + ;; to provide all the codecs and extra features that are + ;; expected (see: + ;; https://review.jami.net/plugins/gitiles/jami-daemon/+/ + ;; refs/heads/master/contrib/src/ffmpeg/rules.mak). + ;; An exception are the ffnvcodec-related switches, which is + ;; not packaged in Guix and would not work with Mesa. + #$@(if (string-contains (%current-system) "linux") + '("--enable-pic" + "--extra-cxxflags=-fPIC" + "--extra-cflags=-fPIC" + "--target-os=linux" + "--enable-indev=v4l2" + "--enable-indev=xcbgrab" + "--enable-vdpau" + "--enable-hwaccel=h264_vdpau" + "--enable-hwaccel=mpeg4_vdpau" + "--enable-vaapi" + "--enable-hwaccel=h264_vaapi" + "--enable-hwaccel=mpeg4_vaapi" + "--enable-hwaccel=h263_vaapi" + "--enable-hwaccel=vp8_vaapi" + "--enable-hwaccel=mjpeg_vaapi" + "--enable-hwaccel=hevc_vaapi" + "--enable-encoder=h264_vaapi" + "--enable-encoder=vp8_vaapi" + "--enable-encoder=mjpeg_vaapi" + "--enable-encoder=hevc_vaapi") + '()) + "--disable-everything" + "--enable-zlib" + "--enable-gpl" + "--enable-swscale" + "--enable-bsfs" + "--disable-filters" + "--disable-programs" + "--disable-postproc" + "--disable-protocols" + "--enable-protocol=crypto" + "--enable-protocol=file" + "--enable-protocol=rtp" + "--enable-protocol=srtp" + "--enable-protocol=tcp" + "--enable-protocol=udp" + "--enable-protocol=unix" + "--enable-protocol=pipe" + + ;; Enable muxers/demuxers. + "--disable-demuxers" + "--disable-muxers" + "--enable-muxer=rtp" + "--enable-muxer=g722" + "--enable-muxer=g726" + "--enable-muxer=g726le" + "--enable-muxer=h263" + "--enable-muxer=h264" + "--enable-muxer=hevc" + "--enable-muxer=matroska" + "--enable-muxer=wav" + "--enable-muxer=webm" + "--enable-muxer=ogg" + "--enable-muxer=pcm_s16be" + "--enable-muxer=pcm_s16le" + "--enable-demuxer=rtp" + "--enable-demuxer=mjpeg" + "--enable-demuxer=mjpeg_2000" + "--enable-demuxer=mpegvideo" + "--enable-demuxer=gif" + "--enable-demuxer=image_jpeg_pipe" + "--enable-demuxer=image_png_pipe" + "--enable-demuxer=image_webp_pipe" + "--enable-demuxer=matroska" + "--enable-demuxer=m4v" + "--enable-demuxer=mp3" + "--enable-demuxer=ogg" + "--enable-demuxer=flac" + "--enable-demuxer=wav" + "--enable-demuxer=ac3" + "--enable-demuxer=g722" + "--enable-demuxer=g723_1" + "--enable-demuxer=g726" + "--enable-demuxer=g726le" + "--enable-demuxer=pcm_mulaw" + "--enable-demuxer=pcm_alaw" + "--enable-demuxer=pcm_s16be" + "--enable-demuxer=pcm_s16le" + "--enable-demuxer=h263" + "--enable-demuxer=h264" + "--enable-demuxer=hevc" + + ;; Enable parsers. + "--enable-parser=h263" + "--enable-parser=h264" + "--enable-parser=hevc" + "--enable-parser=mpeg4video" + "--enable-parser=vp8" + "--enable-parser=vp9" + "--enable-parser=opus" + + ;; Encoders/decoders. + "--enable-encoder=adpcm_g722" + "--enable-decoder=adpcm_g722" + "--enable-encoder=adpcm_g726" + "--enable-decoder=adpcm_g726" + "--enable-encoder=adpcm_g726le" + "--enable-decoder=adpcm_g726le" + "--enable-decoder=g729" + "--enable-encoder=g723_1" + "--enable-decoder=g723_1" + "--enable-encoder=rawvideo" + "--enable-decoder=rawvideo" + "--enable-encoder=libx264" + "--enable-decoder=h264" + "--enable-encoder=pcm_alaw" + "--enable-decoder=pcm_alaw" + "--enable-encoder=pcm_mulaw" + "--enable-decoder=pcm_mulaw" + "--enable-encoder=mpeg4" + "--enable-decoder=mpeg4" + "--enable-encoder=libvpx_vp8" + "--enable-decoder=vp8" + "--enable-decoder=vp9" + "--enable-encoder=h263" + "--enable-encoder=h263p" + "--enable-decoder=h263" + "--enable-encoder=mjpeg" + "--enable-decoder=mjpeg" + "--enable-decoder=mjpegb" + "--enable-libspeex" + "--enable-libopus" + "--enable-libvpx" + "--enable-libx264" + "--enable-encoder=libspeex" + "--enable-decoder=libspeex" + "--enable-encoder=libopus" + "--enable-decoder=libopus" + + ;; Encoders/decoders for ringtones and audio streaming. + "--enable-decoder=flac" + "--enable-decoder=vorbis" + "--enable-decoder=aac" + "--enable-decoder=ac3" + "--enable-decoder=eac3" + "--enable-decoder=mp3" + "--enable-decoder=pcm_u24le" + "--enable-decoder=pcm_u32le" + "--enable-decoder=pcm_u8" + "--enable-decoder=pcm_f16le" + "--enable-decoder=pcm_f32le" + "--enable-decoder=pcm_f64le" + "--enable-decoder=pcm_s16le" + "--enable-decoder=pcm_s24le" + "--enable-decoder=pcm_s32le" + "--enable-decoder=pcm_s64le" + "--enable-decoder=pcm_u16le" + "--enable-encoder=pcm_u8" + "--enable-encoder=pcm_f32le" + "--enable-encoder=pcm_f64le" + "--enable-encoder=pcm_s16le" + "--enable-encoder=pcm_s32le" + "--enable-encoder=pcm_s64le" + + "--enable-decoder=pcm_s16be" + "--enable-decoder=pcm_s16be_planar" + "--enable-decoder=pcm_s16le_planar" + "--enable-decoder=pcm_s24be" + "--enable-decoder=pcm_s24le_planar" + "--enable-decoder=pcm_s32be" + "--enable-decoder=pcm_s32le_planar" + "--enable-decoder=pcm_s64be" + "--enable-decoder=pcm_s8" + "--enable-decoder=pcm_s8_planar" + "--enable-decoder=pcm_u16be" + + ;; Encoders/decoders for images. + "--enable-encoder=gif" + "--enable-decoder=gif" + "--enable-encoder=jpegls" + "--enable-decoder=jpegls" + "--enable-encoder=ljpeg" + "--enable-decoder=jpeg2000" + "--enable-encoder=png" + "--enable-decoder=png" + "--enable-encoder=bmp" + "--enable-decoder=bmp" + "--enable-encoder=tiff" + "--enable-decoder=tiff" + + ;; Filters. + "--enable-filter=scale" + "--enable-filter=overlay" + "--enable-filter=amix" + "--enable-filter=amerge" + "--enable-filter=aresample" + "--enable-filter=format" + "--enable-filter=aformat" + "--enable-filter=fps" + "--enable-filter=transpose" + "--enable-filter=pad" + + "--enable-filter=afir" + "--enable-filter=split" + "--enable-filter=drawbox" + "--enable-filter=drawtext" + "--enable-filter=rotate" + "--enable-filter=loop" + "--enable-filter=setpts" + "--enable-filter=movie" + "--enable-filter=alphamerge" + "--enable-filter=boxblur" + "--enable-filter=lut" + "--enable-filter=negate" + "--enable-filter=colorkey" + "--enable-filter=transpose")))))) + (define-public ffmpegthumbnailer (package (name "ffmpegthumbnailer") |