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 20/61] avcodec/refstruct: Add simple API for refcounted objects
Date: Wed, 27 Sep 2023 00:16:51 +0200
Message-ID: <GV1P250MB0737F50EC95C0DCB3788B3878FC3A@GV1P250MB0737.EURP250.PROD.OUTLOOK.COM> (raw)
In-Reply-To: <GV1P250MB073754E215A199E7219CC13A8FC3A@GV1P250MB0737.EURP250.PROD.OUTLOOK.COM>

For now, this API is supposed to replace all the internal uses
of reference counted objects in libavcodec; "internal" here
means that the object is created in libavcodec and is never
put directly in the hands of anyone outside of it.

It is intended to be made public eventually, but for now
I enjoy the ability to modify it freely.

Several shortcomings of the AVBuffer API motivated this API:
a) The unnecessary allocations (and ensuing error checks)
when using the API. Besides the need for runtime checks it
imposes upon the developer the burden of thinking through
what happens in case an error happens. Furthermore, these
error paths are typically not covered by FATE.
b) The AVBuffer API is designed with buffers and not with
objects in mind: The type for the actual buffers used
is uint8_t*; it pretends to be able to make buffers
writable, but this is wrong in case the buffer is not a POD.
Another instance of this thinking is the lack of a reset
callback in the AVBufferPool API.
c) The AVBuffer API incurs unnecessary indirections by
going through the AVBufferRef.data pointer. In case the user
tries to avoid this indirection and stores a pointer to
AVBuffer.data separately (which also allows to use the correct
type), the user has to keep these two pointers in sync
in case they can change (and in any case has two pointers
occupying space in the containing context). See the following
commit using this API for H.264 parameter sets for an example
of the removal of such syncing code as well as the casts
involved in the parts where only the AVBufferRef* pointer
was stored.
d) Given that the AVBuffer API allows custom allocators,
creating refcounted objects with dedicated free functions
often involves a lot of boilerplate like this:
obj = av_mallocz(sizeof(*obj));
ref = av_buffer_create((uint8_t*)obj, sizeof(*obj), free_func, opaque, 0);
if (!ref) {
    av_free(obj);
    return AVERROR(ENOMEM);
}
(There is also a corresponding av_free() at the end of free_func().)
This is now just
obj = ff_refstruct_alloc_ext(sizeof(*obj), 0, opaque, free_func);
if (!obj)
    return AVERROR(ENOMEM);
See the subsequent patch for the framepool (i.e. get_buffer.c)
for an example.

This API does things differently; it is designed to be lightweight*
as well as geared to the common case where the allocator of the
underlying object does not matter as long as it is big enough and
suitably aligned. This allows to allocate the user data together
with the API's bookkeeping data which avoids an allocation as well
as the need for separate pointers to the user data and the API's
bookkeeping data. This entails that the actual allocation of the
object is performed by refstruct, not the user. This is responsible
for avoiding the boilerplate code mentioned in d).

As a downside, custom allocators are not supported, but it will
become apparent in subsequent commits that there are enough
usecases to make it worthwhile.

Another advantage of this API is that one only needs to include
the relevant header if one uses the API and not when one includes
the header or some other component that uses it. This is because there
is no refstruct type analog of AVBufferRef. This brings with it
one further downside: It is not apparent from the pointer itself
whether the underlying object is managed by the refstruct API
or whether this pointer is a reference to it (or merely a pointer
to it).

Finally, this API supports const-qualified opaque pointees;
this will allow to avoid casting const away by the CBS code.

*: Basically the only exception to the you-only-pay-for-what-you-use
rule is that it always uses atomics for the refcount.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/Makefile    |   1 +
 libavcodec/refstruct.c | 139 +++++++++++++++++++++++++++++++++++++++
 libavcodec/refstruct.h | 145 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 285 insertions(+)
 create mode 100644 libavcodec/refstruct.c
 create mode 100644 libavcodec/refstruct.h

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index cae2e773a1..9e96892365 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -55,6 +55,7 @@ OBJS = ac3_parser.o                                                     \
        profiles.o                                                       \
        qsv_api.o                                                        \
        raw.o                                                            \
+       refstruct.o                                                      \
        utils.o                                                          \
        version.o                                                        \
        vlc.o                                                            \
diff --git a/libavcodec/refstruct.c b/libavcodec/refstruct.c
new file mode 100644
index 0000000000..917cf6b7ac
--- /dev/null
+++ b/libavcodec/refstruct.c
@@ -0,0 +1,139 @@
+/*
+ * 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 <stdatomic.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "internal.h"
+#include "refstruct.h"
+
+#include "libavutil/macros.h"
+#include "libavutil/mem.h"
+
+typedef struct RefCount {
+    /**
+     * An uintptr_t is big enough to hold the address of every reference,
+     * so no overflow can happen when incrementing the refcount as long as
+     * the user does not throw away references.
+     */
+    atomic_uintptr_t  refcount;
+    FFRefStructOpaque opaque;
+    void (*free_cb)(FFRefStructOpaque opaque, void *obj);
+} RefCount;
+
+#if __STDC_VERSION__ >= 201112L
+#define REFCOUNT_OFFSET FFALIGN(sizeof(RefCount), FFMAX3(STRIDE_ALIGN, 16, _Alignof(max_align_t)))
+#else
+#define REFCOUNT_OFFSET FFALIGN(sizeof(RefCount), FFMAX(STRIDE_ALIGN, 16))
+#endif
+
+static RefCount *get_refcount(void *obj)
+{
+    return (RefCount*)((char*)obj - REFCOUNT_OFFSET);
+}
+
+static void *get_userdata(void *buf)
+{
+    return (char*)buf + REFCOUNT_OFFSET;
+}
+
+static void refcount_init(RefCount *ref, FFRefStructOpaque opaque,
+                          void (*free_cb)(FFRefStructOpaque opaque, void *obj))
+{
+    atomic_init(&ref->refcount, 1);
+    ref->opaque  = opaque;
+    ref->free_cb = free_cb;
+}
+
+void *ff_refstruct_alloc_ext_c(size_t size, unsigned flags, FFRefStructOpaque opaque,
+                               void (*free_cb)(FFRefStructOpaque opaque, void *obj))
+{
+    void *buf, *obj;
+
+    if (size > SIZE_MAX - REFCOUNT_OFFSET)
+        return NULL;
+    buf = av_malloc(size + REFCOUNT_OFFSET);
+    if (!buf)
+        return NULL;
+    refcount_init(buf, opaque, free_cb);
+    obj = get_userdata(buf);
+    if (!(flags & FF_REFSTRUCT_FLAG_NO_ZEROING))
+        memset(obj, 0, size);
+
+    return obj;
+}
+
+void *ff_refstruct_allocz(size_t size)
+{
+    return ff_refstruct_alloc_ext(size, 0, NULL, NULL);
+}
+
+void ff_refstruct_unref(void *objp)
+{
+    void *obj;
+    RefCount *ref;
+
+    memcpy(&obj, objp, sizeof(obj));
+    if (!obj)
+        return;
+    memcpy(objp, &(void *){ NULL }, sizeof(obj));
+
+    ref = get_refcount(obj);
+    if (atomic_fetch_sub_explicit(&ref->refcount, 1, memory_order_acq_rel) == 1) {
+        if (ref->free_cb)
+            ref->free_cb(ref->opaque, obj);
+        av_free(ref);
+    }
+
+    return;
+}
+
+void *ff_refstruct_ref(void *obj)
+{
+    RefCount *ref = get_refcount(obj);
+
+    atomic_fetch_add_explicit(&ref->refcount, 1, memory_order_relaxed);
+
+    return obj;
+}
+
+const void *ff_refstruct_ref_c(const void *obj)
+{
+    /* Casting const away here is fine, as it is only supposed
+     * to apply to the user's data and not our bookkeeping data. */
+    RefCount *ref = get_refcount((void*)obj);
+
+    atomic_fetch_add_explicit(&ref->refcount, 1, memory_order_relaxed);
+
+    return obj;
+}
+
+void ff_refstruct_replace(void *dstp, const void *src)
+{
+    const void *dst;
+    memcpy(&dst, dstp, sizeof(dst));
+
+    if (src == dst)
+        return;
+    ff_refstruct_unref(dstp);
+    if (src) {
+        dst = ff_refstruct_ref_c(src);
+        memcpy(dstp, &dst, sizeof(dst));
+    }
+}
diff --git a/libavcodec/refstruct.h b/libavcodec/refstruct.h
new file mode 100644
index 0000000000..0086717c17
--- /dev/null
+++ b/libavcodec/refstruct.h
@@ -0,0 +1,145 @@
+/*
+ * 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
+ */
+
+#ifndef AVCODEC_REFSTRUCT_H
+#define AVCODEC_REFSTRUCT_H
+
+#include <stddef.h>
+
+/**
+ * RefStruct is an API for creating reference-counted objects
+ * with minimal overhead. The API is designed for objects,
+ * not buffers like the AVBuffer API. The main differences
+ * to the AVBuffer API are as follows:
+ *
+ * - It uses void* instead of uint8_t* as its base type due to
+ *   its focus on objects.
+ * - There are no equivalents of AVBuffer and AVBufferRef.
+ *   E.g. there is no way to get the usable size of the object:
+ *   The user is supposed to know what is at the other end of
+ *   the pointer. It also avoids one level of indirection.
+ * - Custom allocators are not supported. This allows to simplify
+ *   the implementation and reduce the amount of allocations.
+ * - It also has the advantage that the user's free callback need
+ *   only free the resources owned by the object, but not the
+ *   object itself.
+ * - Because referencing (and replacing) an object managed by the
+ *   RefStruct API does not involve allocations, they can not fail
+ *   and therefore need not be checked.
+ *
+ * @note Referencing and unreferencing the buffers is thread-safe and thus
+ * may be done from multiple threads simultaneously without any need for
+ * additional locking.
+ */
+
+/**
+ * This union is used for all opaque parameters in this API to spare the user
+ * to cast const away in case the opaque to use is const-qualified.
+ *
+ * The functions provided by this API with an FFRefStructOpaque come in pairs
+ * named foo_c and foo. The foo function accepts void* as opaque and is just
+ * a wrapper around the foo_c function; "_c" means "(potentially) const".
+ */
+typedef union {
+    void *nc;
+    const void *c;
+} FFRefStructOpaque;
+
+/**
+ * If this flag is set in ff_refstruct_alloc_ext_c(), the object will not
+ * be initially zeroed.
+ */
+#define FF_REFSTRUCT_FLAG_NO_ZEROING (1 << 0)
+
+/**
+ * Allocate a refcounted object of usable size `size` managed via
+ * the RefStruct API.
+ *
+ * By default (in the absence of flags to the contrary),
+ * the returned object is initially zeroed.
+ *
+ * @param size    Desired usable size of the returned object.
+ * @param flags   A bitwise combination of FF_REFSTRUCT_FLAG_* flags.
+ * @param opaque  A pointer that will be passed to the free_cb callback.
+ * @param free_cb A callback for freeing this object's content
+ *                when its reference count reaches zero;
+ *                it must not free the object itself.
+ * @return A pointer to an object of the desired size or NULL on failure.
+ */
+void *ff_refstruct_alloc_ext_c(size_t size, unsigned flags, FFRefStructOpaque opaque,
+                               void (*free_cb)(FFRefStructOpaque opaque, void *obj));
+
+/**
+ * A wrapper around ff_refstruct_alloc_ext_c() for the common case
+ * of a non-const qualified opaque.
+ *
+ * @see ff_refstruct_alloc_ext_c()
+ */
+static inline
+void *ff_refstruct_alloc_ext(size_t size, unsigned flags, void *opaque,
+                             void (*free_cb)(FFRefStructOpaque opaque, void *obj))
+{
+    return ff_refstruct_alloc_ext_c(size, flags, (FFRefStructOpaque){.nc = opaque},
+                                    free_cb);
+}
+
+/**
+ * Equivalent to ff_refstruct_alloc_ext(size, 0, NULL, NULL)
+ */
+void *ff_refstruct_allocz(size_t size);
+
+/**
+ * Decrement the reference count of the underlying object and automatically
+ * free the object if there are no more references to it.
+ *
+ * `*objp == NULL` is legal and a no-op.
+ *
+ * @param objp Pointer to a pointer that is either NULL or points to an object
+ *             managed via this API. `*objp` is set to NULL on return.
+ */
+void ff_refstruct_unref(void *objp);
+
+/**
+ * Create a new reference to an object managed via this API,
+ * i.e. increment the reference count of the underlying object
+ * and return obj.
+ * @return a pointer equal to obj.
+ */
+void *ff_refstruct_ref(void *obj);
+
+/**
+ * Analog of ff_refstruct_ref(), but for constant objects.
+ * @see ff_refstruct_ref()
+ */
+const void *ff_refstruct_ref_c(const void *obj);
+
+/**
+ * Ensure `*dstp` refers to the same object as src.
+ *
+ * If `*dstp` is already equal to src, do nothing. Otherwise unreference `*dstp`
+ * and replace it with a new reference to src in case `src != NULL` (this
+ * involves incrementing the reference count of src's underlying object) or
+ * with NULL otherwise.
+ *
+ * @param dstp Pointer to a pointer that is either NULL or points to an object
+ *             managed via this API.
+ * @param src  A pointer to an object managed via this API or NULL.
+ */
+void ff_refstruct_replace(void *dstp, const void *src);
+
+#endif /* AVCODEC_REFSTRUCT_H */
-- 
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 ` Andreas Rheinhardt [this message]
2023-09-26 22:16 ` [FFmpeg-devel] [PATCH 21/61] avcodec/vp3: Share coefficient VLCs between threads Andreas Rheinhardt
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=GV1P250MB0737F50EC95C0DCB3788B3878FC3A@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