From: mkver via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> To: ffmpeg-devel@ffmpeg.org Cc: mkver <code@ffmpeg.org> Subject: [FFmpeg-devel] [PATCH] avcodec/cbrt_tablegen: Avoid static array used only once (PR #20404) Message-ID: <175686425625.25.15885250281461158294@463a07221176> (raw) PR #20404 opened by mkver URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20404 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20404.patch Also fix building with hardcoded tables, which has been broken by #20344. From a3e22d2c394202cef52bee077d22132796cba95c Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> Date: Wed, 3 Sep 2025 01:48:55 +0200 Subject: [PATCH 1/5] avcodec/pcm_tablegen: Fix CONFIG_HARDCODED_TABLES Broken in ae448e00afb43d7f72dfa9c82a4c45994e4fea6a. Notice that config_components.h is safe to include, as it is valid for both the host and the target (in contrast to config.h). Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavcodec/pcm_tablegen.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/pcm_tablegen.h b/libavcodec/pcm_tablegen.h index 590ba59814..60ef9656d5 100644 --- a/libavcodec/pcm_tablegen.h +++ b/libavcodec/pcm_tablegen.h @@ -24,6 +24,7 @@ #define AVCODEC_PCM_TABLEGEN_H #include <stdint.h> +#include "config_components.h" #include "libavutil/attributes.h" /* from g711.c by SUN microsystems (unrestricted use) */ -- 2.49.1 From 74f7c26beba8889d6427ffe83e3afc84803bc71d Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> Date: Tue, 2 Sep 2025 17:19:04 +0200 Subject: [PATCH 2/5] avcodec/cbrt_tablegen: Remove always-false branch Each ff_cbrt_tableinit*() is called at most once, making this check always-false. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavcodec/cbrt_tablegen.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavcodec/cbrt_tablegen.h b/libavcodec/cbrt_tablegen.h index 9af18d8ab5..fae5d547aa 100644 --- a/libavcodec/cbrt_tablegen.h +++ b/libavcodec/cbrt_tablegen.h @@ -40,7 +40,6 @@ uint32_t AAC_RENAME(ff_cbrt_tab)[1 << 13]; av_cold void AAC_RENAME(ff_cbrt_tableinit)(void) { static double cbrt_tab_dbl[1 << 13]; - if (!AAC_RENAME(ff_cbrt_tab)[(1<<13) - 1]) { int i, j, k; double cbrt_val; @@ -67,7 +66,6 @@ av_cold void AAC_RENAME(ff_cbrt_tableinit)(void) for (i = 0; i < 1<<13; i++) AAC_RENAME(ff_cbrt_tab)[i] = CBRT(cbrt_tab_dbl[i]); - } } #endif /* AVCODEC_CBRT_TABLEGEN_H */ -- 2.49.1 From 88c3d9c9179826d23369b9b1699e6ffc4e18c3aa Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> Date: Tue, 2 Sep 2025 20:47:21 +0200 Subject: [PATCH 3/5] avcodec/cbrt_tablegen: Reduce size of LUT only used once ff_cbrt_tableinit{,_fixed}() uses a LUT of doubles of the same size as the actual LUT to be initialized (8192 elems). Said LUT is only used to initialize another LUT, but because it is static, the dirty memory (64KiB) is not released. It is also too large to be put on the stack. This commit mitigates this: We only use a LUT for the powers of odd values, thereby halving its size. The generated LUT stays unchanged. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavcodec/cbrt_tablegen.h | 58 ++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/libavcodec/cbrt_tablegen.h b/libavcodec/cbrt_tablegen.h index fae5d547aa..53ff79f570 100644 --- a/libavcodec/cbrt_tablegen.h +++ b/libavcodec/cbrt_tablegen.h @@ -35,37 +35,53 @@ #define CBRT(x) av_float2int((float)(x)) #endif -uint32_t AAC_RENAME(ff_cbrt_tab)[1 << 13]; +#define LUT_SIZE (1 << 13) +#define TMP_LUT_SIZE (LUT_SIZE/2) + +uint32_t AAC_RENAME(ff_cbrt_tab)[LUT_SIZE]; av_cold void AAC_RENAME(ff_cbrt_tableinit)(void) { - static double cbrt_tab_dbl[1 << 13]; - int i, j, k; - double cbrt_val; + // LUT of k^{4/3} for odd k; element idx corresponds to 2 * idx + 1. + static double cbrt_tab_dbl[TMP_LUT_SIZE]; - for (i = 1; i < 1<<13; i++) - cbrt_tab_dbl[i] = 1; + for (int idx = 0; idx < TMP_LUT_SIZE; ++idx) + cbrt_tab_dbl[idx] = 1; - /* have to take care of non-squarefree numbers */ - for (i = 2; i < 90; i++) { - if (cbrt_tab_dbl[i] == 1) { - cbrt_val = i * cbrt(i); - for (k = i; k < 1<<13; k *= i) - for (j = k; j < 1<<13; j += k) - cbrt_tab_dbl[j] *= cbrt_val; + /* have to take care of non-squarefree numbers; notice that sqrt(LUT_SIZE) = 90; + * idx == 44 corresponds to 89. */ + for (int idx = 1; idx < 45; ++idx) { + if (cbrt_tab_dbl[idx] == 1) { + int i = 2 * idx + 1; + double cbrt_val = i * cbrt(i); + for (int k = i; k < LUT_SIZE; k *= i) { + // We only have to handle k, 3 * k, 5 * k,..., + // because only these are odd. The corresponding indices are + // k >> 1, (k >> 1) + k, (k >> 1) + 2 * k,... + for (int idx2 = k >> 1; idx2 < TMP_LUT_SIZE; idx2 += k) + cbrt_tab_dbl[idx2] *= cbrt_val; } } + } - for (i = 91; i <= 8191; i+= 2) { - if (cbrt_tab_dbl[i] == 1) { - cbrt_val = i * cbrt(i); - for (j = i; j < 1<<13; j += i) - cbrt_tab_dbl[j] *= cbrt_val; - } + for (int idx = 45; idx < TMP_LUT_SIZE; ++idx) { + if (cbrt_tab_dbl[idx] == 1) { + int i = 2 * idx + 1; + double cbrt_val = i * cbrt(i); + for (int idx2 = idx; idx2 < TMP_LUT_SIZE; idx2 += i) + cbrt_tab_dbl[idx2] *= cbrt_val; } + } - for (i = 0; i < 1<<13; i++) - AAC_RENAME(ff_cbrt_tab)[i] = CBRT(cbrt_tab_dbl[i]); + double cbrt_2 = 2 * cbrt(2); + for (int idx = 0; idx < TMP_LUT_SIZE; ++idx) { + double cbrt_val = cbrt_tab_dbl[idx]; + for (int i = 2 * idx + 1; i < LUT_SIZE; i *= 2) { + AAC_RENAME(ff_cbrt_tab)[i] = CBRT(cbrt_val); + cbrt_val *= cbrt_2; + } + } + AAC_RENAME(ff_cbrt_tab)[0] = CBRT(0); } #endif /* AVCODEC_CBRT_TABLEGEN_H */ -- 2.49.1 From 1aa7d3454126360801900832032713224b6308ad Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> Date: Tue, 2 Sep 2025 23:06:32 +0200 Subject: [PATCH 4/5] avcodec/cbrt_tablegen: Avoid LUT only used once This can be done by reusing the destination array to store a temporary LUT (with only half the amount of elements, but double the element size). This relies on certain assumptions about sizes, but they are always fulfilled for systems supported by us (sizeof(double) == 8 is needed/guaranteed since commit 3383a53e7d0abb9639c3ea3481f0eda9dca61a26). Furthermore, sizeof(uint32_t) is always >= four because CHAR_BIT is eight (in fact, sizeof(uint32_t) is four, because the exact width types don't have any padding). Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavcodec/cbrt_data.h | 25 +++++++++++++++----- libavcodec/cbrt_tablegen.h | 36 +++++++++++++++++------------ libavcodec/cbrt_tablegen_template.c | 2 +- 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/libavcodec/cbrt_data.h b/libavcodec/cbrt_data.h index 89117f85b3..bf84dca10d 100644 --- a/libavcodec/cbrt_data.h +++ b/libavcodec/cbrt_data.h @@ -23,18 +23,31 @@ #include <stdint.h> -#include "config.h" +#define LUT_SIZE (1 << 13) -#if CONFIG_HARDCODED_TABLES +#ifndef BUILD_TABLES +#include "config.h" +#define BUILD_TABLES !CONFIG_HARDCODED_TABLES +#endif + +#if !BUILD_TABLES #define ff_cbrt_tableinit_fixed() #define ff_cbrt_tableinit() -extern const uint32_t ff_cbrt_tab[1 << 13]; -extern const uint32_t ff_cbrt_tab_fixed[1 << 13]; +extern const uint32_t ff_cbrt_tab[LUT_SIZE]; +extern const uint32_t ff_cbrt_tab_fixed[LUT_SIZE]; #else void ff_cbrt_tableinit(void); void ff_cbrt_tableinit_fixed(void); -extern uint32_t ff_cbrt_tab[1 << 13]; -extern uint32_t ff_cbrt_tab_fixed[1 << 13]; + +#define TMP_LUT_SIZE (LUT_SIZE / 2) + +extern union CBRT { + uint32_t cbrt_tab[LUT_SIZE]; + double tmp[TMP_LUT_SIZE]; +} ff_cbrt_tab_internal, ff_cbrt_tab_internal_fixed; + +#define ff_cbrt_tab ff_cbrt_tab_internal.cbrt_tab +#define ff_cbrt_tab_fixed ff_cbrt_tab_internal_fixed.cbrt_tab #endif #endif diff --git a/libavcodec/cbrt_tablegen.h b/libavcodec/cbrt_tablegen.h index 53ff79f570..bc040a87e6 100644 --- a/libavcodec/cbrt_tablegen.h +++ b/libavcodec/cbrt_tablegen.h @@ -23,11 +23,13 @@ #ifndef AVCODEC_CBRT_TABLEGEN_H #define AVCODEC_CBRT_TABLEGEN_H +#include <assert.h> #include <stdint.h> #include <math.h> #include "libavutil/attributes.h" #include "libavutil/intfloat.h" #include "libavcodec/aac_defines.h" +#include "cbrt_data.h" #if USE_FIXED #define CBRT(x) lrint((x) * 8192) @@ -35,23 +37,23 @@ #define CBRT(x) av_float2int((float)(x)) #endif -#define LUT_SIZE (1 << 13) -#define TMP_LUT_SIZE (LUT_SIZE/2) - -uint32_t AAC_RENAME(ff_cbrt_tab)[LUT_SIZE]; +union CBRT AAC_RENAME(ff_cbrt_tab_internal); av_cold void AAC_RENAME(ff_cbrt_tableinit)(void) { - // LUT of k^{4/3} for odd k; element idx corresponds to 2 * idx + 1. - static double cbrt_tab_dbl[TMP_LUT_SIZE]; + static_assert(2 * sizeof(AAC_RENAME(ff_cbrt_tab_internal).cbrt_tab[0]) + >= sizeof(AAC_RENAME(ff_cbrt_tab_internal).tmp[0]), + "unexpected sizeofs"); + // We reuse ff_cbrt_tab_internal.tmp as a LUT (of doubles) for the roots + // of the odd integers: tmp[idx] contains (2 * idx + 1)^{4/3}. for (int idx = 0; idx < TMP_LUT_SIZE; ++idx) - cbrt_tab_dbl[idx] = 1; + AAC_RENAME(ff_cbrt_tab_internal).tmp[idx] = 1; /* have to take care of non-squarefree numbers; notice that sqrt(LUT_SIZE) = 90; * idx == 44 corresponds to 89. */ for (int idx = 1; idx < 45; ++idx) { - if (cbrt_tab_dbl[idx] == 1) { + if (AAC_RENAME(ff_cbrt_tab_internal).tmp[idx] == 1) { int i = 2 * idx + 1; double cbrt_val = i * cbrt(i); for (int k = i; k < LUT_SIZE; k *= i) { @@ -59,29 +61,33 @@ av_cold void AAC_RENAME(ff_cbrt_tableinit)(void) // because only these are odd. The corresponding indices are // k >> 1, (k >> 1) + k, (k >> 1) + 2 * k,... for (int idx2 = k >> 1; idx2 < TMP_LUT_SIZE; idx2 += k) - cbrt_tab_dbl[idx2] *= cbrt_val; + AAC_RENAME(ff_cbrt_tab_internal).tmp[idx2] *= cbrt_val; } } } for (int idx = 45; idx < TMP_LUT_SIZE; ++idx) { - if (cbrt_tab_dbl[idx] == 1) { + if (AAC_RENAME(ff_cbrt_tab_internal).tmp[idx] == 1) { int i = 2 * idx + 1; double cbrt_val = i * cbrt(i); for (int idx2 = idx; idx2 < TMP_LUT_SIZE; idx2 += i) - cbrt_tab_dbl[idx2] *= cbrt_val; + AAC_RENAME(ff_cbrt_tab_internal).tmp[idx2] *= cbrt_val; } } double cbrt_2 = 2 * cbrt(2); - for (int idx = 0; idx < TMP_LUT_SIZE; ++idx) { - double cbrt_val = cbrt_tab_dbl[idx]; + for (int idx = TMP_LUT_SIZE - 1; idx >= 0; --idx) { + double cbrt_val = AAC_RENAME(ff_cbrt_tab_internal).tmp[idx]; + // Due to i * sizeof(ff_cbrt_tab_internal.cbrt_tab[0]) >= + // 2 * idx * sizeof(ff_cbrt_tab_internal.cbrt_tab[0]) >= idx * sizeof(double) + // we don't clobber the double-LUT entries with index < idx + // in the loop below. This is why we process idx in descending order. for (int i = 2 * idx + 1; i < LUT_SIZE; i *= 2) { - AAC_RENAME(ff_cbrt_tab)[i] = CBRT(cbrt_val); + AAC_RENAME(ff_cbrt_tab_internal).cbrt_tab[i] = CBRT(cbrt_val); cbrt_val *= cbrt_2; } } - AAC_RENAME(ff_cbrt_tab)[0] = CBRT(0); + AAC_RENAME(ff_cbrt_tab_internal).cbrt_tab[0] = CBRT(0); } #endif /* AVCODEC_CBRT_TABLEGEN_H */ diff --git a/libavcodec/cbrt_tablegen_template.c b/libavcodec/cbrt_tablegen_template.c index 21ed2a6861..06ae152f71 100644 --- a/libavcodec/cbrt_tablegen_template.c +++ b/libavcodec/cbrt_tablegen_template.c @@ -21,7 +21,7 @@ */ #include <stdlib.h> -#define CONFIG_HARDCODED_TABLES 0 +#define BUILD_TABLES 1 #include "libavutil/tablegen.h" #include "cbrt_tablegen.h" #include "tableprint.h" -- 2.49.1 From 450033b13d057a42920297d7c17a374204ddf3e1 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> Date: Wed, 3 Sep 2025 02:53:46 +0200 Subject: [PATCH 5/5] avcodec/cbrt_tablegen: Deduplicate common code Namely the part that creates a temporary LUT. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavcodec/Makefile | 6 ++- libavcodec/cbrt_data.h | 5 +++ libavcodec/cbrt_tablegen.h | 29 +------------- libavcodec/cbrt_tablegen_common.c | 60 +++++++++++++++++++++++++++++ libavcodec/cbrt_tablegen_template.c | 1 + 5 files changed, 71 insertions(+), 30 deletions(-) create mode 100644 libavcodec/cbrt_tablegen_common.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 3d036de4b6..ac143f4103 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -195,11 +195,13 @@ OBJS-$(CONFIG_A64MULTI5_ENCODER) += a64multienc.o elbg.o OBJS-$(CONFIG_AAC_DECODER) += aactab.o \ aacsbr.o aacps_common.o aacps_float.o \ kbdwin.o \ - sbrdsp.o aacpsdsp_float.o cbrt_data.o + sbrdsp.o aacpsdsp_float.o cbrt_data.o \ + $(if $(!CONFIG_HARDCODED_TABLES), cbrt_tablegen_common.o) OBJS-$(CONFIG_AAC_FIXED_DECODER) += aactab.o \ aacsbr_fixed.o aacps_common.o aacps_fixed.o \ kbdwin.o \ - sbrdsp_fixed.o aacpsdsp_fixed.o cbrt_data_fixed.o + sbrdsp_fixed.o aacpsdsp_fixed.o cbrt_data_fixed.o \ + $(if $(!CONFIG_HARDCODED_TABLES), cbrt_tablegen_common.o) OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o aacenctab.o \ aacpsy.o aactab.o \ aacenc_is.o \ diff --git a/libavcodec/cbrt_data.h b/libavcodec/cbrt_data.h index bf84dca10d..8ae3b7651b 100644 --- a/libavcodec/cbrt_data.h +++ b/libavcodec/cbrt_data.h @@ -40,6 +40,11 @@ void ff_cbrt_tableinit(void); void ff_cbrt_tableinit_fixed(void); #define TMP_LUT_SIZE (LUT_SIZE / 2) +/** + * Creates a LUT (of doubles) for the powers of + * the odd integers: tmp_lut[idx] will be set to (2 * idx + 1)^{4/3}. + */ +void ff_cbrt_dbl_tableinit(double tmp_lut[TMP_LUT_SIZE]); extern union CBRT { uint32_t cbrt_tab[LUT_SIZE]; diff --git a/libavcodec/cbrt_tablegen.h b/libavcodec/cbrt_tablegen.h index bc040a87e6..90076dfd8e 100644 --- a/libavcodec/cbrt_tablegen.h +++ b/libavcodec/cbrt_tablegen.h @@ -46,34 +46,7 @@ av_cold void AAC_RENAME(ff_cbrt_tableinit)(void) "unexpected sizeofs"); // We reuse ff_cbrt_tab_internal.tmp as a LUT (of doubles) for the roots // of the odd integers: tmp[idx] contains (2 * idx + 1)^{4/3}. - - for (int idx = 0; idx < TMP_LUT_SIZE; ++idx) - AAC_RENAME(ff_cbrt_tab_internal).tmp[idx] = 1; - - /* have to take care of non-squarefree numbers; notice that sqrt(LUT_SIZE) = 90; - * idx == 44 corresponds to 89. */ - for (int idx = 1; idx < 45; ++idx) { - if (AAC_RENAME(ff_cbrt_tab_internal).tmp[idx] == 1) { - int i = 2 * idx + 1; - double cbrt_val = i * cbrt(i); - for (int k = i; k < LUT_SIZE; k *= i) { - // We only have to handle k, 3 * k, 5 * k,..., - // because only these are odd. The corresponding indices are - // k >> 1, (k >> 1) + k, (k >> 1) + 2 * k,... - for (int idx2 = k >> 1; idx2 < TMP_LUT_SIZE; idx2 += k) - AAC_RENAME(ff_cbrt_tab_internal).tmp[idx2] *= cbrt_val; - } - } - } - - for (int idx = 45; idx < TMP_LUT_SIZE; ++idx) { - if (AAC_RENAME(ff_cbrt_tab_internal).tmp[idx] == 1) { - int i = 2 * idx + 1; - double cbrt_val = i * cbrt(i); - for (int idx2 = idx; idx2 < TMP_LUT_SIZE; idx2 += i) - AAC_RENAME(ff_cbrt_tab_internal).tmp[idx2] *= cbrt_val; - } - } + ff_cbrt_dbl_tableinit(AAC_RENAME(ff_cbrt_tab_internal).tmp); double cbrt_2 = 2 * cbrt(2); for (int idx = TMP_LUT_SIZE - 1; idx >= 0; --idx) { diff --git a/libavcodec/cbrt_tablegen_common.c b/libavcodec/cbrt_tablegen_common.c new file mode 100644 index 0000000000..9b95a6e44a --- /dev/null +++ b/libavcodec/cbrt_tablegen_common.c @@ -0,0 +1,60 @@ +/* + * Common code for AAC cube-root table + * + * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <math.h> + +#include "cbrt_data.h" +#include "libavutil/attributes.h" +#ifdef HAVE_AV_CONFIG_H // Only include libm.h when building for the target, not the host +#include "libavutil/libm.h" +#endif + +av_cold void ff_cbrt_dbl_tableinit(double tmp_lut[TMP_LUT_SIZE]) +{ + for (int idx = 0; idx < TMP_LUT_SIZE; ++idx) + tmp_lut[idx] = 1; + + /* have to take care of non-squarefree numbers; notice that sqrt(LUT_SIZE) = 90; + * idx == 44 corresponds to 89. */ + for (int idx = 1; idx < 45; ++idx) { + if (tmp_lut[idx] == 1) { + int i = 2 * idx + 1; + double cbrt_val = i * cbrt(i); + for (int k = i; k < LUT_SIZE; k *= i) { + // We only have to handle k, 3 * k, 5 * k,..., + // because only these are odd. The corresponding indices are + // k >> 1, (k >> 1) + k, (k >> 1) + 2 * k,... + for (int idx2 = k >> 1; idx2 < TMP_LUT_SIZE; idx2 += k) + tmp_lut[idx2] *= cbrt_val; + } + } + } + + for (int idx = 45; idx < TMP_LUT_SIZE; ++idx) { + if (tmp_lut[idx] == 1) { + int i = 2 * idx + 1; + double cbrt_val = i * cbrt(i); + for (int idx2 = idx; idx2 < TMP_LUT_SIZE; idx2 += i) + tmp_lut[idx2] *= cbrt_val; + } + } +} diff --git a/libavcodec/cbrt_tablegen_template.c b/libavcodec/cbrt_tablegen_template.c index 06ae152f71..4f6aa7e484 100644 --- a/libavcodec/cbrt_tablegen_template.c +++ b/libavcodec/cbrt_tablegen_template.c @@ -24,6 +24,7 @@ #define BUILD_TABLES 1 #include "libavutil/tablegen.h" #include "cbrt_tablegen.h" +#include "cbrt_tablegen_common.c" #include "tableprint.h" int main(void) -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
reply other threads:[~2025-09-03 1:51 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=175686425625.25.15885250281461158294@463a07221176 \ --to=ffmpeg-devel@ffmpeg.org \ --cc=code@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git