Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
To: ffmpeg-devel@ffmpeg.org
Cc: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Subject: [FFmpeg-devel] [PATCH 21/61] avcodec/vp3: Share coefficient VLCs between threads
Date: Wed, 27 Sep 2023 00:16:52 +0200
Message-ID: <GV1P250MB07378A03815C0FBED20761238FC3A@GV1P250MB0737.EURP250.PROD.OUTLOOK.COM> (raw)
In-Reply-To: <GV1P250MB073754E215A199E7219CC13A8FC3A@GV1P250MB0737.EURP250.PROD.OUTLOOK.COM>

These VLCs are very big: The VP3 one have 164382 elements
but due to the overallocation enough memory for 313344 elements
are allocated (1.195 MiB with sizeof(VLCElem) == 4);
for VP4 the numbers are very similar, namely 311296 and 164392
elements. Since 1f4cf92cfbd3accbae582ac63126ed5570ddfd37, each
frame thread has its own copy of these VLCs.

This commit fixes this by sharing these VLCs across threads.
The approach used here will also make it easier to support
stream reconfigurations in case of frame-multithreading
in the future.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/vp3.c | 99 +++++++++++++++++++++++++++++++-----------------
 1 file changed, 65 insertions(+), 34 deletions(-)

diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index 0463909f2f..1abf7e8078 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -45,8 +45,10 @@
 #include "decode.h"
 #include "get_bits.h"
 #include "hpeldsp.h"
+#include "internal.h"
 #include "jpegquanttables.h"
 #include "mathops.h"
+#include "refstruct.h"
 #include "thread.h"
 #include "threadframe.h"
 #include "videodsp.h"
@@ -187,6 +189,10 @@ typedef struct HuffTable {
     uint8_t   nb_entries;
 } HuffTable;
 
+typedef struct CoeffVLCs {
+    VLC vlcs[80];
+} CoeffVLCs;
+
 typedef struct Vp3DecodeContext {
     AVCodecContext *avctx;
     int theora, theora_tables, theora_header;
@@ -289,9 +295,12 @@ typedef struct Vp3DecodeContext {
     int *nkf_coded_fragment_list;
     int num_kf_coded_fragment[3];
 
-    /* The first 16 of the following VLCs are for the dc coefficients;
-       the others are four groups of 16 VLCs each for ac coefficients. */
-    VLC coeff_vlc[5 * 16];
+    /**
+     * The first 16 of the following VLCs are for the dc coefficients;
+     * the others are four groups of 16 VLCs each for ac coefficients.
+     * This is a RefStruct reference to share these VLCs between threads.
+     */
+    CoeffVLCs *coeff_vlc;
 
     /* these arrays need to be on 16-byte boundaries since SSE2 operations
      * index into them */
@@ -365,8 +374,7 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx)
     av_frame_free(&s->last_frame.f);
     av_frame_free(&s->golden_frame.f);
 
-    for (int i = 0; i < FF_ARRAY_ELEMS(s->coeff_vlc); i++)
-        ff_vlc_free(&s->coeff_vlc[i]);
+    ff_refstruct_unref(&s->coeff_vlc);
 
     return 0;
 }
@@ -1295,13 +1303,14 @@ static void reverse_dc_prediction(Vp3DecodeContext *s,
  */
 static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
 {
+    const VLC *coeff_vlc = s->coeff_vlc->vlcs;
     int dc_y_table;
     int dc_c_table;
     int ac_y_table;
     int ac_c_table;
     int residual_eob_run = 0;
-    VLC *y_tables[64];
-    VLC *c_tables[64];
+    const VLC *y_tables[64];
+    const VLC *c_tables[64];
 
     s->dct_tokens[0][0] = s->dct_tokens_base;
 
@@ -1313,7 +1322,7 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
     dc_c_table = get_bits(gb, 4);
 
     /* unpack the Y plane DC coefficients */
-    residual_eob_run = unpack_vlcs(s, gb, &s->coeff_vlc[dc_y_table], 0,
+    residual_eob_run = unpack_vlcs(s, gb, &coeff_vlc[dc_y_table], 0,
                                    0, residual_eob_run);
     if (residual_eob_run < 0)
         return residual_eob_run;
@@ -1324,11 +1333,11 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
     reverse_dc_prediction(s, 0, s->fragment_width[0], s->fragment_height[0]);
 
     /* unpack the C plane DC coefficients */
-    residual_eob_run = unpack_vlcs(s, gb, &s->coeff_vlc[dc_c_table], 0,
+    residual_eob_run = unpack_vlcs(s, gb, &coeff_vlc[dc_c_table], 0,
                                    1, residual_eob_run);
     if (residual_eob_run < 0)
         return residual_eob_run;
-    residual_eob_run = unpack_vlcs(s, gb, &s->coeff_vlc[dc_c_table], 0,
+    residual_eob_run = unpack_vlcs(s, gb, &coeff_vlc[dc_c_table], 0,
                                    2, residual_eob_run);
     if (residual_eob_run < 0)
         return residual_eob_run;
@@ -1350,23 +1359,23 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
     /* build tables of AC VLC tables */
     for (int i = 1; i <= 5; i++) {
         /* AC VLC table group 1 */
-        y_tables[i] = &s->coeff_vlc[ac_y_table + 16];
-        c_tables[i] = &s->coeff_vlc[ac_c_table + 16];
+        y_tables[i] = &coeff_vlc[ac_y_table + 16];
+        c_tables[i] = &coeff_vlc[ac_c_table + 16];
     }
     for (int i = 6; i <= 14; i++) {
         /* AC VLC table group 2 */
-        y_tables[i] = &s->coeff_vlc[ac_y_table + 32];
-        c_tables[i] = &s->coeff_vlc[ac_c_table + 32];
+        y_tables[i] = &coeff_vlc[ac_y_table + 32];
+        c_tables[i] = &coeff_vlc[ac_c_table + 32];
     }
     for (int i = 15; i <= 27; i++) {
         /* AC VLC table group 3 */
-        y_tables[i] = &s->coeff_vlc[ac_y_table + 48];
-        c_tables[i] = &s->coeff_vlc[ac_c_table + 48];
+        y_tables[i] = &coeff_vlc[ac_y_table + 48];
+        c_tables[i] = &coeff_vlc[ac_c_table + 48];
     }
     for (int i = 28; i <= 63; i++) {
         /* AC VLC table group 4 */
-        y_tables[i] = &s->coeff_vlc[ac_y_table + 64];
-        c_tables[i] = &s->coeff_vlc[ac_c_table + 64];
+        y_tables[i] = &coeff_vlc[ac_y_table + 64];
+        c_tables[i] = &coeff_vlc[ac_c_table + 64];
     }
 
     /* decode all AC coefficients */
@@ -1517,6 +1526,7 @@ static void vp4_set_tokens_base(Vp3DecodeContext *s)
 
 static int vp4_unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
 {
+    const VLC *coeff_vlc = s->coeff_vlc->vlcs;
     int dc_y_table;
     int dc_c_table;
     int ac_y_table;
@@ -1539,27 +1549,27 @@ static int vp4_unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
     /* build tables of DC/AC VLC tables */
 
     /* DC table group */
-    tables[0][0] = &s->coeff_vlc[dc_y_table];
-    tables[1][0] = &s->coeff_vlc[dc_c_table];
+    tables[0][0] = &coeff_vlc[dc_y_table];
+    tables[1][0] = &coeff_vlc[dc_c_table];
     for (int i = 1; i <= 5; i++) {
         /* AC VLC table group 1 */
-        tables[0][i] = &s->coeff_vlc[ac_y_table + 16];
-        tables[1][i] = &s->coeff_vlc[ac_c_table + 16];
+        tables[0][i] = &coeff_vlc[ac_y_table + 16];
+        tables[1][i] = &coeff_vlc[ac_c_table + 16];
     }
     for (int i = 6; i <= 14; i++) {
         /* AC VLC table group 2 */
-        tables[0][i] = &s->coeff_vlc[ac_y_table + 32];
-        tables[1][i] = &s->coeff_vlc[ac_c_table + 32];
+        tables[0][i] = &coeff_vlc[ac_y_table + 32];
+        tables[1][i] = &coeff_vlc[ac_c_table + 32];
     }
     for (int i = 15; i <= 27; i++) {
         /* AC VLC table group 3 */
-        tables[0][i] = &s->coeff_vlc[ac_y_table + 48];
-        tables[1][i] = &s->coeff_vlc[ac_c_table + 48];
+        tables[0][i] = &coeff_vlc[ac_y_table + 48];
+        tables[1][i] = &coeff_vlc[ac_c_table + 48];
     }
     for (int i = 28; i <= 63; i++) {
         /* AC VLC table group 4 */
-        tables[0][i] = &s->coeff_vlc[ac_y_table + 64];
-        tables[1][i] = &s->coeff_vlc[ac_c_table + 64];
+        tables[0][i] = &coeff_vlc[ac_y_table + 64];
+        tables[1][i] = &coeff_vlc[ac_c_table + 64];
     }
 
     vp4_set_tokens_base(s);
@@ -2355,6 +2365,14 @@ static av_cold int init_frames(Vp3DecodeContext *s)
     return 0;
 }
 
+static av_cold void free_vlc_tables(FFRefStructOpaque unused, void *obj)
+{
+    CoeffVLCs *vlcs = obj;
+
+    for (int i = 0; i < FF_ARRAY_ELEMS(vlcs->vlcs); i++)
+        ff_vlc_free(&vlcs->vlcs[i]);
+}
+
 static av_cold int vp3_decode_init(AVCodecContext *avctx)
 {
     static AVOnce init_static_once = AV_ONCE_INIT;
@@ -2443,8 +2461,6 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx)
     s->fragment_start[2] = y_fragment_count + c_fragment_count;
 
     if (!s->theora_tables) {
-        const uint8_t (*bias_tabs)[32][2];
-
         for (int i = 0; i < 64; i++) {
             s->coded_dc_scale_factor[0][i] = s->version < 2 ? vp31_dc_scale_factor[i] : vp4_y_dc_scale_factor[i];
             s->coded_dc_scale_factor[1][i] = s->version < 2 ? vp31_dc_scale_factor[i] : vp4_uv_dc_scale_factor[i];
@@ -2463,11 +2479,23 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx)
                 s->qr_base[inter][plane][1] = 2 * inter + (!!plane) * !inter;
             }
         }
+    }
+
+    if (!avctx->internal->is_copy) {
+        CoeffVLCs *vlcs = ff_refstruct_alloc_ext(sizeof(*s->coeff_vlc), 0,
+                                                 NULL, free_vlc_tables);
+        if (!vlcs)
+            return AVERROR(ENOMEM);
+
+        s->coeff_vlc = vlcs;
+
+    if (!s->theora_tables) {
+        const uint8_t (*bias_tabs)[32][2];
 
         /* init VLC tables */
         bias_tabs = CONFIG_VP4_DECODER && s->version >= 2 ? vp4_bias : vp3_bias;
-        for (int i = 0; i < FF_ARRAY_ELEMS(s->coeff_vlc); i++) {
-            ret = ff_vlc_init_from_lengths(&s->coeff_vlc[i], 11, 32,
+        for (int i = 0; i < FF_ARRAY_ELEMS(vlcs->vlcs); i++) {
+            ret = ff_vlc_init_from_lengths(&vlcs->vlcs[i], 11, 32,
                                            &bias_tabs[i][0][1], 2,
                                            &bias_tabs[i][0][0], 2, 1,
                                            0, 0, avctx);
@@ -2475,10 +2503,10 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx)
                 return ret;
         }
     } else {
-        for (int i = 0; i < FF_ARRAY_ELEMS(s->coeff_vlc); i++) {
+        for (int i = 0; i < FF_ARRAY_ELEMS(vlcs->vlcs); i++) {
             const HuffTable *tab = &s->huffman_table[i];
 
-            ret = ff_vlc_init_from_lengths(&s->coeff_vlc[i], 11, tab->nb_entries,
+            ret = ff_vlc_init_from_lengths(&vlcs->vlcs[i], 11, tab->nb_entries,
                                            &tab->entries[0].len, sizeof(*tab->entries),
                                            &tab->entries[0].sym, sizeof(*tab->entries), 1,
                                            0, 0, avctx);
@@ -2486,6 +2514,7 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx)
                 return ret;
         }
     }
+    }
 
     ff_thread_once(&init_static_once, init_tables_once);
 
@@ -2534,6 +2563,8 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *
     const Vp3DecodeContext *s1 = src->priv_data;
     int qps_changed = 0, err;
 
+    ff_refstruct_replace(&s->coeff_vlc, s1->coeff_vlc);
+
     if (!s1->current_frame.f->data[0] ||
         s->width != s1->width || s->height != s1->height) {
         if (s != s1)
-- 
2.34.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

  parent reply	other threads:[~2023-09-26 22:19 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-26 22:12 [FFmpeg-devel] [PATCH 01/61] avcodec/vlc: Add functions to init static VLCElem[] without VLC Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 02/61] avcodec/vp3: Make VLC tables static where possible Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 03/61] avcodec/vp3: Increase some VLC tables Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 04/61] avcodec/h264_cavlc: Avoid superfluous VLC structures Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 05/61] avcodec/h264_cavlc: Avoid indirection for coefficient table VLCs Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 06/61] avcodec/h264_cavlc: Remove code duplication Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 07/61] avcodec/asvdec: Avoid superfluous VLC structures Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 08/61] avcodec/faxcompr: " Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 09/61] avcodec/h261dec: " Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 10/61] avcodec/ituh263dec: " Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 11/61] avcodec/msmpeg4_vc1_data: " Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 12/61] avcodec/svq1dec: " Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 13/61] avcodec/svq1dec: Increase size of VLC Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 14/61] avcodec/rv40: Avoid superfluous VLC structures Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 15/61] avcodec/mpc7: " Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 16/61] avcodec/intrax8: " Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 17/61] avcodec/clearvideo: " Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 18/61] avcodec/atrac9dec: " Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 19/61] avcodec/imc: " Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 20/61] avcodec/refstruct: Add simple API for refcounted objects Andreas Rheinhardt
2023-09-26 22:16 ` Andreas Rheinhardt [this message]
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 22/61] avcodec/vp3: Avoid complete VLC struct, only use VLCElem* Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 23/61] avcodec/vp3: Reindent after the previous commits Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 24/61] avcodec/rv34: Avoid superfluous VLC structures Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 25/61] avcodec/rv34: Constify pointer to static object Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 26/61] avcodec/wnv1: Avoid unnecessary VLC structure Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 27/61] avcodec/mv30: " Andreas Rheinhardt
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 28/61] avcodec/vqcdec: " Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 29/61] avcodec/mobiclip: " Andreas Rheinhardt
2023-09-27 23:20   ` Michael Niedermayer
2023-09-27 23:44     ` Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 30/61] avcodec/mimic: " Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 31/61] avcodec/imm4: " Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 32/61] avcodec/lagarith: " Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 33/61] avcodec/speedhqdec: " Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 34/61] avcodec/vc1: Avoid superfluous VLC structures Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 35/61] avcodec/4xm: Avoid unnecessary " Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 36/61] avcodec/indeo2: Avoid unnecessary VLC structure Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 37/61] avcodec/mss4: Partially inline max_depth and nb_bits of VLC Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 38/61] avcodec/mpeg4videodec: Avoid superfluous VLC structures Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 39/61] avcodec/msmpeg4dec: " Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 40/61] avcodec/aacps: Remove unused AVCodecContext* parameter from ff_ps_apply Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 41/61] avcodec/aacps: Pass logctx as void* instead of AVCodecContext* Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 42/61] avcodec/aacdectab: Deduplicate common decoder tables Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 43/61] avcodec/aacdec_template: Deduplicate VLCs Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 44/61] avcodec/aacdec_template: Don't init unused table for fixed-point decoder Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 45/61] avcodec/aactab: Improve included headers Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 46/61] avcodec/aacdec_common: Avoid superfluous VLC structures Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 47/61] avcodec/aacsbr_template: Deduplicate VLCs Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 48/61] avcodec/aacdec_common: Avoid superfluous VLC structures for SBR VLCs Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 49/61] avcodec/aacdec_common: Switch to ff_vlc_init_tables_from_lengths() Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 50/61] avcodec/aacdec_common: Combine huffman tabs Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 51/61] avcodec/aacdec_common: Apply offset for SBR VLCs during init Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 52/61] avcodec/aacps: Move initializing common stuff to aacdec_common.c Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 53/61] avcodec/aacps_common: Avoid superfluous VLC structures Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 54/61] avcodec/aacps_common: Switch to ff_vlc_init_tables_from_lengths() Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 55/61] avcodec/aacps_common: Combine huffman tabels Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 56/61] avcodec/aacps_common: Apply offset for VLCs during init Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 57/61] avcodec/mpegaudiodec_common: Avoid superfluous VLC structures Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 58/61] avcodec/mpeg12: Avoid unnecessary " Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 59/61] avcodec/wmaprodec: Avoid superfluous " Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 60/61] avcodec/wmavoice: Avoid unnecessary VLC structure Andreas Rheinhardt
2023-09-26 22:17 ` [FFmpeg-devel] [PATCH 61/61] avcodec/vlc: Remove unused macros Andreas Rheinhardt
2023-10-30 23:08 ` [FFmpeg-devel] [PATCH 01/61] avcodec/vlc: Add functions to init static VLCElem[] without VLC Andreas Rheinhardt

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=GV1P250MB07378A03815C0FBED20761238FC3A@GV1P250MB0737.EURP250.PROD.OUTLOOK.COM \
    --to=andreas.rheinhardt@outlook.com \
    --cc=ffmpeg-devel@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