Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 1/3] doc: Explain what "context" means
@ 2024-04-18 15:06 Andrew Sayers
  2024-04-18 15:06 ` [FFmpeg-devel] [PATCH 2/3] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
                   ` (3 more replies)
  0 siblings, 4 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-04-18 15:06 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

Based largely on the explanation by Stefano Sabatini:
https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325854.html
---
 doc/jargon.md | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 96 insertions(+)
 create mode 100644 doc/jargon.md

diff --git a/doc/jargon.md b/doc/jargon.md
new file mode 100644
index 0000000000..3b78ffb61f
--- /dev/null
+++ b/doc/jargon.md
@@ -0,0 +1,96 @@
+# Jargon
+
+Terms used throughout the code that developers may need to know.
+
+@anchor context
+
+## Context
+
+A design pattern that stores the context (e.g. configuration) for a series
+of operations in a "context" structure, and moves other information elsewhere.
+
+Consider a trivial program to print uppercase text:
+
+```c
+/*
+ * Contextual information about where to print a series of messages
+ */
+struct UpperCasePrinterContext {
+    FILE* out;
+};
+
+/*
+ * Extra information about messages to print.
+ * This could be used multiple times in a single context,
+ * or reused several times across multiple contexts.
+ */
+struct PrintInfo {
+    char* str;
+};
+
+void print(
+    struct UpperCasePrinterContext * ctx,
+    struct PrintInfo * info
+) {
+    for ( char* c = info->str; *c; ++c ) {
+        char C = toupper(*c);
+        fwrite( &C, 1, 1, ctx->out );
+    }
+}
+
+int main()
+{
+    struct PrintInfo hello, world;
+    struct UpperCasePrinterContext ctx;
+
+    hello.str = "hello, ";
+    world.str = "world!\n";
+
+    ctx.out = stdout;
+
+    print( &ctx, &hello );
+    print( &ctx, &world );
+
+    return 0;
+}
+```
+
+The `UpperCasePrinterContext` object contains the information that's about
+the context of the current job (i.e. printing things to standard output).
+Information with a lifetime different than that of the context is moved
+to the `PrintInfo` object.
+
+FFmpeg's main context structures all happen to face some common problems:
+
+- querying, setting and getting options
+- handling "private" internal context, including options for
+  a particular instance of the generic context
+- configuring log message verbosity and content
+
+FFmpeg gradually converged on the AVClass struct to store this information,
+then converged on the @ref avoptions "AVOptions" system to manipulate it,
+so modern code often uses the terms "context", "AVClass context structure"
+and "AVOptions-enabled struct" interchangeably.  But it is occasionally
+necessary to distinguish between them - for example, AVMediaCodecContext
+is a context that does not use AVClass.
+
+To understand how this all works, consider some requirements for the
+`libx264` encoder:
+
+- it has to support common encoder options like "bitrate"
+- it has to support encoder-specific options like "profile"
+- it has to provide useful feedback about unsupported options
+
+Common encoder options like "bitrate" are stored in the AVCodecContext class,
+while encoder-specific options like "profile" are stored in an X264Context
+instance in AVCodecContext::priv_data.  These options are then exposed to
+users through a tree of AVOption objects, which include user-visible help
+text and machine-readable information about the memory location to read/write
+each option.  Common @ref avoptions "AVOptions" functionality lets you get
+and set those values, and provides readable feedback about errors.  Although
+X264Context can be set by users, it is not part of the public interface,
+so new releases can modify it without affecting the API version.
+
+FFmpeg itself uses context structures to handle FFmpeg-specific problems,
+but the design pattern, as well as the AVClass and @ref avoptions "AVOptions"
+implementations, are general solutions you can use for any purpose.
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH 2/3] lavu: Clarify relationship between AVClass, AVOption and context
  2024-04-18 15:06 [FFmpeg-devel] [PATCH 1/3] doc: Explain what "context" means Andrew Sayers
@ 2024-04-18 15:06 ` Andrew Sayers
  2024-04-18 15:06 ` [FFmpeg-devel] [PATCH 3/3] all: Link to "context" from all contexts with documentation Andrew Sayers
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-04-18 15:06 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

---
 libavutil/log.h | 11 ++++++++---
 libavutil/opt.h |  7 ++++---
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/libavutil/log.h b/libavutil/log.h
index ab7ceabe22..b5c739dab1 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -59,9 +59,14 @@ typedef enum {
 struct AVOptionRanges;
 
 /**
- * Describe the class of an AVClass context structure. That is an
- * arbitrary struct of which the first field is a pointer to an
- * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).
+ * Metadata about an arbitrary data structure
+ *
+ * A @ref context "context struct" whose first member is a pointer
+ * to an AVClass object is called an "AVClass context structure"
+ * (e.g. AVCodecContext, AVFormatContext etc.).
+ *
+ * AVClass is often combined with @ref avoptions "AVOptions" to create
+ * "AVOptions-enabled structs" that can be easily configured by users.
  */
 typedef struct AVClass {
     /**
diff --git a/libavutil/opt.h b/libavutil/opt.h
index e6013662f6..b817d15554 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -39,9 +39,10 @@
  * @defgroup avoptions AVOptions
  * @ingroup lavu_data
  * @{
- * AVOptions provide a generic system to declare options on arbitrary structs
- * ("objects"). An option can have a help text, a type and a range of possible
- * values. Options may then be enumerated, read and written to.
+ * Builds on AVClass, adding a generic system to declare options.
+ *
+ * An option can have a help text, a type and a range of possible values.
+ * Options may then be enumerated, read and written to.
  *
  * There are two modes of access to members of AVOption and its child structs.
  * One is called 'native access', and refers to access from the code that
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH 3/3] all: Link to "context" from all contexts with documentation
  2024-04-18 15:06 [FFmpeg-devel] [PATCH 1/3] doc: Explain what "context" means Andrew Sayers
  2024-04-18 15:06 ` [FFmpeg-devel] [PATCH 2/3] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
@ 2024-04-18 15:06 ` Andrew Sayers
  2024-04-20  7:25 ` [FFmpeg-devel] [PATCH 1/3] doc: Explain what "context" means Stefano Sabatini
  2024-05-15 15:54 ` [FFmpeg-devel] [PATCH v4 0/4] Explain what "context" means Andrew Sayers
  3 siblings, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-04-18 15:06 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

Some headings needed to be rewritten to accomodate the text,
(hopefully) without changing the meaning.
---
 libavcodec/aacdec.h              |  2 +-
 libavcodec/aacenc.h              |  2 +-
 libavcodec/ac3enc.h              |  2 +-
 libavcodec/amfenc.h              |  2 +-
 libavcodec/atrac.h               |  2 +-
 libavcodec/avcodec.h             |  3 ++-
 libavcodec/bsf.h                 |  2 +-
 libavcodec/d3d11va.h             |  3 +--
 libavcodec/mediacodec.h          |  2 +-
 libavcodec/qsv.h                 |  6 ++++--
 libavcodec/sbr.h                 |  2 +-
 libavcodec/vdpau.h               |  3 ++-
 libavcodec/videotoolbox.h        |  5 +++--
 libavfilter/avfilter.h           |  2 +-
 libavformat/avformat.h           |  3 ++-
 libavformat/avio.h               |  3 ++-
 libavutil/hwcontext.h            | 21 ++++++++++++---------
 libavutil/hwcontext_cuda.h       |  2 +-
 libavutil/hwcontext_d3d11va.h    |  4 ++--
 libavutil/hwcontext_d3d12va.h    |  6 +++---
 libavutil/hwcontext_drm.h        |  2 +-
 libavutil/hwcontext_dxva2.h      |  4 ++--
 libavutil/hwcontext_mediacodec.h |  2 +-
 libavutil/hwcontext_opencl.h     |  4 ++--
 libavutil/hwcontext_qsv.h        |  4 ++--
 libavutil/hwcontext_vaapi.h      |  6 +++---
 libavutil/hwcontext_vdpau.h      |  2 +-
 libavutil/hwcontext_vulkan.h     |  4 ++--
 28 files changed, 57 insertions(+), 48 deletions(-)

diff --git a/libavcodec/aacdec.h b/libavcodec/aacdec.h
index 1b245f9258..3a5317cd54 100644
--- a/libavcodec/aacdec.h
+++ b/libavcodec/aacdec.h
@@ -181,7 +181,7 @@ typedef struct DynamicRangeControl {
 } DynamicRangeControl;
 
 /**
- * main AAC decoding context
+ * main AAC decoding @ref context "context"
  */
 typedef struct AACDecContext {
     const struct AVClass  *class;
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index 8899f90ac7..c91f99bc6c 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -193,7 +193,7 @@ typedef struct AACPCEInfo {
 } AACPCEInfo;
 
 /**
- * AAC encoder context
+ * AAC encoder @ref context "context"
  */
 typedef struct AACEncContext {
     AVClass *av_class;
diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
index 227744d27f..68d8736f7a 100644
--- a/libavcodec/ac3enc.h
+++ b/libavcodec/ac3enc.h
@@ -151,7 +151,7 @@ typedef struct AC3Block {
 } AC3Block;
 
 /**
- * AC-3 encoder private context.
+ * AC-3 encoder private @ref context "context"
  */
 typedef struct AC3EncodeContext {
     AVClass *av_class;                      ///< AVClass used for AVOption
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..71138e7f76 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
 } AmfTraceWriter;
 
 /**
-* AMF encoder context
+* AMF encoder @ref context "context"
 */
 
 typedef struct AmfContext {
diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
index 05208bbee6..acdd0a741a 100644
--- a/libavcodec/atrac.h
+++ b/libavcodec/atrac.h
@@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
 } AtracGainInfo;
 
 /**
- *  Gain compensation context structure.
+ *  Gain compensation @ref context "context"
  */
 typedef struct AtracGCContext {
     float   gain_tab1[16];  ///< gain compensation level table
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 968009a192..a1f1430dde 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -430,7 +430,8 @@ typedef struct RcOverride{
 #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
 
 /**
- * main external API structure.
+ * @ref context "Context" for an encode or decode session
+ *
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
index a09c69f242..23c3cc87e4 100644
--- a/libavcodec/bsf.h
+++ b/libavcodec/bsf.h
@@ -56,7 +56,7 @@
  */
 
 /**
- * The bitstream filter state.
+ * Bitstream filter @ref context "context"
  *
  * This struct must be allocated with av_bsf_alloc() and freed with
  * av_bsf_free().
diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
index 27f40e5519..087c99f161 100644
--- a/libavcodec/d3d11va.h
+++ b/libavcodec/d3d11va.h
@@ -46,8 +46,7 @@
  */
 
 /**
- * This structure is used to provides the necessary configurations and data
- * to the Direct3D11 FFmpeg HWAccel implementation.
+ * @ref context "Context" for the Direct3D11 FFmpeg HWAccel implementation
  *
  * The application must make it available as AVCodecContext.hwaccel_context.
  *
diff --git a/libavcodec/mediacodec.h b/libavcodec/mediacodec.h
index 4e9b56a618..d983e7ff1a 100644
--- a/libavcodec/mediacodec.h
+++ b/libavcodec/mediacodec.h
@@ -26,7 +26,7 @@
 #include "libavcodec/avcodec.h"
 
 /**
- * This structure holds a reference to a android/view/Surface object that will
+ * @ref context "Context" for the android/view/Surface object that will
  * be used as output by the decoder.
  *
  */
diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
index c156b08d07..e75351ae27 100644
--- a/libavcodec/qsv.h
+++ b/libavcodec/qsv.h
@@ -26,8 +26,10 @@
 #include "libavutil/buffer.h"
 
 /**
- * This struct is used for communicating QSV parameters between libavcodec and
- * the caller. It is managed by the caller and must be assigned to
+ * @ref context "Context" for communicating QSV parameters between libavcodec
+ * and the caller.
+ *
+ * It is managed by the caller and must be assigned to
  * AVCodecContext.hwaccel_context.
  * - decoding: hwaccel_context must be set on return from the get_format()
  *             callback
diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
index fe3a39603a..65f7a6da8f 100644
--- a/libavcodec/sbr.h
+++ b/libavcodec/sbr.h
@@ -116,7 +116,7 @@ typedef struct SBRData {
 typedef struct SpectralBandReplication SpectralBandReplication;
 
 /**
- * aacsbr functions pointers
+ * aacsbr functions pointer @ref context "context"
  */
 typedef struct AACSBRContext {
     int (*sbr_lf_gen)(SpectralBandReplication *sbr,
diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
index 8021c25761..a9ff8b5f47 100644
--- a/libavcodec/vdpau.h
+++ b/libavcodec/vdpau.h
@@ -64,8 +64,9 @@ typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, struct AVFrame *,
                                const VdpBitstreamBuffer *);
 
 /**
- * This structure is used to share data between the libavcodec library and
+ * @ref context "Context" to share data between the libavcodec library and
  * the client video application.
+ *
  * This structure will be allocated and stored in AVCodecContext.hwaccel_context
  * by av_vdpau_bind_context(). Members can be set by the user once
  * during initialization or through each AVCodecContext.get_buffer()
diff --git a/libavcodec/videotoolbox.h b/libavcodec/videotoolbox.h
index d68d76e400..ece008157c 100644
--- a/libavcodec/videotoolbox.h
+++ b/libavcodec/videotoolbox.h
@@ -49,8 +49,9 @@
 #include "libavutil/attributes.h"
 
 /**
- * This struct holds all the information that needs to be passed
- * between the caller and libavcodec for initializing Videotoolbox decoding.
+ * @ref context "Context" for information passed between the caller and libavcodec
+ * for initializing Videotoolbox decoding.
+ *
  * Its size is not a part of the public ABI, it must be allocated with
  * av_videotoolbox_alloc_context() and freed with av_free().
  */
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index a34e61f23c..41bdc30d89 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -403,7 +403,7 @@ unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output);
  */
 #define AVFILTER_THREAD_SLICE (1 << 0)
 
-/** An instance of a filter */
+/** @ref context "Context" for a filter */
 struct AVFilterContext {
     const AVClass *av_class;        ///< needed for av_log() and filters common options
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 8afdcd9fd0..6bb08a0b0c 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1241,7 +1241,8 @@ enum AVDurationEstimationMethod {
 };
 
 /**
- * Format I/O context.
+ * Format I/O @ref context "context"
+ *
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
diff --git a/libavformat/avio.h b/libavformat/avio.h
index ebf611187d..e18d542377 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -146,7 +146,8 @@ enum AVIODataMarkerType {
 };
 
 /**
- * Bytestream IO Context.
+ * Bytestream I/O @ref context "context"
+ *
  * New public fields can be added with minor version bumps.
  * Removal, reordering and changes to existing public fields require
  * a major version bump.
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index bac30debae..f94f44906c 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -41,12 +41,13 @@ enum AVHWDeviceType {
 };
 
 /**
- * This struct aggregates all the (hardware/vendor-specific) "high-level" state,
- * i.e. state that is not tied to a concrete processing configuration.
- * E.g., in an API that supports hardware-accelerated encoding and decoding,
- * this struct will (if possible) wrap the state that is common to both encoding
- * and decoding and from which specific instances of encoders or decoders can be
- * derived.
+ * @ref context "Context" for (hardware/vendor-specific) "high-level" state.
+ *
+ * "High-level state" is anything that is not tied to a concrete processing
+ * configuration. E.g., in an API that supports hardware-accelerated encoding
+ * and decoding, this struct will (if possible) wrap the state that is common
+ * to both encoding and decoding and from which specific instances of encoders
+ * or decoders can be derived.
  *
  * This struct is reference-counted with the AVBuffer mechanism. The
  * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field
@@ -103,9 +104,11 @@ typedef struct AVHWDeviceContext {
 } AVHWDeviceContext;
 
 /**
- * This struct describes a set or pool of "hardware" frames (i.e. those with
- * data not located in normal system memory). All the frames in the pool are
- * assumed to be allocated in the same way and interchangeable.
+ * @ref context "context" for a pool of "hardware" frames (those with
+ * data not located in normal system memory)
+ *
+ * All the frames in the pool are assumed to be allocated in the same way and
+ * interchangeable.
  *
  * This struct is reference-counted with the AVBuffer mechanism and tied to a
  * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor
diff --git a/libavutil/hwcontext_cuda.h b/libavutil/hwcontext_cuda.h
index cbad434fea..befa978cf9 100644
--- a/libavutil/hwcontext_cuda.h
+++ b/libavutil/hwcontext_cuda.h
@@ -37,7 +37,7 @@
 typedef struct AVCUDADeviceContextInternal AVCUDADeviceContextInternal;
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVCUDADeviceContext {
     CUcontext cuda_ctx;
diff --git a/libavutil/hwcontext_d3d11va.h b/libavutil/hwcontext_d3d11va.h
index 77d2d72f1b..eac7d6062a 100644
--- a/libavutil/hwcontext_d3d11va.h
+++ b/libavutil/hwcontext_d3d11va.h
@@ -40,7 +40,7 @@
 #include <stdint.h>
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVD3D11VADeviceContext {
     /**
@@ -126,7 +126,7 @@ typedef struct AVD3D11FrameDescriptor {
 } AVD3D11FrameDescriptor;
 
 /**
- * This struct is allocated as AVHWFramesContext.hwctx
+ * This @ref context "context" is allocated as AVHWFramesContext.hwctx
  */
 typedef struct AVD3D11VAFramesContext {
     /**
diff --git a/libavutil/hwcontext_d3d12va.h b/libavutil/hwcontext_d3d12va.h
index ff06e6f2ef..d170f74b4d 100644
--- a/libavutil/hwcontext_d3d12va.h
+++ b/libavutil/hwcontext_d3d12va.h
@@ -37,7 +37,7 @@
 #include <d3d12video.h>
 
 /**
- * @brief This struct is allocated as AVHWDeviceContext.hwctx
+ * @brief This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  *
  */
 typedef struct AVD3D12VADeviceContext {
@@ -78,7 +78,7 @@ typedef struct AVD3D12VADeviceContext {
 } AVD3D12VADeviceContext;
 
 /**
- * @brief This struct is used to sync d3d12 execution
+ * @brief This @ref context "context" is used to sync d3d12 execution
  *
  */
 typedef struct AVD3D12VASyncContext {
@@ -120,7 +120,7 @@ typedef struct AVD3D12VAFrame {
 } AVD3D12VAFrame;
 
 /**
- * @brief This struct is allocated as AVHWFramesContext.hwctx
+ * @brief This @ref context "context" is allocated as AVHWFramesContext.hwctx
  *
  */
 typedef struct AVD3D12VAFramesContext {
diff --git a/libavutil/hwcontext_drm.h b/libavutil/hwcontext_drm.h
index 42709f215e..b7b1bad171 100644
--- a/libavutil/hwcontext_drm.h
+++ b/libavutil/hwcontext_drm.h
@@ -152,7 +152,7 @@ typedef struct AVDRMFrameDescriptor {
 /**
  * DRM device.
  *
- * Allocated as AVHWDeviceContext.hwctx.
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx.
  */
 typedef struct AVDRMDeviceContext {
     /**
diff --git a/libavutil/hwcontext_dxva2.h b/libavutil/hwcontext_dxva2.h
index e1b79bc0de..b77b7293ab 100644
--- a/libavutil/hwcontext_dxva2.h
+++ b/libavutil/hwcontext_dxva2.h
@@ -34,14 +34,14 @@
 #include <dxva2api.h>
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVDXVA2DeviceContext {
     IDirect3DDeviceManager9 *devmgr;
 } AVDXVA2DeviceContext;
 
 /**
- * This struct is allocated as AVHWFramesContext.hwctx
+ * This @ref context "context" is allocated as AVHWFramesContext.hwctx
  */
 typedef struct AVDXVA2FramesContext {
     /**
diff --git a/libavutil/hwcontext_mediacodec.h b/libavutil/hwcontext_mediacodec.h
index fc0263cabc..39381b56c5 100644
--- a/libavutil/hwcontext_mediacodec.h
+++ b/libavutil/hwcontext_mediacodec.h
@@ -22,7 +22,7 @@
 /**
  * MediaCodec details.
  *
- * Allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVMediaCodecDeviceContext {
     /**
diff --git a/libavutil/hwcontext_opencl.h b/libavutil/hwcontext_opencl.h
index ef54486c95..fc5b1bb24f 100644
--- a/libavutil/hwcontext_opencl.h
+++ b/libavutil/hwcontext_opencl.h
@@ -58,7 +58,7 @@ typedef struct AVOpenCLFrameDescriptor {
 /**
  * OpenCL device details.
  *
- * Allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVOpenCLDeviceContext {
     /**
@@ -84,7 +84,7 @@ typedef struct AVOpenCLDeviceContext {
 /**
  * OpenCL-specific data associated with a frame pool.
  *
- * Allocated as AVHWFramesContext.hwctx.
+ * This @ref context "context" is allocated as AVHWFramesContext.hwctx.
  */
 typedef struct AVOpenCLFramesContext {
     /**
diff --git a/libavutil/hwcontext_qsv.h b/libavutil/hwcontext_qsv.h
index e2dba8ad83..c7cc88627b 100644
--- a/libavutil/hwcontext_qsv.h
+++ b/libavutil/hwcontext_qsv.h
@@ -30,7 +30,7 @@
  */
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVQSVDeviceContext {
     mfxSession session;
@@ -48,7 +48,7 @@ typedef struct AVQSVDeviceContext {
 } AVQSVDeviceContext;
 
 /**
- * This struct is allocated as AVHWFramesContext.hwctx
+ * This @ref context "context" is allocated as AVHWFramesContext.hwctx
  */
 typedef struct AVQSVFramesContext {
     mfxFrameSurface1 *surfaces;
diff --git a/libavutil/hwcontext_vaapi.h b/libavutil/hwcontext_vaapi.h
index 0b2e071cb3..e1940a5fe0 100644
--- a/libavutil/hwcontext_vaapi.h
+++ b/libavutil/hwcontext_vaapi.h
@@ -63,7 +63,7 @@ enum {
 /**
  * VAAPI connection details.
  *
- * Allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVVAAPIDeviceContext {
     /**
@@ -83,7 +83,7 @@ typedef struct AVVAAPIDeviceContext {
 /**
  * VAAPI-specific data associated with a frame pool.
  *
- * Allocated as AVHWFramesContext.hwctx.
+ * This @ref context "context" is allocated as AVHWFramesContext.hwctx.
  */
 typedef struct AVVAAPIFramesContext {
     /**
@@ -105,7 +105,7 @@ typedef struct AVVAAPIFramesContext {
 /**
  * VAAPI hardware pipeline configuration details.
  *
- * Allocated with av_hwdevice_hwconfig_alloc().
+ * This struct is allocated with av_hwdevice_hwconfig_alloc().
  */
 typedef struct AVVAAPIHWConfig {
     /**
diff --git a/libavutil/hwcontext_vdpau.h b/libavutil/hwcontext_vdpau.h
index 1b7ea1e443..b26f7f171e 100644
--- a/libavutil/hwcontext_vdpau.h
+++ b/libavutil/hwcontext_vdpau.h
@@ -30,7 +30,7 @@
  */
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVVDPAUDeviceContext {
     VdpDevice          device;
diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h
index cbbd2390c1..d6897a96fa 100644
--- a/libavutil/hwcontext_vulkan.h
+++ b/libavutil/hwcontext_vulkan.h
@@ -39,7 +39,7 @@ typedef struct AVVkFrame AVVkFrame;
  */
 
 /**
- * Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
+ * Main Vulkan @ref context "context", allocated as AVHWDeviceContext.hwctx.
  * All of these can be set before init to change what the context uses
  */
 typedef struct AVVulkanDeviceContext {
@@ -172,7 +172,7 @@ typedef enum AVVkFrameFlags {
 } AVVkFrameFlags;
 
 /**
- * Allocated as AVHWFramesContext.hwctx, used to set pool-specific options
+ * This @ref context "context" is allocated as AVHWFramesContext.hwctx, used to set pool-specific options
  */
 typedef struct AVVulkanFramesContext {
     /**
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH 1/3] doc: Explain what "context" means
  2024-04-18 15:06 [FFmpeg-devel] [PATCH 1/3] doc: Explain what "context" means Andrew Sayers
  2024-04-18 15:06 ` [FFmpeg-devel] [PATCH 2/3] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
  2024-04-18 15:06 ` [FFmpeg-devel] [PATCH 3/3] all: Link to "context" from all contexts with documentation Andrew Sayers
@ 2024-04-20  7:25 ` Stefano Sabatini
  2024-04-20 12:18   ` Andrew Sayers
  2024-04-20 12:19   ` [FFmpeg-devel] [PATCH v2 " Andrew Sayers
  2024-05-15 15:54 ` [FFmpeg-devel] [PATCH v4 0/4] Explain what "context" means Andrew Sayers
  3 siblings, 2 replies; 39+ messages in thread
From: Stefano Sabatini @ 2024-04-20  7:25 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Andrew Sayers

On date Thursday 2024-04-18 16:06:12 +0100, Andrew Sayers wrote:
> Based largely on the explanation by Stefano Sabatini:
> https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325854.html
> ---
>  doc/jargon.md | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 96 insertions(+)
>  create mode 100644 doc/jargon.md
> 
> diff --git a/doc/jargon.md b/doc/jargon.md
> new file mode 100644
> index 0000000000..3b78ffb61f

> --- /dev/null
> +++ b/doc/jargon.md

We currently have a single .md file in doc (for historical reason we
still stick to texinfo). Also how is this integrated into doxygen?


> @@ -0,0 +1,96 @@
> +# Jargon
> +
> +Terms used throughout the code that developers may need to know.
> +
> +@anchor context
> +
> +## Context
> +
> +A design pattern that stores the context (e.g. configuration) for a series
> +of operations in a "context" structure, and moves other information elsewhere.
> +
> +Consider a trivial program to print uppercase text:
> +
> +```c

> +/*
> + * Contextual information about where to print a series of messages
> + */

Style:
/**
 * Contextual information about where to print a series of messages
 */

> +struct UpperCasePrinterContext {
> +    FILE* out;

here and below, use:
VAR *out;

for overall consistency with the project style.

> +};
> +
> +/*
> + * Extra information about messages to print.
> + * This could be used multiple times in a single context,
> + * or reused several times across multiple contexts.
> + */
> +struct PrintInfo {
> +    char* str;
> +};
> +
> +void print(
> +    struct UpperCasePrinterContext * ctx,
> +    struct PrintInfo * info
> +) {
> +    for ( char* c = info->str; *c; ++c ) {
> +        char C = toupper(*c);
> +        fwrite( &C, 1, 1, ctx->out );
> +    }
> +}
> +

> +int main()
> +{
> +    struct PrintInfo hello, world;
> +    struct UpperCasePrinterContext ctx;
> +
> +    hello.str = "hello, ";
> +    world.str = "world!\n";
> +
> +    ctx.out = stdout;
> +
> +    print( &ctx, &hello );
> +    print( &ctx, &world );
> +
> +    return 0;
> +}

I'm not sure this is a fitting example. Usually the context is a
public structure and the internal context (which corresponds to the
PrintInfo struct) is private to the implementation. In this case the
API user is not interested at all at its implmentation.

You can think the context provides the "object"/instance where some
operations are done - this is alike in object oriented programming,
where the context corresponds to the self, so that you create/allocate
the object, initialize it, and invoke operations on the object.

So using this analogy, the example would be:

struct UpperCasePrinterContext {...};

// this corresponds to a "method" defined on the context/object
void uppercase_printer_print(UpperCasePrinterContext *ctx, const char *str);

Or maybe you want to define the property in the context itself, so you
do:
uppercase_ctx.str = "foobar";

then you have:
void uppercase_printer_print(UpperCasePrinterContext *ctx);

On a typical FFmpeg context you typically do (see
doc/examples/encode.c example):
    // create the context
    c = avcodec_alloc_context3(codec);

    // set parameters, either in the context or by using the av_opt API
    c->bit_rate = 400000;
    c->width = 352;
    c->height = 288;
    c->time_base = (AVRational){1, 25};
    c->framerate = (AVRational){25, 1};
    // ...

    // invoke the methods defined in the context
    ret = avcodec_send_frame(enc_ctx, frame);
    if (ret < 0) {
        fprintf(stderr, "Error sending a frame for encoding\n");
        exit(1);
    }

    while (ret >= 0) {
        ret = avcodec_receive_packet(enc_ctx, pkt);
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
            return;
        else if (ret < 0) {
            fprintf(stderr, "Error during encoding\n");
            exit(1);
        }
        ...
        av_packet_unref(pkt);
    }

[...]

Note also that "context" in the FFmpeg jargon is not very specific
because it might be different depending on the implementation, for
example it might not have an av_opt_* interface (for example
libavutil/hash.h).

> +```
> +

> +The `UpperCasePrinterContext` object contains the information that's about
> +the context of the current job (i.e. printing things to standard output).

I find this confusing, it is essentially saying that the context (the
"object") is the context of the current job.

> +Information with a lifetime different than that of the context is moved
> +to the `PrintInfo` object.
> +

> +FFmpeg's main context structures all happen to face some common problems:
> +
> +- querying, setting and getting options
> +- handling "private" internal context, including options for
> +  a particular instance of the generic context
> +- configuring log message verbosity and content
> +

> +FFmpeg gradually converged on the AVClass struct to store this information,
> +then converged on the @ref avoptions "AVOptions" system to manipulate it,
> +so modern code often uses the terms "context", "AVClass context structure"
> +and "AVOptions-enabled struct" interchangeably.  But it is occasionally
> +necessary to distinguish between them - for example, AVMediaCodecContext
> +is a context that does not use AVClass.
> +
> +To understand how this all works, consider some requirements for the
> +`libx264` encoder:
> +
> +- it has to support common encoder options like "bitrate"
> +- it has to support encoder-specific options like "profile"
> +- it has to provide useful feedback about unsupported options
> +
> +Common encoder options like "bitrate" are stored in the AVCodecContext class,
> +while encoder-specific options like "profile" are stored in an X264Context
> +instance in AVCodecContext::priv_data.  These options are then exposed to
> +users through a tree of AVOption objects, which include user-visible help
> +text and machine-readable information about the memory location to read/write
> +each option.  Common @ref avoptions "AVOptions" functionality lets you get

> +and set those values, and provides readable feedback about errors.

> Although X264Context can be set by users,

Can it? The X264Context is defined within the implementation, so it is
not exposed to the user, the only way to set it is through the private
options to be set through the AVCodecContext options through the
av_opt API - in other words you cannot set the context directly as you
do with the "generic" options defined in the AVCodecContext.

> it is not part of the public interface, so new releases can modify
> it without affecting the API version.

[...]
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH 1/3] doc: Explain what "context" means
  2024-04-20  7:25 ` [FFmpeg-devel] [PATCH 1/3] doc: Explain what "context" means Stefano Sabatini
@ 2024-04-20 12:18   ` Andrew Sayers
  2024-04-20 16:13     ` Stefano Sabatini
  2024-04-20 12:19   ` [FFmpeg-devel] [PATCH v2 " Andrew Sayers
  1 sibling, 1 reply; 39+ messages in thread
From: Andrew Sayers @ 2024-04-20 12:18 UTC (permalink / raw)
  To: ffmpeg-devel

On 20/04/2024 08:25, Stefano Sabatini wrote:
> On date Thursday 2024-04-18 16:06:12 +0100, Andrew Sayers wrote:
>> Based largely on the explanation by Stefano Sabatini:
>> https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325854.html
>> ---
>>   doc/jargon.md | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 96 insertions(+)
>>   create mode 100644 doc/jargon.md
>>
>> diff --git a/doc/jargon.md b/doc/jargon.md
>> new file mode 100644
>> index 0000000000..3b78ffb61f
>> --- /dev/null
>> +++ b/doc/jargon.md
> We currently have a single .md file in doc (for historical reason we
> still stick to texinfo). Also how is this integrated into doxygen?

Doxygen automatically renders all /*.md and /doc/*.md files to pages at [1]
which is the only place I'd know to look for this sort of thing. it seems
like texinfo is more for man pages etc., which would be hard to link from
doxygen?  By the way, a file called "jargon" seemed like a better idea than
e.g. a "design_patterns" file or a section in AVClass.  I've rewritten the
document completely based on your feedback - same markdown file for now,
but happy to move/reformat.

The points below should be addressed by the new patch, so I'll let that
speak for itself.  But there's a general issue that's worth mentioning...

Technically, it sounds like a more accurate description would be "Context
is an FFmpeg convention that has become fairly rigorous over the years".
But IMHO readers would uncharitably read that as "Context is some weird
FFmpeg thing they're stuck with because they picked a pre-OOP language".
Arguing "Context is a design pattern that groups objects by lifespan"
emphasises the lessons a newbie can take from FFmpeg and use elsewhere,
so they get more value from the time they spent reading the document.
I've tried to write the document to start with the more useful argument,
then gradually ease in to the more accurate one.

Note: I previously sent this from the wrong e-mail address - apologies for
spam if the other one makes it past moderation.

[1] https://ffmpeg.org/doxygen/trunk/pages.html

>
>> @@ -0,0 +1,96 @@
>> +# Jargon
>> +
>> +Terms used throughout the code that developers may need to know.
>> +
>> +@anchor context
>> +
>> +## Context
>> +
>> +A design pattern that stores the context (e.g. configuration) for a series
>> +of operations in a "context" structure, and moves other information elsewhere.
>> +
>> +Consider a trivial program to print uppercase text:
>> +
>> +```c
>> +/*
>> + * Contextual information about where to print a series of messages
>> + */
> Style:
> /**
>   * Contextual information about where to print a series of messages
>   */
>
>> +struct UpperCasePrinterContext {
>> +    FILE* out;
> here and below, use:
> VAR *out;
>
> for overall consistency with the project style.
>
>> +};
>> +
>> +/*
>> + * Extra information about messages to print.
>> + * This could be used multiple times in a single context,
>> + * or reused several times across multiple contexts.
>> + */
>> +struct PrintInfo {
>> +    char* str;
>> +};
>> +
>> +void print(
>> +    struct UpperCasePrinterContext * ctx,
>> +    struct PrintInfo * info
>> +) {
>> +    for ( char* c = info->str; *c; ++c ) {
>> +        char C = toupper(*c);
>> +        fwrite( &C, 1, 1, ctx->out );
>> +    }
>> +}
>> +
>> +int main()
>> +{
>> +    struct PrintInfo hello, world;
>> +    struct UpperCasePrinterContext ctx;
>> +
>> +    hello.str = "hello, ";
>> +    world.str = "world!\n";
>> +
>> +    ctx.out = stdout;
>> +
>> +    print( &ctx, &hello );
>> +    print( &ctx, &world );
>> +
>> +    return 0;
>> +}
> I'm not sure this is a fitting example. Usually the context is a
> public structure and the internal context (which corresponds to the
> PrintInfo struct) is private to the implementation. In this case the
> API user is not interested at all at its implmentation.
>
> You can think the context provides the "object"/instance where some
> operations are done - this is alike in object oriented programming,
> where the context corresponds to the self, so that you create/allocate
> the object, initialize it, and invoke operations on the object.
>
> So using this analogy, the example would be:
>
> struct UpperCasePrinterContext {...};
>
> // this corresponds to a "method" defined on the context/object
> void uppercase_printer_print(UpperCasePrinterContext *ctx, const char *str);
>
> Or maybe you want to define the property in the context itself, so you
> do:
> uppercase_ctx.str = "foobar";
>
> then you have:
> void uppercase_printer_print(UpperCasePrinterContext *ctx);
>
> On a typical FFmpeg context you typically do (see
> doc/examples/encode.c example):
>      // create the context
>      c = avcodec_alloc_context3(codec);
>
>      // set parameters, either in the context or by using the av_opt API
>      c->bit_rate = 400000;
>      c->width = 352;
>      c->height = 288;
>      c->time_base = (AVRational){1, 25};
>      c->framerate = (AVRational){25, 1};
>      // ...
>
>      // invoke the methods defined in the context
>      ret = avcodec_send_frame(enc_ctx, frame);
>      if (ret < 0) {
>          fprintf(stderr, "Error sending a frame for encoding\n");
>          exit(1);
>      }
>
>      while (ret >= 0) {
>          ret = avcodec_receive_packet(enc_ctx, pkt);
>          if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
>              return;
>          else if (ret < 0) {
>              fprintf(stderr, "Error during encoding\n");
>              exit(1);
>          }
>          ...
>          av_packet_unref(pkt);
>      }
>
> [...]
>
> Note also that "context" in the FFmpeg jargon is not very specific
> because it might be different depending on the implementation, for
> example it might not have an av_opt_* interface (for example
> libavutil/hash.h).
>
>> +```
>> +
>> +The `UpperCasePrinterContext` object contains the information that's about
>> +the context of the current job (i.e. printing things to standard output).
> I find this confusing, it is essentially saying that the context (the
> "object") is the context of the current job.
>
>> +Information with a lifetime different than that of the context is moved
>> +to the `PrintInfo` object.
>> +
>> +FFmpeg's main context structures all happen to face some common problems:
>> +
>> +- querying, setting and getting options
>> +- handling "private" internal context, including options for
>> +  a particular instance of the generic context
>> +- configuring log message verbosity and content
>> +
>> +FFmpeg gradually converged on the AVClass struct to store this information,
>> +then converged on the @ref avoptions "AVOptions" system to manipulate it,
>> +so modern code often uses the terms "context", "AVClass context structure"
>> +and "AVOptions-enabled struct" interchangeably.  But it is occasionally
>> +necessary to distinguish between them - for example, AVMediaCodecContext
>> +is a context that does not use AVClass.
>> +
>> +To understand how this all works, consider some requirements for the
>> +`libx264` encoder:
>> +
>> +- it has to support common encoder options like "bitrate"
>> +- it has to support encoder-specific options like "profile"
>> +- it has to provide useful feedback about unsupported options
>> +
>> +Common encoder options like "bitrate" are stored in the AVCodecContext class,
>> +while encoder-specific options like "profile" are stored in an X264Context
>> +instance in AVCodecContext::priv_data.  These options are then exposed to
>> +users through a tree of AVOption objects, which include user-visible help
>> +text and machine-readable information about the memory location to read/write
>> +each option.  Common @ref avoptions "AVOptions" functionality lets you get
>> +and set those values, and provides readable feedback about errors.
>> Although X264Context can be set by users,
> Can it? The X264Context is defined within the implementation, so it is
> not exposed to the user, the only way to set it is through the private
> options to be set through the AVCodecContext options through the
> av_opt API - in other words you cannot set the context directly as you
> do with the "generic" options defined in the AVCodecContext.
>
>> it is not part of the public interface, so new releases can modify
>> it without affecting the API version.
> [...]
> _______________________________________________
> 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".
>
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v2 1/3] doc: Explain what "context" means
  2024-04-20  7:25 ` [FFmpeg-devel] [PATCH 1/3] doc: Explain what "context" means Stefano Sabatini
  2024-04-20 12:18   ` Andrew Sayers
@ 2024-04-20 12:19   ` Andrew Sayers
  2024-04-20 12:19     ` [FFmpeg-devel] [PATCH v2 2/3] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
                       ` (2 more replies)
  1 sibling, 3 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-04-20 12:19 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

Based largely on the explanation by Stefano Sabatini:
https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325854.html
---
 doc/jargon.md | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 169 insertions(+)
 create mode 100644 doc/jargon.md

diff --git a/doc/jargon.md b/doc/jargon.md
new file mode 100644
index 0000000000..f967b5c8bc
--- /dev/null
+++ b/doc/jargon.md
@@ -0,0 +1,169 @@
+# Jargon
+
+Terms used throughout the code that developers may need to know.
+
+@anchor context
+
+## Context
+
+A design pattern that stores the context (e.g. configuration) for a series
+of operations in a "context" structure, and moves other information with
+a longer or shorter lifetime elsewhere.
+
+Consider a code snippet to modify text then print it:
+
+```c
+/**
+ * Contextual information about printing a series of messages
+ */
+struct ModifyThenPrintContext {
+
+    /**
+     * Members of the context usually are usually part of its public API...
+     */
+    FILE *out;
+
+    /**
+     * ... but check the documentation just in case
+     */
+    [[deprecated]]
+    int no_longer_part_of_the_public_api;
+
+    /**
+     * The "internal context" is private to the context itself.
+     *
+     * Unlike the members above, the private context is not guaranteed
+     * and can change arbitrarily between versions.
+     */
+    void* priv_data;
+};
+
+/**
+ * Long-lifetime information, reused by many contexts
+ */
+enum ModifyThenPrintDialect {
+    MODIFY_THEN_PRINT_PLAIN_TEXT,
+    MODIFY_THEN_PRINT_REGEX,
+    MODIFY_THEN_PRINT_REGEX_PCRE
+};
+
+/**
+ * Short-lifetime information, used repeatedly in a single context
+ */
+struct ModifyThenPrintMessage {
+    char *str;
+    char *replace_this;
+    char *with_this;
+};
+
+/**
+ * Allocate and initialize a ModifyThenPrintContext
+ *
+ * This creates a new pointer, then fills in some sensible defaults.
+ *
+ * We can reasonably assume this function will initialise `priv_data`
+ * with a dialect-specific object, but shouldn't make any assumptions
+ * about what that object is.
+ *
+ */
+int ModifyThenPrintContext_alloc_context(struct ModifyThenPrintContext **ctx,
+                                         FILE *out,
+                                         enum ModifyThenPrintDialect dialect);
+
+/**
+ * Uninitialize and deallocate a ModifyThenPrintContext
+ *
+ * This does any work required by the private context in `priv_data`
+ * (e.g. deallocating it), then deallocates the main context itself.
+ *
+ */
+int ModifyThenPrintContext_free(struct ModifyThenPrintContext *ctx);
+
+/**
+ * Print a single message
+ */
+int ModifyThenPrintContext_print(struct ModifyThenPrintContext *ctx,
+                                 struct ModifyThenPrintMessage *msg);
+
+int print_hello_world()
+{
+
+    int ret = 0;
+
+    struct ModifyThenPrintContext *ctx;
+
+    struct ModifyThenPrintMessage hello_world;
+
+    if ( ModifyThenPrintContext_alloc_context( &ctx, stdout, MODIFY_THEN_PRINT_REGEX ) < 0 ) {
+        ret = -1;
+        goto EXIT_WITHOUT_CLEANUP;
+    }
+
+    hello_world.replace_this = "Hi|Hullo";
+    hello_world.with_this    = "Hello";
+
+    hello_world.str = "Hi, world!\n";
+    if ( ModifyThenPrintContext_print( ctx, &hello_world ) < 0 ) {
+        ret = -1;
+        goto FINISH;
+    }
+
+    hello_world.str = "Hullo, world!\n";
+    if ( ModifyThenPrintContext_print( ctx, &hello_world ) < 0 ) {
+        ret = -1;
+        goto FINISH;
+    }
+
+    FINISH:
+    if ( ModifyThenPrintContext_free( ctx ) ) {
+        ret = -1;
+        goto EXIT_WITHOUT_CLEANUP;
+    }
+
+    EXIT_WITHOUT_CLEANUP:
+    return ret;
+
+}
+```
+
+In the example above, the `ModifyThenPrintContext` object contains information
+that's needed for exactly the lifetime of the current job (i.e. how to modify
+and where to print).  Information with a longer or shorter lifetime is moved
+to `ModifyThenPrintDialect` and `ModifyThenPrintMessage`.
+
+FFmpeg uses the context pattern to solve a variety of problems. But the most
+common contexts (AVCodecContext, AVFormatContext etc.) tend to have a lot of
+requirements in common:
+
+- need to query, set and get options
+  - including options whose implementation is not part of the public API
+- need to configure log message verbosity and content
+
+FFmpeg gradually converged on the AVClass struct to store that information,
+then converged on the @ref avoptions "AVOptions" system to manipulate it.
+So the terms "context", "AVClass context structure" and "AVOptions-enabled
+struct" are often used interchangeably when it's not important to emphasise
+the difference.  But for example, AVMediaCodecContext uses the context
+pattern, but is not an AVClass context structure, so cannot be manipulated
+with AVOptions.
+
+To understand AVClass context structures, consider the `libx264` encoder:
+
+- it has to support common encoder options like "bitrate"
+- it has to support encoder-specific options like "profile"
+  - the exact options could change quickly if a legal ruling forces a change of backend
+- it has to provide useful feedback about unsupported options
+
+Common encoder options like "bitrate" are stored in the AVCodecContext class,
+while encoder-specific options like "profile" are stored in an X264Context
+instance in AVCodecContext::priv_data.  These options are then exposed through
+a tree of AVOption objects, which include user-visible help text and
+machine-readable information about the memory location to read/write
+each option.  Common @ref avoptions "AVOptions" functionality lets end users
+get and set those values, and provides readable feedback about errors.  But
+even though they can be manipulated through an API, the X264Context class is
+private and new releases can modify it without affecting the public interface.
+
+FFmpeg itself uses the context design pattern to solve many problems.
+You can use this pattern anywhere it would be useful, and may want to use
+AVClass and @ref avoptions "AVOptions" if they're relevant to your situation.
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v2 2/3] lavu: Clarify relationship between AVClass, AVOption and context
  2024-04-20 12:19   ` [FFmpeg-devel] [PATCH v2 " Andrew Sayers
@ 2024-04-20 12:19     ` Andrew Sayers
  2024-04-20 12:19     ` [FFmpeg-devel] [PATCH v2 3/3] all: Link to "context" from all contexts with documentation Andrew Sayers
  2024-04-20 16:48     ` [FFmpeg-devel] [PATCH v2 1/3] doc: Explain what "context" means Stefano Sabatini
  2 siblings, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-04-20 12:19 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

---
 libavutil/log.h | 11 ++++++++---
 libavutil/opt.h |  7 ++++---
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/libavutil/log.h b/libavutil/log.h
index ab7ceabe22..b5c739dab1 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -59,9 +59,14 @@ typedef enum {
 struct AVOptionRanges;
 
 /**
- * Describe the class of an AVClass context structure. That is an
- * arbitrary struct of which the first field is a pointer to an
- * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).
+ * Metadata about an arbitrary data structure
+ *
+ * A @ref context "context struct" whose first member is a pointer
+ * to an AVClass object is called an "AVClass context structure"
+ * (e.g. AVCodecContext, AVFormatContext etc.).
+ *
+ * AVClass is often combined with @ref avoptions "AVOptions" to create
+ * "AVOptions-enabled structs" that can be easily configured by users.
  */
 typedef struct AVClass {
     /**
diff --git a/libavutil/opt.h b/libavutil/opt.h
index e6013662f6..b817d15554 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -39,9 +39,10 @@
  * @defgroup avoptions AVOptions
  * @ingroup lavu_data
  * @{
- * AVOptions provide a generic system to declare options on arbitrary structs
- * ("objects"). An option can have a help text, a type and a range of possible
- * values. Options may then be enumerated, read and written to.
+ * Builds on AVClass, adding a generic system to declare options.
+ *
+ * An option can have a help text, a type and a range of possible values.
+ * Options may then be enumerated, read and written to.
  *
  * There are two modes of access to members of AVOption and its child structs.
  * One is called 'native access', and refers to access from the code that
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v2 3/3] all: Link to "context" from all contexts with documentation
  2024-04-20 12:19   ` [FFmpeg-devel] [PATCH v2 " Andrew Sayers
  2024-04-20 12:19     ` [FFmpeg-devel] [PATCH v2 2/3] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
@ 2024-04-20 12:19     ` Andrew Sayers
  2024-04-20 16:48     ` [FFmpeg-devel] [PATCH v2 1/3] doc: Explain what "context" means Stefano Sabatini
  2 siblings, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-04-20 12:19 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

Some headings needed to be rewritten to accomodate the text,
(hopefully) without changing the meaning.
---
 libavcodec/aacdec.h              |  2 +-
 libavcodec/aacenc.h              |  2 +-
 libavcodec/ac3enc.h              |  2 +-
 libavcodec/amfenc.h              |  2 +-
 libavcodec/atrac.h               |  2 +-
 libavcodec/avcodec.h             |  3 ++-
 libavcodec/bsf.h                 |  2 +-
 libavcodec/d3d11va.h             |  3 +--
 libavcodec/mediacodec.h          |  2 +-
 libavcodec/qsv.h                 |  6 ++++--
 libavcodec/sbr.h                 |  2 +-
 libavcodec/vdpau.h               |  3 ++-
 libavcodec/videotoolbox.h        |  5 +++--
 libavfilter/avfilter.h           |  2 +-
 libavformat/avformat.h           |  3 ++-
 libavformat/avio.h               |  3 ++-
 libavutil/hwcontext.h            | 21 ++++++++++++---------
 libavutil/hwcontext_cuda.h       |  2 +-
 libavutil/hwcontext_d3d11va.h    |  4 ++--
 libavutil/hwcontext_d3d12va.h    |  6 +++---
 libavutil/hwcontext_drm.h        |  2 +-
 libavutil/hwcontext_dxva2.h      |  4 ++--
 libavutil/hwcontext_mediacodec.h |  2 +-
 libavutil/hwcontext_opencl.h     |  4 ++--
 libavutil/hwcontext_qsv.h        |  4 ++--
 libavutil/hwcontext_vaapi.h      |  6 +++---
 libavutil/hwcontext_vdpau.h      |  2 +-
 libavutil/hwcontext_vulkan.h     |  4 ++--
 28 files changed, 57 insertions(+), 48 deletions(-)

diff --git a/libavcodec/aacdec.h b/libavcodec/aacdec.h
index 1b245f9258..3a5317cd54 100644
--- a/libavcodec/aacdec.h
+++ b/libavcodec/aacdec.h
@@ -181,7 +181,7 @@ typedef struct DynamicRangeControl {
 } DynamicRangeControl;
 
 /**
- * main AAC decoding context
+ * main AAC decoding @ref context "context"
  */
 typedef struct AACDecContext {
     const struct AVClass  *class;
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index 8899f90ac7..c91f99bc6c 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -193,7 +193,7 @@ typedef struct AACPCEInfo {
 } AACPCEInfo;
 
 /**
- * AAC encoder context
+ * AAC encoder @ref context "context"
  */
 typedef struct AACEncContext {
     AVClass *av_class;
diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
index 30812617cc..4b6b3c222b 100644
--- a/libavcodec/ac3enc.h
+++ b/libavcodec/ac3enc.h
@@ -152,7 +152,7 @@ typedef struct AC3Block {
 } AC3Block;
 
 /**
- * AC-3 encoder private context.
+ * AC-3 encoder private @ref context "context"
  */
 typedef struct AC3EncodeContext {
     AVClass *av_class;                      ///< AVClass used for AVOption
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..71138e7f76 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
 } AmfTraceWriter;
 
 /**
-* AMF encoder context
+* AMF encoder @ref context "context"
 */
 
 typedef struct AmfContext {
diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
index 05208bbee6..acdd0a741a 100644
--- a/libavcodec/atrac.h
+++ b/libavcodec/atrac.h
@@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
 } AtracGainInfo;
 
 /**
- *  Gain compensation context structure.
+ *  Gain compensation @ref context "context"
  */
 typedef struct AtracGCContext {
     float   gain_tab1[16];  ///< gain compensation level table
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 968009a192..a1f1430dde 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -430,7 +430,8 @@ typedef struct RcOverride{
 #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
 
 /**
- * main external API structure.
+ * @ref context "Context" for an encode or decode session
+ *
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
index a09c69f242..23c3cc87e4 100644
--- a/libavcodec/bsf.h
+++ b/libavcodec/bsf.h
@@ -56,7 +56,7 @@
  */
 
 /**
- * The bitstream filter state.
+ * Bitstream filter @ref context "context"
  *
  * This struct must be allocated with av_bsf_alloc() and freed with
  * av_bsf_free().
diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
index 27f40e5519..087c99f161 100644
--- a/libavcodec/d3d11va.h
+++ b/libavcodec/d3d11va.h
@@ -46,8 +46,7 @@
  */
 
 /**
- * This structure is used to provides the necessary configurations and data
- * to the Direct3D11 FFmpeg HWAccel implementation.
+ * @ref context "Context" for the Direct3D11 FFmpeg HWAccel implementation
  *
  * The application must make it available as AVCodecContext.hwaccel_context.
  *
diff --git a/libavcodec/mediacodec.h b/libavcodec/mediacodec.h
index 4e9b56a618..d983e7ff1a 100644
--- a/libavcodec/mediacodec.h
+++ b/libavcodec/mediacodec.h
@@ -26,7 +26,7 @@
 #include "libavcodec/avcodec.h"
 
 /**
- * This structure holds a reference to a android/view/Surface object that will
+ * @ref context "Context" for the android/view/Surface object that will
  * be used as output by the decoder.
  *
  */
diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
index c156b08d07..e75351ae27 100644
--- a/libavcodec/qsv.h
+++ b/libavcodec/qsv.h
@@ -26,8 +26,10 @@
 #include "libavutil/buffer.h"
 
 /**
- * This struct is used for communicating QSV parameters between libavcodec and
- * the caller. It is managed by the caller and must be assigned to
+ * @ref context "Context" for communicating QSV parameters between libavcodec
+ * and the caller.
+ *
+ * It is managed by the caller and must be assigned to
  * AVCodecContext.hwaccel_context.
  * - decoding: hwaccel_context must be set on return from the get_format()
  *             callback
diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
index fe3a39603a..65f7a6da8f 100644
--- a/libavcodec/sbr.h
+++ b/libavcodec/sbr.h
@@ -116,7 +116,7 @@ typedef struct SBRData {
 typedef struct SpectralBandReplication SpectralBandReplication;
 
 /**
- * aacsbr functions pointers
+ * aacsbr functions pointer @ref context "context"
  */
 typedef struct AACSBRContext {
     int (*sbr_lf_gen)(SpectralBandReplication *sbr,
diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
index 8021c25761..a9ff8b5f47 100644
--- a/libavcodec/vdpau.h
+++ b/libavcodec/vdpau.h
@@ -64,8 +64,9 @@ typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, struct AVFrame *,
                                const VdpBitstreamBuffer *);
 
 /**
- * This structure is used to share data between the libavcodec library and
+ * @ref context "Context" to share data between the libavcodec library and
  * the client video application.
+ *
  * This structure will be allocated and stored in AVCodecContext.hwaccel_context
  * by av_vdpau_bind_context(). Members can be set by the user once
  * during initialization or through each AVCodecContext.get_buffer()
diff --git a/libavcodec/videotoolbox.h b/libavcodec/videotoolbox.h
index d68d76e400..ece008157c 100644
--- a/libavcodec/videotoolbox.h
+++ b/libavcodec/videotoolbox.h
@@ -49,8 +49,9 @@
 #include "libavutil/attributes.h"
 
 /**
- * This struct holds all the information that needs to be passed
- * between the caller and libavcodec for initializing Videotoolbox decoding.
+ * @ref context "Context" for information passed between the caller and libavcodec
+ * for initializing Videotoolbox decoding.
+ *
  * Its size is not a part of the public ABI, it must be allocated with
  * av_videotoolbox_alloc_context() and freed with av_free().
  */
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index a34e61f23c..41bdc30d89 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -403,7 +403,7 @@ unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output);
  */
 #define AVFILTER_THREAD_SLICE (1 << 0)
 
-/** An instance of a filter */
+/** @ref context "Context" for a filter */
 struct AVFilterContext {
     const AVClass *av_class;        ///< needed for av_log() and filters common options
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 8afdcd9fd0..6bb08a0b0c 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1241,7 +1241,8 @@ enum AVDurationEstimationMethod {
 };
 
 /**
- * Format I/O context.
+ * Format I/O @ref context "context"
+ *
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
diff --git a/libavformat/avio.h b/libavformat/avio.h
index ebf611187d..e18d542377 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -146,7 +146,8 @@ enum AVIODataMarkerType {
 };
 
 /**
- * Bytestream IO Context.
+ * Bytestream I/O @ref context "context"
+ *
  * New public fields can be added with minor version bumps.
  * Removal, reordering and changes to existing public fields require
  * a major version bump.
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index bac30debae..f94f44906c 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -41,12 +41,13 @@ enum AVHWDeviceType {
 };
 
 /**
- * This struct aggregates all the (hardware/vendor-specific) "high-level" state,
- * i.e. state that is not tied to a concrete processing configuration.
- * E.g., in an API that supports hardware-accelerated encoding and decoding,
- * this struct will (if possible) wrap the state that is common to both encoding
- * and decoding and from which specific instances of encoders or decoders can be
- * derived.
+ * @ref context "Context" for (hardware/vendor-specific) "high-level" state.
+ *
+ * "High-level state" is anything that is not tied to a concrete processing
+ * configuration. E.g., in an API that supports hardware-accelerated encoding
+ * and decoding, this struct will (if possible) wrap the state that is common
+ * to both encoding and decoding and from which specific instances of encoders
+ * or decoders can be derived.
  *
  * This struct is reference-counted with the AVBuffer mechanism. The
  * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field
@@ -103,9 +104,11 @@ typedef struct AVHWDeviceContext {
 } AVHWDeviceContext;
 
 /**
- * This struct describes a set or pool of "hardware" frames (i.e. those with
- * data not located in normal system memory). All the frames in the pool are
- * assumed to be allocated in the same way and interchangeable.
+ * @ref context "context" for a pool of "hardware" frames (those with
+ * data not located in normal system memory)
+ *
+ * All the frames in the pool are assumed to be allocated in the same way and
+ * interchangeable.
  *
  * This struct is reference-counted with the AVBuffer mechanism and tied to a
  * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor
diff --git a/libavutil/hwcontext_cuda.h b/libavutil/hwcontext_cuda.h
index cbad434fea..befa978cf9 100644
--- a/libavutil/hwcontext_cuda.h
+++ b/libavutil/hwcontext_cuda.h
@@ -37,7 +37,7 @@
 typedef struct AVCUDADeviceContextInternal AVCUDADeviceContextInternal;
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVCUDADeviceContext {
     CUcontext cuda_ctx;
diff --git a/libavutil/hwcontext_d3d11va.h b/libavutil/hwcontext_d3d11va.h
index 77d2d72f1b..eac7d6062a 100644
--- a/libavutil/hwcontext_d3d11va.h
+++ b/libavutil/hwcontext_d3d11va.h
@@ -40,7 +40,7 @@
 #include <stdint.h>
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVD3D11VADeviceContext {
     /**
@@ -126,7 +126,7 @@ typedef struct AVD3D11FrameDescriptor {
 } AVD3D11FrameDescriptor;
 
 /**
- * This struct is allocated as AVHWFramesContext.hwctx
+ * This @ref context "context" is allocated as AVHWFramesContext.hwctx
  */
 typedef struct AVD3D11VAFramesContext {
     /**
diff --git a/libavutil/hwcontext_d3d12va.h b/libavutil/hwcontext_d3d12va.h
index ff06e6f2ef..d170f74b4d 100644
--- a/libavutil/hwcontext_d3d12va.h
+++ b/libavutil/hwcontext_d3d12va.h
@@ -37,7 +37,7 @@
 #include <d3d12video.h>
 
 /**
- * @brief This struct is allocated as AVHWDeviceContext.hwctx
+ * @brief This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  *
  */
 typedef struct AVD3D12VADeviceContext {
@@ -78,7 +78,7 @@ typedef struct AVD3D12VADeviceContext {
 } AVD3D12VADeviceContext;
 
 /**
- * @brief This struct is used to sync d3d12 execution
+ * @brief This @ref context "context" is used to sync d3d12 execution
  *
  */
 typedef struct AVD3D12VASyncContext {
@@ -120,7 +120,7 @@ typedef struct AVD3D12VAFrame {
 } AVD3D12VAFrame;
 
 /**
- * @brief This struct is allocated as AVHWFramesContext.hwctx
+ * @brief This @ref context "context" is allocated as AVHWFramesContext.hwctx
  *
  */
 typedef struct AVD3D12VAFramesContext {
diff --git a/libavutil/hwcontext_drm.h b/libavutil/hwcontext_drm.h
index 42709f215e..b7b1bad171 100644
--- a/libavutil/hwcontext_drm.h
+++ b/libavutil/hwcontext_drm.h
@@ -152,7 +152,7 @@ typedef struct AVDRMFrameDescriptor {
 /**
  * DRM device.
  *
- * Allocated as AVHWDeviceContext.hwctx.
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx.
  */
 typedef struct AVDRMDeviceContext {
     /**
diff --git a/libavutil/hwcontext_dxva2.h b/libavutil/hwcontext_dxva2.h
index e1b79bc0de..b77b7293ab 100644
--- a/libavutil/hwcontext_dxva2.h
+++ b/libavutil/hwcontext_dxva2.h
@@ -34,14 +34,14 @@
 #include <dxva2api.h>
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVDXVA2DeviceContext {
     IDirect3DDeviceManager9 *devmgr;
 } AVDXVA2DeviceContext;
 
 /**
- * This struct is allocated as AVHWFramesContext.hwctx
+ * This @ref context "context" is allocated as AVHWFramesContext.hwctx
  */
 typedef struct AVDXVA2FramesContext {
     /**
diff --git a/libavutil/hwcontext_mediacodec.h b/libavutil/hwcontext_mediacodec.h
index fc0263cabc..39381b56c5 100644
--- a/libavutil/hwcontext_mediacodec.h
+++ b/libavutil/hwcontext_mediacodec.h
@@ -22,7 +22,7 @@
 /**
  * MediaCodec details.
  *
- * Allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVMediaCodecDeviceContext {
     /**
diff --git a/libavutil/hwcontext_opencl.h b/libavutil/hwcontext_opencl.h
index ef54486c95..fc5b1bb24f 100644
--- a/libavutil/hwcontext_opencl.h
+++ b/libavutil/hwcontext_opencl.h
@@ -58,7 +58,7 @@ typedef struct AVOpenCLFrameDescriptor {
 /**
  * OpenCL device details.
  *
- * Allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVOpenCLDeviceContext {
     /**
@@ -84,7 +84,7 @@ typedef struct AVOpenCLDeviceContext {
 /**
  * OpenCL-specific data associated with a frame pool.
  *
- * Allocated as AVHWFramesContext.hwctx.
+ * This @ref context "context" is allocated as AVHWFramesContext.hwctx.
  */
 typedef struct AVOpenCLFramesContext {
     /**
diff --git a/libavutil/hwcontext_qsv.h b/libavutil/hwcontext_qsv.h
index e2dba8ad83..c7cc88627b 100644
--- a/libavutil/hwcontext_qsv.h
+++ b/libavutil/hwcontext_qsv.h
@@ -30,7 +30,7 @@
  */
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVQSVDeviceContext {
     mfxSession session;
@@ -48,7 +48,7 @@ typedef struct AVQSVDeviceContext {
 } AVQSVDeviceContext;
 
 /**
- * This struct is allocated as AVHWFramesContext.hwctx
+ * This @ref context "context" is allocated as AVHWFramesContext.hwctx
  */
 typedef struct AVQSVFramesContext {
     mfxFrameSurface1 *surfaces;
diff --git a/libavutil/hwcontext_vaapi.h b/libavutil/hwcontext_vaapi.h
index 0b2e071cb3..e1940a5fe0 100644
--- a/libavutil/hwcontext_vaapi.h
+++ b/libavutil/hwcontext_vaapi.h
@@ -63,7 +63,7 @@ enum {
 /**
  * VAAPI connection details.
  *
- * Allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVVAAPIDeviceContext {
     /**
@@ -83,7 +83,7 @@ typedef struct AVVAAPIDeviceContext {
 /**
  * VAAPI-specific data associated with a frame pool.
  *
- * Allocated as AVHWFramesContext.hwctx.
+ * This @ref context "context" is allocated as AVHWFramesContext.hwctx.
  */
 typedef struct AVVAAPIFramesContext {
     /**
@@ -105,7 +105,7 @@ typedef struct AVVAAPIFramesContext {
 /**
  * VAAPI hardware pipeline configuration details.
  *
- * Allocated with av_hwdevice_hwconfig_alloc().
+ * This struct is allocated with av_hwdevice_hwconfig_alloc().
  */
 typedef struct AVVAAPIHWConfig {
     /**
diff --git a/libavutil/hwcontext_vdpau.h b/libavutil/hwcontext_vdpau.h
index 1b7ea1e443..b26f7f171e 100644
--- a/libavutil/hwcontext_vdpau.h
+++ b/libavutil/hwcontext_vdpau.h
@@ -30,7 +30,7 @@
  */
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVVDPAUDeviceContext {
     VdpDevice          device;
diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h
index cbbd2390c1..d6897a96fa 100644
--- a/libavutil/hwcontext_vulkan.h
+++ b/libavutil/hwcontext_vulkan.h
@@ -39,7 +39,7 @@ typedef struct AVVkFrame AVVkFrame;
  */
 
 /**
- * Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
+ * Main Vulkan @ref context "context", allocated as AVHWDeviceContext.hwctx.
  * All of these can be set before init to change what the context uses
  */
 typedef struct AVVulkanDeviceContext {
@@ -172,7 +172,7 @@ typedef enum AVVkFrameFlags {
 } AVVkFrameFlags;
 
 /**
- * Allocated as AVHWFramesContext.hwctx, used to set pool-specific options
+ * This @ref context "context" is allocated as AVHWFramesContext.hwctx, used to set pool-specific options
  */
 typedef struct AVVulkanFramesContext {
     /**
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH 1/3] doc: Explain what "context" means
  2024-04-20 12:18   ` Andrew Sayers
@ 2024-04-20 16:13     ` Stefano Sabatini
  0 siblings, 0 replies; 39+ messages in thread
From: Stefano Sabatini @ 2024-04-20 16:13 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On date Saturday 2024-04-20 13:18:29 +0100, Andrew Sayers wrote:
> On 20/04/2024 08:25, Stefano Sabatini wrote:
> > On date Thursday 2024-04-18 16:06:12 +0100, Andrew Sayers wrote:
> > > Based largely on the explanation by Stefano Sabatini:
> > > https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325854.html
> > > ---
> > >   doc/jargon.md | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > >   1 file changed, 96 insertions(+)
> > >   create mode 100644 doc/jargon.md
> > > 
> > > diff --git a/doc/jargon.md b/doc/jargon.md
> > > new file mode 100644
> > > index 0000000000..3b78ffb61f
> > > --- /dev/null
> > > +++ b/doc/jargon.md
> > We currently have a single .md file in doc (for historical reason we
> > still stick to texinfo). Also how is this integrated into doxygen?
> 

> Doxygen automatically renders all /*.md and /doc/*.md files to pages at [1]
> which is the only place I'd know to look for this sort of thing. it seems
> like texinfo is more for man pages etc., which would be hard to link from
> doxygen?  By the way, a file called "jargon" seemed like a better idea than
> e.g. a "design_patterns" file or a section in AVClass.  I've rewritten the
> document completely based on your feedback - same markdown file for now,
> but happy to move/reformat.

If this is the case, probably we should move the files to a dedicated
directory (doxygen?) to avoid to mix too many things in the same
bundle (can be done as a separated patch though since we might think
about what we really want to include in the doxygen docs).

> The points below should be addressed by the new patch, so I'll let that
> speak for itself.  But there's a general issue that's worth mentioning...
> 

> Technically, it sounds like a more accurate description would be "Context
> is an FFmpeg convention that has become fairly rigorous over the years".
> But IMHO readers would uncharitably read that as "Context is some weird
> FFmpeg thing they're stuck with because they picked a pre-OOP language".
> Arguing "Context is a design pattern that groups objects by lifespan"
> emphasises the lessons a newbie can take from FFmpeg and use elsewhere,
> so they get more value from the time they spent reading the document.
> I've tried to write the document to start with the more useful argument,
> then gradually ease in to the more accurate one.

But, I don't think this is really something very rigourous, because it
is used in different "contexts" with sligthly different features
(e.g. you can have a structure named "context" but without an AVClass
or options).

And it's not really about lifespan, and not really specific for
FFmpeg, in C programming this is used to provide a "context" for
several "methods" operating on a given struct - so basically a light
implementation of an object-oriented-based API.

[...]
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/3] doc: Explain what "context" means
  2024-04-20 12:19   ` [FFmpeg-devel] [PATCH v2 " Andrew Sayers
  2024-04-20 12:19     ` [FFmpeg-devel] [PATCH v2 2/3] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
  2024-04-20 12:19     ` [FFmpeg-devel] [PATCH v2 3/3] all: Link to "context" from all contexts with documentation Andrew Sayers
@ 2024-04-20 16:48     ` Stefano Sabatini
  2024-04-20 22:17       ` Andrew Sayers
  2 siblings, 1 reply; 39+ messages in thread
From: Stefano Sabatini @ 2024-04-20 16:48 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Andrew Sayers

On date Saturday 2024-04-20 13:19:41 +0100, Andrew Sayers wrote:
> Based largely on the explanation by Stefano Sabatini:
> https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325854.html
> ---
>  doc/jargon.md | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 169 insertions(+)
>  create mode 100644 doc/jargon.md
> 
> diff --git a/doc/jargon.md b/doc/jargon.md
> new file mode 100644
> index 0000000000..f967b5c8bc
> --- /dev/null
> +++ b/doc/jargon.md
> @@ -0,0 +1,169 @@
> +# Jargon
> +
> +Terms used throughout the code that developers may need to know.
> +
> +@anchor context
> +

> +## Context
> +

> +A design pattern that stores the context (e.g. configuration) for a series
> +of operations in a "context" structure, and moves other information with
> +a longer or shorter lifetime elsewhere.

I'd skip the mention of a design pattern since this is about the
jargon.

So a simplified variant would be:

A "context" is a a structure used to store information
(e.g. configuration and/or internal state) for a series of operations
working on the same data.

> +
> +Consider a code snippet to modify text then print it:
> +
> +```c
> +/**
> + * Contextual information about printing a series of messages
> + */
> +struct ModifyThenPrintContext {
> +
> +    /**
> +     * Members of the context usually are usually part of its public API...
> +     */
> +    FILE *out;
> +
> +    /**
> +     * ... but check the documentation just in case
> +     */
> +    [[deprecated]]
> +    int no_longer_part_of_the_public_api;
> +
> +    /**
> +     * The "internal context" is private to the context itself.
> +     *
> +     * Unlike the members above, the private context is not guaranteed
> +     * and can change arbitrarily between versions.
> +     */
> +    void* priv_data;
> +};
> +
> +/**
> + * Long-lifetime information, reused by many contexts
> + */
> +enum ModifyThenPrintDialect {
> +    MODIFY_THEN_PRINT_PLAIN_TEXT,
> +    MODIFY_THEN_PRINT_REGEX,
> +    MODIFY_THEN_PRINT_REGEX_PCRE
> +};
> +
> +/**
> + * Short-lifetime information, used repeatedly in a single context
> + */
> +struct ModifyThenPrintMessage {
> +    char *str;
> +    char *replace_this;
> +    char *with_this;
> +};
> +
> +/**
> + * Allocate and initialize a ModifyThenPrintContext
> + *
> + * This creates a new pointer, then fills in some sensible defaults.
> + *
> + * We can reasonably assume this function will initialise `priv_data`
> + * with a dialect-specific object, but shouldn't make any assumptions
> + * about what that object is.
> + *
> + */
> +int ModifyThenPrintContext_alloc_context(struct ModifyThenPrintContext **ctx,
> +                                         FILE *out,
> +                                         enum ModifyThenPrintDialect dialect);
> +
> +/**
> + * Uninitialize and deallocate a ModifyThenPrintContext
> + *
> + * This does any work required by the private context in `priv_data`
> + * (e.g. deallocating it), then deallocates the main context itself.
> + *
> + */
> +int ModifyThenPrintContext_free(struct ModifyThenPrintContext *ctx);
> +
> +/**
> + * Print a single message
> + */
> +int ModifyThenPrintContext_print(struct ModifyThenPrintContext *ctx,
> +                                 struct ModifyThenPrintMessage *msg);
> +
> +int print_hello_world()
> +{
> +
> +    int ret = 0;
> +
> +    struct ModifyThenPrintContext *ctx;
> +
> +    struct ModifyThenPrintMessage hello_world;
> +
> +    if ( ModifyThenPrintContext_alloc_context( &ctx, stdout, MODIFY_THEN_PRINT_REGEX ) < 0 ) {
> +        ret = -1;
> +        goto EXIT_WITHOUT_CLEANUP;
> +    }
> +
> +    hello_world.replace_this = "Hi|Hullo";
> +    hello_world.with_this    = "Hello";
> +
> +    hello_world.str = "Hi, world!\n";
> +    if ( ModifyThenPrintContext_print( ctx, &hello_world ) < 0 ) {
> +        ret = -1;
> +        goto FINISH;
> +    }
> +
> +    hello_world.str = "Hullo, world!\n";
> +    if ( ModifyThenPrintContext_print( ctx, &hello_world ) < 0 ) {
> +        ret = -1;
> +        goto FINISH;
> +    }
> +
> +    FINISH:
> +    if ( ModifyThenPrintContext_free( ctx ) ) {
> +        ret = -1;
> +        goto EXIT_WITHOUT_CLEANUP;
> +    }
> +
> +    EXIT_WITHOUT_CLEANUP:
> +    return ret;
> +
> +}
> +```
> +

> +In the example above, the `ModifyThenPrintContext` object contains information
> +that's needed for exactly the lifetime of the current job (i.e. how to modify
> +and where to print).  Information with a longer or shorter lifetime is moved
> +to `ModifyThenPrintDialect` and `ModifyThenPrintMessage`.

I still find this overly complex, I would rather use a typical example
of AVCodecContext for encoding or decoding or something even simpler
(for example md5.h).

About the internal "private" context, this is mostly relevant for
FFmpeg development, and not really useful for API users (basically
they don't even need to know about the private data).

For example all they need to know is that for AVCodecContext generic
options they can set the fields in the context itself, or use
AVOptions, but they can only use AVOptions for "private" options.

We are not still enforcing the use of AVOption to set all options,
although we might want in the future.

> +
> +FFmpeg uses the context pattern to solve a variety of problems. But the most
> +common contexts (AVCodecContext, AVFormatContext etc.) tend to have a lot of
> +requirements in common:
> +
> +- need to query, set and get options
> +  - including options whose implementation is not part of the public API
> +- need to configure log message verbosity and content
> +
> +FFmpeg gradually converged on the AVClass struct to store that information,
> +then converged on the @ref avoptions "AVOptions" system to manipulate it.
> +So the terms "context", "AVClass context structure" and "AVOptions-enabled
> +struct" are often used interchangeably when it's not important to emphasise
> +the difference.  But for example, AVMediaCodecContext uses the context
> +pattern, but is not an AVClass context structure, so cannot be manipulated
> +with AVOptions.
> +
> +To understand AVClass context structures, consider the `libx264` encoder:
> +
> +- it has to support common encoder options like "bitrate"
> +- it has to support encoder-specific options like "profile"
> +  - the exact options could change quickly if a legal ruling forces a change of backend
> +- it has to provide useful feedback about unsupported options
> +
> +Common encoder options like "bitrate" are stored in the AVCodecContext class,
> +while encoder-specific options like "profile" are stored in an X264Context
> +instance in AVCodecContext::priv_data.  These options are then exposed through
> +a tree of AVOption objects, which include user-visible help text and
> +machine-readable information about the memory location to read/write
> +each option.  Common @ref avoptions "AVOptions" functionality lets end users
> +get and set those values, and provides readable feedback about errors.  But
> +even though they can be manipulated through an API, the X264Context class is
> +private and new releases can modify it without affecting the public interface.
> +

I like this section, looks useful to explain the internals.

> +FFmpeg itself uses the context design pattern to solve many problems.
> +You can use this pattern anywhere it would be useful, and may want to use
> +AVClass and @ref avoptions "AVOptions" if they're relevant to your situation.

But again, I'm confused by this since it's confusing two levels:
internal API development and API usage. When you write "may want to
use" it seems to refer to the former, but the user should not really
care about this (unless he wants to know how the internal
implementation works).

In fact, while one user might want to use the FFmpeg API as a generic
development toolkit (and therefore create its own custom API with
AVClass and AVOptions) I don't think this is really very common.
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/3] doc: Explain what "context" means
  2024-04-20 16:48     ` [FFmpeg-devel] [PATCH v2 1/3] doc: Explain what "context" means Stefano Sabatini
@ 2024-04-20 22:17       ` Andrew Sayers
  2024-04-22  8:02         ` Stefano Sabatini
  0 siblings, 1 reply; 39+ messages in thread
From: Andrew Sayers @ 2024-04-20 22:17 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Sat, Apr 20, 2024 at 06:48:32PM +0200, Stefano Sabatini wrote:
> On date Saturday 2024-04-20 13:19:41 +0100, Andrew Sayers wrote:
> > Based largely on the explanation by Stefano Sabatini:
> > https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325854.html
> > ---
> >  doc/jargon.md | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 169 insertions(+)
> >  create mode 100644 doc/jargon.md
> > 
> > diff --git a/doc/jargon.md b/doc/jargon.md
> > new file mode 100644
> > index 0000000000..f967b5c8bc
> > --- /dev/null
> > +++ b/doc/jargon.md
> > @@ -0,0 +1,169 @@
> > +# Jargon
> > +
> > +Terms used throughout the code that developers may need to know.
> > +
> > +@anchor context
> > +
> 
> > +## Context
> > +
> 
> > +A design pattern that stores the context (e.g. configuration) for a series
> > +of operations in a "context" structure, and moves other information with
> > +a longer or shorter lifetime elsewhere.
> 
> I'd skip the mention of a design pattern since this is about the
> jargon.
> 
> So a simplified variant would be:
> 
> A "context" is a a structure used to store information
> (e.g. configuration and/or internal state) for a series of operations
> working on the same data.

I think there's a pattern to the problems I'm having in this thread -
*anchoring effects*.

If you ask someone "is 5 a big number?" then "is 5 thousand a big number?",
they'll probably say "yes" to the second question.  But if you ask them
"is 5 billian a big number?" then "is 5 thousand a big number?", they'll
probably say "no".  In each case, their concept of "bigness" has been
anchored by the first question you asked.

When I originally tried to learn FFmpeg back in the day, I got nowhere with my
default OOP mindset.  It wasn't until I thought to read the examples with a
procedural mindset that it started making any sense, and I think that has
*anchored* my mental model of FFmpeg to a mindset that made it hard to think
deeply about its object-oriented bits.

Yesterday I would have agreed this was just one piece of jargon that needed
pinning down.  But if other people have similarly mis-anchored themselves,
this question might need to be a bit easier for them to find.

> 
> > +
> > +Consider a code snippet to modify text then print it:
> > +
> > +```c
> > +/**
> > + * Contextual information about printing a series of messages
> > + */
> > +struct ModifyThenPrintContext {
> > +
> > +    /**
> > +     * Members of the context usually are usually part of its public API...
> > +     */
> > +    FILE *out;
> > +
> > +    /**
> > +     * ... but check the documentation just in case
> > +     */
> > +    [[deprecated]]
> > +    int no_longer_part_of_the_public_api;
> > +
> > +    /**
> > +     * The "internal context" is private to the context itself.
> > +     *
> > +     * Unlike the members above, the private context is not guaranteed
> > +     * and can change arbitrarily between versions.
> > +     */
> > +    void* priv_data;
> > +};
> > +
> > +/**
> > + * Long-lifetime information, reused by many contexts
> > + */
> > +enum ModifyThenPrintDialect {
> > +    MODIFY_THEN_PRINT_PLAIN_TEXT,
> > +    MODIFY_THEN_PRINT_REGEX,
> > +    MODIFY_THEN_PRINT_REGEX_PCRE
> > +};
> > +
> > +/**
> > + * Short-lifetime information, used repeatedly in a single context
> > + */
> > +struct ModifyThenPrintMessage {
> > +    char *str;
> > +    char *replace_this;
> > +    char *with_this;
> > +};
> > +
> > +/**
> > + * Allocate and initialize a ModifyThenPrintContext
> > + *
> > + * This creates a new pointer, then fills in some sensible defaults.
> > + *
> > + * We can reasonably assume this function will initialise `priv_data`
> > + * with a dialect-specific object, but shouldn't make any assumptions
> > + * about what that object is.
> > + *
> > + */
> > +int ModifyThenPrintContext_alloc_context(struct ModifyThenPrintContext **ctx,
> > +                                         FILE *out,
> > +                                         enum ModifyThenPrintDialect dialect);
> > +
> > +/**
> > + * Uninitialize and deallocate a ModifyThenPrintContext
> > + *
> > + * This does any work required by the private context in `priv_data`
> > + * (e.g. deallocating it), then deallocates the main context itself.
> > + *
> > + */
> > +int ModifyThenPrintContext_free(struct ModifyThenPrintContext *ctx);
> > +
> > +/**
> > + * Print a single message
> > + */
> > +int ModifyThenPrintContext_print(struct ModifyThenPrintContext *ctx,
> > +                                 struct ModifyThenPrintMessage *msg);
> > +
> > +int print_hello_world()
> > +{
> > +
> > +    int ret = 0;
> > +
> > +    struct ModifyThenPrintContext *ctx;
> > +
> > +    struct ModifyThenPrintMessage hello_world;
> > +
> > +    if ( ModifyThenPrintContext_alloc_context( &ctx, stdout, MODIFY_THEN_PRINT_REGEX ) < 0 ) {
> > +        ret = -1;
> > +        goto EXIT_WITHOUT_CLEANUP;
> > +    }
> > +
> > +    hello_world.replace_this = "Hi|Hullo";
> > +    hello_world.with_this    = "Hello";
> > +
> > +    hello_world.str = "Hi, world!\n";
> > +    if ( ModifyThenPrintContext_print( ctx, &hello_world ) < 0 ) {
> > +        ret = -1;
> > +        goto FINISH;
> > +    }
> > +
> > +    hello_world.str = "Hullo, world!\n";
> > +    if ( ModifyThenPrintContext_print( ctx, &hello_world ) < 0 ) {
> > +        ret = -1;
> > +        goto FINISH;
> > +    }
> > +
> > +    FINISH:
> > +    if ( ModifyThenPrintContext_free( ctx ) ) {
> > +        ret = -1;
> > +        goto EXIT_WITHOUT_CLEANUP;
> > +    }
> > +
> > +    EXIT_WITHOUT_CLEANUP:
> > +    return ret;
> > +
> > +}
> > +```
> > +
> 
> > +In the example above, the `ModifyThenPrintContext` object contains information
> > +that's needed for exactly the lifetime of the current job (i.e. how to modify
> > +and where to print).  Information with a longer or shorter lifetime is moved
> > +to `ModifyThenPrintDialect` and `ModifyThenPrintMessage`.
> 
> I still find this overly complex, I would rather use a typical example
> of AVCodecContext for encoding or decoding or something even simpler
> (for example md5.h).
> 
> About the internal "private" context, this is mostly relevant for
> FFmpeg development, and not really useful for API users (basically
> they don't even need to know about the private data).
> 
> For example all they need to know is that for AVCodecContext generic
> options they can set the fields in the context itself, or use
> AVOptions, but they can only use AVOptions for "private" options.
> 
> We are not still enforcing the use of AVOption to set all options,
> although we might want in the future.

I think you're saying that "context structure" is synonymous with "context",
and is FFmpeg's term for a common style of C structure; but that other projects
might use a different word, or write that style of struct without naming it at
all?  If so, I'd argue it's important to give people a non-FFmpeg-specific
*anchor*, but that we should expand the later FFmpeg-specific example, so they
have an idea of how it's used around here.

A quick grep of the source suggests that "private context" is an accepted
synonym for "internal context".  And it sounds like it fulfils the same purpose
as C++ "private" access.  If both statements are true, then yes it doesn't need
to go in the example, and the whole topic can be cut down to a line like "the
main context is for public members, the private context is for private members".
Sound good?

If we have public and private members, and then AVOption members are a third
thing, the document should probably address the natural assumption that they're
equivalent to C++ "protected" members (i.e. not fully private to the class, but
not fully open to the public).  How about "It might help to think of
AVOption-accessible public members as having 'protected' access, in that you
should access them through the AVOptions API unless you know what you're
doing.  This rule isn't always followed in practice, especially in older code"?

> 
> > +
> > +FFmpeg uses the context pattern to solve a variety of problems. But the most
> > +common contexts (AVCodecContext, AVFormatContext etc.) tend to have a lot of
> > +requirements in common:
> > +
> > +- need to query, set and get options
> > +  - including options whose implementation is not part of the public API
> > +- need to configure log message verbosity and content
> > +
> > +FFmpeg gradually converged on the AVClass struct to store that information,
> > +then converged on the @ref avoptions "AVOptions" system to manipulate it.
> > +So the terms "context", "AVClass context structure" and "AVOptions-enabled
> > +struct" are often used interchangeably when it's not important to emphasise
> > +the difference.  But for example, AVMediaCodecContext uses the context
> > +pattern, but is not an AVClass context structure, so cannot be manipulated
> > +with AVOptions.
> > +
> > +To understand AVClass context structures, consider the `libx264` encoder:
> > +
> > +- it has to support common encoder options like "bitrate"
> > +- it has to support encoder-specific options like "profile"
> > +  - the exact options could change quickly if a legal ruling forces a change of backend
> > +- it has to provide useful feedback about unsupported options
> > +
> > +Common encoder options like "bitrate" are stored in the AVCodecContext class,
> > +while encoder-specific options like "profile" are stored in an X264Context
> > +instance in AVCodecContext::priv_data.  These options are then exposed through
> > +a tree of AVOption objects, which include user-visible help text and
> > +machine-readable information about the memory location to read/write
> > +each option.  Common @ref avoptions "AVOptions" functionality lets end users
> > +get and set those values, and provides readable feedback about errors.  But
> > +even though they can be manipulated through an API, the X264Context class is
> > +private and new releases can modify it without affecting the public interface.
> > +
> 
> I like this section, looks useful to explain the internals.
> 
> > +FFmpeg itself uses the context design pattern to solve many problems.
> > +You can use this pattern anywhere it would be useful, and may want to use
> > +AVClass and @ref avoptions "AVOptions" if they're relevant to your situation.
> 
> But again, I'm confused by this since it's confusing two levels:
> internal API development and API usage. When you write "may want to
> use" it seems to refer to the former, but the user should not really
> care about this (unless he wants to know how the internal
> implementation works).
> 
> In fact, while one user might want to use the FFmpeg API as a generic
> development toolkit (and therefore create its own custom API with
> AVClass and AVOptions) I don't think this is really very common.

I think this is another anchoring problem on my part.  The AVOptions docs[1]
describe how to add AVOptions in accessible language that made me think it was
aimed at ordinary programmers who happen to use FFmpeg.  Would it be better for
the line below "Implementing AVOptions" on that page to say something like:

 This section describes how to add AVOptions capabilities to a struct.
+It is intended for developers of new FFmpeg libraries, but use outside of FFmpeg
+is also possible.

If so, I'll make a separate patch for that and rewrite the document to match.

	- Andrew Sayers

[1] https://ffmpeg.org/doxygen/trunk/group__avoptions.html#details
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v2 1/3] doc: Explain what "context" means
  2024-04-20 22:17       ` Andrew Sayers
@ 2024-04-22  8:02         ` Stefano Sabatini
  2024-04-22 15:56           ` [FFmpeg-devel] [PATCH v3 0/3] all: Link to "context" from all contexts with documentation Andrew Sayers
  0 siblings, 1 reply; 39+ messages in thread
From: Stefano Sabatini @ 2024-04-22  8:02 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On date Saturday 2024-04-20 23:17:57 +0100, Andrew Sayers wrote:
> On Sat, Apr 20, 2024 at 06:48:32PM +0200, Stefano Sabatini wrote:
> > On date Saturday 2024-04-20 13:19:41 +0100, Andrew Sayers wrote:
> > > Based largely on the explanation by Stefano Sabatini:
> > > https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325854.html
> > > ---
> > >  doc/jargon.md | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 169 insertions(+)
> > >  create mode 100644 doc/jargon.md
> > > 
> > > diff --git a/doc/jargon.md b/doc/jargon.md
> > > new file mode 100644
> > > index 0000000000..f967b5c8bc
> > > --- /dev/null
> > > +++ b/doc/jargon.md
> > > @@ -0,0 +1,169 @@
> > > +# Jargon
> > > +
> > > +Terms used throughout the code that developers may need to know.
> > > +
> > > +@anchor context
> > > +
> > 
> > > +## Context
> > > +
> > 
> > > +A design pattern that stores the context (e.g. configuration) for a series
> > > +of operations in a "context" structure, and moves other information with
> > > +a longer or shorter lifetime elsewhere.
> > 
> > I'd skip the mention of a design pattern since this is about the
> > jargon.
> > 
> > So a simplified variant would be:
> > 
> > A "context" is a a structure used to store information
> > (e.g. configuration and/or internal state) for a series of operations
> > working on the same data.
> 
> I think there's a pattern to the problems I'm having in this thread -
> *anchoring effects*.
> 
> If you ask someone "is 5 a big number?" then "is 5 thousand a big number?",
> they'll probably say "yes" to the second question.  But if you ask them
> "is 5 billian a big number?" then "is 5 thousand a big number?", they'll
> probably say "no".  In each case, their concept of "bigness" has been
> anchored by the first question you asked.
> 
> When I originally tried to learn FFmpeg back in the day, I got nowhere with my
> default OOP mindset.  It wasn't until I thought to read the examples with a
> procedural mindset that it started making any sense, and I think that has
> *anchored* my mental model of FFmpeg to a mindset that made it hard to think
> deeply about its object-oriented bits.
> 
> Yesterday I would have agreed this was just one piece of jargon that needed
> pinning down.  But if other people have similarly mis-anchored themselves,
> this question might need to be a bit easier for them to find.
> 
[...]
> > About the internal "private" context, this is mostly relevant for
> > FFmpeg development, and not really useful for API users (basically
> > they don't even need to know about the private data).
> > 
> > For example all they need to know is that for AVCodecContext generic
> > options they can set the fields in the context itself, or use
> > AVOptions, but they can only use AVOptions for "private" options.
> > 
> > We are not still enforcing the use of AVOption to set all options,
> > although we might want in the future.
> 

> I think you're saying that "context structure" is synonymous with "context",
> and is FFmpeg's term for a common style of C structure; but that other projects
> might use a different word, or write that style of struct without naming it at
> all?

Correct, althought this style is pretty common in plain C and there
are some commonly used conventions (e.g. the first parameter of the
related functions is usually the "context") but there is no common
jargon.

Examples:
https://github.com/freeswitch/sofia-sip/blob/master/libsofia-sip-ua/nua/nua_client.h
https://github.com/GNOME/glib/blob/main/gio/gsettings.h
https://code.videolan.org/videolan/x264/-/blob/master/x264.h?ref_type=heads

The meaning of "context" in FFmpeg maps pretty well on the meaning of
the English term (provides the context for a given operation needing
to work on the same data and with a changing state).

> If so, I'd argue it's important to give people a non-FFmpeg-specific
> *anchor*, but that we should expand the later FFmpeg-specific example, so they
> have an idea of how it's used around here.
> 

> A quick grep of the source suggests that "private context" is an accepted
> synonym for "internal context".  And it sounds like it fulfils the same purpose
> as C++ "private" access.  If both statements are true, then yes it doesn't need
> to go in the example, and the whole topic can be cut down to a line like "the
> main context is for public members, the private context is for private members".
> Sound good?

The "internal context" was added to specify options which are not
already covered in the "generic" options. Initially the options were
only specified in the "global" public context, as fields in the
generic structure (e.g. AVCodecContext for encoding/decoding).

One of the problems was that we needed to query the options - for
example so that you can print all the options with ffmpeg -help
encoder=libx264, so AVOptions were added to query those fields through
some form of rudimetary "introspection" (the AVOptions API implies
that there is a struct containing the offsets of the fields, together
with other metadata - a description, a type, and other data to perform
validation).

Later as more codecs/formats were added, there was the need to support
options only specified for specific elements. Such options were stored
in a private context.

In summary:
> the main context is for public members, the private context is for private members

This is correct with the clarification that members correspond to the
options the user can set/get on the affected component (encoder,
decoder, muxers, demuxers, filters etc) using the AVOptions API.

> 
> If we have public and private members, and then AVOption members are a third
> thing, the document should probably address the natural assumption that they're
> equivalent to C++ "protected" members (i.e. not fully private to the class, but
> not fully open to the public).  How about "It might help to think of
> AVOption-accessible public members as having 'protected' access, in that you
> should access them through the AVOptions API unless you know what you're
> doing.  This rule isn't always followed in practice, especially in older code"?

On the other hand, I'm worried to adopt the OOP terminology, as this
might convey the wrong impression that there is a complete OOP
internal implementation or that there is a perfect mapping with OOP
concepts. Also a pure C programmer might not be familiar with the OOP
terminology, and this might be confusing to her.

For example, the main reason for private options was not really to
make them protected, but rather to make it possible to set
component-specific (aka private) options. For setting generic options,
it's still pretty common to set the fields directly, although this has
several disadvantages (no validation is performed, and this is not
robust to API changes - e.g. in case the field is moved in the
structure).

Private options fields direct access is technically not possible
(i.e. you cannot set an option for the x264 encoder by directly
accessing the private x264 context, since this is an opaque field), so
this is not even a concern.

[...]
> > > +FFmpeg itself uses the context design pattern to solve many problems.
> > > +You can use this pattern anywhere it would be useful, and may want to use
> > > +AVClass and @ref avoptions "AVOptions" if they're relevant to your situation.
> > 
> > But again, I'm confused by this since it's confusing two levels:
> > internal API development and API usage. When you write "may want to
> > use" it seems to refer to the former, but the user should not really
> > care about this (unless he wants to know how the internal
> > implementation works).
> > 
> > In fact, while one user might want to use the FFmpeg API as a generic
> > development toolkit (and therefore create its own custom API with
> > AVClass and AVOptions) I don't think this is really very common.
> 

> I think this is another anchoring problem on my part.  The AVOptions docs[1]
> describe how to add AVOptions in accessible language that made me think it was
> aimed at ordinary programmers who happen to use FFmpeg.  Would it be better for
> the line below "Implementing AVOptions" on that page to say something like:
> 
>  This section describes how to add AVOptions capabilities to a struct.

> +It is intended for developers of new FFmpeg libraries, but use outside of FFmpeg
> +is also possible.

Yes, but I'd say instead:

It is intended for developers of FFmpeg/internal FFmpeg development,
...

(since usually FFmpeg is extended by adding new API - e.g. new headers
or new functions - not necessarily libraries).

> 
> If so, I'll make a separate patch for that and rewrite the document to match.

Thanks.
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v3 0/3] all: Link to "context" from all contexts with documentation
  2024-04-22  8:02         ` Stefano Sabatini
@ 2024-04-22 15:56           ` Andrew Sayers
  2024-04-22 15:56             ` [FFmpeg-devel] [PATCH v3 1/3] doc: Explain what "context" means Andrew Sayers
                               ` (2 more replies)
  0 siblings, 3 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-04-22 15:56 UTC (permalink / raw)
  To: ffmpeg-devel

I've updated the link in patch 1 to point to this thread instead of your
original post.

I've heavily rewritten "jargon.md" and renamed it to "context.md", reflecting
how it's more important than I previously realised.  I think it's safe to leave
it in markdown format in doc/ now - it shouldn't open the floodgates to more
files, and that seems like a safe enough bridge to cross when we come to it.

The links in patches 2 and 3 have been updated to point to the new file, but
are otherwise unchanged.

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v3 1/3] doc: Explain what "context" means
  2024-04-22 15:56           ` [FFmpeg-devel] [PATCH v3 0/3] all: Link to "context" from all contexts with documentation Andrew Sayers
@ 2024-04-22 15:56             ` Andrew Sayers
  2024-04-22 17:05               ` Stefano Sabatini
  2024-04-22 15:56             ` [FFmpeg-devel] [PATCH v3 2/3] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
  2024-04-22 15:56             ` [FFmpeg-devel] [PATCH v3 3/3] all: Link to "context" from all contexts with documentation Andrew Sayers
  2 siblings, 1 reply; 39+ messages in thread
From: Andrew Sayers @ 2024-04-22 15:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

Derived from detailed explanations kindly provided by Stefano Sabatini:
https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325903.html
---
 doc/context.md | 276 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 276 insertions(+)
 create mode 100644 doc/context.md

diff --git a/doc/context.md b/doc/context.md
new file mode 100644
index 0000000000..73caacf54f
--- /dev/null
+++ b/doc/context.md
@@ -0,0 +1,276 @@
+# Context-oriented programming
+
+Like many C projects, FFmpeg has adopted the subset of object-oriented techniques
+that help solve its problems.  Object-like structures are called "contexts",
+and this document provides a general introduction to how they work.
+
+Object-oriented programming usually focusses on *access* as a primary concern.
+For example, members of an object are visibly designated "private", "constant"
+etc. to control how they are accessed.  *Reflection* is a secondary concern,
+where it is provided at all.  For example, C++ has no built-in way to get a
+string containing the name of a variable.
+
+Reflection is extremely important for FFmpeg, because user-facing options are
+implemented by reflecting state at runtime.  Limiting access is a secondary
+concern, mainly important for ensuring implementation details can change
+between versions.
+
+An object-oriented programmer learning FFmpeg should be careful not to fixate on
+FFmpeg's access control features, nor to overlook its reflection capabilities.
+Both are present, but have been given the level of focus appropriate for the task.
+
+## Example: modify text then print it
+
+The example below shows a context structure that receives input strings,
+modifies them in some context-dependant way, then prints them to a specified
+filehandle.
+
+```c
+/**
+ * Type information, accessible at runtime.
+ *
+ * Useful when configuring objects.
+ */
+enum ModifyThenPrintDialect {
+    MODIFY_THEN_PRINT_PLAIN_TEXT = 0,
+    MODIFY_THEN_PRINT_REGEX      = 1,
+    MODIFY_THEN_PRINT_REGEX_PCRE = 2
+};
+
+/**
+ * User-facing information about types
+ *
+ * Useful for describing contexts to the user.
+ */
+static const char* ModifyThenPrintDialectName[] = {
+    "plain text",
+    "regular expression",
+    "Perl-compatible regular expression"
+};
+
+/**
+ * Context for functions that modify strings before printing them
+ */
+struct ModifyThenPrintContext {
+
+    /**
+     * Information about the type of this particular instance
+     *
+     * Object-oriented programs would probably represent this example
+     * as a sub-class, but some instance-specific functionality
+     * behaves more like a mixin.
+     */
+    enum ModifyThenPrintDialect dialect;
+
+    /**
+     * Internal context
+     *
+     * Object-oriented programs would put private members in here,
+     * but could also use it to store a virtual function table
+     * or other "invisible" information.
+     */
+    void* priv_data;
+
+    /**
+     * User-configurable options
+     *
+     * Best set through an API, but can be set directly if necessary
+     *
+     * Data from users needs to be validated before it's set, and the API
+     * might e.g. want to update some internal buffer when these change.
+     * Setting this directly is always less robust than using an API,
+     * but might be worthwhile if you're willing to spend the time checking
+     * for edge cases, and don't mind your code misbehaving if future
+     * versions change the API but not the structure.
+     *
+     * Object-oriented programs would likely make these protected members,
+     * initialised in a constructor and accessed with getters and setters.
+     * Making them user-configurable would be left to the programmer.
+     */
+    char *replace_this;
+    char *with_this;
+
+    /**
+     * Programmer-configurable variable
+     *
+     * Object-oriented programs would represent this as a public member.
+     */
+    FILE *out;
+
+};
+
+/**
+ * Allocate and initialize a ModifyThenPrintContext
+ *
+ * This creates a new pointer, then fills in some sensible defaults.
+ *
+ * We can reasonably assume this function will initialise `priv_data`
+ * with a dialect-specific object, but shouldn't make any assumptions
+ * about what that object is.
+ *
+ * Object-oriented programs would likely represent this as an
+ * allocator function and a constructor.
+ */
+int ModifyThenPrintContext_alloc_context(struct ModifyThenPrintContext **ctx,
+                                         enum ModifyThenPrintDialect dialect,
+                                         FILE *out);
+
+/**
+ * Uninitialize and deallocate a ModifyThenPrintContext
+ *
+ * This does any work required by the internal context (e.g. deallocating
+ * `priv_data`), then deallocates the main context itself.
+ *
+ * Object-oriented programs would likely represent this as a
+ * destructor and a deallocator.
+ */
+int ModifyThenPrintContext_free(struct ModifyThenPrintContext *ctx);
+
+/**
+ * Configure a ModifyThenPrintContext
+ *
+ * This checks the arguments are valid in the context's dialect,
+ * then updates the options as necessary
+ *
+ * Object-oriented programs would likely represent this as a
+ * collection of setter functions.
+ */
+int ModifyThenPrintContext_configure(struct ModifyThenPrintContext *ctx,
+                                     char* replace_this,
+                                     char* with_this);
+
+/**
+ * Print the contents of a ModifyThenPrintContext to a filehandle
+ *
+ * Provides human-readable information about keys and values.
+ *
+ * Object-oriented programs would likely represent this with some kind of
+ * `serialise` operation.
+ */
+int ModifyThenPrintContext_dump(struct ModifyThenPrintContext **ctx,
+                                FILE *dump_fh);
+
+/**
+ * Print a single message
+ *
+ * Object-oriented programs would likely represent this with a member function.
+ */
+int ModifyThenPrintContext_print(struct ModifyThenPrintContext *ctx,
+                                 char *msg);
+
+/**
+ * How this context might be used in practice
+ */
+int print_hello_world()
+{
+
+    int ret = 0;
+
+    struct ModifyThenPrintContext *ctx;
+
+    if ( ModifyThenPrintContext_alloc_context( &ctx, MODIFY_THEN_PRINT_REGEX, stdout ) < 0 ) {
+        ret = -1;
+        goto EXIT_WITHOUT_CLEANUP;
+    }
+
+    if ( ModifyThenPrintContext_configure(ctx, "Hi|Hullo", "Hello") < 0 ) {
+        ret = -1;
+        goto FINISH;
+    }
+
+    if ( ModifyThenPrintContext_print( ctx, "Hi, world!\n" ) < 0 ) {
+        ret = -1;
+        goto FINISH;
+    }
+
+    if ( ModifyThenPrintContext_print( ctx, "Hullo, world!\n" ) < 0 ) {
+        ret = -1;
+        goto FINISH;
+    }
+
+    FINISH:
+    if ( ModifyThenPrintContext_free( ctx ) ) {
+        ret = -1;
+        goto EXIT_WITHOUT_CLEANUP;
+    }
+
+    EXIT_WITHOUT_CLEANUP:
+    return ret;
+
+}
+```
+
+## FFmpeg context structures
+
+The example above is a generic example of a context structure and its
+associated functions.  Some FFmpeg contexts are no more complex than
+that example, just as some objects are just key/value stores with some
+functions attached.  But here are some examples to show the variety of
+contexts available in FFmpeg.
+
+AVHashContext presents a generic API for hashing data.  @ref hash.h
+"Its associated functions" show how to create, use and destroy a hash.
+The exact algorithm is specified by passing a string to av_hash_alloc(),
+and the list of strings can be retrieved from av_hash_names().
+Algorithm-specific internal context is stored in AVHashContext::ctx.
+
+AVCodecContext is a complex member representing data about an encoding or
+decoding session.  @ref avcodec.h "Its associated functions" provide an
+abstract interface to encode and decode data.  Like most widely-used contexts,
+its first member is an AVClass pointer containing instance-specific information.
+That means it's an *AVClass context structure* (discussed in more detail below).
+
+X264Context contains the internal context for an AVCodecContext that uses
+the x264 library.  @ref libx264.c "Its associated functions" provide a concrete
+implementation for interacting with libx264.  This class is not directly
+accessible through FFmpeg's public interface, so unlike AVCodecContext it can
+change significantly between releases.
+
+## Reflection with AVClass and AVOptions
+
+An *AVClass context structure* is a context whose first member is an AVClass
+that reflects its contents.  An *@ref avoptions "AVOptions"-enabled struct*
+is a structure which reflects its contents using the @ref avoptions "AVOptions"
+API.  These terms have become synonymous in modern usage, but you might notice
+some distinction when looking at code written after AVClass was developed but
+before @ref avoptions "AVOptions" was added.
+
+At first glance, an object-oriented programmer might be tempted to look at AVClass
+as a base class that contexts inherit from.  But unlike a base class, an AVClass
+doesn't imply any theoretical relationship between objects, and contexts of the
+same type will often have different AVClass values.  It's even theoretically possible
+for a single AVClass to be shared between contexts of different types.  A better
+analogy would be to [C++ concepts](https://en.wikipedia.org/wiki/Concepts_(C%2B%2B))
+or [Java interfaces](https://en.wikipedia.org/wiki/Interface_(Java)).
+
+To understand how AVClass and @ref avoptions "AVOptions" work,
+consider the requirements for a `libx264` encoder:
+
+- it has to support common encoder options like "bitrate"
+- it has to support encoder-specific options like "profile"
+  - the exact options could change quickly if a legal ruling forces a change of backend
+- it has to provide useful feedback to users about unsupported options
+
+Common encoder options like "bitrate" need to be stored in AVCodecContext itself
+to avoid duplicating code, while encoder-specific options like "profile" have to
+be stored in the X264Context instance stored in AVCodecContext::priv_data.
+But both need to be presented to users (along with help text, default values etc.)
+in a way that makes it easy to build user interfaces to get and set those options.
+
+A context's AVClass member contains a list of AVOption objects, describing
+the user-configurable members of the class.  It also contains functions to
+iterate through a tree of AVClass objects representing internal context either
+for the current object or for any class that could potentially exist in the
+current version of FFmpeg.
+
+The @ref avoptions "AVOptions" API accepts any AVClass context structure,
+looks through its AVOption data, and uses that to examine, introspect, and modify
+the structure.  Because the API doesn't contain any type-specific information,
+it can be used to create a general user interface that adapts automatically
+when e.g. a new version of FFmpeg adds a new configuration option.
+
+## Summary
+
+FFmpeg uses "contexts" in ways that are often resemble object-oriented programming.
+But it focuses less on encapsulation within arbitrarily complex systems,
+and more on providing reflectivity to make pleasant user interfaces.
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v3 2/3] lavu: Clarify relationship between AVClass, AVOption and context
  2024-04-22 15:56           ` [FFmpeg-devel] [PATCH v3 0/3] all: Link to "context" from all contexts with documentation Andrew Sayers
  2024-04-22 15:56             ` [FFmpeg-devel] [PATCH v3 1/3] doc: Explain what "context" means Andrew Sayers
@ 2024-04-22 15:56             ` Andrew Sayers
  2024-04-22 15:56             ` [FFmpeg-devel] [PATCH v3 3/3] all: Link to "context" from all contexts with documentation Andrew Sayers
  2 siblings, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-04-22 15:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

---
 libavutil/log.h | 11 ++++++++---
 libavutil/opt.h |  7 ++++---
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/libavutil/log.h b/libavutil/log.h
index ab7ceabe22..cfbf416679 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -59,9 +59,14 @@ typedef enum {
 struct AVOptionRanges;
 
 /**
- * Describe the class of an AVClass context structure. That is an
- * arbitrary struct of which the first field is a pointer to an
- * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).
+ * Metadata about an arbitrary data structure
+ *
+ * A @ref md_doc_2context "context struct" whose first member is a pointer
+ * to an AVClass object is called an "AVClass context structure"
+ * (e.g. AVCodecContext, AVFormatContext etc.).
+ *
+ * AVClass is often combined with @ref avoptions "AVOptions" to create
+ * "AVOptions-enabled structs" that can be easily configured by users.
  */
 typedef struct AVClass {
     /**
diff --git a/libavutil/opt.h b/libavutil/opt.h
index e6013662f6..b817d15554 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -39,9 +39,10 @@
  * @defgroup avoptions AVOptions
  * @ingroup lavu_data
  * @{
- * AVOptions provide a generic system to declare options on arbitrary structs
- * ("objects"). An option can have a help text, a type and a range of possible
- * values. Options may then be enumerated, read and written to.
+ * Builds on AVClass, adding a generic system to declare options.
+ *
+ * An option can have a help text, a type and a range of possible values.
+ * Options may then be enumerated, read and written to.
  *
  * There are two modes of access to members of AVOption and its child structs.
  * One is called 'native access', and refers to access from the code that
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v3 3/3] all: Link to "context" from all contexts with documentation
  2024-04-22 15:56           ` [FFmpeg-devel] [PATCH v3 0/3] all: Link to "context" from all contexts with documentation Andrew Sayers
  2024-04-22 15:56             ` [FFmpeg-devel] [PATCH v3 1/3] doc: Explain what "context" means Andrew Sayers
  2024-04-22 15:56             ` [FFmpeg-devel] [PATCH v3 2/3] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
@ 2024-04-22 15:56             ` Andrew Sayers
  2 siblings, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-04-22 15:56 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

Some headings needed to be rewritten to accomodate the text,
(hopefully) without changing the meaning.
---
 libavcodec/aacdec.h              |  2 +-
 libavcodec/aacenc.h              |  2 +-
 libavcodec/ac3enc.h              |  2 +-
 libavcodec/amfenc.h              |  2 +-
 libavcodec/atrac.h               |  2 +-
 libavcodec/avcodec.h             |  3 ++-
 libavcodec/bsf.h                 |  2 +-
 libavcodec/d3d11va.h             |  3 +--
 libavcodec/mediacodec.h          |  2 +-
 libavcodec/qsv.h                 |  6 ++++--
 libavcodec/sbr.h                 |  2 +-
 libavcodec/vdpau.h               |  3 ++-
 libavcodec/videotoolbox.h        |  5 +++--
 libavfilter/avfilter.h           |  2 +-
 libavformat/avformat.h           |  3 ++-
 libavformat/avio.h               |  3 ++-
 libavutil/hwcontext.h            | 21 ++++++++++++---------
 libavutil/hwcontext_cuda.h       |  2 +-
 libavutil/hwcontext_d3d11va.h    |  4 ++--
 libavutil/hwcontext_d3d12va.h    |  6 +++---
 libavutil/hwcontext_drm.h        |  2 +-
 libavutil/hwcontext_dxva2.h      |  4 ++--
 libavutil/hwcontext_mediacodec.h |  2 +-
 libavutil/hwcontext_opencl.h     |  4 ++--
 libavutil/hwcontext_qsv.h        |  4 ++--
 libavutil/hwcontext_vaapi.h      |  6 +++---
 libavutil/hwcontext_vdpau.h      |  2 +-
 libavutil/hwcontext_vulkan.h     |  4 ++--
 28 files changed, 57 insertions(+), 48 deletions(-)

diff --git a/libavcodec/aacdec.h b/libavcodec/aacdec.h
index 1b245f9258..715886ae07 100644
--- a/libavcodec/aacdec.h
+++ b/libavcodec/aacdec.h
@@ -181,7 +181,7 @@ typedef struct DynamicRangeControl {
 } DynamicRangeControl;
 
 /**
- * main AAC decoding context
+ * main AAC decoding @ref md_doc_2context "context"
  */
 typedef struct AACDecContext {
     const struct AVClass  *class;
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index 8899f90ac7..755f0495a2 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -193,7 +193,7 @@ typedef struct AACPCEInfo {
 } AACPCEInfo;
 
 /**
- * AAC encoder context
+ * AAC encoder @ref md_doc_2context "context"
  */
 typedef struct AACEncContext {
     AVClass *av_class;
diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
index 30812617cc..c725007077 100644
--- a/libavcodec/ac3enc.h
+++ b/libavcodec/ac3enc.h
@@ -152,7 +152,7 @@ typedef struct AC3Block {
 } AC3Block;
 
 /**
- * AC-3 encoder private context.
+ * AC-3 encoder private @ref md_doc_2context "context"
  */
 typedef struct AC3EncodeContext {
     AVClass *av_class;                      ///< AVClass used for AVOption
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..f142ede63a 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
 } AmfTraceWriter;
 
 /**
-* AMF encoder context
+* AMF encoder @ref md_doc_2context "context"
 */
 
 typedef struct AmfContext {
diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
index 05208bbee6..1527e376a9 100644
--- a/libavcodec/atrac.h
+++ b/libavcodec/atrac.h
@@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
 } AtracGainInfo;
 
 /**
- *  Gain compensation context structure.
+ *  Gain compensation @ref md_doc_2context "context"
  */
 typedef struct AtracGCContext {
     float   gain_tab1[16];  ///< gain compensation level table
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 968009a192..9180fedca7 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -430,7 +430,8 @@ typedef struct RcOverride{
 #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
 
 /**
- * main external API structure.
+ * @ref md_doc_2context "Context" for an encode or decode session
+ *
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
index a09c69f242..bf79afa7cc 100644
--- a/libavcodec/bsf.h
+++ b/libavcodec/bsf.h
@@ -56,7 +56,7 @@
  */
 
 /**
- * The bitstream filter state.
+ * Bitstream filter @ref md_doc_2context "context"
  *
  * This struct must be allocated with av_bsf_alloc() and freed with
  * av_bsf_free().
diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
index 27f40e5519..ec0c472ab9 100644
--- a/libavcodec/d3d11va.h
+++ b/libavcodec/d3d11va.h
@@ -46,8 +46,7 @@
  */
 
 /**
- * This structure is used to provides the necessary configurations and data
- * to the Direct3D11 FFmpeg HWAccel implementation.
+ * @ref md_doc_2context "Context" for the Direct3D11 FFmpeg HWAccel implementation
  *
  * The application must make it available as AVCodecContext.hwaccel_context.
  *
diff --git a/libavcodec/mediacodec.h b/libavcodec/mediacodec.h
index 4e9b56a618..9967a7cfb3 100644
--- a/libavcodec/mediacodec.h
+++ b/libavcodec/mediacodec.h
@@ -26,7 +26,7 @@
 #include "libavcodec/avcodec.h"
 
 /**
- * This structure holds a reference to a android/view/Surface object that will
+ * @ref md_doc_2context "Context" for the android/view/Surface object that will
  * be used as output by the decoder.
  *
  */
diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
index c156b08d07..8b8160a4b1 100644
--- a/libavcodec/qsv.h
+++ b/libavcodec/qsv.h
@@ -26,8 +26,10 @@
 #include "libavutil/buffer.h"
 
 /**
- * This struct is used for communicating QSV parameters between libavcodec and
- * the caller. It is managed by the caller and must be assigned to
+ * @ref md_doc_2context "Context" for communicating QSV parameters between libavcodec
+ * and the caller.
+ *
+ * It is managed by the caller and must be assigned to
  * AVCodecContext.hwaccel_context.
  * - decoding: hwaccel_context must be set on return from the get_format()
  *             callback
diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
index fe3a39603a..98ad9024a9 100644
--- a/libavcodec/sbr.h
+++ b/libavcodec/sbr.h
@@ -116,7 +116,7 @@ typedef struct SBRData {
 typedef struct SpectralBandReplication SpectralBandReplication;
 
 /**
- * aacsbr functions pointers
+ * aacsbr functions pointer @ref md_doc_2context "context"
  */
 typedef struct AACSBRContext {
     int (*sbr_lf_gen)(SpectralBandReplication *sbr,
diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
index 8021c25761..227b85727d 100644
--- a/libavcodec/vdpau.h
+++ b/libavcodec/vdpau.h
@@ -64,8 +64,9 @@ typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, struct AVFrame *,
                                const VdpBitstreamBuffer *);
 
 /**
- * This structure is used to share data between the libavcodec library and
+ * @ref md_doc_2context "Context" to share data between the libavcodec library and
  * the client video application.
+ *
  * This structure will be allocated and stored in AVCodecContext.hwaccel_context
  * by av_vdpau_bind_context(). Members can be set by the user once
  * during initialization or through each AVCodecContext.get_buffer()
diff --git a/libavcodec/videotoolbox.h b/libavcodec/videotoolbox.h
index d68d76e400..f15e79f325 100644
--- a/libavcodec/videotoolbox.h
+++ b/libavcodec/videotoolbox.h
@@ -49,8 +49,9 @@
 #include "libavutil/attributes.h"
 
 /**
- * This struct holds all the information that needs to be passed
- * between the caller and libavcodec for initializing Videotoolbox decoding.
+ * @ref md_doc_2context "Context" for information passed between the caller and libavcodec
+ * for initializing Videotoolbox decoding.
+ *
  * Its size is not a part of the public ABI, it must be allocated with
  * av_videotoolbox_alloc_context() and freed with av_free().
  */
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index a34e61f23c..54b5f9dc43 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -403,7 +403,7 @@ unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output);
  */
 #define AVFILTER_THREAD_SLICE (1 << 0)
 
-/** An instance of a filter */
+/** @ref md_doc_2context "Context" for a filter */
 struct AVFilterContext {
     const AVClass *av_class;        ///< needed for av_log() and filters common options
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 8afdcd9fd0..28243c06c4 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1241,7 +1241,8 @@ enum AVDurationEstimationMethod {
 };
 
 /**
- * Format I/O context.
+ * Format I/O @ref md_doc_2context "context"
+ *
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
diff --git a/libavformat/avio.h b/libavformat/avio.h
index ebf611187d..b525c93194 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -146,7 +146,8 @@ enum AVIODataMarkerType {
 };
 
 /**
- * Bytestream IO Context.
+ * Bytestream I/O @ref md_doc_2context "context"
+ *
  * New public fields can be added with minor version bumps.
  * Removal, reordering and changes to existing public fields require
  * a major version bump.
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index bac30debae..60064cf08b 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -41,12 +41,13 @@ enum AVHWDeviceType {
 };
 
 /**
- * This struct aggregates all the (hardware/vendor-specific) "high-level" state,
- * i.e. state that is not tied to a concrete processing configuration.
- * E.g., in an API that supports hardware-accelerated encoding and decoding,
- * this struct will (if possible) wrap the state that is common to both encoding
- * and decoding and from which specific instances of encoders or decoders can be
- * derived.
+ * @ref md_doc_2context "Context" for (hardware/vendor-specific) "high-level" state.
+ *
+ * "High-level state" is anything that is not tied to a concrete processing
+ * configuration. E.g., in an API that supports hardware-accelerated encoding
+ * and decoding, this struct will (if possible) wrap the state that is common
+ * to both encoding and decoding and from which specific instances of encoders
+ * or decoders can be derived.
  *
  * This struct is reference-counted with the AVBuffer mechanism. The
  * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field
@@ -103,9 +104,11 @@ typedef struct AVHWDeviceContext {
 } AVHWDeviceContext;
 
 /**
- * This struct describes a set or pool of "hardware" frames (i.e. those with
- * data not located in normal system memory). All the frames in the pool are
- * assumed to be allocated in the same way and interchangeable.
+ * @ref md_doc_2context "context" for a pool of "hardware" frames (those with
+ * data not located in normal system memory)
+ *
+ * All the frames in the pool are assumed to be allocated in the same way and
+ * interchangeable.
  *
  * This struct is reference-counted with the AVBuffer mechanism and tied to a
  * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor
diff --git a/libavutil/hwcontext_cuda.h b/libavutil/hwcontext_cuda.h
index cbad434fea..e259892688 100644
--- a/libavutil/hwcontext_cuda.h
+++ b/libavutil/hwcontext_cuda.h
@@ -37,7 +37,7 @@
 typedef struct AVCUDADeviceContextInternal AVCUDADeviceContextInternal;
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVCUDADeviceContext {
     CUcontext cuda_ctx;
diff --git a/libavutil/hwcontext_d3d11va.h b/libavutil/hwcontext_d3d11va.h
index 77d2d72f1b..101d1cb6f8 100644
--- a/libavutil/hwcontext_d3d11va.h
+++ b/libavutil/hwcontext_d3d11va.h
@@ -40,7 +40,7 @@
 #include <stdint.h>
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVD3D11VADeviceContext {
     /**
@@ -126,7 +126,7 @@ typedef struct AVD3D11FrameDescriptor {
 } AVD3D11FrameDescriptor;
 
 /**
- * This struct is allocated as AVHWFramesContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
  */
 typedef struct AVD3D11VAFramesContext {
     /**
diff --git a/libavutil/hwcontext_d3d12va.h b/libavutil/hwcontext_d3d12va.h
index ff06e6f2ef..c623914c2b 100644
--- a/libavutil/hwcontext_d3d12va.h
+++ b/libavutil/hwcontext_d3d12va.h
@@ -37,7 +37,7 @@
 #include <d3d12video.h>
 
 /**
- * @brief This struct is allocated as AVHWDeviceContext.hwctx
+ * @brief This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  *
  */
 typedef struct AVD3D12VADeviceContext {
@@ -78,7 +78,7 @@ typedef struct AVD3D12VADeviceContext {
 } AVD3D12VADeviceContext;
 
 /**
- * @brief This struct is used to sync d3d12 execution
+ * @brief This @ref md_doc_2context "context" is used to sync d3d12 execution
  *
  */
 typedef struct AVD3D12VASyncContext {
@@ -120,7 +120,7 @@ typedef struct AVD3D12VAFrame {
 } AVD3D12VAFrame;
 
 /**
- * @brief This struct is allocated as AVHWFramesContext.hwctx
+ * @brief This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
  *
  */
 typedef struct AVD3D12VAFramesContext {
diff --git a/libavutil/hwcontext_drm.h b/libavutil/hwcontext_drm.h
index 42709f215e..8329e69966 100644
--- a/libavutil/hwcontext_drm.h
+++ b/libavutil/hwcontext_drm.h
@@ -152,7 +152,7 @@ typedef struct AVDRMFrameDescriptor {
 /**
  * DRM device.
  *
- * Allocated as AVHWDeviceContext.hwctx.
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx.
  */
 typedef struct AVDRMDeviceContext {
     /**
diff --git a/libavutil/hwcontext_dxva2.h b/libavutil/hwcontext_dxva2.h
index e1b79bc0de..c679c16af0 100644
--- a/libavutil/hwcontext_dxva2.h
+++ b/libavutil/hwcontext_dxva2.h
@@ -34,14 +34,14 @@
 #include <dxva2api.h>
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVDXVA2DeviceContext {
     IDirect3DDeviceManager9 *devmgr;
 } AVDXVA2DeviceContext;
 
 /**
- * This struct is allocated as AVHWFramesContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
  */
 typedef struct AVDXVA2FramesContext {
     /**
diff --git a/libavutil/hwcontext_mediacodec.h b/libavutil/hwcontext_mediacodec.h
index fc0263cabc..e81193247b 100644
--- a/libavutil/hwcontext_mediacodec.h
+++ b/libavutil/hwcontext_mediacodec.h
@@ -22,7 +22,7 @@
 /**
  * MediaCodec details.
  *
- * Allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVMediaCodecDeviceContext {
     /**
diff --git a/libavutil/hwcontext_opencl.h b/libavutil/hwcontext_opencl.h
index ef54486c95..7abd97db2b 100644
--- a/libavutil/hwcontext_opencl.h
+++ b/libavutil/hwcontext_opencl.h
@@ -58,7 +58,7 @@ typedef struct AVOpenCLFrameDescriptor {
 /**
  * OpenCL device details.
  *
- * Allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVOpenCLDeviceContext {
     /**
@@ -84,7 +84,7 @@ typedef struct AVOpenCLDeviceContext {
 /**
  * OpenCL-specific data associated with a frame pool.
  *
- * Allocated as AVHWFramesContext.hwctx.
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
  */
 typedef struct AVOpenCLFramesContext {
     /**
diff --git a/libavutil/hwcontext_qsv.h b/libavutil/hwcontext_qsv.h
index e2dba8ad83..b63ebddaef 100644
--- a/libavutil/hwcontext_qsv.h
+++ b/libavutil/hwcontext_qsv.h
@@ -30,7 +30,7 @@
  */
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVQSVDeviceContext {
     mfxSession session;
@@ -48,7 +48,7 @@ typedef struct AVQSVDeviceContext {
 } AVQSVDeviceContext;
 
 /**
- * This struct is allocated as AVHWFramesContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
  */
 typedef struct AVQSVFramesContext {
     mfxFrameSurface1 *surfaces;
diff --git a/libavutil/hwcontext_vaapi.h b/libavutil/hwcontext_vaapi.h
index 0b2e071cb3..4a897eb851 100644
--- a/libavutil/hwcontext_vaapi.h
+++ b/libavutil/hwcontext_vaapi.h
@@ -63,7 +63,7 @@ enum {
 /**
  * VAAPI connection details.
  *
- * Allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVVAAPIDeviceContext {
     /**
@@ -83,7 +83,7 @@ typedef struct AVVAAPIDeviceContext {
 /**
  * VAAPI-specific data associated with a frame pool.
  *
- * Allocated as AVHWFramesContext.hwctx.
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
  */
 typedef struct AVVAAPIFramesContext {
     /**
@@ -105,7 +105,7 @@ typedef struct AVVAAPIFramesContext {
 /**
  * VAAPI hardware pipeline configuration details.
  *
- * Allocated with av_hwdevice_hwconfig_alloc().
+ * This struct is allocated with av_hwdevice_hwconfig_alloc().
  */
 typedef struct AVVAAPIHWConfig {
     /**
diff --git a/libavutil/hwcontext_vdpau.h b/libavutil/hwcontext_vdpau.h
index 1b7ea1e443..e305caa595 100644
--- a/libavutil/hwcontext_vdpau.h
+++ b/libavutil/hwcontext_vdpau.h
@@ -30,7 +30,7 @@
  */
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVVDPAUDeviceContext {
     VdpDevice          device;
diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h
index cbbd2390c1..1869870032 100644
--- a/libavutil/hwcontext_vulkan.h
+++ b/libavutil/hwcontext_vulkan.h
@@ -39,7 +39,7 @@ typedef struct AVVkFrame AVVkFrame;
  */
 
 /**
- * Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
+ * Main Vulkan @ref md_doc_2context "context", allocated as AVHWDeviceContext.hwctx.
  * All of these can be set before init to change what the context uses
  */
 typedef struct AVVulkanDeviceContext {
@@ -172,7 +172,7 @@ typedef enum AVVkFrameFlags {
 } AVVkFrameFlags;
 
 /**
- * Allocated as AVHWFramesContext.hwctx, used to set pool-specific options
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx, used to set pool-specific options
  */
 typedef struct AVVulkanFramesContext {
     /**
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v3 1/3] doc: Explain what "context" means
  2024-04-22 15:56             ` [FFmpeg-devel] [PATCH v3 1/3] doc: Explain what "context" means Andrew Sayers
@ 2024-04-22 17:05               ` Stefano Sabatini
  2024-04-29  9:10                 ` Andrew Sayers
  2024-04-29  9:24                 ` [FFmpeg-devel] [PATCH v4 1/4] " Andrew Sayers
  0 siblings, 2 replies; 39+ messages in thread
From: Stefano Sabatini @ 2024-04-22 17:05 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Andrew Sayers

On date Monday 2024-04-22 16:56:48 +0100, Andrew Sayers wrote:
> Derived from detailed explanations kindly provided by Stefano Sabatini:
> https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325903.html
> ---
>  doc/context.md | 276 +++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 276 insertions(+)
>  create mode 100644 doc/context.md
> 
> diff --git a/doc/context.md b/doc/context.md
> new file mode 100644
> index 0000000000..73caacf54f
> --- /dev/null
> +++ b/doc/context.md
> @@ -0,0 +1,276 @@
> +# Context-oriented programming
> +
> +Like many C projects, FFmpeg has adopted the subset of object-oriented techniques
> +that help solve its problems.  Object-like structures are called "contexts",
> +and this document provides a general introduction to how they work.
> +
> +Object-oriented programming usually focusses on *access* as a primary concern.
> +For example, members of an object are visibly designated "private", "constant"
> +etc. to control how they are accessed.  *Reflection* is a secondary concern,
> +where it is provided at all.  For example, C++ has no built-in way to get a
> +string containing the name of a variable.
> +
> +Reflection is extremely important for FFmpeg, because user-facing options are
> +implemented by reflecting state at runtime. Limiting access is a secondary
> +concern, mainly important for ensuring implementation details can change
> +between versions.
> +
> +An object-oriented programmer learning FFmpeg should be careful not to fixate on
> +FFmpeg's access control features, nor to overlook its reflection capabilities.
> +Both are present, but have been given the level of focus appropriate for the task.
> +
> +## Example: modify text then print it
> +
> +The example below shows a context structure that receives input strings,
> +modifies them in some context-dependant way, then prints them to a specified
> +filehandle.
> +
> +```c
> +/**
> + * Type information, accessible at runtime.
> + *
> + * Useful when configuring objects.
> + */
> +enum ModifyThenPrintDialect {
> +    MODIFY_THEN_PRINT_PLAIN_TEXT = 0,
> +    MODIFY_THEN_PRINT_REGEX      = 1,
> +    MODIFY_THEN_PRINT_REGEX_PCRE = 2
> +};
> +
> +/**
> + * User-facing information about types
> + *
> + * Useful for describing contexts to the user.
> + */
> +static const char* ModifyThenPrintDialectName[] = {
> +    "plain text",
> +    "regular expression",
> +    "Perl-compatible regular expression"
> +};
> +
> +/**
> + * Context for functions that modify strings before printing them
> + */
> +struct ModifyThenPrintContext {
> +
> +    /**
> +     * Information about the type of this particular instance
> +     *
> +     * Object-oriented programs would probably represent this example
> +     * as a sub-class, but some instance-specific functionality
> +     * behaves more like a mixin.
> +     */
> +    enum ModifyThenPrintDialect dialect;
> +
> +    /**
> +     * Internal context
> +     *
> +     * Object-oriented programs would put private members in here,
> +     * but could also use it to store a virtual function table
> +     * or other "invisible" information.
> +     */

> +    void* priv_data;

style:
type *name;

here and below


> +
> +    /**
> +     * User-configurable options
> +     *
> +     * Best set through an API, but can be set directly if necessary
> +     *
> +     * Data from users needs to be validated before it's set, and the API
> +     * might e.g. want to update some internal buffer when these change.
> +     * Setting this directly is always less robust than using an API,
> +     * but might be worthwhile if you're willing to spend the time checking
> +     * for edge cases, and don't mind your code misbehaving if future
> +     * versions change the API but not the structure.
> +     *
> +     * Object-oriented programs would likely make these protected members,
> +     * initialised in a constructor and accessed with getters and setters.
> +     * Making them user-configurable would be left to the programmer.
> +     */
> +    char *replace_this;
> +    char *with_this;
> +
> +    /**
> +     * Programmer-configurable variable
> +     *
> +     * Object-oriented programs would represent this as a public member.
> +     */
> +    FILE *out;
> +
> +};
> +
> +/**
> + * Allocate and initialize a ModifyThenPrintContext
> + *
> + * This creates a new pointer, then fills in some sensible defaults.
> + *
> + * We can reasonably assume this function will initialise `priv_data`
> + * with a dialect-specific object, but shouldn't make any assumptions
> + * about what that object is.
> + *
> + * Object-oriented programs would likely represent this as an
> + * allocator function and a constructor.
> + */
> +int ModifyThenPrintContext_alloc_context(struct ModifyThenPrintContext **ctx,
> +                                         enum ModifyThenPrintDialect dialect,
> +                                         FILE *out);
> +
> +/**
> + * Uninitialize and deallocate a ModifyThenPrintContext
> + *
> + * This does any work required by the internal context (e.g. deallocating
> + * `priv_data`), then deallocates the main context itself.
> + *
> + * Object-oriented programs would likely represent this as a
> + * destructor and a deallocator.
> + */
> +int ModifyThenPrintContext_free(struct ModifyThenPrintContext *ctx);
> +
> +/**
> + * Configure a ModifyThenPrintContext
> + *
> + * This checks the arguments are valid in the context's dialect,
> + * then updates the options as necessary
> + *
> + * Object-oriented programs would likely represent this as a
> + * collection of setter functions.
> + */
> +int ModifyThenPrintContext_configure(struct ModifyThenPrintContext *ctx,
> +                                     char* replace_this,
> +                                     char* with_this);
> +
> +/**
> + * Print the contents of a ModifyThenPrintContext to a filehandle
> + *
> + * Provides human-readable information about keys and values.
> + *
> + * Object-oriented programs would likely represent this with some kind of
> + * `serialise` operation.
> + */
> +int ModifyThenPrintContext_dump(struct ModifyThenPrintContext **ctx,
> +                                FILE *dump_fh);
> +
> +/**
> + * Print a single message
> + *
> + * Object-oriented programs would likely represent this with a member function.
> + */
> +int ModifyThenPrintContext_print(struct ModifyThenPrintContext *ctx,
> +                                 char *msg);
> +
> +/**
> + * How this context might be used in practice
> + */
> +int print_hello_world()
> +{
> +
> +    int ret = 0;
> +
> +    struct ModifyThenPrintContext *ctx;
> +
> +    if ( ModifyThenPrintContext_alloc_context( &ctx, MODIFY_THEN_PRINT_REGEX, stdout ) < 0 ) {
> +        ret = -1;
> +        goto EXIT_WITHOUT_CLEANUP;
> +    }
> +
> +    if ( ModifyThenPrintContext_configure(ctx, "Hi|Hullo", "Hello") < 0 ) {
> +        ret = -1;
> +        goto FINISH;
> +    }
> +
> +    if ( ModifyThenPrintContext_print( ctx, "Hi, world!\n" ) < 0 ) {
> +        ret = -1;
> +        goto FINISH;
> +    }
> +
> +    if ( ModifyThenPrintContext_print( ctx, "Hullo, world!\n" ) < 0 ) {
> +        ret = -1;
> +        goto FINISH;
> +    }
> +
> +    FINISH:
> +    if ( ModifyThenPrintContext_free( ctx ) ) {
> +        ret = -1;
> +        goto EXIT_WITHOUT_CLEANUP;
> +    }
> +
> +    EXIT_WITHOUT_CLEANUP:
> +    return ret;
> +
> +}
> +```

I don't have a strong opinion, but I'd probably focus on providing a
typical example of a common API (check doc/examples). Also I see here
there is a strong focus on OOP, this might be counter-productive in
case the reader is not familiar with OOP terminology.

OTOH the content might be useful for readers coming from an OOP
background and terminology. I wonder if this content might be isolated
in a dedicated section, so that non-OOP readers can simply skip it.

But this is not a strong objection, and can be possibly reworked in a
later step.

> +
> +## FFmpeg context structures
> +
> +The example above is a generic example of a context structure and its
> +associated functions.  Some FFmpeg contexts are no more complex than
> +that example, just as some objects are just key/value stores with some
> +functions attached.  But here are some examples to show the variety of
> +contexts available in FFmpeg.
> +
> +AVHashContext presents a generic API for hashing data.  @ref hash.h
> +"Its associated functions" show how to create, use and destroy a hash.
> +The exact algorithm is specified by passing a string to av_hash_alloc(),
> +and the list of strings can be retrieved from av_hash_names().
> +Algorithm-specific internal context is stored in AVHashContext::ctx.
> +
> +AVCodecContext is a complex member representing data about an encoding or
> +decoding session.  @ref avcodec.h "Its associated functions" provide an
> +abstract interface to encode and decode data.  Like most widely-used contexts,
> +its first member is an AVClass pointer containing instance-specific information.
> +That means it's an *AVClass context structure* (discussed in more detail below).
> +
> +X264Context contains the internal context for an AVCodecContext that uses
> +the x264 library.  @ref libx264.c "Its associated functions" provide a concrete

> +implementation for interacting with libx264.  This class is not directly
> +accessible through FFmpeg's public interface, so unlike AVCodecContext it can
> +change significantly between releases.

Note: still, we are not supposed to break compatibilty, for example by
changing the private option names, or this will break both scripts
using the ff* tools and applications using the libav* libraries, since
they refer to those option names. In other words, the options names
provide the public API to interact with a specific codec.

> +## Reflection with AVClass and AVOptions
> +
> +An *AVClass context structure* is a context whose first member is an AVClass
> +that reflects its contents.  An *@ref avoptions "AVOptions"-enabled struct*
> +is a structure which reflects its contents using the @ref avoptions "AVOptions"
> +API.

"reflects its contents" is a bit too strong, we want only to be able
to set and query options on such structures. In some cases the
AVOptions API is abused also to get "properties" from the structures
(see for example the "location" option in libavformation/http.c). But
the whole content in general is not available through AVOptions, only
a specific subset which is supposed to configure the structure.

> These terms have become synonymous in modern usage, but you might notice
> +some distinction when looking at code written after AVClass was developed but
> +before @ref avoptions "AVOptions" was added.
> +
> +At first glance, an object-oriented programmer might be tempted to look at AVClass
> +as a base class that contexts inherit from.  But unlike a base class, an AVClass
> +doesn't imply any theoretical relationship between objects, and contexts of the
> +same type will often have different AVClass values.  It's even theoretically possible
> +for a single AVClass to be shared between contexts of different types.  A better
> +analogy would be to [C++ concepts](https://en.wikipedia.org/wiki/Concepts_(C%2B%2B))
> +or [Java interfaces](https://en.wikipedia.org/wiki/Interface_(Java)).
> +
> +To understand how AVClass and @ref avoptions "AVOptions" work,
> +consider the requirements for a `libx264` encoder:
> +
> +- it has to support common encoder options like "bitrate"

> +- it has to support encoder-specific options like "profile"

> +  - the exact options could change quickly if a legal ruling forces a change of backend

but this will be a compatiblity break for most applications and
scripts (you will notice in this case because people will complain
aloud about the breakage), so we need to be careful when changing
options following the usual deprecation dance

> +- it has to provide useful feedback to users about unsupported options
> +
> +Common encoder options like "bitrate" need to be stored in AVCodecContext itself
> +to avoid duplicating code, while encoder-specific options like "profile" have to
> +be stored in the X264Context instance stored in AVCodecContext::priv_data.

> +But both need to be presented to users (along with help text, default values etc.)
> +in a way that makes it easy to build user interfaces to get and set those options.

nit: s/easy/possible/

> +
> +A context's AVClass member contains a list of AVOption objects, describing
> +the user-configurable members of the class.  It also contains functions to
> +iterate through a tree of AVClass objects representing internal context either
> +for the current object or for any class that could potentially exist in the
> +current version of FFmpeg.
> +
> +The @ref avoptions "AVOptions" API accepts any AVClass context structure,
> +looks through its AVOption data, and uses that to examine, introspect, and modify
> +the structure.  Because the API doesn't contain any type-specific information,
> +it can be used to create a general user interface that adapts automatically
> +when e.g. a new version of FFmpeg adds a new configuration option.
> +
> +## Summary
> +

> +FFmpeg uses "contexts" in ways that are often resemble object-oriented programming.
> +But it focuses less on encapsulation within arbitrarily complex systems,
> +and more on providing reflectivity to make pleasant user interfaces.

nit++: s/pleasant//, here the point is to make them possible, we don't
know if they are pleasant :-)

[...]

Note: I'll be probably offline for one week or so.
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v3 1/3] doc: Explain what "context" means
  2024-04-22 17:05               ` Stefano Sabatini
@ 2024-04-29  9:10                 ` Andrew Sayers
  2024-05-02 10:03                   ` Andrew Sayers
  2024-05-05  7:29                   ` Stefano Sabatini
  2024-04-29  9:24                 ` [FFmpeg-devel] [PATCH v4 1/4] " Andrew Sayers
  1 sibling, 2 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-04-29  9:10 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Mon, Apr 22, 2024 at 07:05:12PM +0200, Stefano Sabatini wrote:
> On date Monday 2024-04-22 16:56:48 +0100, Andrew Sayers wrote:
> > Derived from detailed explanations kindly provided by Stefano Sabatini:
> > https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325903.html
> > ---
> >  doc/context.md | 276 +++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 276 insertions(+)
> >  create mode 100644 doc/context.md
> > 
> > diff --git a/doc/context.md b/doc/context.md
> > new file mode 100644
> > index 0000000000..73caacf54f
> > --- /dev/null
> > +++ b/doc/context.md
> > @@ -0,0 +1,276 @@
> > +# Context-oriented programming
> > +
> > +Like many C projects, FFmpeg has adopted the subset of object-oriented techniques
> > +that help solve its problems.  Object-like structures are called "contexts",
> > +and this document provides a general introduction to how they work.
> > +
> > +Object-oriented programming usually focusses on *access* as a primary concern.
> > +For example, members of an object are visibly designated "private", "constant"
> > +etc. to control how they are accessed.  *Reflection* is a secondary concern,
> > +where it is provided at all.  For example, C++ has no built-in way to get a
> > +string containing the name of a variable.
> > +
> > +Reflection is extremely important for FFmpeg, because user-facing options are
> > +implemented by reflecting state at runtime. Limiting access is a secondary
> > +concern, mainly important for ensuring implementation details can change
> > +between versions.
> > +
> > +An object-oriented programmer learning FFmpeg should be careful not to fixate on
> > +FFmpeg's access control features, nor to overlook its reflection capabilities.
> > +Both are present, but have been given the level of focus appropriate for the task.
> > +
> > +## Example: modify text then print it
> > +
> > +The example below shows a context structure that receives input strings,
> > +modifies them in some context-dependant way, then prints them to a specified
> > +filehandle.
> > +
> > +```c
> > +/**
> > + * Type information, accessible at runtime.
> > + *
> > + * Useful when configuring objects.
> > + */
> > +enum ModifyThenPrintDialect {
> > +    MODIFY_THEN_PRINT_PLAIN_TEXT = 0,
> > +    MODIFY_THEN_PRINT_REGEX      = 1,
> > +    MODIFY_THEN_PRINT_REGEX_PCRE = 2
> > +};
> > +
> > +/**
> > + * User-facing information about types
> > + *
> > + * Useful for describing contexts to the user.
> > + */
> > +static const char* ModifyThenPrintDialectName[] = {
> > +    "plain text",
> > +    "regular expression",
> > +    "Perl-compatible regular expression"
> > +};
> > +
> > +/**
> > + * Context for functions that modify strings before printing them
> > + */
> > +struct ModifyThenPrintContext {
> > +
> > +    /**
> > +     * Information about the type of this particular instance
> > +     *
> > +     * Object-oriented programs would probably represent this example
> > +     * as a sub-class, but some instance-specific functionality
> > +     * behaves more like a mixin.
> > +     */
> > +    enum ModifyThenPrintDialect dialect;
> > +
> > +    /**
> > +     * Internal context
> > +     *
> > +     * Object-oriented programs would put private members in here,
> > +     * but could also use it to store a virtual function table
> > +     * or other "invisible" information.
> > +     */
> 
> > +    void* priv_data;
> 
> style:
> type *name;
> 
> here and below
> 
> 
> > +
> > +    /**
> > +     * User-configurable options
> > +     *
> > +     * Best set through an API, but can be set directly if necessary
> > +     *
> > +     * Data from users needs to be validated before it's set, and the API
> > +     * might e.g. want to update some internal buffer when these change.
> > +     * Setting this directly is always less robust than using an API,
> > +     * but might be worthwhile if you're willing to spend the time checking
> > +     * for edge cases, and don't mind your code misbehaving if future
> > +     * versions change the API but not the structure.
> > +     *
> > +     * Object-oriented programs would likely make these protected members,
> > +     * initialised in a constructor and accessed with getters and setters.
> > +     * Making them user-configurable would be left to the programmer.
> > +     */
> > +    char *replace_this;
> > +    char *with_this;
> > +
> > +    /**
> > +     * Programmer-configurable variable
> > +     *
> > +     * Object-oriented programs would represent this as a public member.
> > +     */
> > +    FILE *out;
> > +
> > +};
> > +
> > +/**
> > + * Allocate and initialize a ModifyThenPrintContext
> > + *
> > + * This creates a new pointer, then fills in some sensible defaults.
> > + *
> > + * We can reasonably assume this function will initialise `priv_data`
> > + * with a dialect-specific object, but shouldn't make any assumptions
> > + * about what that object is.
> > + *
> > + * Object-oriented programs would likely represent this as an
> > + * allocator function and a constructor.
> > + */
> > +int ModifyThenPrintContext_alloc_context(struct ModifyThenPrintContext **ctx,
> > +                                         enum ModifyThenPrintDialect dialect,
> > +                                         FILE *out);
> > +
> > +/**
> > + * Uninitialize and deallocate a ModifyThenPrintContext
> > + *
> > + * This does any work required by the internal context (e.g. deallocating
> > + * `priv_data`), then deallocates the main context itself.
> > + *
> > + * Object-oriented programs would likely represent this as a
> > + * destructor and a deallocator.
> > + */
> > +int ModifyThenPrintContext_free(struct ModifyThenPrintContext *ctx);
> > +
> > +/**
> > + * Configure a ModifyThenPrintContext
> > + *
> > + * This checks the arguments are valid in the context's dialect,
> > + * then updates the options as necessary
> > + *
> > + * Object-oriented programs would likely represent this as a
> > + * collection of setter functions.
> > + */
> > +int ModifyThenPrintContext_configure(struct ModifyThenPrintContext *ctx,
> > +                                     char* replace_this,
> > +                                     char* with_this);
> > +
> > +/**
> > + * Print the contents of a ModifyThenPrintContext to a filehandle
> > + *
> > + * Provides human-readable information about keys and values.
> > + *
> > + * Object-oriented programs would likely represent this with some kind of
> > + * `serialise` operation.
> > + */
> > +int ModifyThenPrintContext_dump(struct ModifyThenPrintContext **ctx,
> > +                                FILE *dump_fh);
> > +
> > +/**
> > + * Print a single message
> > + *
> > + * Object-oriented programs would likely represent this with a member function.
> > + */
> > +int ModifyThenPrintContext_print(struct ModifyThenPrintContext *ctx,
> > +                                 char *msg);
> > +
> > +/**
> > + * How this context might be used in practice
> > + */
> > +int print_hello_world()
> > +{
> > +
> > +    int ret = 0;
> > +
> > +    struct ModifyThenPrintContext *ctx;
> > +
> > +    if ( ModifyThenPrintContext_alloc_context( &ctx, MODIFY_THEN_PRINT_REGEX, stdout ) < 0 ) {
> > +        ret = -1;
> > +        goto EXIT_WITHOUT_CLEANUP;
> > +    }
> > +
> > +    if ( ModifyThenPrintContext_configure(ctx, "Hi|Hullo", "Hello") < 0 ) {
> > +        ret = -1;
> > +        goto FINISH;
> > +    }
> > +
> > +    if ( ModifyThenPrintContext_print( ctx, "Hi, world!\n" ) < 0 ) {
> > +        ret = -1;
> > +        goto FINISH;
> > +    }
> > +
> > +    if ( ModifyThenPrintContext_print( ctx, "Hullo, world!\n" ) < 0 ) {
> > +        ret = -1;
> > +        goto FINISH;
> > +    }
> > +
> > +    FINISH:
> > +    if ( ModifyThenPrintContext_free( ctx ) ) {
> > +        ret = -1;
> > +        goto EXIT_WITHOUT_CLEANUP;
> > +    }
> > +
> > +    EXIT_WITHOUT_CLEANUP:
> > +    return ret;
> > +
> > +}
> > +```
> 
> I don't have a strong opinion, but I'd probably focus on providing a
> typical example of a common API (check doc/examples). Also I see here
> there is a strong focus on OOP, this might be counter-productive in
> case the reader is not familiar with OOP terminology.
> 
> OTOH the content might be useful for readers coming from an OOP
> background and terminology. I wonder if this content might be isolated
> in a dedicated section, so that non-OOP readers can simply skip it.
> 
> But this is not a strong objection, and can be possibly reworked in a
> later step.
> 

This is really a document for FFmpeg newbies, so we need to assume as
little prior knowledge as possible.  After a few days to think it
over, I think we should avoid assuming...

Knowledge of object-oriented programming.  For example, this should be
useful to a research mathematician with a project that involves codec
algorithms.  So the next draft should feel less like "FFmpeg for OOP
devs" and more like "FFmpeg for newbies (with some optional OOP
background reading)".

Knowing that programming doesn't *have* to be object-oriented.
OOP has become so ubiquitous nowadays, there are plenty of programmers
who will insist everything is OOP if you just speak loudly and slowly.
This is a harder problem in some ways, because someone who doesn't
understand can always re-read until they do, while someone who jumps
to the wrong conclusion will just keep reading and try to make things
fit their assumption (e.g. my earlier messages in this thread!).
So the "how it differs from OOP" stuff needs to stay fairly prominent.

Knowing anything about FFmpeg (or multimedia in general).  I like the
idea of tweaking `doc/examples` to better introduce FFmpeg
fundamentals, but explaining "context" is a steep enough learning
curve on its own - introducing concepts like "stream" and "codec" at
the same time seems like too much.

> > +
> > +## FFmpeg context structures
> > +
> > +The example above is a generic example of a context structure and its
> > +associated functions.  Some FFmpeg contexts are no more complex than
> > +that example, just as some objects are just key/value stores with some
> > +functions attached.  But here are some examples to show the variety of
> > +contexts available in FFmpeg.
> > +
> > +AVHashContext presents a generic API for hashing data.  @ref hash.h
> > +"Its associated functions" show how to create, use and destroy a hash.
> > +The exact algorithm is specified by passing a string to av_hash_alloc(),
> > +and the list of strings can be retrieved from av_hash_names().
> > +Algorithm-specific internal context is stored in AVHashContext::ctx.
> > +
> > +AVCodecContext is a complex member representing data about an encoding or
> > +decoding session.  @ref avcodec.h "Its associated functions" provide an
> > +abstract interface to encode and decode data.  Like most widely-used contexts,
> > +its first member is an AVClass pointer containing instance-specific information.
> > +That means it's an *AVClass context structure* (discussed in more detail below).
> > +
> > +X264Context contains the internal context for an AVCodecContext that uses
> > +the x264 library.  @ref libx264.c "Its associated functions" provide a concrete
> 
> > +implementation for interacting with libx264.  This class is not directly
> > +accessible through FFmpeg's public interface, so unlike AVCodecContext it can
> > +change significantly between releases.
> 
> Note: still, we are not supposed to break compatibilty, for example by
> changing the private option names, or this will break both scripts
> using the ff* tools and applications using the libav* libraries, since
> they refer to those option names. In other words, the options names
> provide the public API to interact with a specific codec.
> 
> > +## Reflection with AVClass and AVOptions
> > +
> > +An *AVClass context structure* is a context whose first member is an AVClass
> > +that reflects its contents.  An *@ref avoptions "AVOptions"-enabled struct*
> > +is a structure which reflects its contents using the @ref avoptions "AVOptions"
> > +API.
> 
> "reflects its contents" is a bit too strong, we want only to be able
> to set and query options on such structures. In some cases the
> AVOptions API is abused also to get "properties" from the structures
> (see for example the "location" option in libavformation/http.c). But
> the whole content in general is not available through AVOptions, only
> a specific subset which is supposed to configure the structure.
> 
> > These terms have become synonymous in modern usage, but you might notice
> > +some distinction when looking at code written after AVClass was developed but
> > +before @ref avoptions "AVOptions" was added.
> > +
> > +At first glance, an object-oriented programmer might be tempted to look at AVClass
> > +as a base class that contexts inherit from.  But unlike a base class, an AVClass
> > +doesn't imply any theoretical relationship between objects, and contexts of the
> > +same type will often have different AVClass values.  It's even theoretically possible
> > +for a single AVClass to be shared between contexts of different types.  A better
> > +analogy would be to [C++ concepts](https://en.wikipedia.org/wiki/Concepts_(C%2B%2B))
> > +or [Java interfaces](https://en.wikipedia.org/wiki/Interface_(Java)).
> > +
> > +To understand how AVClass and @ref avoptions "AVOptions" work,
> > +consider the requirements for a `libx264` encoder:
> > +
> > +- it has to support common encoder options like "bitrate"
> 
> > +- it has to support encoder-specific options like "profile"
> 
> > +  - the exact options could change quickly if a legal ruling forces a change of backend
> 
> but this will be a compatiblity break for most applications and
> scripts (you will notice in this case because people will complain
> aloud about the breakage), so we need to be careful when changing
> options following the usual deprecation dance
> 
> > +- it has to provide useful feedback to users about unsupported options
> > +
> > +Common encoder options like "bitrate" need to be stored in AVCodecContext itself
> > +to avoid duplicating code, while encoder-specific options like "profile" have to
> > +be stored in the X264Context instance stored in AVCodecContext::priv_data.
> 
> > +But both need to be presented to users (along with help text, default values etc.)
> > +in a way that makes it easy to build user interfaces to get and set those options.
> 
> nit: s/easy/possible/
> 
> > +
> > +A context's AVClass member contains a list of AVOption objects, describing
> > +the user-configurable members of the class.  It also contains functions to
> > +iterate through a tree of AVClass objects representing internal context either
> > +for the current object or for any class that could potentially exist in the
> > +current version of FFmpeg.
> > +
> > +The @ref avoptions "AVOptions" API accepts any AVClass context structure,
> > +looks through its AVOption data, and uses that to examine, introspect, and modify
> > +the structure.  Because the API doesn't contain any type-specific information,
> > +it can be used to create a general user interface that adapts automatically
> > +when e.g. a new version of FFmpeg adds a new configuration option.
> > +
> > +## Summary
> > +
> 
> > +FFmpeg uses "contexts" in ways that are often resemble object-oriented programming.
> > +But it focuses less on encapsulation within arbitrarily complex systems,
> > +and more on providing reflectivity to make pleasant user interfaces.
> 
> nit++: s/pleasant//, here the point is to make them possible, we don't
> know if they are pleasant :-)

Comments above should be reflected in a patch I'll send after writing this.
The patch also adds more links from the code, because I noticed doxygen was
replacing all "Context for foo" comments with links to some private struct
that happened to be called "Context".

I've also gone through the code looking for edge cases we haven't covered.
Here are some questions trying to prompt an "oh yeah I forgot to mention
that"-type answer.  Anything where the answer is more like "that should
probably be rewritten to be clearer", let me know and I'll avoid confusing
newbies with it.

av_ambient_viewing_environment_create_side_data() takes an AVFrame as its
first argument, and returns a new AVAmbientViewingEnvironment.  What is the
context object for that function - AVFrame or AVAmbientViewingEnvironment?

av_register_bitstream_filter() (deprecated 4.0, removed 5.0) took an
`AVBitStreamFilter *` as its first argument, but I don't think you'd say
the argument provided "context" for the function.  So would I be right in
saying `AVBitStreamFilter *` is not a context, despite looking like one?

av_buffersink_*() all take a `const AVFilterContext *` argument.
What does the difference between av_buffersink prefix and AVFilter type mean?

av_channel_description_bprint() takes a `struct AVBPrint *` as its first
argument, then `enum AVChannel`.  Is the context AVBPrint, AVChannel,
or both?  Does it make sense for a function to have two contexts?

Related to the previous question, does `av_cmp_q()` count as a function
with two contexts?  Or no contexts?

Finally, a general question - functions of the form "avfoo" seem like they
are more consistent than "av_foo".  Does the underscore mean anything?
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v4 1/4] doc: Explain what "context" means
  2024-04-22 17:05               ` Stefano Sabatini
  2024-04-29  9:10                 ` Andrew Sayers
@ 2024-04-29  9:24                 ` Andrew Sayers
  2024-04-29  9:24                   ` [FFmpeg-devel] [PATCH v4 2/4] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
                                     ` (3 more replies)
  1 sibling, 4 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-04-29  9:24 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

Derived from detailed explanations kindly provided by Stefano Sabatini:
https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325903.html
---
 doc/context.md | 308 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 308 insertions(+)
 create mode 100644 doc/context.md

diff --git a/doc/context.md b/doc/context.md
new file mode 100644
index 0000000000..73297f53aa
--- /dev/null
+++ b/doc/context.md
@@ -0,0 +1,308 @@
+# Introduction to contexts
+
+Like many C projects, FFmpeg has adopted the subset of
+[object-oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming)
+techniques that help solve its problems.  Object-like structures are called "contexts",
+and this document provides a general introduction to how they work.
+
+Object-oriented programming tends to focus on
+[access](https://en.wikipedia.org/wiki/Access_modifiers) as a primary concern.
+For example, members of a class are often designated "private" to indicate
+they are only accessible to code that's part of the class.  Less focus is put on
+[reflection](https://en.wikipedia.org/wiki/Reflection_(computer_programming)),
+where it is provided at all.  For example, C++ has no built-in way to serialize
+the state of an arbitrary object.
+
+Reflection is extremely important for FFmpeg, because user-facing
+options are implemented by reflecting the state of contexts.  Limiting
+access is a secondary concern, mainly important for ensuring
+implementation details can change between versions.
+
+Knowledge of object-oriented programming concepts can help when learning FFmpeg,
+but it's important not to fixate on FFmpeg's access control features,
+nor to overlook its reflection capabilities.  This document compares
+FFmpeg and OOP techniques where relevant, but does not require an understanding
+of object-oriented programming.
+
+## Example: modify text then print it
+
+The example below shows a context structure that receives input strings,
+modifies them in some context-dependant way, then prints them to a specified
+filehandle.
+
+```c
+/**
+ * Type information, accessible at runtime.
+ *
+ * Useful when configuring objects.
+ */
+enum ModifyThenPrintDialect {
+    MODIFY_THEN_PRINT_DIALECT_PLAIN_TEXT = 0,
+    MODIFY_THEN_PRINT_DIALECT_REGEX      = 1,
+    MODIFY_THEN_PRINT_DIALECT_REGEX_PCRE = 2
+};
+
+/**
+ * User-facing information about types
+ *
+ * Useful for describing contexts to the user.
+ */
+static const char *ModifyThenPrintDialectName[] = {
+    "plain text",
+    "regular expression",
+    "Perl-compatible regular expression"
+};
+
+/**
+ * Context for functions that modify strings before printing them
+ */
+struct ModifyThenPrintContext {
+
+    /**
+     * Information about the type of this particular instance
+     *
+     * Object-oriented programs would probably replace this with "sub-classes",
+     * where each class extends the base class to implement one dialect.
+     * But information about a type can also work more like "mixins",
+     * where several pieces of unrelated functionality are blended together
+     * to create an interface for a specific purpose.
+     */
+    enum ModifyThenPrintDialect dialect;
+
+    /**
+     * Internal context
+     *
+     * Contains anything that isn't part of the public interface.
+     * The most obvious OOP analogy is to "private" members that are only
+     * accessible to code that's part of the class.  But it could also contain
+     * information about "virtual functions" - functions that every sub-class
+     * guarantees to implement, but in their own class-specific way.
+     */
+    void *priv_data;
+
+    /**
+     * User-configurable options
+     *
+     * Best set through an API, but can be set directly if necessary
+     *
+     * Data from users needs to be validated before it's set, and the API
+     * might e.g. want to update some internal buffer for performance reasons.
+     * Setting these directly is always less robust than using an API,
+     * but might be worthwhile if you're willing to spend the time checking
+     * for edge cases, and don't mind your code misbehaving if future
+     * versions change the API but not the structure.
+     *
+     * Object-oriented programs would likely make these "protected" members,
+     * initialised in a constructor and accessed with getters and setters.
+     * That means code *related* to this class can access them directly,
+     * while unrelated code accesses them indirectly by calling functions.
+     *
+     * But the "protected access" analogy is quite limited. In particular,
+     * protected members don't have any special reflective properties,
+     * whereas FFmpeg options are usually configurable by end users.
+     */
+    char *replace_this;
+    char *with_this;
+
+    /**
+     * Programmer-configurable variable
+     *
+     * Object-oriented programs would represent this as a public member.
+     */
+    FILE *out;
+
+};
+
+/**
+ * Allocate and initialize a ModifyThenPrintContext
+ *
+ * Creates a new pointer, then fills in some sensible defaults.
+ *
+ * We can reasonably assume this function will initialise `priv_data`
+ * with a dialect-specific object, but shouldn't make any assumptions
+ * about what that object is.
+ *
+ * Object-oriented programs would likely implement this with "allocator"
+ * and "constructor" functions, (i.e. separate functions that reserve memory
+ * for an object and set its initial values).
+ */
+int ModifyThenPrintContext_alloc_context(struct ModifyThenPrintContext **ctx,
+                                         enum ModifyThenPrintDialect dialect,
+                                         FILE *out);
+
+/**
+ * Uninitialize and deallocate a ModifyThenPrintContext
+ *
+ * Does any work required by the internal context (e.g. deallocating
+ * `priv_data`), then deallocates the main context itself.
+ *
+ * Object-oriented programs would likely implement this with
+ * destructor and deallocator functions (i.e. separate functions
+ * that do the opposite of the allocator and constructor above).
+ */
+int ModifyThenPrintContext_free(struct ModifyThenPrintContext *ctx);
+
+/**
+ * Configure a ModifyThenPrintContext
+ *
+ * Checks that the arguments are valid in the context's dialect,
+ * then updates the options as necessary
+ *
+ * Object-oriented programs would likely represent this as a
+ * pair of "setter" functions (functions whose only job is to
+ * validate and update a value).
+ */
+int ModifyThenPrintContext_configure(struct ModifyThenPrintContext *ctx,
+                                     char *replace_this,
+                                     char *with_this);
+
+/**
+ * Print a single message
+ *
+ * Object-oriented programs would likely represent this with an ordinary
+ * member function (a function called like `context->function(...)`
+ * instead of `function( context, ... )`).
+ */
+int ModifyThenPrintContext_print(struct ModifyThenPrintContext *ctx,
+                                 char *msg);
+
+/**
+ * Print the contents of a ModifyThenPrintContext to a filehandle
+ *
+ * Provides human-readable information about keys and values.
+ *
+ * Object-oriented programs would likely represent this with some kind of
+ * `serialize` function (a function that iterates through all members,
+ * printing each one's name and contents to the file).  These can be member
+ * functions, but in practice many languages implement it some other way -
+ * an example of the lack of focus on reflection in object-oriented languages.
+ */
+int ModifyThenPrintContext_dump(struct ModifyThenPrintContext **ctx,
+                                FILE *dump_fh);
+
+/**
+ * How this context might be used in practice
+ */
+int print_hello_world()
+{
+
+    int ret = 0;
+
+    struct ModifyThenPrintContext *ctx;
+
+    if ( ModifyThenPrintContext_alloc_context( &ctx, MODIFY_THEN_PRINT_DIALECT_REGEX, stdout ) < 0 ) {
+        ret = -1;
+        goto EXIT_WITHOUT_CLEANUP;
+    }
+
+    if ( ModifyThenPrintContext_configure(ctx, "Hi|Hullo", "Hello") < 0 ) {
+        ret = -1;
+        goto FINISH;
+    }
+
+    if ( ModifyThenPrintContext_print( ctx, "Hi, world!\n" ) < 0 ) {
+        ret = -1;
+        goto FINISH;
+    }
+
+    if ( ModifyThenPrintContext_print( ctx, "Hullo, world!\n" ) < 0 ) {
+        ret = -1;
+        goto FINISH;
+    }
+
+    FINISH:
+    if ( ModifyThenPrintContext_free( ctx ) ) {
+        ret = -1;
+        goto EXIT_WITHOUT_CLEANUP;
+    }
+
+    EXIT_WITHOUT_CLEANUP:
+    return ret;
+
+}
+```
+
+## FFmpeg context structures
+
+The example above shows a generic context structure and its associated
+functions.  Some FFmpeg contexts are no more complex than that example,
+just as some objects are just key/value stores with some functions attached.
+But here are some examples to show the variety of contexts available in FFmpeg.
+
+AVHashContext presents a generic API for hashing data.  @ref hash.h
+"Its associated functions" show how to create, use and destroy a hash.
+The exact algorithm is specified by passing a string to av_hash_alloc(),
+and the list of strings can be retrieved from av_hash_names().
+Algorithm-specific internal context is stored in AVHashContext::ctx.
+
+AVCodecContext is a complex context representing data about an encoding or
+decoding session.  @ref avcodec.h "Its associated functions" provide an
+abstract interface to encode and decode data.  Like most widely-used contexts,
+its first member is an AVClass pointer containing instance-specific information.
+That means it's an *AVClass context structure* (discussed below).
+
+X264Context contains the internal context for an AVCodecContext that uses
+the x264 library.  @ref libx264.c "Its associated functions" provide a concrete
+implementation for interacting with libx264.  This class is not directly
+accessible through FFmpeg's public interface, so it's easier to change
+X264Context than to change AVCodecContext between releases.
+
+## Reflection with AVClass and AVOptions
+
+AVClass is a struct containing general information about a context.
+It's a generic version of `ModifyThenPrintDialect` in the example.
+An *AVClass context structure* is a context whose first member
+is an AVClass that reflects the context's interface.
+
+AVOption is a struct containing information about a member of a context,
+or of an internal context.  `replace_this` and `with_this` in the example
+would echa have an associated AVOption value stored in the context's AVClass.
+An *@ref avoptions "AVOptions"-enabled struct* is a structure which reflects
+its contents using the @ref avoptions "AVOptions" API.
+
+The terms *AVClass context structure* and *@ref avoptions "AVOptions"-enabled
+struct* have become synonymous in modern usage, although you might notice some
+distinction when looking at code written after AVClass was developed but
+before @ref avoptions "AVOptions" was added.
+
+Even though the name "AVClass" implies an analogy to an object-oriented
+base [class](https://en.wikipedia.org/wiki/Class_(computer_programming)), they
+behave more like [C++ concepts](https://en.wikipedia.org/wiki/Concepts_(C%2B%2B))
+or [Java interfaces](https://en.wikipedia.org/wiki/Interface_(Java)).  Unlike a
+base class, an AVClass doesn't imply any theoretical relationship between objects,
+and contexts of the same type will often have different AVClass values.  It's even
+theoretically possible for a single AVClass to be shared between contexts of
+different types.
+
+To understand how AVClass and @ref avoptions "AVOptions" work,
+consider the requirements for a `libx264` encoder:
+
+- it has to support common encoder options like "bitrate"
+- it has to support encoder-specific options like "profile"
+  - the exact options could change quickly if a legal ruling forces a change of backend
+- it must not expose implementation details (e.g. its encoding buffer)
+  - otherwise, trivial improvements would force an increase of the major API version
+- it has to provide useful feedback to users about unsupported options
+
+Common encoder options like "bitrate" need to be stored in AVCodecContext itself
+to avoid duplicating code, while encoder-specific options like "profile" have to
+be stored in the X264Context instance stored in AVCodecContext::priv_data.
+But both need to be presented to users (along with help text, default values etc.)
+in a way that makes it practical to build user interfaces to get and set those options.
+
+A context's AVClass contains a list of AVOption members, describing the
+user-configurable options in the class.  It also contains a tree of further AVClass
+members that represent internal context either for the current object or for any
+object of the same type that could potentially exist in the current version of FFmpeg.
+
+The @ref avoptions "AVOptions" API accepts any AVClass context structure,
+looks through its AVOption data, and uses that to examine, introspect, and modify
+the structure.  Because the API doesn't contain any type-specific information,
+it can be used to create a general user interface that adapts automatically
+when e.g. a new version of FFmpeg adds a new configuration option.
+
+## Summary
+
+FFmpeg uses "contexts" in ways that often resemble object-oriented programming.
+But it focuses less on encapsulation within arbitrarily complex systems,
+and more on providing reflectivity to make good user interfaces.
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v4 2/4] lavu: Clarify relationship between AVClass, AVOption and context
  2024-04-29  9:24                 ` [FFmpeg-devel] [PATCH v4 1/4] " Andrew Sayers
@ 2024-04-29  9:24                   ` Andrew Sayers
  2024-04-29  9:24                   ` [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation Andrew Sayers
                                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-04-29  9:24 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

---
 libavutil/log.h | 11 ++++++++---
 libavutil/opt.h |  7 ++++---
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/libavutil/log.h b/libavutil/log.h
index ab7ceabe22..cfbf416679 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -59,9 +59,14 @@ typedef enum {
 struct AVOptionRanges;
 
 /**
- * Describe the class of an AVClass context structure. That is an
- * arbitrary struct of which the first field is a pointer to an
- * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).
+ * Metadata about an arbitrary data structure
+ *
+ * A @ref md_doc_2context "context struct" whose first member is a pointer
+ * to an AVClass object is called an "AVClass context structure"
+ * (e.g. AVCodecContext, AVFormatContext etc.).
+ *
+ * AVClass is often combined with @ref avoptions "AVOptions" to create
+ * "AVOptions-enabled structs" that can be easily configured by users.
  */
 typedef struct AVClass {
     /**
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 855e363091..82ac933a2a 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -39,9 +39,10 @@
  * @defgroup avoptions AVOptions
  * @ingroup lavu_data
  * @{
- * AVOptions provide a generic system to declare options on arbitrary structs
- * ("objects"). An option can have a help text, a type and a range of possible
- * values. Options may then be enumerated, read and written to.
+ * Builds on AVClass, adding a generic system to declare options.
+ *
+ * An option can have a help text, a type and a range of possible values.
+ * Options may then be enumerated, read and written to.
  *
  * There are two modes of access to members of AVOption and its child structs.
  * One is called 'native access', and refers to access from the code that
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation
  2024-04-29  9:24                 ` [FFmpeg-devel] [PATCH v4 1/4] " Andrew Sayers
  2024-04-29  9:24                   ` [FFmpeg-devel] [PATCH v4 2/4] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
@ 2024-04-29  9:24                   ` Andrew Sayers
  2024-05-02 11:01                     ` Lynne
  2024-04-29  9:24                   ` [FFmpeg-devel] [PATCH v4 4/4] lavf: Add documentation for private "Context" classes Andrew Sayers
  2024-05-05  8:31                   ` [FFmpeg-devel] [PATCH v4 1/4] doc: Explain what "context" means Andreas Rheinhardt
  3 siblings, 1 reply; 39+ messages in thread
From: Andrew Sayers @ 2024-04-29  9:24 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

Some headings needed to be rewritten to accomodate the text,
(hopefully) without changing the meaning.
---
 libavcodec/aac/aacdec.h            |  2 +-
 libavcodec/aacenc.h                |  2 +-
 libavcodec/ac3enc.h                |  2 +-
 libavcodec/amfenc.h                |  2 +-
 libavcodec/atrac.h                 |  2 +-
 libavcodec/avcodec.h               |  3 ++-
 libavcodec/bsf.h                   |  2 +-
 libavcodec/cbs.h                   |  2 +-
 libavcodec/d3d11va.h               |  3 +--
 libavcodec/h264dsp.h               |  2 +-
 libavcodec/h264pred.h              |  2 +-
 libavcodec/mediacodec.h            |  2 +-
 libavcodec/mpegaudiodec_template.c |  2 +-
 libavcodec/pthread_frame.c         |  4 ++--
 libavcodec/qsv.h                   |  6 ++++--
 libavcodec/sbr.h                   |  2 +-
 libavcodec/smacker.c               |  2 +-
 libavcodec/vdpau.h                 |  3 ++-
 libavcodec/videotoolbox.h          |  5 +++--
 libavfilter/avfilter.h             |  2 +-
 libavformat/avformat.h             |  3 ++-
 libavformat/avio.h                 |  3 ++-
 libavutil/audio_fifo.h             |  2 +-
 libavutil/hwcontext.h              | 21 ++++++++++++---------
 libavutil/hwcontext_cuda.h         |  2 +-
 libavutil/hwcontext_d3d11va.h      |  4 ++--
 libavutil/hwcontext_d3d12va.h      |  6 +++---
 libavutil/hwcontext_drm.h          |  2 +-
 libavutil/hwcontext_dxva2.h        |  4 ++--
 libavutil/hwcontext_mediacodec.h   |  2 +-
 libavutil/hwcontext_opencl.h       |  4 ++--
 libavutil/hwcontext_qsv.h          |  4 ++--
 libavutil/hwcontext_vaapi.h        |  6 +++---
 libavutil/hwcontext_vdpau.h        |  2 +-
 libavutil/hwcontext_vulkan.h       |  4 ++--
 libavutil/lfg.h                    |  2 +-
 36 files changed, 66 insertions(+), 57 deletions(-)

diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
index 4cf764e2e9..71d61813f4 100644
--- a/libavcodec/aac/aacdec.h
+++ b/libavcodec/aac/aacdec.h
@@ -248,7 +248,7 @@ typedef struct AACDecDSP {
 } AACDecDSP;
 
 /**
- * main AAC decoding context
+ * main AAC decoding @ref md_doc_2context "context"
  */
 struct AACDecContext {
     const struct AVClass  *class;
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index d07960620e..1a645f4719 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -207,7 +207,7 @@ typedef struct AACPCEInfo {
 } AACPCEInfo;
 
 /**
- * AAC encoder context
+ * AAC encoder @ref md_doc_2context "context"
  */
 typedef struct AACEncContext {
     AVClass *av_class;
diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
index 30812617cc..c725007077 100644
--- a/libavcodec/ac3enc.h
+++ b/libavcodec/ac3enc.h
@@ -152,7 +152,7 @@ typedef struct AC3Block {
 } AC3Block;
 
 /**
- * AC-3 encoder private context.
+ * AC-3 encoder private @ref md_doc_2context "context"
  */
 typedef struct AC3EncodeContext {
     AVClass *av_class;                      ///< AVClass used for AVOption
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..f142ede63a 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
 } AmfTraceWriter;
 
 /**
-* AMF encoder context
+* AMF encoder @ref md_doc_2context "context"
 */
 
 typedef struct AmfContext {
diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
index 05208bbee6..1527e376a9 100644
--- a/libavcodec/atrac.h
+++ b/libavcodec/atrac.h
@@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
 } AtracGainInfo;
 
 /**
- *  Gain compensation context structure.
+ *  Gain compensation @ref md_doc_2context "context"
  */
 typedef struct AtracGCContext {
     float   gain_tab1[16];  ///< gain compensation level table
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 968009a192..9180fedca7 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -430,7 +430,8 @@ typedef struct RcOverride{
 #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
 
 /**
- * main external API structure.
+ * @ref md_doc_2context "Context" for an encode or decode session
+ *
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
index a09c69f242..bf79afa7cc 100644
--- a/libavcodec/bsf.h
+++ b/libavcodec/bsf.h
@@ -56,7 +56,7 @@
  */
 
 /**
- * The bitstream filter state.
+ * Bitstream filter @ref md_doc_2context "context"
  *
  * This struct must be allocated with av_bsf_alloc() and freed with
  * av_bsf_free().
diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h
index d479b1ac2d..0ff64d2fef 100644
--- a/libavcodec/cbs.h
+++ b/libavcodec/cbs.h
@@ -214,7 +214,7 @@ typedef void (*CBSTraceWriteCallback)(void *trace_context,
                                       int64_t value);
 
 /**
- * Context structure for coded bitstream operations.
+ * @ref md_doc_2context "Context" structure for coded bitstream operations.
  */
 typedef struct CodedBitstreamContext {
     /**
diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
index 27f40e5519..ec0c472ab9 100644
--- a/libavcodec/d3d11va.h
+++ b/libavcodec/d3d11va.h
@@ -46,8 +46,7 @@
  */
 
 /**
- * This structure is used to provides the necessary configurations and data
- * to the Direct3D11 FFmpeg HWAccel implementation.
+ * @ref md_doc_2context "Context" for the Direct3D11 FFmpeg HWAccel implementation
  *
  * The application must make it available as AVCodecContext.hwaccel_context.
  *
diff --git a/libavcodec/h264dsp.h b/libavcodec/h264dsp.h
index e0880c4d88..27256c5605 100644
--- a/libavcodec/h264dsp.h
+++ b/libavcodec/h264dsp.h
@@ -37,7 +37,7 @@ typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src,
                                    int weightd, int weights, int offset);
 
 /**
- * Context for storing H.264 DSP functions
+ * @ref md_doc_2context "Context" for storing H.264 DSP functions
  */
 typedef struct H264DSPContext {
     /* weighted MC */
diff --git a/libavcodec/h264pred.h b/libavcodec/h264pred.h
index cb008548fc..2b076f8846 100644
--- a/libavcodec/h264pred.h
+++ b/libavcodec/h264pred.h
@@ -89,7 +89,7 @@
 #define PART_NOT_AVAILABLE -2
 
 /**
- * Context for storing H.264 prediction functions
+ * @ref md_doc_2context "Context" for storing H.264 prediction functions
  */
 typedef struct H264PredContext {
     void(*pred4x4[9 + 3 + 3])(uint8_t *src, const uint8_t *topright,
diff --git a/libavcodec/mediacodec.h b/libavcodec/mediacodec.h
index 4e9b56a618..9967a7cfb3 100644
--- a/libavcodec/mediacodec.h
+++ b/libavcodec/mediacodec.h
@@ -26,7 +26,7 @@
 #include "libavcodec/avcodec.h"
 
 /**
- * This structure holds a reference to a android/view/Surface object that will
+ * @ref md_doc_2context "Context" for the android/view/Surface object that will
  * be used as output by the decoder.
  *
  */
diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c
index c73b1e0054..15d63215d1 100644
--- a/libavcodec/mpegaudiodec_template.c
+++ b/libavcodec/mpegaudiodec_template.c
@@ -1691,7 +1691,7 @@ static int decode_frame_adu(AVCodecContext *avctx, AVFrame *frame,
 #if CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER
 
 /**
- * Context for MP3On4 decoder
+ * @ref md_doc_2context "Context" for MP3On4 decoder
  */
 typedef struct MP3On4DecodeContext {
     int frames;                     ///< number of mp3 frames per block (number of mp3 decoder instances)
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index 67f09c1f48..74f05eedcf 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -71,7 +71,7 @@ typedef struct ThreadFrameProgress {
 } ThreadFrameProgress;
 
 /**
- * Context used by codec threads and stored in their AVCodecInternal thread_ctx.
+ * @ref md_doc_2context "Context" used by codec threads and stored in their AVCodecInternal thread_ctx.
  */
 typedef struct PerThreadContext {
     struct FrameThreadContext *parent;
@@ -111,7 +111,7 @@ typedef struct PerThreadContext {
 } PerThreadContext;
 
 /**
- * Context stored in the client AVCodecInternal thread_ctx.
+ * @ref md_doc_2context "Context" stored in the client AVCodecInternal thread_ctx.
  */
 typedef struct FrameThreadContext {
     PerThreadContext *threads;     ///< The contexts for each thread.
diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
index c156b08d07..8b8160a4b1 100644
--- a/libavcodec/qsv.h
+++ b/libavcodec/qsv.h
@@ -26,8 +26,10 @@
 #include "libavutil/buffer.h"
 
 /**
- * This struct is used for communicating QSV parameters between libavcodec and
- * the caller. It is managed by the caller and must be assigned to
+ * @ref md_doc_2context "Context" for communicating QSV parameters between libavcodec
+ * and the caller.
+ *
+ * It is managed by the caller and must be assigned to
  * AVCodecContext.hwaccel_context.
  * - decoding: hwaccel_context must be set on return from the get_format()
  *             callback
diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
index fe3a39603a..98ad9024a9 100644
--- a/libavcodec/sbr.h
+++ b/libavcodec/sbr.h
@@ -116,7 +116,7 @@ typedef struct SBRData {
 typedef struct SpectralBandReplication SpectralBandReplication;
 
 /**
- * aacsbr functions pointers
+ * aacsbr functions pointer @ref md_doc_2context "context"
  */
 typedef struct AACSBRContext {
     int (*sbr_lf_gen)(SpectralBandReplication *sbr,
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
index 8f198d6957..1ca39a74a0 100644
--- a/libavcodec/smacker.c
+++ b/libavcodec/smacker.c
@@ -68,7 +68,7 @@ typedef struct HuffEntry {
 } HuffEntry;
 
 /**
- * Context used for code reconstructing
+ * @ref md_doc_2context "Context" used for code reconstructing
  */
 typedef struct HuffContext {
     int current;
diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
index 8021c25761..227b85727d 100644
--- a/libavcodec/vdpau.h
+++ b/libavcodec/vdpau.h
@@ -64,8 +64,9 @@ typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, struct AVFrame *,
                                const VdpBitstreamBuffer *);
 
 /**
- * This structure is used to share data between the libavcodec library and
+ * @ref md_doc_2context "Context" to share data between the libavcodec library and
  * the client video application.
+ *
  * This structure will be allocated and stored in AVCodecContext.hwaccel_context
  * by av_vdpau_bind_context(). Members can be set by the user once
  * during initialization or through each AVCodecContext.get_buffer()
diff --git a/libavcodec/videotoolbox.h b/libavcodec/videotoolbox.h
index d68d76e400..f15e79f325 100644
--- a/libavcodec/videotoolbox.h
+++ b/libavcodec/videotoolbox.h
@@ -49,8 +49,9 @@
 #include "libavutil/attributes.h"
 
 /**
- * This struct holds all the information that needs to be passed
- * between the caller and libavcodec for initializing Videotoolbox decoding.
+ * @ref md_doc_2context "Context" for information passed between the caller and libavcodec
+ * for initializing Videotoolbox decoding.
+ *
  * Its size is not a part of the public ABI, it must be allocated with
  * av_videotoolbox_alloc_context() and freed with av_free().
  */
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index a34e61f23c..54b5f9dc43 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -403,7 +403,7 @@ unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output);
  */
 #define AVFILTER_THREAD_SLICE (1 << 0)
 
-/** An instance of a filter */
+/** @ref md_doc_2context "Context" for a filter */
 struct AVFilterContext {
     const AVClass *av_class;        ///< needed for av_log() and filters common options
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 8afdcd9fd0..28243c06c4 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1241,7 +1241,8 @@ enum AVDurationEstimationMethod {
 };
 
 /**
- * Format I/O context.
+ * Format I/O @ref md_doc_2context "context"
+ *
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
diff --git a/libavformat/avio.h b/libavformat/avio.h
index ebf611187d..b525c93194 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -146,7 +146,8 @@ enum AVIODataMarkerType {
 };
 
 /**
- * Bytestream IO Context.
+ * Bytestream I/O @ref md_doc_2context "context"
+ *
  * New public fields can be added with minor version bumps.
  * Removal, reordering and changes to existing public fields require
  * a major version bump.
diff --git a/libavutil/audio_fifo.h b/libavutil/audio_fifo.h
index fa5f59a2be..de29715462 100644
--- a/libavutil/audio_fifo.h
+++ b/libavutil/audio_fifo.h
@@ -39,7 +39,7 @@
  */
 
 /**
- * Context for an Audio FIFO Buffer.
+ * @ref md_doc_2context "Context" for an Audio FIFO Buffer.
  *
  * - Operates at the sample level rather than the byte level.
  * - Supports multiple channels with either planar or packed sample format.
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index bac30debae..60064cf08b 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -41,12 +41,13 @@ enum AVHWDeviceType {
 };
 
 /**
- * This struct aggregates all the (hardware/vendor-specific) "high-level" state,
- * i.e. state that is not tied to a concrete processing configuration.
- * E.g., in an API that supports hardware-accelerated encoding and decoding,
- * this struct will (if possible) wrap the state that is common to both encoding
- * and decoding and from which specific instances of encoders or decoders can be
- * derived.
+ * @ref md_doc_2context "Context" for (hardware/vendor-specific) "high-level" state.
+ *
+ * "High-level state" is anything that is not tied to a concrete processing
+ * configuration. E.g., in an API that supports hardware-accelerated encoding
+ * and decoding, this struct will (if possible) wrap the state that is common
+ * to both encoding and decoding and from which specific instances of encoders
+ * or decoders can be derived.
  *
  * This struct is reference-counted with the AVBuffer mechanism. The
  * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field
@@ -103,9 +104,11 @@ typedef struct AVHWDeviceContext {
 } AVHWDeviceContext;
 
 /**
- * This struct describes a set or pool of "hardware" frames (i.e. those with
- * data not located in normal system memory). All the frames in the pool are
- * assumed to be allocated in the same way and interchangeable.
+ * @ref md_doc_2context "context" for a pool of "hardware" frames (those with
+ * data not located in normal system memory)
+ *
+ * All the frames in the pool are assumed to be allocated in the same way and
+ * interchangeable.
  *
  * This struct is reference-counted with the AVBuffer mechanism and tied to a
  * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor
diff --git a/libavutil/hwcontext_cuda.h b/libavutil/hwcontext_cuda.h
index cbad434fea..e259892688 100644
--- a/libavutil/hwcontext_cuda.h
+++ b/libavutil/hwcontext_cuda.h
@@ -37,7 +37,7 @@
 typedef struct AVCUDADeviceContextInternal AVCUDADeviceContextInternal;
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVCUDADeviceContext {
     CUcontext cuda_ctx;
diff --git a/libavutil/hwcontext_d3d11va.h b/libavutil/hwcontext_d3d11va.h
index 77d2d72f1b..101d1cb6f8 100644
--- a/libavutil/hwcontext_d3d11va.h
+++ b/libavutil/hwcontext_d3d11va.h
@@ -40,7 +40,7 @@
 #include <stdint.h>
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVD3D11VADeviceContext {
     /**
@@ -126,7 +126,7 @@ typedef struct AVD3D11FrameDescriptor {
 } AVD3D11FrameDescriptor;
 
 /**
- * This struct is allocated as AVHWFramesContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
  */
 typedef struct AVD3D11VAFramesContext {
     /**
diff --git a/libavutil/hwcontext_d3d12va.h b/libavutil/hwcontext_d3d12va.h
index ff06e6f2ef..c623914c2b 100644
--- a/libavutil/hwcontext_d3d12va.h
+++ b/libavutil/hwcontext_d3d12va.h
@@ -37,7 +37,7 @@
 #include <d3d12video.h>
 
 /**
- * @brief This struct is allocated as AVHWDeviceContext.hwctx
+ * @brief This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  *
  */
 typedef struct AVD3D12VADeviceContext {
@@ -78,7 +78,7 @@ typedef struct AVD3D12VADeviceContext {
 } AVD3D12VADeviceContext;
 
 /**
- * @brief This struct is used to sync d3d12 execution
+ * @brief This @ref md_doc_2context "context" is used to sync d3d12 execution
  *
  */
 typedef struct AVD3D12VASyncContext {
@@ -120,7 +120,7 @@ typedef struct AVD3D12VAFrame {
 } AVD3D12VAFrame;
 
 /**
- * @brief This struct is allocated as AVHWFramesContext.hwctx
+ * @brief This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
  *
  */
 typedef struct AVD3D12VAFramesContext {
diff --git a/libavutil/hwcontext_drm.h b/libavutil/hwcontext_drm.h
index 42709f215e..8329e69966 100644
--- a/libavutil/hwcontext_drm.h
+++ b/libavutil/hwcontext_drm.h
@@ -152,7 +152,7 @@ typedef struct AVDRMFrameDescriptor {
 /**
  * DRM device.
  *
- * Allocated as AVHWDeviceContext.hwctx.
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx.
  */
 typedef struct AVDRMDeviceContext {
     /**
diff --git a/libavutil/hwcontext_dxva2.h b/libavutil/hwcontext_dxva2.h
index e1b79bc0de..c679c16af0 100644
--- a/libavutil/hwcontext_dxva2.h
+++ b/libavutil/hwcontext_dxva2.h
@@ -34,14 +34,14 @@
 #include <dxva2api.h>
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVDXVA2DeviceContext {
     IDirect3DDeviceManager9 *devmgr;
 } AVDXVA2DeviceContext;
 
 /**
- * This struct is allocated as AVHWFramesContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
  */
 typedef struct AVDXVA2FramesContext {
     /**
diff --git a/libavutil/hwcontext_mediacodec.h b/libavutil/hwcontext_mediacodec.h
index fc0263cabc..e81193247b 100644
--- a/libavutil/hwcontext_mediacodec.h
+++ b/libavutil/hwcontext_mediacodec.h
@@ -22,7 +22,7 @@
 /**
  * MediaCodec details.
  *
- * Allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVMediaCodecDeviceContext {
     /**
diff --git a/libavutil/hwcontext_opencl.h b/libavutil/hwcontext_opencl.h
index ef54486c95..7abd97db2b 100644
--- a/libavutil/hwcontext_opencl.h
+++ b/libavutil/hwcontext_opencl.h
@@ -58,7 +58,7 @@ typedef struct AVOpenCLFrameDescriptor {
 /**
  * OpenCL device details.
  *
- * Allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVOpenCLDeviceContext {
     /**
@@ -84,7 +84,7 @@ typedef struct AVOpenCLDeviceContext {
 /**
  * OpenCL-specific data associated with a frame pool.
  *
- * Allocated as AVHWFramesContext.hwctx.
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
  */
 typedef struct AVOpenCLFramesContext {
     /**
diff --git a/libavutil/hwcontext_qsv.h b/libavutil/hwcontext_qsv.h
index e2dba8ad83..b63ebddaef 100644
--- a/libavutil/hwcontext_qsv.h
+++ b/libavutil/hwcontext_qsv.h
@@ -30,7 +30,7 @@
  */
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVQSVDeviceContext {
     mfxSession session;
@@ -48,7 +48,7 @@ typedef struct AVQSVDeviceContext {
 } AVQSVDeviceContext;
 
 /**
- * This struct is allocated as AVHWFramesContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
  */
 typedef struct AVQSVFramesContext {
     mfxFrameSurface1 *surfaces;
diff --git a/libavutil/hwcontext_vaapi.h b/libavutil/hwcontext_vaapi.h
index 0b2e071cb3..4a897eb851 100644
--- a/libavutil/hwcontext_vaapi.h
+++ b/libavutil/hwcontext_vaapi.h
@@ -63,7 +63,7 @@ enum {
 /**
  * VAAPI connection details.
  *
- * Allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVVAAPIDeviceContext {
     /**
@@ -83,7 +83,7 @@ typedef struct AVVAAPIDeviceContext {
 /**
  * VAAPI-specific data associated with a frame pool.
  *
- * Allocated as AVHWFramesContext.hwctx.
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
  */
 typedef struct AVVAAPIFramesContext {
     /**
@@ -105,7 +105,7 @@ typedef struct AVVAAPIFramesContext {
 /**
  * VAAPI hardware pipeline configuration details.
  *
- * Allocated with av_hwdevice_hwconfig_alloc().
+ * This struct is allocated with av_hwdevice_hwconfig_alloc().
  */
 typedef struct AVVAAPIHWConfig {
     /**
diff --git a/libavutil/hwcontext_vdpau.h b/libavutil/hwcontext_vdpau.h
index 1b7ea1e443..e305caa595 100644
--- a/libavutil/hwcontext_vdpau.h
+++ b/libavutil/hwcontext_vdpau.h
@@ -30,7 +30,7 @@
  */
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVVDPAUDeviceContext {
     VdpDevice          device;
diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h
index cbbd2390c1..1869870032 100644
--- a/libavutil/hwcontext_vulkan.h
+++ b/libavutil/hwcontext_vulkan.h
@@ -39,7 +39,7 @@ typedef struct AVVkFrame AVVkFrame;
  */
 
 /**
- * Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
+ * Main Vulkan @ref md_doc_2context "context", allocated as AVHWDeviceContext.hwctx.
  * All of these can be set before init to change what the context uses
  */
 typedef struct AVVulkanDeviceContext {
@@ -172,7 +172,7 @@ typedef enum AVVkFrameFlags {
 } AVVkFrameFlags;
 
 /**
- * Allocated as AVHWFramesContext.hwctx, used to set pool-specific options
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx, used to set pool-specific options
  */
 typedef struct AVVulkanFramesContext {
     /**
diff --git a/libavutil/lfg.h b/libavutil/lfg.h
index e75a986f12..7f4ff5b62f 100644
--- a/libavutil/lfg.h
+++ b/libavutil/lfg.h
@@ -25,7 +25,7 @@
 #include <stdint.h>
 
 /**
- * Context structure for the Lagged Fibonacci PRNG.
+ * @ref md_doc_2context "Context" structure for the Lagged Fibonacci PRNG.
  * The exact layout, types and content of this struct may change and should
  * not be accessed directly. Only its `sizeof()` is guaranteed to stay the same
  * to allow easy instanciation.
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v4 4/4] lavf: Add documentation for private "Context" classes
  2024-04-29  9:24                 ` [FFmpeg-devel] [PATCH v4 1/4] " Andrew Sayers
  2024-04-29  9:24                   ` [FFmpeg-devel] [PATCH v4 2/4] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
  2024-04-29  9:24                   ` [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation Andrew Sayers
@ 2024-04-29  9:24                   ` Andrew Sayers
  2024-05-05  8:31                   ` [FFmpeg-devel] [PATCH v4 1/4] doc: Explain what "context" means Andreas Rheinhardt
  3 siblings, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-04-29  9:24 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

Doxygen thinks any text like "Context for foo" is a link to a struct called "Context".
Add a description and a better link, to avoid confusing readers.
---
 libavformat/async.c | 3 +++
 libavformat/cache.c | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/libavformat/async.c b/libavformat/async.c
index e096b0bc6f..3c28d418ae 100644
--- a/libavformat/async.c
+++ b/libavformat/async.c
@@ -53,6 +53,9 @@ typedef struct RingBuffer
     int           read_pos;
 } RingBuffer;
 
+/**
+ * @brief @ref md_doc_2context "Context" for testing async
+ */
 typedef struct Context {
     AVClass        *class;
     URLContext     *inner;
diff --git a/libavformat/cache.c b/libavformat/cache.c
index 5f78adba9d..3cc0edec82 100644
--- a/libavformat/cache.c
+++ b/libavformat/cache.c
@@ -52,6 +52,9 @@ typedef struct CacheEntry {
     int size;
 } CacheEntry;
 
+/**
+ * @brief @ref md_doc_2context "Context" for a cache
+ */
 typedef struct Context {
     AVClass *class;
     int fd;
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v3 1/3] doc: Explain what "context" means
  2024-04-29  9:10                 ` Andrew Sayers
@ 2024-05-02 10:03                   ` Andrew Sayers
  2024-05-05  7:29                   ` Stefano Sabatini
  1 sibling, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-05-02 10:03 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Mon, Apr 29, 2024 at 10:10:35AM +0100, Andrew Sayers wrote:
> 
> I've also gone through the code looking for edge cases we haven't covered.
> Here are some questions trying to prompt an "oh yeah I forgot to mention
> that"-type answer.  Anything where the answer is more like "that should
> probably be rewritten to be clearer", let me know and I'll avoid confusing
> newbies with it.
> 
> av_ambient_viewing_environment_create_side_data() takes an AVFrame as its
> first argument, and returns a new AVAmbientViewingEnvironment.  What is the
> context object for that function - AVFrame or AVAmbientViewingEnvironment?
> 
> av_register_bitstream_filter() (deprecated 4.0, removed 5.0) took an
> `AVBitStreamFilter *` as its first argument, but I don't think you'd say
> the argument provided "context" for the function.  So would I be right in
> saying `AVBitStreamFilter *` is not a context, despite looking like one?
> 
> av_buffersink_*() all take a `const AVFilterContext *` argument.
> What does the difference between av_buffersink prefix and AVFilter type mean?
> 
> av_channel_description_bprint() takes a `struct AVBPrint *` as its first
> argument, then `enum AVChannel`.  Is the context AVBPrint, AVChannel,
> or both?  Does it make sense for a function to have two contexts?
> 
> Related to the previous question, does `av_cmp_q()` count as a function
> with two contexts?  Or no contexts?
> 
> Finally, a general question - functions of the form "avfoo" seem like they
> are more consistent than "av_foo".  Does the underscore mean anything?

One extra question I hadn't thought to ask before - when, if at all, would an
ordinary user be expected to access the contents of AVClass directly?  Or
AVOption for that matter?  For example, it's not clear to me how people are
supposed to use AVClass.category - is this an important use case we haven't
covered?  Either way, happy to propose an AVClass patch to make it clearer.

It's my turn to be off for a few days, so will pick up any responses next week.
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation
  2024-04-29  9:24                   ` [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation Andrew Sayers
@ 2024-05-02 11:01                     ` Lynne
  2024-05-02 11:14                       ` Andrew Sayers
  2024-05-02 13:00                       ` Zhao Zhili
  0 siblings, 2 replies; 39+ messages in thread
From: Lynne @ 2024-05-02 11:01 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

Apr 29, 2024, 11:24 by ffmpeg-devel@pileofstuff.org:

> Some headings needed to be rewritten to accomodate the text,
> (hopefully) without changing the meaning.
> ---
>  libavcodec/aac/aacdec.h            |  2 +-
>  libavcodec/aacenc.h                |  2 +-
>  libavcodec/ac3enc.h                |  2 +-
>  libavcodec/amfenc.h                |  2 +-
>  libavcodec/atrac.h                 |  2 +-
>  libavcodec/avcodec.h               |  3 ++-
>  libavcodec/bsf.h                   |  2 +-
>  libavcodec/cbs.h                   |  2 +-
>  libavcodec/d3d11va.h               |  3 +--
>  libavcodec/h264dsp.h               |  2 +-
>  libavcodec/h264pred.h              |  2 +-
>  libavcodec/mediacodec.h            |  2 +-
>  libavcodec/mpegaudiodec_template.c |  2 +-
>  libavcodec/pthread_frame.c         |  4 ++--
>  libavcodec/qsv.h                   |  6 ++++--
>  libavcodec/sbr.h                   |  2 +-
>  libavcodec/smacker.c               |  2 +-
>  libavcodec/vdpau.h                 |  3 ++-
>  libavcodec/videotoolbox.h          |  5 +++--
>  libavfilter/avfilter.h             |  2 +-
>  libavformat/avformat.h             |  3 ++-
>  libavformat/avio.h                 |  3 ++-
>  libavutil/audio_fifo.h             |  2 +-
>  libavutil/hwcontext.h              | 21 ++++++++++++---------
>  libavutil/hwcontext_cuda.h         |  2 +-
>  libavutil/hwcontext_d3d11va.h      |  4 ++--
>  libavutil/hwcontext_d3d12va.h      |  6 +++---
>  libavutil/hwcontext_drm.h          |  2 +-
>  libavutil/hwcontext_dxva2.h        |  4 ++--
>  libavutil/hwcontext_mediacodec.h   |  2 +-
>  libavutil/hwcontext_opencl.h       |  4 ++--
>  libavutil/hwcontext_qsv.h          |  4 ++--
>  libavutil/hwcontext_vaapi.h        |  6 +++---
>  libavutil/hwcontext_vdpau.h        |  2 +-
>  libavutil/hwcontext_vulkan.h       |  4 ++--
>  libavutil/lfg.h                    |  2 +-
>  36 files changed, 66 insertions(+), 57 deletions(-)
>
> diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
> index 4cf764e2e9..71d61813f4 100644
> --- a/libavcodec/aac/aacdec.h
> +++ b/libavcodec/aac/aacdec.h
> @@ -248,7 +248,7 @@ typedef struct AACDecDSP {
>  } AACDecDSP;
>  
>  /**
> - * main AAC decoding context
> + * main AAC decoding @ref md_doc_2context "context"
>  */
>  struct AACDecContext {
>  const struct AVClass  *class;
> diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
> index d07960620e..1a645f4719 100644
> --- a/libavcodec/aacenc.h
> +++ b/libavcodec/aacenc.h
> @@ -207,7 +207,7 @@ typedef struct AACPCEInfo {
>  } AACPCEInfo;
>  
>  /**
> - * AAC encoder context
> + * AAC encoder @ref md_doc_2context "context"
>  */
>  typedef struct AACEncContext {
>  AVClass *av_class;
> diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
> index 30812617cc..c725007077 100644
> --- a/libavcodec/ac3enc.h
> +++ b/libavcodec/ac3enc.h
> @@ -152,7 +152,7 @@ typedef struct AC3Block {
>  } AC3Block;
>  
>  /**
> - * AC-3 encoder private context.
> + * AC-3 encoder private @ref md_doc_2context "context"
>  */
>  typedef struct AC3EncodeContext {
>  AVClass *av_class;                      ///< AVClass used for AVOption
> diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
> index 2dbd378ef8..f142ede63a 100644
> --- a/libavcodec/amfenc.h
> +++ b/libavcodec/amfenc.h
> @@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
>  } AmfTraceWriter;
>  
>  /**
> -* AMF encoder context
> +* AMF encoder @ref md_doc_2context "context"
>  */
>  
>  typedef struct AmfContext {
> diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
> index 05208bbee6..1527e376a9 100644
> --- a/libavcodec/atrac.h
> +++ b/libavcodec/atrac.h
> @@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
>  } AtracGainInfo;
>  
>  /**
> - *  Gain compensation context structure.
> + *  Gain compensation @ref md_doc_2context "context"
>  */
>  typedef struct AtracGCContext {
>  float   gain_tab1[16];  ///< gain compensation level table
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index 968009a192..9180fedca7 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -430,7 +430,8 @@ typedef struct RcOverride{
>  #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
>  
>  /**
> - * main external API structure.
> + * @ref md_doc_2context "Context" for an encode or decode session
> + *
>  * New fields can be added to the end with minor version bumps.
>  * Removal, reordering and changes to existing fields require a major
>  * version bump.
> diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
> index a09c69f242..bf79afa7cc 100644
> --- a/libavcodec/bsf.h
> +++ b/libavcodec/bsf.h
> @@ -56,7 +56,7 @@
>  */
>  
>  /**
> - * The bitstream filter state.
> + * Bitstream filter @ref md_doc_2context "context"
>  *
>  * This struct must be allocated with av_bsf_alloc() and freed with
>  * av_bsf_free().
> diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h
> index d479b1ac2d..0ff64d2fef 100644
> --- a/libavcodec/cbs.h
> +++ b/libavcodec/cbs.h
> @@ -214,7 +214,7 @@ typedef void (*CBSTraceWriteCallback)(void *trace_context,
>  int64_t value);
>  
>  /**
> - * Context structure for coded bitstream operations.
> + * @ref md_doc_2context "Context" structure for coded bitstream operations.
>  */
>  typedef struct CodedBitstreamContext {
>  /**
> diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
> index 27f40e5519..ec0c472ab9 100644
> --- a/libavcodec/d3d11va.h
> +++ b/libavcodec/d3d11va.h
> @@ -46,8 +46,7 @@
>  */
>  
>  /**
> - * This structure is used to provides the necessary configurations and data
> - * to the Direct3D11 FFmpeg HWAccel implementation.
> + * @ref md_doc_2context "Context" for the Direct3D11 FFmpeg HWAccel implementation
>  *
>  * The application must make it available as AVCodecContext.hwaccel_context.
>  *
> diff --git a/libavcodec/h264dsp.h b/libavcodec/h264dsp.h
> index e0880c4d88..27256c5605 100644
> --- a/libavcodec/h264dsp.h
> +++ b/libavcodec/h264dsp.h
> @@ -37,7 +37,7 @@ typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src,
>  int weightd, int weights, int offset);
>  
>  /**
> - * Context for storing H.264 DSP functions
> + * @ref md_doc_2context "Context" for storing H.264 DSP functions
>  */
>  typedef struct H264DSPContext {
>  /* weighted MC */
> diff --git a/libavcodec/h264pred.h b/libavcodec/h264pred.h
> index cb008548fc..2b076f8846 100644
> --- a/libavcodec/h264pred.h
> +++ b/libavcodec/h264pred.h
> @@ -89,7 +89,7 @@
>  #define PART_NOT_AVAILABLE -2
>  
>  /**
> - * Context for storing H.264 prediction functions
> + * @ref md_doc_2context "Context" for storing H.264 prediction functions
>  */
>  typedef struct H264PredContext {
>  void(*pred4x4[9 + 3 + 3])(uint8_t *src, const uint8_t *topright,
> diff --git a/libavcodec/mediacodec.h b/libavcodec/mediacodec.h
> index 4e9b56a618..9967a7cfb3 100644
> --- a/libavcodec/mediacodec.h
> +++ b/libavcodec/mediacodec.h
> @@ -26,7 +26,7 @@
>  #include "libavcodec/avcodec.h"
>  
>  /**
> - * This structure holds a reference to a android/view/Surface object that will
> + * @ref md_doc_2context "Context" for the android/view/Surface object that will
>  * be used as output by the decoder.
>  *
>  */
> diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c
> index c73b1e0054..15d63215d1 100644
> --- a/libavcodec/mpegaudiodec_template.c
> +++ b/libavcodec/mpegaudiodec_template.c
> @@ -1691,7 +1691,7 @@ static int decode_frame_adu(AVCodecContext *avctx, AVFrame *frame,
>  #if CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER
>  
>  /**
> - * Context for MP3On4 decoder
> + * @ref md_doc_2context "Context" for MP3On4 decoder
>  */
>  typedef struct MP3On4DecodeContext {
>  int frames;                     ///< number of mp3 frames per block (number of mp3 decoder instances)
> diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
> index 67f09c1f48..74f05eedcf 100644
> --- a/libavcodec/pthread_frame.c
> +++ b/libavcodec/pthread_frame.c
> @@ -71,7 +71,7 @@ typedef struct ThreadFrameProgress {
>  } ThreadFrameProgress;
>  
>  /**
> - * Context used by codec threads and stored in their AVCodecInternal thread_ctx.
> + * @ref md_doc_2context "Context" used by codec threads and stored in their AVCodecInternal thread_ctx.
>  */
>  typedef struct PerThreadContext {
>  struct FrameThreadContext *parent;
> @@ -111,7 +111,7 @@ typedef struct PerThreadContext {
>  } PerThreadContext;
>  
>  /**
> - * Context stored in the client AVCodecInternal thread_ctx.
> + * @ref md_doc_2context "Context" stored in the client AVCodecInternal thread_ctx.
>  */
>  typedef struct FrameThreadContext {
>  PerThreadContext *threads;     ///< The contexts for each thread.
> diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
> index c156b08d07..8b8160a4b1 100644
> --- a/libavcodec/qsv.h
> +++ b/libavcodec/qsv.h
> @@ -26,8 +26,10 @@
>  #include "libavutil/buffer.h"
>  
>  /**
> - * This struct is used for communicating QSV parameters between libavcodec and
> - * the caller. It is managed by the caller and must be assigned to
> + * @ref md_doc_2context "Context" for communicating QSV parameters between libavcodec
> + * and the caller.
> + *
> + * It is managed by the caller and must be assigned to
>  * AVCodecContext.hwaccel_context.
>  * - decoding: hwaccel_context must be set on return from the get_format()
>  *             callback
> diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
> index fe3a39603a..98ad9024a9 100644
> --- a/libavcodec/sbr.h
> +++ b/libavcodec/sbr.h
> @@ -116,7 +116,7 @@ typedef struct SBRData {
>  typedef struct SpectralBandReplication SpectralBandReplication;
>  
>  /**
> - * aacsbr functions pointers
> + * aacsbr functions pointer @ref md_doc_2context "context"
>  */
>  typedef struct AACSBRContext {
>  int (*sbr_lf_gen)(SpectralBandReplication *sbr,
> diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
> index 8f198d6957..1ca39a74a0 100644
> --- a/libavcodec/smacker.c
> +++ b/libavcodec/smacker.c
> @@ -68,7 +68,7 @@ typedef struct HuffEntry {
>  } HuffEntry;
>  
>  /**
> - * Context used for code reconstructing
> + * @ref md_doc_2context "Context" used for code reconstructing
>  */
>  typedef struct HuffContext {
>  int current;
> diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
> index 8021c25761..227b85727d 100644
> --- a/libavcodec/vdpau.h
> +++ b/libavcodec/vdpau.h
> @@ -64,8 +64,9 @@ typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, struct AVFrame *,
>  const VdpBitstreamBuffer *);
>  
>  /**
> - * This structure is used to share data between the libavcodec library and
> + * @ref md_doc_2context "Context" to share data between the libavcodec library and
>  * the client video application.
> + *
>  * This structure will be allocated and stored in AVCodecContext.hwaccel_context
>  * by av_vdpau_bind_context(). Members can be set by the user once
>  * during initialization or through each AVCodecContext.get_buffer()
> diff --git a/libavcodec/videotoolbox.h b/libavcodec/videotoolbox.h
> index d68d76e400..f15e79f325 100644
> --- a/libavcodec/videotoolbox.h
> +++ b/libavcodec/videotoolbox.h
> @@ -49,8 +49,9 @@
>  #include "libavutil/attributes.h"
>  
>  /**
> - * This struct holds all the information that needs to be passed
> - * between the caller and libavcodec for initializing Videotoolbox decoding.
> + * @ref md_doc_2context "Context" for information passed between the caller and libavcodec
> + * for initializing Videotoolbox decoding.
> + *
>  * Its size is not a part of the public ABI, it must be allocated with
>  * av_videotoolbox_alloc_context() and freed with av_free().
>  */
> diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
> index a34e61f23c..54b5f9dc43 100644
> --- a/libavfilter/avfilter.h
> +++ b/libavfilter/avfilter.h
> @@ -403,7 +403,7 @@ unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output);
>  */
>  #define AVFILTER_THREAD_SLICE (1 << 0)
>  
> -/** An instance of a filter */
> +/** @ref md_doc_2context "Context" for a filter */
>  struct AVFilterContext {
>  const AVClass *av_class;        ///< needed for av_log() and filters common options
>  
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index 8afdcd9fd0..28243c06c4 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -1241,7 +1241,8 @@ enum AVDurationEstimationMethod {
>  };
>  
>  /**
> - * Format I/O context.
> + * Format I/O @ref md_doc_2context "context"
> + *
>  * New fields can be added to the end with minor version bumps.
>  * Removal, reordering and changes to existing fields require a major
>  * version bump.
> diff --git a/libavformat/avio.h b/libavformat/avio.h
> index ebf611187d..b525c93194 100644
> --- a/libavformat/avio.h
> +++ b/libavformat/avio.h
> @@ -146,7 +146,8 @@ enum AVIODataMarkerType {
>  };
>  
>  /**
> - * Bytestream IO Context.
> + * Bytestream I/O @ref md_doc_2context "context"
> + *
>  * New public fields can be added with minor version bumps.
>  * Removal, reordering and changes to existing public fields require
>  * a major version bump.
> diff --git a/libavutil/audio_fifo.h b/libavutil/audio_fifo.h
> index fa5f59a2be..de29715462 100644
> --- a/libavutil/audio_fifo.h
> +++ b/libavutil/audio_fifo.h
> @@ -39,7 +39,7 @@
>  */
>  
>  /**
> - * Context for an Audio FIFO Buffer.
> + * @ref md_doc_2context "Context" for an Audio FIFO Buffer.
>  *
>  * - Operates at the sample level rather than the byte level.
>  * - Supports multiple channels with either planar or packed sample format.
> diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
> index bac30debae..60064cf08b 100644
> --- a/libavutil/hwcontext.h
> +++ b/libavutil/hwcontext.h
> @@ -41,12 +41,13 @@ enum AVHWDeviceType {
>  };
>  
>  /**
> - * This struct aggregates all the (hardware/vendor-specific) "high-level" state,
> - * i.e. state that is not tied to a concrete processing configuration.
> - * E.g., in an API that supports hardware-accelerated encoding and decoding,
> - * this struct will (if possible) wrap the state that is common to both encoding
> - * and decoding and from which specific instances of encoders or decoders can be
> - * derived.
> + * @ref md_doc_2context "Context" for (hardware/vendor-specific) "high-level" state.
> + *
> + * "High-level state" is anything that is not tied to a concrete processing
> + * configuration. E.g., in an API that supports hardware-accelerated encoding
> + * and decoding, this struct will (if possible) wrap the state that is common
> + * to both encoding and decoding and from which specific instances of encoders
> + * or decoders can be derived.
>  *
>  * This struct is reference-counted with the AVBuffer mechanism. The
>  * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field
> @@ -103,9 +104,11 @@ typedef struct AVHWDeviceContext {
>  } AVHWDeviceContext;
>  
>  /**
> - * This struct describes a set or pool of "hardware" frames (i.e. those with
> - * data not located in normal system memory). All the frames in the pool are
> - * assumed to be allocated in the same way and interchangeable.
> + * @ref md_doc_2context "context" for a pool of "hardware" frames (those with
> + * data not located in normal system memory)
> + *
> + * All the frames in the pool are assumed to be allocated in the same way and
> + * interchangeable.
>  *
>  * This struct is reference-counted with the AVBuffer mechanism and tied to a
>  * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor
> diff --git a/libavutil/hwcontext_cuda.h b/libavutil/hwcontext_cuda.h
> index cbad434fea..e259892688 100644
> --- a/libavutil/hwcontext_cuda.h
> +++ b/libavutil/hwcontext_cuda.h
> @@ -37,7 +37,7 @@
>  typedef struct AVCUDADeviceContextInternal AVCUDADeviceContextInternal;
>  
>  /**
> - * This struct is allocated as AVHWDeviceContext.hwctx
> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>  */
>  typedef struct AVCUDADeviceContext {
>  CUcontext cuda_ctx;
> diff --git a/libavutil/hwcontext_d3d11va.h b/libavutil/hwcontext_d3d11va.h
> index 77d2d72f1b..101d1cb6f8 100644
> --- a/libavutil/hwcontext_d3d11va.h
> +++ b/libavutil/hwcontext_d3d11va.h
> @@ -40,7 +40,7 @@
>  #include <stdint.h>
>  
>  /**
> - * This struct is allocated as AVHWDeviceContext.hwctx
> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>  */
>  typedef struct AVD3D11VADeviceContext {
>  /**
> @@ -126,7 +126,7 @@ typedef struct AVD3D11FrameDescriptor {
>  } AVD3D11FrameDescriptor;
>  
>  /**
> - * This struct is allocated as AVHWFramesContext.hwctx
> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
>  */
>  typedef struct AVD3D11VAFramesContext {
>  /**
> diff --git a/libavutil/hwcontext_d3d12va.h b/libavutil/hwcontext_d3d12va.h
> index ff06e6f2ef..c623914c2b 100644
> --- a/libavutil/hwcontext_d3d12va.h
> +++ b/libavutil/hwcontext_d3d12va.h
> @@ -37,7 +37,7 @@
>  #include <d3d12video.h>
>  
>  /**
> - * @brief This struct is allocated as AVHWDeviceContext.hwctx
> + * @brief This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>  *
>  */
>  typedef struct AVD3D12VADeviceContext {
> @@ -78,7 +78,7 @@ typedef struct AVD3D12VADeviceContext {
>  } AVD3D12VADeviceContext;
>  
>  /**
> - * @brief This struct is used to sync d3d12 execution
> + * @brief This @ref md_doc_2context "context" is used to sync d3d12 execution
>  *
>  */
>  typedef struct AVD3D12VASyncContext {
> @@ -120,7 +120,7 @@ typedef struct AVD3D12VAFrame {
>  } AVD3D12VAFrame;
>  
>  /**
> - * @brief This struct is allocated as AVHWFramesContext.hwctx
> + * @brief This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
>  *
>  */
>  typedef struct AVD3D12VAFramesContext {
> diff --git a/libavutil/hwcontext_drm.h b/libavutil/hwcontext_drm.h
> index 42709f215e..8329e69966 100644
> --- a/libavutil/hwcontext_drm.h
> +++ b/libavutil/hwcontext_drm.h
> @@ -152,7 +152,7 @@ typedef struct AVDRMFrameDescriptor {
>  /**
>  * DRM device.
>  *
> - * Allocated as AVHWDeviceContext.hwctx.
> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx.
>  */
>  typedef struct AVDRMDeviceContext {
>  /**
> diff --git a/libavutil/hwcontext_dxva2.h b/libavutil/hwcontext_dxva2.h
> index e1b79bc0de..c679c16af0 100644
> --- a/libavutil/hwcontext_dxva2.h
> +++ b/libavutil/hwcontext_dxva2.h
> @@ -34,14 +34,14 @@
>  #include <dxva2api.h>
>  
>  /**
> - * This struct is allocated as AVHWDeviceContext.hwctx
> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>  */
>  typedef struct AVDXVA2DeviceContext {
>  IDirect3DDeviceManager9 *devmgr;
>  } AVDXVA2DeviceContext;
>  
>  /**
> - * This struct is allocated as AVHWFramesContext.hwctx
> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
>  */
>  typedef struct AVDXVA2FramesContext {
>  /**
> diff --git a/libavutil/hwcontext_mediacodec.h b/libavutil/hwcontext_mediacodec.h
> index fc0263cabc..e81193247b 100644
> --- a/libavutil/hwcontext_mediacodec.h
> +++ b/libavutil/hwcontext_mediacodec.h
> @@ -22,7 +22,7 @@
>  /**
>  * MediaCodec details.
>  *
> - * Allocated as AVHWDeviceContext.hwctx
> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>  */
>  typedef struct AVMediaCodecDeviceContext {
>  /**
> diff --git a/libavutil/hwcontext_opencl.h b/libavutil/hwcontext_opencl.h
> index ef54486c95..7abd97db2b 100644
> --- a/libavutil/hwcontext_opencl.h
> +++ b/libavutil/hwcontext_opencl.h
> @@ -58,7 +58,7 @@ typedef struct AVOpenCLFrameDescriptor {
>  /**
>  * OpenCL device details.
>  *
> - * Allocated as AVHWDeviceContext.hwctx
> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>  */
>  typedef struct AVOpenCLDeviceContext {
>  /**
> @@ -84,7 +84,7 @@ typedef struct AVOpenCLDeviceContext {
>  /**
>  * OpenCL-specific data associated with a frame pool.
>  *
> - * Allocated as AVHWFramesContext.hwctx.
> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
>  */
>  typedef struct AVOpenCLFramesContext {
>  /**
> diff --git a/libavutil/hwcontext_qsv.h b/libavutil/hwcontext_qsv.h
> index e2dba8ad83..b63ebddaef 100644
> --- a/libavutil/hwcontext_qsv.h
> +++ b/libavutil/hwcontext_qsv.h
> @@ -30,7 +30,7 @@
>  */
>  
>  /**
> - * This struct is allocated as AVHWDeviceContext.hwctx
> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>  */
>  typedef struct AVQSVDeviceContext {
>  mfxSession session;
> @@ -48,7 +48,7 @@ typedef struct AVQSVDeviceContext {
>  } AVQSVDeviceContext;
>  
>  /**
> - * This struct is allocated as AVHWFramesContext.hwctx
> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
>  */
>  typedef struct AVQSVFramesContext {
>  mfxFrameSurface1 *surfaces;
> diff --git a/libavutil/hwcontext_vaapi.h b/libavutil/hwcontext_vaapi.h
> index 0b2e071cb3..4a897eb851 100644
> --- a/libavutil/hwcontext_vaapi.h
> +++ b/libavutil/hwcontext_vaapi.h
> @@ -63,7 +63,7 @@ enum {
>  /**
>  * VAAPI connection details.
>  *
> - * Allocated as AVHWDeviceContext.hwctx
> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>  */
>  typedef struct AVVAAPIDeviceContext {
>  /**
> @@ -83,7 +83,7 @@ typedef struct AVVAAPIDeviceContext {
>  /**
>  * VAAPI-specific data associated with a frame pool.
>  *
> - * Allocated as AVHWFramesContext.hwctx.
> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
>  */
>  typedef struct AVVAAPIFramesContext {
>  /**
> @@ -105,7 +105,7 @@ typedef struct AVVAAPIFramesContext {
>  /**
>  * VAAPI hardware pipeline configuration details.
>  *
> - * Allocated with av_hwdevice_hwconfig_alloc().
> + * This struct is allocated with av_hwdevice_hwconfig_alloc().
>  */
>  typedef struct AVVAAPIHWConfig {
>  /**
> diff --git a/libavutil/hwcontext_vdpau.h b/libavutil/hwcontext_vdpau.h
> index 1b7ea1e443..e305caa595 100644
> --- a/libavutil/hwcontext_vdpau.h
> +++ b/libavutil/hwcontext_vdpau.h
> @@ -30,7 +30,7 @@
>  */
>  
>  /**
> - * This struct is allocated as AVHWDeviceContext.hwctx
> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>  */
>  typedef struct AVVDPAUDeviceContext {
>  VdpDevice          device;
> diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h
> index cbbd2390c1..1869870032 100644
> --- a/libavutil/hwcontext_vulkan.h
> +++ b/libavutil/hwcontext_vulkan.h
> @@ -39,7 +39,7 @@ typedef struct AVVkFrame AVVkFrame;
>  */
>  
>  /**
> - * Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
> + * Main Vulkan @ref md_doc_2context "context", allocated as AVHWDeviceContext.hwctx.
>  * All of these can be set before init to change what the context uses
>  */
>  typedef struct AVVulkanDeviceContext {
> @@ -172,7 +172,7 @@ typedef enum AVVkFrameFlags {
>  } AVVkFrameFlags;
>  
>  /**
> - * Allocated as AVHWFramesContext.hwctx, used to set pool-specific options
> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx, used to set pool-specific options
>  */
>  typedef struct AVVulkanFramesContext {
>  /**
> diff --git a/libavutil/lfg.h b/libavutil/lfg.h
> index e75a986f12..7f4ff5b62f 100644
> --- a/libavutil/lfg.h
> +++ b/libavutil/lfg.h
> @@ -25,7 +25,7 @@
>  #include <stdint.h>
>  
>  /**
> - * Context structure for the Lagged Fibonacci PRNG.
> + * @ref md_doc_2context "Context" structure for the Lagged Fibonacci PRNG.
>  * The exact layout, types and content of this struct may change and should
>  * not be accessed directly. Only its `sizeof()` is guaranteed to stay the same
>  * to allow easy instanciation.
>

Could you at least not put "context" in quotation marks?
To be honest, I'm not sure this makes documentation any better.
A context is an essential term we use in our codebase that's pretty
universal. Explaining again and again at every mention is annoying.
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation
  2024-05-02 11:01                     ` Lynne
@ 2024-05-02 11:14                       ` Andrew Sayers
  2024-05-02 13:00                       ` Zhao Zhili
  1 sibling, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-05-02 11:14 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Thu, May 02, 2024 at 01:01:43PM +0200, Lynne wrote:
> Apr 29, 2024, 11:24 by ffmpeg-devel@pileofstuff.org:
> 
> > Some headings needed to be rewritten to accomodate the text,
> > (hopefully) without changing the meaning.
> > ---
> >  libavcodec/aac/aacdec.h            |  2 +-
> >  libavcodec/aacenc.h                |  2 +-
> >  libavcodec/ac3enc.h                |  2 +-
> >  libavcodec/amfenc.h                |  2 +-
> >  libavcodec/atrac.h                 |  2 +-
> >  libavcodec/avcodec.h               |  3 ++-
> >  libavcodec/bsf.h                   |  2 +-
> >  libavcodec/cbs.h                   |  2 +-
> >  libavcodec/d3d11va.h               |  3 +--
> >  libavcodec/h264dsp.h               |  2 +-
> >  libavcodec/h264pred.h              |  2 +-
> >  libavcodec/mediacodec.h            |  2 +-
> >  libavcodec/mpegaudiodec_template.c |  2 +-
> >  libavcodec/pthread_frame.c         |  4 ++--
> >  libavcodec/qsv.h                   |  6 ++++--
> >  libavcodec/sbr.h                   |  2 +-
> >  libavcodec/smacker.c               |  2 +-
> >  libavcodec/vdpau.h                 |  3 ++-
> >  libavcodec/videotoolbox.h          |  5 +++--
> >  libavfilter/avfilter.h             |  2 +-
> >  libavformat/avformat.h             |  3 ++-
> >  libavformat/avio.h                 |  3 ++-
> >  libavutil/audio_fifo.h             |  2 +-
> >  libavutil/hwcontext.h              | 21 ++++++++++++---------
> >  libavutil/hwcontext_cuda.h         |  2 +-
> >  libavutil/hwcontext_d3d11va.h      |  4 ++--
> >  libavutil/hwcontext_d3d12va.h      |  6 +++---
> >  libavutil/hwcontext_drm.h          |  2 +-
> >  libavutil/hwcontext_dxva2.h        |  4 ++--
> >  libavutil/hwcontext_mediacodec.h   |  2 +-
> >  libavutil/hwcontext_opencl.h       |  4 ++--
> >  libavutil/hwcontext_qsv.h          |  4 ++--
> >  libavutil/hwcontext_vaapi.h        |  6 +++---
> >  libavutil/hwcontext_vdpau.h        |  2 +-
> >  libavutil/hwcontext_vulkan.h       |  4 ++--
> >  libavutil/lfg.h                    |  2 +-
> >  36 files changed, 66 insertions(+), 57 deletions(-)
> >
> > diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
> > index 4cf764e2e9..71d61813f4 100644
> > --- a/libavcodec/aac/aacdec.h
> > +++ b/libavcodec/aac/aacdec.h
> > @@ -248,7 +248,7 @@ typedef struct AACDecDSP {
> >  } AACDecDSP;
> >  
> >  /**
> > - * main AAC decoding context
> > + * main AAC decoding @ref md_doc_2context "context"
> >  */
> >  struct AACDecContext {
> >  const struct AVClass  *class;
> > diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
> > index d07960620e..1a645f4719 100644
> > --- a/libavcodec/aacenc.h
> > +++ b/libavcodec/aacenc.h
> > @@ -207,7 +207,7 @@ typedef struct AACPCEInfo {
> >  } AACPCEInfo;
> >  
> >  /**
> > - * AAC encoder context
> > + * AAC encoder @ref md_doc_2context "context"
> >  */
> >  typedef struct AACEncContext {
> >  AVClass *av_class;
> > diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
> > index 30812617cc..c725007077 100644
> > --- a/libavcodec/ac3enc.h
> > +++ b/libavcodec/ac3enc.h
> > @@ -152,7 +152,7 @@ typedef struct AC3Block {
> >  } AC3Block;
> >  
> >  /**
> > - * AC-3 encoder private context.
> > + * AC-3 encoder private @ref md_doc_2context "context"
> >  */
> >  typedef struct AC3EncodeContext {
> >  AVClass *av_class;                      ///< AVClass used for AVOption
> > diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
> > index 2dbd378ef8..f142ede63a 100644
> > --- a/libavcodec/amfenc.h
> > +++ b/libavcodec/amfenc.h
> > @@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
> >  } AmfTraceWriter;
> >  
> >  /**
> > -* AMF encoder context
> > +* AMF encoder @ref md_doc_2context "context"
> >  */
> >  
> >  typedef struct AmfContext {
> > diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
> > index 05208bbee6..1527e376a9 100644
> > --- a/libavcodec/atrac.h
> > +++ b/libavcodec/atrac.h
> > @@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
> >  } AtracGainInfo;
> >  
> >  /**
> > - *  Gain compensation context structure.
> > + *  Gain compensation @ref md_doc_2context "context"
> >  */
> >  typedef struct AtracGCContext {
> >  float   gain_tab1[16];  ///< gain compensation level table
> > diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> > index 968009a192..9180fedca7 100644
> > --- a/libavcodec/avcodec.h
> > +++ b/libavcodec/avcodec.h
> > @@ -430,7 +430,8 @@ typedef struct RcOverride{
> >  #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
> >  
> >  /**
> > - * main external API structure.
> > + * @ref md_doc_2context "Context" for an encode or decode session
> > + *
> >  * New fields can be added to the end with minor version bumps.
> >  * Removal, reordering and changes to existing fields require a major
> >  * version bump.
> > diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
> > index a09c69f242..bf79afa7cc 100644
> > --- a/libavcodec/bsf.h
> > +++ b/libavcodec/bsf.h
> > @@ -56,7 +56,7 @@
> >  */
> >  
> >  /**
> > - * The bitstream filter state.
> > + * Bitstream filter @ref md_doc_2context "context"
> >  *
> >  * This struct must be allocated with av_bsf_alloc() and freed with
> >  * av_bsf_free().
> > diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h
> > index d479b1ac2d..0ff64d2fef 100644
> > --- a/libavcodec/cbs.h
> > +++ b/libavcodec/cbs.h
> > @@ -214,7 +214,7 @@ typedef void (*CBSTraceWriteCallback)(void *trace_context,
> >  int64_t value);
> >  
> >  /**
> > - * Context structure for coded bitstream operations.
> > + * @ref md_doc_2context "Context" structure for coded bitstream operations.
> >  */
> >  typedef struct CodedBitstreamContext {
> >  /**
> > diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
> > index 27f40e5519..ec0c472ab9 100644
> > --- a/libavcodec/d3d11va.h
> > +++ b/libavcodec/d3d11va.h
> > @@ -46,8 +46,7 @@
> >  */
> >  
> >  /**
> > - * This structure is used to provides the necessary configurations and data
> > - * to the Direct3D11 FFmpeg HWAccel implementation.
> > + * @ref md_doc_2context "Context" for the Direct3D11 FFmpeg HWAccel implementation
> >  *
> >  * The application must make it available as AVCodecContext.hwaccel_context.
> >  *
> > diff --git a/libavcodec/h264dsp.h b/libavcodec/h264dsp.h
> > index e0880c4d88..27256c5605 100644
> > --- a/libavcodec/h264dsp.h
> > +++ b/libavcodec/h264dsp.h
> > @@ -37,7 +37,7 @@ typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src,
> >  int weightd, int weights, int offset);
> >  
> >  /**
> > - * Context for storing H.264 DSP functions
> > + * @ref md_doc_2context "Context" for storing H.264 DSP functions
> >  */
> >  typedef struct H264DSPContext {
> >  /* weighted MC */
> > diff --git a/libavcodec/h264pred.h b/libavcodec/h264pred.h
> > index cb008548fc..2b076f8846 100644
> > --- a/libavcodec/h264pred.h
> > +++ b/libavcodec/h264pred.h
> > @@ -89,7 +89,7 @@
> >  #define PART_NOT_AVAILABLE -2
> >  
> >  /**
> > - * Context for storing H.264 prediction functions
> > + * @ref md_doc_2context "Context" for storing H.264 prediction functions
> >  */
> >  typedef struct H264PredContext {
> >  void(*pred4x4[9 + 3 + 3])(uint8_t *src, const uint8_t *topright,
> > diff --git a/libavcodec/mediacodec.h b/libavcodec/mediacodec.h
> > index 4e9b56a618..9967a7cfb3 100644
> > --- a/libavcodec/mediacodec.h
> > +++ b/libavcodec/mediacodec.h
> > @@ -26,7 +26,7 @@
> >  #include "libavcodec/avcodec.h"
> >  
> >  /**
> > - * This structure holds a reference to a android/view/Surface object that will
> > + * @ref md_doc_2context "Context" for the android/view/Surface object that will
> >  * be used as output by the decoder.
> >  *
> >  */
> > diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c
> > index c73b1e0054..15d63215d1 100644
> > --- a/libavcodec/mpegaudiodec_template.c
> > +++ b/libavcodec/mpegaudiodec_template.c
> > @@ -1691,7 +1691,7 @@ static int decode_frame_adu(AVCodecContext *avctx, AVFrame *frame,
> >  #if CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER
> >  
> >  /**
> > - * Context for MP3On4 decoder
> > + * @ref md_doc_2context "Context" for MP3On4 decoder
> >  */
> >  typedef struct MP3On4DecodeContext {
> >  int frames;                     ///< number of mp3 frames per block (number of mp3 decoder instances)
> > diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
> > index 67f09c1f48..74f05eedcf 100644
> > --- a/libavcodec/pthread_frame.c
> > +++ b/libavcodec/pthread_frame.c
> > @@ -71,7 +71,7 @@ typedef struct ThreadFrameProgress {
> >  } ThreadFrameProgress;
> >  
> >  /**
> > - * Context used by codec threads and stored in their AVCodecInternal thread_ctx.
> > + * @ref md_doc_2context "Context" used by codec threads and stored in their AVCodecInternal thread_ctx.
> >  */
> >  typedef struct PerThreadContext {
> >  struct FrameThreadContext *parent;
> > @@ -111,7 +111,7 @@ typedef struct PerThreadContext {
> >  } PerThreadContext;
> >  
> >  /**
> > - * Context stored in the client AVCodecInternal thread_ctx.
> > + * @ref md_doc_2context "Context" stored in the client AVCodecInternal thread_ctx.
> >  */
> >  typedef struct FrameThreadContext {
> >  PerThreadContext *threads;     ///< The contexts for each thread.
> > diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
> > index c156b08d07..8b8160a4b1 100644
> > --- a/libavcodec/qsv.h
> > +++ b/libavcodec/qsv.h
> > @@ -26,8 +26,10 @@
> >  #include "libavutil/buffer.h"
> >  
> >  /**
> > - * This struct is used for communicating QSV parameters between libavcodec and
> > - * the caller. It is managed by the caller and must be assigned to
> > + * @ref md_doc_2context "Context" for communicating QSV parameters between libavcodec
> > + * and the caller.
> > + *
> > + * It is managed by the caller and must be assigned to
> >  * AVCodecContext.hwaccel_context.
> >  * - decoding: hwaccel_context must be set on return from the get_format()
> >  *             callback
> > diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
> > index fe3a39603a..98ad9024a9 100644
> > --- a/libavcodec/sbr.h
> > +++ b/libavcodec/sbr.h
> > @@ -116,7 +116,7 @@ typedef struct SBRData {
> >  typedef struct SpectralBandReplication SpectralBandReplication;
> >  
> >  /**
> > - * aacsbr functions pointers
> > + * aacsbr functions pointer @ref md_doc_2context "context"
> >  */
> >  typedef struct AACSBRContext {
> >  int (*sbr_lf_gen)(SpectralBandReplication *sbr,
> > diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
> > index 8f198d6957..1ca39a74a0 100644
> > --- a/libavcodec/smacker.c
> > +++ b/libavcodec/smacker.c
> > @@ -68,7 +68,7 @@ typedef struct HuffEntry {
> >  } HuffEntry;
> >  
> >  /**
> > - * Context used for code reconstructing
> > + * @ref md_doc_2context "Context" used for code reconstructing
> >  */
> >  typedef struct HuffContext {
> >  int current;
> > diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
> > index 8021c25761..227b85727d 100644
> > --- a/libavcodec/vdpau.h
> > +++ b/libavcodec/vdpau.h
> > @@ -64,8 +64,9 @@ typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, struct AVFrame *,
> >  const VdpBitstreamBuffer *);
> >  
> >  /**
> > - * This structure is used to share data between the libavcodec library and
> > + * @ref md_doc_2context "Context" to share data between the libavcodec library and
> >  * the client video application.
> > + *
> >  * This structure will be allocated and stored in AVCodecContext.hwaccel_context
> >  * by av_vdpau_bind_context(). Members can be set by the user once
> >  * during initialization or through each AVCodecContext.get_buffer()
> > diff --git a/libavcodec/videotoolbox.h b/libavcodec/videotoolbox.h
> > index d68d76e400..f15e79f325 100644
> > --- a/libavcodec/videotoolbox.h
> > +++ b/libavcodec/videotoolbox.h
> > @@ -49,8 +49,9 @@
> >  #include "libavutil/attributes.h"
> >  
> >  /**
> > - * This struct holds all the information that needs to be passed
> > - * between the caller and libavcodec for initializing Videotoolbox decoding.
> > + * @ref md_doc_2context "Context" for information passed between the caller and libavcodec
> > + * for initializing Videotoolbox decoding.
> > + *
> >  * Its size is not a part of the public ABI, it must be allocated with
> >  * av_videotoolbox_alloc_context() and freed with av_free().
> >  */
> > diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
> > index a34e61f23c..54b5f9dc43 100644
> > --- a/libavfilter/avfilter.h
> > +++ b/libavfilter/avfilter.h
> > @@ -403,7 +403,7 @@ unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output);
> >  */
> >  #define AVFILTER_THREAD_SLICE (1 << 0)
> >  
> > -/** An instance of a filter */
> > +/** @ref md_doc_2context "Context" for a filter */
> >  struct AVFilterContext {
> >  const AVClass *av_class;        ///< needed for av_log() and filters common options
> >  
> > diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> > index 8afdcd9fd0..28243c06c4 100644
> > --- a/libavformat/avformat.h
> > +++ b/libavformat/avformat.h
> > @@ -1241,7 +1241,8 @@ enum AVDurationEstimationMethod {
> >  };
> >  
> >  /**
> > - * Format I/O context.
> > + * Format I/O @ref md_doc_2context "context"
> > + *
> >  * New fields can be added to the end with minor version bumps.
> >  * Removal, reordering and changes to existing fields require a major
> >  * version bump.
> > diff --git a/libavformat/avio.h b/libavformat/avio.h
> > index ebf611187d..b525c93194 100644
> > --- a/libavformat/avio.h
> > +++ b/libavformat/avio.h
> > @@ -146,7 +146,8 @@ enum AVIODataMarkerType {
> >  };
> >  
> >  /**
> > - * Bytestream IO Context.
> > + * Bytestream I/O @ref md_doc_2context "context"
> > + *
> >  * New public fields can be added with minor version bumps.
> >  * Removal, reordering and changes to existing public fields require
> >  * a major version bump.
> > diff --git a/libavutil/audio_fifo.h b/libavutil/audio_fifo.h
> > index fa5f59a2be..de29715462 100644
> > --- a/libavutil/audio_fifo.h
> > +++ b/libavutil/audio_fifo.h
> > @@ -39,7 +39,7 @@
> >  */
> >  
> >  /**
> > - * Context for an Audio FIFO Buffer.
> > + * @ref md_doc_2context "Context" for an Audio FIFO Buffer.
> >  *
> >  * - Operates at the sample level rather than the byte level.
> >  * - Supports multiple channels with either planar or packed sample format.
> > diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
> > index bac30debae..60064cf08b 100644
> > --- a/libavutil/hwcontext.h
> > +++ b/libavutil/hwcontext.h
> > @@ -41,12 +41,13 @@ enum AVHWDeviceType {
> >  };
> >  
> >  /**
> > - * This struct aggregates all the (hardware/vendor-specific) "high-level" state,
> > - * i.e. state that is not tied to a concrete processing configuration.
> > - * E.g., in an API that supports hardware-accelerated encoding and decoding,
> > - * this struct will (if possible) wrap the state that is common to both encoding
> > - * and decoding and from which specific instances of encoders or decoders can be
> > - * derived.
> > + * @ref md_doc_2context "Context" for (hardware/vendor-specific) "high-level" state.
> > + *
> > + * "High-level state" is anything that is not tied to a concrete processing
> > + * configuration. E.g., in an API that supports hardware-accelerated encoding
> > + * and decoding, this struct will (if possible) wrap the state that is common
> > + * to both encoding and decoding and from which specific instances of encoders
> > + * or decoders can be derived.
> >  *
> >  * This struct is reference-counted with the AVBuffer mechanism. The
> >  * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field
> > @@ -103,9 +104,11 @@ typedef struct AVHWDeviceContext {
> >  } AVHWDeviceContext;
> >  
> >  /**
> > - * This struct describes a set or pool of "hardware" frames (i.e. those with
> > - * data not located in normal system memory). All the frames in the pool are
> > - * assumed to be allocated in the same way and interchangeable.
> > + * @ref md_doc_2context "context" for a pool of "hardware" frames (those with
> > + * data not located in normal system memory)
> > + *
> > + * All the frames in the pool are assumed to be allocated in the same way and
> > + * interchangeable.
> >  *
> >  * This struct is reference-counted with the AVBuffer mechanism and tied to a
> >  * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor
> > diff --git a/libavutil/hwcontext_cuda.h b/libavutil/hwcontext_cuda.h
> > index cbad434fea..e259892688 100644
> > --- a/libavutil/hwcontext_cuda.h
> > +++ b/libavutil/hwcontext_cuda.h
> > @@ -37,7 +37,7 @@
> >  typedef struct AVCUDADeviceContextInternal AVCUDADeviceContextInternal;
> >  
> >  /**
> > - * This struct is allocated as AVHWDeviceContext.hwctx
> > + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >  */
> >  typedef struct AVCUDADeviceContext {
> >  CUcontext cuda_ctx;
> > diff --git a/libavutil/hwcontext_d3d11va.h b/libavutil/hwcontext_d3d11va.h
> > index 77d2d72f1b..101d1cb6f8 100644
> > --- a/libavutil/hwcontext_d3d11va.h
> > +++ b/libavutil/hwcontext_d3d11va.h
> > @@ -40,7 +40,7 @@
> >  #include <stdint.h>
> >  
> >  /**
> > - * This struct is allocated as AVHWDeviceContext.hwctx
> > + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >  */
> >  typedef struct AVD3D11VADeviceContext {
> >  /**
> > @@ -126,7 +126,7 @@ typedef struct AVD3D11FrameDescriptor {
> >  } AVD3D11FrameDescriptor;
> >  
> >  /**
> > - * This struct is allocated as AVHWFramesContext.hwctx
> > + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
> >  */
> >  typedef struct AVD3D11VAFramesContext {
> >  /**
> > diff --git a/libavutil/hwcontext_d3d12va.h b/libavutil/hwcontext_d3d12va.h
> > index ff06e6f2ef..c623914c2b 100644
> > --- a/libavutil/hwcontext_d3d12va.h
> > +++ b/libavutil/hwcontext_d3d12va.h
> > @@ -37,7 +37,7 @@
> >  #include <d3d12video.h>
> >  
> >  /**
> > - * @brief This struct is allocated as AVHWDeviceContext.hwctx
> > + * @brief This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >  *
> >  */
> >  typedef struct AVD3D12VADeviceContext {
> > @@ -78,7 +78,7 @@ typedef struct AVD3D12VADeviceContext {
> >  } AVD3D12VADeviceContext;
> >  
> >  /**
> > - * @brief This struct is used to sync d3d12 execution
> > + * @brief This @ref md_doc_2context "context" is used to sync d3d12 execution
> >  *
> >  */
> >  typedef struct AVD3D12VASyncContext {
> > @@ -120,7 +120,7 @@ typedef struct AVD3D12VAFrame {
> >  } AVD3D12VAFrame;
> >  
> >  /**
> > - * @brief This struct is allocated as AVHWFramesContext.hwctx
> > + * @brief This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
> >  *
> >  */
> >  typedef struct AVD3D12VAFramesContext {
> > diff --git a/libavutil/hwcontext_drm.h b/libavutil/hwcontext_drm.h
> > index 42709f215e..8329e69966 100644
> > --- a/libavutil/hwcontext_drm.h
> > +++ b/libavutil/hwcontext_drm.h
> > @@ -152,7 +152,7 @@ typedef struct AVDRMFrameDescriptor {
> >  /**
> >  * DRM device.
> >  *
> > - * Allocated as AVHWDeviceContext.hwctx.
> > + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx.
> >  */
> >  typedef struct AVDRMDeviceContext {
> >  /**
> > diff --git a/libavutil/hwcontext_dxva2.h b/libavutil/hwcontext_dxva2.h
> > index e1b79bc0de..c679c16af0 100644
> > --- a/libavutil/hwcontext_dxva2.h
> > +++ b/libavutil/hwcontext_dxva2.h
> > @@ -34,14 +34,14 @@
> >  #include <dxva2api.h>
> >  
> >  /**
> > - * This struct is allocated as AVHWDeviceContext.hwctx
> > + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >  */
> >  typedef struct AVDXVA2DeviceContext {
> >  IDirect3DDeviceManager9 *devmgr;
> >  } AVDXVA2DeviceContext;
> >  
> >  /**
> > - * This struct is allocated as AVHWFramesContext.hwctx
> > + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
> >  */
> >  typedef struct AVDXVA2FramesContext {
> >  /**
> > diff --git a/libavutil/hwcontext_mediacodec.h b/libavutil/hwcontext_mediacodec.h
> > index fc0263cabc..e81193247b 100644
> > --- a/libavutil/hwcontext_mediacodec.h
> > +++ b/libavutil/hwcontext_mediacodec.h
> > @@ -22,7 +22,7 @@
> >  /**
> >  * MediaCodec details.
> >  *
> > - * Allocated as AVHWDeviceContext.hwctx
> > + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >  */
> >  typedef struct AVMediaCodecDeviceContext {
> >  /**
> > diff --git a/libavutil/hwcontext_opencl.h b/libavutil/hwcontext_opencl.h
> > index ef54486c95..7abd97db2b 100644
> > --- a/libavutil/hwcontext_opencl.h
> > +++ b/libavutil/hwcontext_opencl.h
> > @@ -58,7 +58,7 @@ typedef struct AVOpenCLFrameDescriptor {
> >  /**
> >  * OpenCL device details.
> >  *
> > - * Allocated as AVHWDeviceContext.hwctx
> > + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >  */
> >  typedef struct AVOpenCLDeviceContext {
> >  /**
> > @@ -84,7 +84,7 @@ typedef struct AVOpenCLDeviceContext {
> >  /**
> >  * OpenCL-specific data associated with a frame pool.
> >  *
> > - * Allocated as AVHWFramesContext.hwctx.
> > + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
> >  */
> >  typedef struct AVOpenCLFramesContext {
> >  /**
> > diff --git a/libavutil/hwcontext_qsv.h b/libavutil/hwcontext_qsv.h
> > index e2dba8ad83..b63ebddaef 100644
> > --- a/libavutil/hwcontext_qsv.h
> > +++ b/libavutil/hwcontext_qsv.h
> > @@ -30,7 +30,7 @@
> >  */
> >  
> >  /**
> > - * This struct is allocated as AVHWDeviceContext.hwctx
> > + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >  */
> >  typedef struct AVQSVDeviceContext {
> >  mfxSession session;
> > @@ -48,7 +48,7 @@ typedef struct AVQSVDeviceContext {
> >  } AVQSVDeviceContext;
> >  
> >  /**
> > - * This struct is allocated as AVHWFramesContext.hwctx
> > + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
> >  */
> >  typedef struct AVQSVFramesContext {
> >  mfxFrameSurface1 *surfaces;
> > diff --git a/libavutil/hwcontext_vaapi.h b/libavutil/hwcontext_vaapi.h
> > index 0b2e071cb3..4a897eb851 100644
> > --- a/libavutil/hwcontext_vaapi.h
> > +++ b/libavutil/hwcontext_vaapi.h
> > @@ -63,7 +63,7 @@ enum {
> >  /**
> >  * VAAPI connection details.
> >  *
> > - * Allocated as AVHWDeviceContext.hwctx
> > + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >  */
> >  typedef struct AVVAAPIDeviceContext {
> >  /**
> > @@ -83,7 +83,7 @@ typedef struct AVVAAPIDeviceContext {
> >  /**
> >  * VAAPI-specific data associated with a frame pool.
> >  *
> > - * Allocated as AVHWFramesContext.hwctx.
> > + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
> >  */
> >  typedef struct AVVAAPIFramesContext {
> >  /**
> > @@ -105,7 +105,7 @@ typedef struct AVVAAPIFramesContext {
> >  /**
> >  * VAAPI hardware pipeline configuration details.
> >  *
> > - * Allocated with av_hwdevice_hwconfig_alloc().
> > + * This struct is allocated with av_hwdevice_hwconfig_alloc().
> >  */
> >  typedef struct AVVAAPIHWConfig {
> >  /**
> > diff --git a/libavutil/hwcontext_vdpau.h b/libavutil/hwcontext_vdpau.h
> > index 1b7ea1e443..e305caa595 100644
> > --- a/libavutil/hwcontext_vdpau.h
> > +++ b/libavutil/hwcontext_vdpau.h
> > @@ -30,7 +30,7 @@
> >  */
> >  
> >  /**
> > - * This struct is allocated as AVHWDeviceContext.hwctx
> > + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >  */
> >  typedef struct AVVDPAUDeviceContext {
> >  VdpDevice          device;
> > diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h
> > index cbbd2390c1..1869870032 100644
> > --- a/libavutil/hwcontext_vulkan.h
> > +++ b/libavutil/hwcontext_vulkan.h
> > @@ -39,7 +39,7 @@ typedef struct AVVkFrame AVVkFrame;
> >  */
> >  
> >  /**
> > - * Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
> > + * Main Vulkan @ref md_doc_2context "context", allocated as AVHWDeviceContext.hwctx.
> >  * All of these can be set before init to change what the context uses
> >  */
> >  typedef struct AVVulkanDeviceContext {
> > @@ -172,7 +172,7 @@ typedef enum AVVkFrameFlags {
> >  } AVVkFrameFlags;
> >  
> >  /**
> > - * Allocated as AVHWFramesContext.hwctx, used to set pool-specific options
> > + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx, used to set pool-specific options
> >  */
> >  typedef struct AVVulkanFramesContext {
> >  /**
> > diff --git a/libavutil/lfg.h b/libavutil/lfg.h
> > index e75a986f12..7f4ff5b62f 100644
> > --- a/libavutil/lfg.h
> > +++ b/libavutil/lfg.h
> > @@ -25,7 +25,7 @@
> >  #include <stdint.h>
> >  
> >  /**
> > - * Context structure for the Lagged Fibonacci PRNG.
> > + * @ref md_doc_2context "Context" structure for the Lagged Fibonacci PRNG.
> >  * The exact layout, types and content of this struct may change and should
> >  * not be accessed directly. Only its `sizeof()` is guaranteed to stay the same
> >  * to allow easy instanciation.
> >
> 
> Could you at least not put "context" in quotation marks?
> To be honest, I'm not sure this makes documentation any better.
> A context is an essential term we use in our codebase that's pretty
> universal. Explaining again and again at every mention is annoying.

I'll check when I get back, but sadly the documentation implies quotation marks
are mandatory[0].  FWIW, it's rendered without quotes in the final documentation.

I don't really follow the second part - surely if it's essential for readers to
understand, and it's not common enough outside of FFmpeg that they can be
assumed to already know it, there need to be links everywhere in order for the
documentation to be any use to new readers?

[0] https://www.doxygen.nl/manual/commands.html#cmdref
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation
  2024-05-02 11:01                     ` Lynne
  2024-05-02 11:14                       ` Andrew Sayers
@ 2024-05-02 13:00                       ` Zhao Zhili
  2024-05-02 13:27                         ` Andrew Sayers
  1 sibling, 1 reply; 39+ messages in thread
From: Zhao Zhili @ 2024-05-02 13:00 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



> On May 2, 2024, at 19:01, Lynne <dev@lynne.ee> wrote:
> 
> Apr 29, 2024, 11:24 by ffmpeg-devel@pileofstuff.org:
> 
>> Some headings needed to be rewritten to accomodate the text,
>> (hopefully) without changing the meaning.
>> ---
>> libavcodec/aac/aacdec.h            |  2 +-
>> libavcodec/aacenc.h                |  2 +-
>> libavcodec/ac3enc.h                |  2 +-
>> libavcodec/amfenc.h                |  2 +-
>> libavcodec/atrac.h                 |  2 +-
>> libavcodec/avcodec.h               |  3 ++-
>> libavcodec/bsf.h                   |  2 +-
>> libavcodec/cbs.h                   |  2 +-
>> libavcodec/d3d11va.h               |  3 +--
>> libavcodec/h264dsp.h               |  2 +-
>> libavcodec/h264pred.h              |  2 +-
>> libavcodec/mediacodec.h            |  2 +-
>> libavcodec/mpegaudiodec_template.c |  2 +-
>> libavcodec/pthread_frame.c         |  4 ++--
>> libavcodec/qsv.h                   |  6 ++++--
>> libavcodec/sbr.h                   |  2 +-
>> libavcodec/smacker.c               |  2 +-
>> libavcodec/vdpau.h                 |  3 ++-
>> libavcodec/videotoolbox.h          |  5 +++--
>> libavfilter/avfilter.h             |  2 +-
>> libavformat/avformat.h             |  3 ++-
>> libavformat/avio.h                 |  3 ++-
>> libavutil/audio_fifo.h             |  2 +-
>> libavutil/hwcontext.h              | 21 ++++++++++++---------
>> libavutil/hwcontext_cuda.h         |  2 +-
>> libavutil/hwcontext_d3d11va.h      |  4 ++--
>> libavutil/hwcontext_d3d12va.h      |  6 +++---
>> libavutil/hwcontext_drm.h          |  2 +-
>> libavutil/hwcontext_dxva2.h        |  4 ++--
>> libavutil/hwcontext_mediacodec.h   |  2 +-
>> libavutil/hwcontext_opencl.h       |  4 ++--
>> libavutil/hwcontext_qsv.h          |  4 ++--
>> libavutil/hwcontext_vaapi.h        |  6 +++---
>> libavutil/hwcontext_vdpau.h        |  2 +-
>> libavutil/hwcontext_vulkan.h       |  4 ++--
>> libavutil/lfg.h                    |  2 +-
>> 36 files changed, 66 insertions(+), 57 deletions(-)
>> 
>> diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
>> index 4cf764e2e9..71d61813f4 100644
>> --- a/libavcodec/aac/aacdec.h
>> +++ b/libavcodec/aac/aacdec.h
>> @@ -248,7 +248,7 @@ typedef struct AACDecDSP {
>> } AACDecDSP;
>> 
>> /**
>> - * main AAC decoding context
>> + * main AAC decoding @ref md_doc_2context "context"
>> */
>> struct AACDecContext {
>> const struct AVClass  *class;
>> diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
>> index d07960620e..1a645f4719 100644
>> --- a/libavcodec/aacenc.h
>> +++ b/libavcodec/aacenc.h
>> @@ -207,7 +207,7 @@ typedef struct AACPCEInfo {
>> } AACPCEInfo;
>> 
>> /**
>> - * AAC encoder context
>> + * AAC encoder @ref md_doc_2context "context"
>> */
>> typedef struct AACEncContext {
>> AVClass *av_class;
>> diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
>> index 30812617cc..c725007077 100644
>> --- a/libavcodec/ac3enc.h
>> +++ b/libavcodec/ac3enc.h
>> @@ -152,7 +152,7 @@ typedef struct AC3Block {
>> } AC3Block;
>> 
>> /**
>> - * AC-3 encoder private context.
>> + * AC-3 encoder private @ref md_doc_2context "context"
>> */
>> typedef struct AC3EncodeContext {
>> AVClass *av_class;                      ///< AVClass used for AVOption
>> diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
>> index 2dbd378ef8..f142ede63a 100644
>> --- a/libavcodec/amfenc.h
>> +++ b/libavcodec/amfenc.h
>> @@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
>> } AmfTraceWriter;
>> 
>> /**
>> -* AMF encoder context
>> +* AMF encoder @ref md_doc_2context "context"
>> */
>> 
>> typedef struct AmfContext {
>> diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
>> index 05208bbee6..1527e376a9 100644
>> --- a/libavcodec/atrac.h
>> +++ b/libavcodec/atrac.h
>> @@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
>> } AtracGainInfo;
>> 
>> /**
>> - *  Gain compensation context structure.
>> + *  Gain compensation @ref md_doc_2context "context"
>> */
>> typedef struct AtracGCContext {
>> float   gain_tab1[16];  ///< gain compensation level table
>> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
>> index 968009a192..9180fedca7 100644
>> --- a/libavcodec/avcodec.h
>> +++ b/libavcodec/avcodec.h
>> @@ -430,7 +430,8 @@ typedef struct RcOverride{
>> #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
>> 
>> /**
>> - * main external API structure.
>> + * @ref md_doc_2context "Context" for an encode or decode session
>> + *
>> * New fields can be added to the end with minor version bumps.
>> * Removal, reordering and changes to existing fields require a major
>> * version bump.
>> diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
>> index a09c69f242..bf79afa7cc 100644
>> --- a/libavcodec/bsf.h
>> +++ b/libavcodec/bsf.h
>> @@ -56,7 +56,7 @@
>> */
>> 
>> /**
>> - * The bitstream filter state.
>> + * Bitstream filter @ref md_doc_2context "context"
>> *
>> * This struct must be allocated with av_bsf_alloc() and freed with
>> * av_bsf_free().
>> diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h
>> index d479b1ac2d..0ff64d2fef 100644
>> --- a/libavcodec/cbs.h
>> +++ b/libavcodec/cbs.h
>> @@ -214,7 +214,7 @@ typedef void (*CBSTraceWriteCallback)(void *trace_context,
>> int64_t value);
>> 
>> /**
>> - * Context structure for coded bitstream operations.
>> + * @ref md_doc_2context "Context" structure for coded bitstream operations.
>> */
>> typedef struct CodedBitstreamContext {
>> /**
>> diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
>> index 27f40e5519..ec0c472ab9 100644
>> --- a/libavcodec/d3d11va.h
>> +++ b/libavcodec/d3d11va.h
>> @@ -46,8 +46,7 @@
>> */
>> 
>> /**
>> - * This structure is used to provides the necessary configurations and data
>> - * to the Direct3D11 FFmpeg HWAccel implementation.
>> + * @ref md_doc_2context "Context" for the Direct3D11 FFmpeg HWAccel implementation
>> *
>> * The application must make it available as AVCodecContext.hwaccel_context.
>> *
>> diff --git a/libavcodec/h264dsp.h b/libavcodec/h264dsp.h
>> index e0880c4d88..27256c5605 100644
>> --- a/libavcodec/h264dsp.h
>> +++ b/libavcodec/h264dsp.h
>> @@ -37,7 +37,7 @@ typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src,
>> int weightd, int weights, int offset);
>> 
>> /**
>> - * Context for storing H.264 DSP functions
>> + * @ref md_doc_2context "Context" for storing H.264 DSP functions
>> */
>> typedef struct H264DSPContext {
>> /* weighted MC */
>> diff --git a/libavcodec/h264pred.h b/libavcodec/h264pred.h
>> index cb008548fc..2b076f8846 100644
>> --- a/libavcodec/h264pred.h
>> +++ b/libavcodec/h264pred.h
>> @@ -89,7 +89,7 @@
>> #define PART_NOT_AVAILABLE -2
>> 
>> /**
>> - * Context for storing H.264 prediction functions
>> + * @ref md_doc_2context "Context" for storing H.264 prediction functions
>> */
>> typedef struct H264PredContext {
>> void(*pred4x4[9 + 3 + 3])(uint8_t *src, const uint8_t *topright,
>> diff --git a/libavcodec/mediacodec.h b/libavcodec/mediacodec.h
>> index 4e9b56a618..9967a7cfb3 100644
>> --- a/libavcodec/mediacodec.h
>> +++ b/libavcodec/mediacodec.h
>> @@ -26,7 +26,7 @@
>> #include "libavcodec/avcodec.h"
>> 
>> /**
>> - * This structure holds a reference to a android/view/Surface object that will
>> + * @ref md_doc_2context "Context" for the android/view/Surface object that will
>> * be used as output by the decoder.
>> *
>> */
>> diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c
>> index c73b1e0054..15d63215d1 100644
>> --- a/libavcodec/mpegaudiodec_template.c
>> +++ b/libavcodec/mpegaudiodec_template.c
>> @@ -1691,7 +1691,7 @@ static int decode_frame_adu(AVCodecContext *avctx, AVFrame *frame,
>> #if CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER
>> 
>> /**
>> - * Context for MP3On4 decoder
>> + * @ref md_doc_2context "Context" for MP3On4 decoder
>> */
>> typedef struct MP3On4DecodeContext {
>> int frames;                     ///< number of mp3 frames per block (number of mp3 decoder instances)
>> diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
>> index 67f09c1f48..74f05eedcf 100644
>> --- a/libavcodec/pthread_frame.c
>> +++ b/libavcodec/pthread_frame.c
>> @@ -71,7 +71,7 @@ typedef struct ThreadFrameProgress {
>> } ThreadFrameProgress;
>> 
>> /**
>> - * Context used by codec threads and stored in their AVCodecInternal thread_ctx.
>> + * @ref md_doc_2context "Context" used by codec threads and stored in their AVCodecInternal thread_ctx.
>> */
>> typedef struct PerThreadContext {
>> struct FrameThreadContext *parent;
>> @@ -111,7 +111,7 @@ typedef struct PerThreadContext {
>> } PerThreadContext;
>> 
>> /**
>> - * Context stored in the client AVCodecInternal thread_ctx.
>> + * @ref md_doc_2context "Context" stored in the client AVCodecInternal thread_ctx.
>> */
>> typedef struct FrameThreadContext {
>> PerThreadContext *threads;     ///< The contexts for each thread.
>> diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
>> index c156b08d07..8b8160a4b1 100644
>> --- a/libavcodec/qsv.h
>> +++ b/libavcodec/qsv.h
>> @@ -26,8 +26,10 @@
>> #include "libavutil/buffer.h"
>> 
>> /**
>> - * This struct is used for communicating QSV parameters between libavcodec and
>> - * the caller. It is managed by the caller and must be assigned to
>> + * @ref md_doc_2context "Context" for communicating QSV parameters between libavcodec
>> + * and the caller.
>> + *
>> + * It is managed by the caller and must be assigned to
>> * AVCodecContext.hwaccel_context.
>> * - decoding: hwaccel_context must be set on return from the get_format()
>> *             callback
>> diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
>> index fe3a39603a..98ad9024a9 100644
>> --- a/libavcodec/sbr.h
>> +++ b/libavcodec/sbr.h
>> @@ -116,7 +116,7 @@ typedef struct SBRData {
>> typedef struct SpectralBandReplication SpectralBandReplication;
>> 
>> /**
>> - * aacsbr functions pointers
>> + * aacsbr functions pointer @ref md_doc_2context "context"
>> */
>> typedef struct AACSBRContext {
>> int (*sbr_lf_gen)(SpectralBandReplication *sbr,
>> diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
>> index 8f198d6957..1ca39a74a0 100644
>> --- a/libavcodec/smacker.c
>> +++ b/libavcodec/smacker.c
>> @@ -68,7 +68,7 @@ typedef struct HuffEntry {
>> } HuffEntry;
>> 
>> /**
>> - * Context used for code reconstructing
>> + * @ref md_doc_2context "Context" used for code reconstructing
>> */
>> typedef struct HuffContext {
>> int current;
>> diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
>> index 8021c25761..227b85727d 100644
>> --- a/libavcodec/vdpau.h
>> +++ b/libavcodec/vdpau.h
>> @@ -64,8 +64,9 @@ typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, struct AVFrame *,
>> const VdpBitstreamBuffer *);
>> 
>> /**
>> - * This structure is used to share data between the libavcodec library and
>> + * @ref md_doc_2context "Context" to share data between the libavcodec library and
>> * the client video application.
>> + *
>> * This structure will be allocated and stored in AVCodecContext.hwaccel_context
>> * by av_vdpau_bind_context(). Members can be set by the user once
>> * during initialization or through each AVCodecContext.get_buffer()
>> diff --git a/libavcodec/videotoolbox.h b/libavcodec/videotoolbox.h
>> index d68d76e400..f15e79f325 100644
>> --- a/libavcodec/videotoolbox.h
>> +++ b/libavcodec/videotoolbox.h
>> @@ -49,8 +49,9 @@
>> #include "libavutil/attributes.h"
>> 
>> /**
>> - * This struct holds all the information that needs to be passed
>> - * between the caller and libavcodec for initializing Videotoolbox decoding.
>> + * @ref md_doc_2context "Context" for information passed between the caller and libavcodec
>> + * for initializing Videotoolbox decoding.
>> + *
>> * Its size is not a part of the public ABI, it must be allocated with
>> * av_videotoolbox_alloc_context() and freed with av_free().
>> */
>> diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
>> index a34e61f23c..54b5f9dc43 100644
>> --- a/libavfilter/avfilter.h
>> +++ b/libavfilter/avfilter.h
>> @@ -403,7 +403,7 @@ unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output);
>> */
>> #define AVFILTER_THREAD_SLICE (1 << 0)
>> 
>> -/** An instance of a filter */
>> +/** @ref md_doc_2context "Context" for a filter */
>> struct AVFilterContext {
>> const AVClass *av_class;        ///< needed for av_log() and filters common options
>> 
>> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
>> index 8afdcd9fd0..28243c06c4 100644
>> --- a/libavformat/avformat.h
>> +++ b/libavformat/avformat.h
>> @@ -1241,7 +1241,8 @@ enum AVDurationEstimationMethod {
>> };
>> 
>> /**
>> - * Format I/O context.
>> + * Format I/O @ref md_doc_2context "context"
>> + *
>> * New fields can be added to the end with minor version bumps.
>> * Removal, reordering and changes to existing fields require a major
>> * version bump.
>> diff --git a/libavformat/avio.h b/libavformat/avio.h
>> index ebf611187d..b525c93194 100644
>> --- a/libavformat/avio.h
>> +++ b/libavformat/avio.h
>> @@ -146,7 +146,8 @@ enum AVIODataMarkerType {
>> };
>> 
>> /**
>> - * Bytestream IO Context.
>> + * Bytestream I/O @ref md_doc_2context "context"
>> + *
>> * New public fields can be added with minor version bumps.
>> * Removal, reordering and changes to existing public fields require
>> * a major version bump.
>> diff --git a/libavutil/audio_fifo.h b/libavutil/audio_fifo.h
>> index fa5f59a2be..de29715462 100644
>> --- a/libavutil/audio_fifo.h
>> +++ b/libavutil/audio_fifo.h
>> @@ -39,7 +39,7 @@
>> */
>> 
>> /**
>> - * Context for an Audio FIFO Buffer.
>> + * @ref md_doc_2context "Context" for an Audio FIFO Buffer.
>> *
>> * - Operates at the sample level rather than the byte level.
>> * - Supports multiple channels with either planar or packed sample format.
>> diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
>> index bac30debae..60064cf08b 100644
>> --- a/libavutil/hwcontext.h
>> +++ b/libavutil/hwcontext.h
>> @@ -41,12 +41,13 @@ enum AVHWDeviceType {
>> };
>> 
>> /**
>> - * This struct aggregates all the (hardware/vendor-specific) "high-level" state,
>> - * i.e. state that is not tied to a concrete processing configuration.
>> - * E.g., in an API that supports hardware-accelerated encoding and decoding,
>> - * this struct will (if possible) wrap the state that is common to both encoding
>> - * and decoding and from which specific instances of encoders or decoders can be
>> - * derived.
>> + * @ref md_doc_2context "Context" for (hardware/vendor-specific) "high-level" state.
>> + *
>> + * "High-level state" is anything that is not tied to a concrete processing
>> + * configuration. E.g., in an API that supports hardware-accelerated encoding
>> + * and decoding, this struct will (if possible) wrap the state that is common
>> + * to both encoding and decoding and from which specific instances of encoders
>> + * or decoders can be derived.
>> *
>> * This struct is reference-counted with the AVBuffer mechanism. The
>> * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field
>> @@ -103,9 +104,11 @@ typedef struct AVHWDeviceContext {
>> } AVHWDeviceContext;
>> 
>> /**
>> - * This struct describes a set or pool of "hardware" frames (i.e. those with
>> - * data not located in normal system memory). All the frames in the pool are
>> - * assumed to be allocated in the same way and interchangeable.
>> + * @ref md_doc_2context "context" for a pool of "hardware" frames (those with
>> + * data not located in normal system memory)
>> + *
>> + * All the frames in the pool are assumed to be allocated in the same way and
>> + * interchangeable.
>> *
>> * This struct is reference-counted with the AVBuffer mechanism and tied to a
>> * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor
>> diff --git a/libavutil/hwcontext_cuda.h b/libavutil/hwcontext_cuda.h
>> index cbad434fea..e259892688 100644
>> --- a/libavutil/hwcontext_cuda.h
>> +++ b/libavutil/hwcontext_cuda.h
>> @@ -37,7 +37,7 @@
>> typedef struct AVCUDADeviceContextInternal AVCUDADeviceContextInternal;
>> 
>> /**
>> - * This struct is allocated as AVHWDeviceContext.hwctx
>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>> */
>> typedef struct AVCUDADeviceContext {
>> CUcontext cuda_ctx;
>> diff --git a/libavutil/hwcontext_d3d11va.h b/libavutil/hwcontext_d3d11va.h
>> index 77d2d72f1b..101d1cb6f8 100644
>> --- a/libavutil/hwcontext_d3d11va.h
>> +++ b/libavutil/hwcontext_d3d11va.h
>> @@ -40,7 +40,7 @@
>> #include <stdint.h>
>> 
>> /**
>> - * This struct is allocated as AVHWDeviceContext.hwctx
>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>> */
>> typedef struct AVD3D11VADeviceContext {
>> /**
>> @@ -126,7 +126,7 @@ typedef struct AVD3D11FrameDescriptor {
>> } AVD3D11FrameDescriptor;
>> 
>> /**
>> - * This struct is allocated as AVHWFramesContext.hwctx
>> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
>> */
>> typedef struct AVD3D11VAFramesContext {
>> /**
>> diff --git a/libavutil/hwcontext_d3d12va.h b/libavutil/hwcontext_d3d12va.h
>> index ff06e6f2ef..c623914c2b 100644
>> --- a/libavutil/hwcontext_d3d12va.h
>> +++ b/libavutil/hwcontext_d3d12va.h
>> @@ -37,7 +37,7 @@
>> #include <d3d12video.h>
>> 
>> /**
>> - * @brief This struct is allocated as AVHWDeviceContext.hwctx
>> + * @brief This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>> *
>> */
>> typedef struct AVD3D12VADeviceContext {
>> @@ -78,7 +78,7 @@ typedef struct AVD3D12VADeviceContext {
>> } AVD3D12VADeviceContext;
>> 
>> /**
>> - * @brief This struct is used to sync d3d12 execution
>> + * @brief This @ref md_doc_2context "context" is used to sync d3d12 execution
>> *
>> */
>> typedef struct AVD3D12VASyncContext {
>> @@ -120,7 +120,7 @@ typedef struct AVD3D12VAFrame {
>> } AVD3D12VAFrame;
>> 
>> /**
>> - * @brief This struct is allocated as AVHWFramesContext.hwctx
>> + * @brief This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
>> *
>> */
>> typedef struct AVD3D12VAFramesContext {
>> diff --git a/libavutil/hwcontext_drm.h b/libavutil/hwcontext_drm.h
>> index 42709f215e..8329e69966 100644
>> --- a/libavutil/hwcontext_drm.h
>> +++ b/libavutil/hwcontext_drm.h
>> @@ -152,7 +152,7 @@ typedef struct AVDRMFrameDescriptor {
>> /**
>> * DRM device.
>> *
>> - * Allocated as AVHWDeviceContext.hwctx.
>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx.
>> */
>> typedef struct AVDRMDeviceContext {
>> /**
>> diff --git a/libavutil/hwcontext_dxva2.h b/libavutil/hwcontext_dxva2.h
>> index e1b79bc0de..c679c16af0 100644
>> --- a/libavutil/hwcontext_dxva2.h
>> +++ b/libavutil/hwcontext_dxva2.h
>> @@ -34,14 +34,14 @@
>> #include <dxva2api.h>
>> 
>> /**
>> - * This struct is allocated as AVHWDeviceContext.hwctx
>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>> */
>> typedef struct AVDXVA2DeviceContext {
>> IDirect3DDeviceManager9 *devmgr;
>> } AVDXVA2DeviceContext;
>> 
>> /**
>> - * This struct is allocated as AVHWFramesContext.hwctx
>> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
>> */
>> typedef struct AVDXVA2FramesContext {
>> /**
>> diff --git a/libavutil/hwcontext_mediacodec.h b/libavutil/hwcontext_mediacodec.h
>> index fc0263cabc..e81193247b 100644
>> --- a/libavutil/hwcontext_mediacodec.h
>> +++ b/libavutil/hwcontext_mediacodec.h
>> @@ -22,7 +22,7 @@
>> /**
>> * MediaCodec details.
>> *
>> - * Allocated as AVHWDeviceContext.hwctx
>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>> */
>> typedef struct AVMediaCodecDeviceContext {
>> /**
>> diff --git a/libavutil/hwcontext_opencl.h b/libavutil/hwcontext_opencl.h
>> index ef54486c95..7abd97db2b 100644
>> --- a/libavutil/hwcontext_opencl.h
>> +++ b/libavutil/hwcontext_opencl.h
>> @@ -58,7 +58,7 @@ typedef struct AVOpenCLFrameDescriptor {
>> /**
>> * OpenCL device details.
>> *
>> - * Allocated as AVHWDeviceContext.hwctx
>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>> */
>> typedef struct AVOpenCLDeviceContext {
>> /**
>> @@ -84,7 +84,7 @@ typedef struct AVOpenCLDeviceContext {
>> /**
>> * OpenCL-specific data associated with a frame pool.
>> *
>> - * Allocated as AVHWFramesContext.hwctx.
>> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
>> */
>> typedef struct AVOpenCLFramesContext {
>> /**
>> diff --git a/libavutil/hwcontext_qsv.h b/libavutil/hwcontext_qsv.h
>> index e2dba8ad83..b63ebddaef 100644
>> --- a/libavutil/hwcontext_qsv.h
>> +++ b/libavutil/hwcontext_qsv.h
>> @@ -30,7 +30,7 @@
>> */
>> 
>> /**
>> - * This struct is allocated as AVHWDeviceContext.hwctx
>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>> */
>> typedef struct AVQSVDeviceContext {
>> mfxSession session;
>> @@ -48,7 +48,7 @@ typedef struct AVQSVDeviceContext {
>> } AVQSVDeviceContext;
>> 
>> /**
>> - * This struct is allocated as AVHWFramesContext.hwctx
>> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
>> */
>> typedef struct AVQSVFramesContext {
>> mfxFrameSurface1 *surfaces;
>> diff --git a/libavutil/hwcontext_vaapi.h b/libavutil/hwcontext_vaapi.h
>> index 0b2e071cb3..4a897eb851 100644
>> --- a/libavutil/hwcontext_vaapi.h
>> +++ b/libavutil/hwcontext_vaapi.h
>> @@ -63,7 +63,7 @@ enum {
>> /**
>> * VAAPI connection details.
>> *
>> - * Allocated as AVHWDeviceContext.hwctx
>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>> */
>> typedef struct AVVAAPIDeviceContext {
>> /**
>> @@ -83,7 +83,7 @@ typedef struct AVVAAPIDeviceContext {
>> /**
>> * VAAPI-specific data associated with a frame pool.
>> *
>> - * Allocated as AVHWFramesContext.hwctx.
>> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
>> */
>> typedef struct AVVAAPIFramesContext {
>> /**
>> @@ -105,7 +105,7 @@ typedef struct AVVAAPIFramesContext {
>> /**
>> * VAAPI hardware pipeline configuration details.
>> *
>> - * Allocated with av_hwdevice_hwconfig_alloc().
>> + * This struct is allocated with av_hwdevice_hwconfig_alloc().
>> */
>> typedef struct AVVAAPIHWConfig {
>> /**
>> diff --git a/libavutil/hwcontext_vdpau.h b/libavutil/hwcontext_vdpau.h
>> index 1b7ea1e443..e305caa595 100644
>> --- a/libavutil/hwcontext_vdpau.h
>> +++ b/libavutil/hwcontext_vdpau.h
>> @@ -30,7 +30,7 @@
>> */
>> 
>> /**
>> - * This struct is allocated as AVHWDeviceContext.hwctx
>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>> */
>> typedef struct AVVDPAUDeviceContext {
>> VdpDevice          device;
>> diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h
>> index cbbd2390c1..1869870032 100644
>> --- a/libavutil/hwcontext_vulkan.h
>> +++ b/libavutil/hwcontext_vulkan.h
>> @@ -39,7 +39,7 @@ typedef struct AVVkFrame AVVkFrame;
>> */
>> 
>> /**
>> - * Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
>> + * Main Vulkan @ref md_doc_2context "context", allocated as AVHWDeviceContext.hwctx.
>> * All of these can be set before init to change what the context uses
>> */
>> typedef struct AVVulkanDeviceContext {
>> @@ -172,7 +172,7 @@ typedef enum AVVkFrameFlags {
>> } AVVkFrameFlags;
>> 
>> /**
>> - * Allocated as AVHWFramesContext.hwctx, used to set pool-specific options
>> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx, used to set pool-specific options
>> */
>> typedef struct AVVulkanFramesContext {
>> /**
>> diff --git a/libavutil/lfg.h b/libavutil/lfg.h
>> index e75a986f12..7f4ff5b62f 100644
>> --- a/libavutil/lfg.h
>> +++ b/libavutil/lfg.h
>> @@ -25,7 +25,7 @@
>> #include <stdint.h>
>> 
>> /**
>> - * Context structure for the Lagged Fibonacci PRNG.
>> + * @ref md_doc_2context "Context" structure for the Lagged Fibonacci PRNG.
>> * The exact layout, types and content of this struct may change and should
>> * not be accessed directly. Only its `sizeof()` is guaranteed to stay the same
>> * to allow easy instanciation.
>> 
> 
> Could you at least not put "context" in quotation marks?
> To be honest, I'm not sure this makes documentation any better.
> A context is an essential term we use in our codebase that's pretty
> universal. Explaining again and again at every mention is annoying.

+1. I don’t think “context" is specific to FFmpeg, it’s like common naming conventions.

> _______________________________________________
> 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".

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation
  2024-05-02 13:00                       ` Zhao Zhili
@ 2024-05-02 13:27                         ` Andrew Sayers
  2024-05-02 13:39                           ` Zhao Zhili
  0 siblings, 1 reply; 39+ messages in thread
From: Andrew Sayers @ 2024-05-02 13:27 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Thu, May 02, 2024 at 09:00:42PM +0800, Zhao Zhili wrote:
> 
> 
> > On May 2, 2024, at 19:01, Lynne <dev@lynne.ee> wrote:
> > 
> > Apr 29, 2024, 11:24 by ffmpeg-devel@pileofstuff.org:
> > 
> >> Some headings needed to be rewritten to accomodate the text,
> >> (hopefully) without changing the meaning.
> >> ---
> >> libavcodec/aac/aacdec.h            |  2 +-
> >> libavcodec/aacenc.h                |  2 +-
> >> libavcodec/ac3enc.h                |  2 +-
> >> libavcodec/amfenc.h                |  2 +-
> >> libavcodec/atrac.h                 |  2 +-
> >> libavcodec/avcodec.h               |  3 ++-
> >> libavcodec/bsf.h                   |  2 +-
> >> libavcodec/cbs.h                   |  2 +-
> >> libavcodec/d3d11va.h               |  3 +--
> >> libavcodec/h264dsp.h               |  2 +-
> >> libavcodec/h264pred.h              |  2 +-
> >> libavcodec/mediacodec.h            |  2 +-
> >> libavcodec/mpegaudiodec_template.c |  2 +-
> >> libavcodec/pthread_frame.c         |  4 ++--
> >> libavcodec/qsv.h                   |  6 ++++--
> >> libavcodec/sbr.h                   |  2 +-
> >> libavcodec/smacker.c               |  2 +-
> >> libavcodec/vdpau.h                 |  3 ++-
> >> libavcodec/videotoolbox.h          |  5 +++--
> >> libavfilter/avfilter.h             |  2 +-
> >> libavformat/avformat.h             |  3 ++-
> >> libavformat/avio.h                 |  3 ++-
> >> libavutil/audio_fifo.h             |  2 +-
> >> libavutil/hwcontext.h              | 21 ++++++++++++---------
> >> libavutil/hwcontext_cuda.h         |  2 +-
> >> libavutil/hwcontext_d3d11va.h      |  4 ++--
> >> libavutil/hwcontext_d3d12va.h      |  6 +++---
> >> libavutil/hwcontext_drm.h          |  2 +-
> >> libavutil/hwcontext_dxva2.h        |  4 ++--
> >> libavutil/hwcontext_mediacodec.h   |  2 +-
> >> libavutil/hwcontext_opencl.h       |  4 ++--
> >> libavutil/hwcontext_qsv.h          |  4 ++--
> >> libavutil/hwcontext_vaapi.h        |  6 +++---
> >> libavutil/hwcontext_vdpau.h        |  2 +-
> >> libavutil/hwcontext_vulkan.h       |  4 ++--
> >> libavutil/lfg.h                    |  2 +-
> >> 36 files changed, 66 insertions(+), 57 deletions(-)
> >> 
> >> diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
> >> index 4cf764e2e9..71d61813f4 100644
> >> --- a/libavcodec/aac/aacdec.h
> >> +++ b/libavcodec/aac/aacdec.h
> >> @@ -248,7 +248,7 @@ typedef struct AACDecDSP {
> >> } AACDecDSP;
> >> 
> >> /**
> >> - * main AAC decoding context
> >> + * main AAC decoding @ref md_doc_2context "context"
> >> */
> >> struct AACDecContext {
> >> const struct AVClass  *class;
> >> diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
> >> index d07960620e..1a645f4719 100644
> >> --- a/libavcodec/aacenc.h
> >> +++ b/libavcodec/aacenc.h
> >> @@ -207,7 +207,7 @@ typedef struct AACPCEInfo {
> >> } AACPCEInfo;
> >> 
> >> /**
> >> - * AAC encoder context
> >> + * AAC encoder @ref md_doc_2context "context"
> >> */
> >> typedef struct AACEncContext {
> >> AVClass *av_class;
> >> diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
> >> index 30812617cc..c725007077 100644
> >> --- a/libavcodec/ac3enc.h
> >> +++ b/libavcodec/ac3enc.h
> >> @@ -152,7 +152,7 @@ typedef struct AC3Block {
> >> } AC3Block;
> >> 
> >> /**
> >> - * AC-3 encoder private context.
> >> + * AC-3 encoder private @ref md_doc_2context "context"
> >> */
> >> typedef struct AC3EncodeContext {
> >> AVClass *av_class;                      ///< AVClass used for AVOption
> >> diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
> >> index 2dbd378ef8..f142ede63a 100644
> >> --- a/libavcodec/amfenc.h
> >> +++ b/libavcodec/amfenc.h
> >> @@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
> >> } AmfTraceWriter;
> >> 
> >> /**
> >> -* AMF encoder context
> >> +* AMF encoder @ref md_doc_2context "context"
> >> */
> >> 
> >> typedef struct AmfContext {
> >> diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
> >> index 05208bbee6..1527e376a9 100644
> >> --- a/libavcodec/atrac.h
> >> +++ b/libavcodec/atrac.h
> >> @@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
> >> } AtracGainInfo;
> >> 
> >> /**
> >> - *  Gain compensation context structure.
> >> + *  Gain compensation @ref md_doc_2context "context"
> >> */
> >> typedef struct AtracGCContext {
> >> float   gain_tab1[16];  ///< gain compensation level table
> >> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> >> index 968009a192..9180fedca7 100644
> >> --- a/libavcodec/avcodec.h
> >> +++ b/libavcodec/avcodec.h
> >> @@ -430,7 +430,8 @@ typedef struct RcOverride{
> >> #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
> >> 
> >> /**
> >> - * main external API structure.
> >> + * @ref md_doc_2context "Context" for an encode or decode session
> >> + *
> >> * New fields can be added to the end with minor version bumps.
> >> * Removal, reordering and changes to existing fields require a major
> >> * version bump.
> >> diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
> >> index a09c69f242..bf79afa7cc 100644
> >> --- a/libavcodec/bsf.h
> >> +++ b/libavcodec/bsf.h
> >> @@ -56,7 +56,7 @@
> >> */
> >> 
> >> /**
> >> - * The bitstream filter state.
> >> + * Bitstream filter @ref md_doc_2context "context"
> >> *
> >> * This struct must be allocated with av_bsf_alloc() and freed with
> >> * av_bsf_free().
> >> diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h
> >> index d479b1ac2d..0ff64d2fef 100644
> >> --- a/libavcodec/cbs.h
> >> +++ b/libavcodec/cbs.h
> >> @@ -214,7 +214,7 @@ typedef void (*CBSTraceWriteCallback)(void *trace_context,
> >> int64_t value);
> >> 
> >> /**
> >> - * Context structure for coded bitstream operations.
> >> + * @ref md_doc_2context "Context" structure for coded bitstream operations.
> >> */
> >> typedef struct CodedBitstreamContext {
> >> /**
> >> diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
> >> index 27f40e5519..ec0c472ab9 100644
> >> --- a/libavcodec/d3d11va.h
> >> +++ b/libavcodec/d3d11va.h
> >> @@ -46,8 +46,7 @@
> >> */
> >> 
> >> /**
> >> - * This structure is used to provides the necessary configurations and data
> >> - * to the Direct3D11 FFmpeg HWAccel implementation.
> >> + * @ref md_doc_2context "Context" for the Direct3D11 FFmpeg HWAccel implementation
> >> *
> >> * The application must make it available as AVCodecContext.hwaccel_context.
> >> *
> >> diff --git a/libavcodec/h264dsp.h b/libavcodec/h264dsp.h
> >> index e0880c4d88..27256c5605 100644
> >> --- a/libavcodec/h264dsp.h
> >> +++ b/libavcodec/h264dsp.h
> >> @@ -37,7 +37,7 @@ typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src,
> >> int weightd, int weights, int offset);
> >> 
> >> /**
> >> - * Context for storing H.264 DSP functions
> >> + * @ref md_doc_2context "Context" for storing H.264 DSP functions
> >> */
> >> typedef struct H264DSPContext {
> >> /* weighted MC */
> >> diff --git a/libavcodec/h264pred.h b/libavcodec/h264pred.h
> >> index cb008548fc..2b076f8846 100644
> >> --- a/libavcodec/h264pred.h
> >> +++ b/libavcodec/h264pred.h
> >> @@ -89,7 +89,7 @@
> >> #define PART_NOT_AVAILABLE -2
> >> 
> >> /**
> >> - * Context for storing H.264 prediction functions
> >> + * @ref md_doc_2context "Context" for storing H.264 prediction functions
> >> */
> >> typedef struct H264PredContext {
> >> void(*pred4x4[9 + 3 + 3])(uint8_t *src, const uint8_t *topright,
> >> diff --git a/libavcodec/mediacodec.h b/libavcodec/mediacodec.h
> >> index 4e9b56a618..9967a7cfb3 100644
> >> --- a/libavcodec/mediacodec.h
> >> +++ b/libavcodec/mediacodec.h
> >> @@ -26,7 +26,7 @@
> >> #include "libavcodec/avcodec.h"
> >> 
> >> /**
> >> - * This structure holds a reference to a android/view/Surface object that will
> >> + * @ref md_doc_2context "Context" for the android/view/Surface object that will
> >> * be used as output by the decoder.
> >> *
> >> */
> >> diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c
> >> index c73b1e0054..15d63215d1 100644
> >> --- a/libavcodec/mpegaudiodec_template.c
> >> +++ b/libavcodec/mpegaudiodec_template.c
> >> @@ -1691,7 +1691,7 @@ static int decode_frame_adu(AVCodecContext *avctx, AVFrame *frame,
> >> #if CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER
> >> 
> >> /**
> >> - * Context for MP3On4 decoder
> >> + * @ref md_doc_2context "Context" for MP3On4 decoder
> >> */
> >> typedef struct MP3On4DecodeContext {
> >> int frames;                     ///< number of mp3 frames per block (number of mp3 decoder instances)
> >> diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
> >> index 67f09c1f48..74f05eedcf 100644
> >> --- a/libavcodec/pthread_frame.c
> >> +++ b/libavcodec/pthread_frame.c
> >> @@ -71,7 +71,7 @@ typedef struct ThreadFrameProgress {
> >> } ThreadFrameProgress;
> >> 
> >> /**
> >> - * Context used by codec threads and stored in their AVCodecInternal thread_ctx.
> >> + * @ref md_doc_2context "Context" used by codec threads and stored in their AVCodecInternal thread_ctx.
> >> */
> >> typedef struct PerThreadContext {
> >> struct FrameThreadContext *parent;
> >> @@ -111,7 +111,7 @@ typedef struct PerThreadContext {
> >> } PerThreadContext;
> >> 
> >> /**
> >> - * Context stored in the client AVCodecInternal thread_ctx.
> >> + * @ref md_doc_2context "Context" stored in the client AVCodecInternal thread_ctx.
> >> */
> >> typedef struct FrameThreadContext {
> >> PerThreadContext *threads;     ///< The contexts for each thread.
> >> diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
> >> index c156b08d07..8b8160a4b1 100644
> >> --- a/libavcodec/qsv.h
> >> +++ b/libavcodec/qsv.h
> >> @@ -26,8 +26,10 @@
> >> #include "libavutil/buffer.h"
> >> 
> >> /**
> >> - * This struct is used for communicating QSV parameters between libavcodec and
> >> - * the caller. It is managed by the caller and must be assigned to
> >> + * @ref md_doc_2context "Context" for communicating QSV parameters between libavcodec
> >> + * and the caller.
> >> + *
> >> + * It is managed by the caller and must be assigned to
> >> * AVCodecContext.hwaccel_context.
> >> * - decoding: hwaccel_context must be set on return from the get_format()
> >> *             callback
> >> diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
> >> index fe3a39603a..98ad9024a9 100644
> >> --- a/libavcodec/sbr.h
> >> +++ b/libavcodec/sbr.h
> >> @@ -116,7 +116,7 @@ typedef struct SBRData {
> >> typedef struct SpectralBandReplication SpectralBandReplication;
> >> 
> >> /**
> >> - * aacsbr functions pointers
> >> + * aacsbr functions pointer @ref md_doc_2context "context"
> >> */
> >> typedef struct AACSBRContext {
> >> int (*sbr_lf_gen)(SpectralBandReplication *sbr,
> >> diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
> >> index 8f198d6957..1ca39a74a0 100644
> >> --- a/libavcodec/smacker.c
> >> +++ b/libavcodec/smacker.c
> >> @@ -68,7 +68,7 @@ typedef struct HuffEntry {
> >> } HuffEntry;
> >> 
> >> /**
> >> - * Context used for code reconstructing
> >> + * @ref md_doc_2context "Context" used for code reconstructing
> >> */
> >> typedef struct HuffContext {
> >> int current;
> >> diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
> >> index 8021c25761..227b85727d 100644
> >> --- a/libavcodec/vdpau.h
> >> +++ b/libavcodec/vdpau.h
> >> @@ -64,8 +64,9 @@ typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, struct AVFrame *,
> >> const VdpBitstreamBuffer *);
> >> 
> >> /**
> >> - * This structure is used to share data between the libavcodec library and
> >> + * @ref md_doc_2context "Context" to share data between the libavcodec library and
> >> * the client video application.
> >> + *
> >> * This structure will be allocated and stored in AVCodecContext.hwaccel_context
> >> * by av_vdpau_bind_context(). Members can be set by the user once
> >> * during initialization or through each AVCodecContext.get_buffer()
> >> diff --git a/libavcodec/videotoolbox.h b/libavcodec/videotoolbox.h
> >> index d68d76e400..f15e79f325 100644
> >> --- a/libavcodec/videotoolbox.h
> >> +++ b/libavcodec/videotoolbox.h
> >> @@ -49,8 +49,9 @@
> >> #include "libavutil/attributes.h"
> >> 
> >> /**
> >> - * This struct holds all the information that needs to be passed
> >> - * between the caller and libavcodec for initializing Videotoolbox decoding.
> >> + * @ref md_doc_2context "Context" for information passed between the caller and libavcodec
> >> + * for initializing Videotoolbox decoding.
> >> + *
> >> * Its size is not a part of the public ABI, it must be allocated with
> >> * av_videotoolbox_alloc_context() and freed with av_free().
> >> */
> >> diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
> >> index a34e61f23c..54b5f9dc43 100644
> >> --- a/libavfilter/avfilter.h
> >> +++ b/libavfilter/avfilter.h
> >> @@ -403,7 +403,7 @@ unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output);
> >> */
> >> #define AVFILTER_THREAD_SLICE (1 << 0)
> >> 
> >> -/** An instance of a filter */
> >> +/** @ref md_doc_2context "Context" for a filter */
> >> struct AVFilterContext {
> >> const AVClass *av_class;        ///< needed for av_log() and filters common options
> >> 
> >> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> >> index 8afdcd9fd0..28243c06c4 100644
> >> --- a/libavformat/avformat.h
> >> +++ b/libavformat/avformat.h
> >> @@ -1241,7 +1241,8 @@ enum AVDurationEstimationMethod {
> >> };
> >> 
> >> /**
> >> - * Format I/O context.
> >> + * Format I/O @ref md_doc_2context "context"
> >> + *
> >> * New fields can be added to the end with minor version bumps.
> >> * Removal, reordering and changes to existing fields require a major
> >> * version bump.
> >> diff --git a/libavformat/avio.h b/libavformat/avio.h
> >> index ebf611187d..b525c93194 100644
> >> --- a/libavformat/avio.h
> >> +++ b/libavformat/avio.h
> >> @@ -146,7 +146,8 @@ enum AVIODataMarkerType {
> >> };
> >> 
> >> /**
> >> - * Bytestream IO Context.
> >> + * Bytestream I/O @ref md_doc_2context "context"
> >> + *
> >> * New public fields can be added with minor version bumps.
> >> * Removal, reordering and changes to existing public fields require
> >> * a major version bump.
> >> diff --git a/libavutil/audio_fifo.h b/libavutil/audio_fifo.h
> >> index fa5f59a2be..de29715462 100644
> >> --- a/libavutil/audio_fifo.h
> >> +++ b/libavutil/audio_fifo.h
> >> @@ -39,7 +39,7 @@
> >> */
> >> 
> >> /**
> >> - * Context for an Audio FIFO Buffer.
> >> + * @ref md_doc_2context "Context" for an Audio FIFO Buffer.
> >> *
> >> * - Operates at the sample level rather than the byte level.
> >> * - Supports multiple channels with either planar or packed sample format.
> >> diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
> >> index bac30debae..60064cf08b 100644
> >> --- a/libavutil/hwcontext.h
> >> +++ b/libavutil/hwcontext.h
> >> @@ -41,12 +41,13 @@ enum AVHWDeviceType {
> >> };
> >> 
> >> /**
> >> - * This struct aggregates all the (hardware/vendor-specific) "high-level" state,
> >> - * i.e. state that is not tied to a concrete processing configuration.
> >> - * E.g., in an API that supports hardware-accelerated encoding and decoding,
> >> - * this struct will (if possible) wrap the state that is common to both encoding
> >> - * and decoding and from which specific instances of encoders or decoders can be
> >> - * derived.
> >> + * @ref md_doc_2context "Context" for (hardware/vendor-specific) "high-level" state.
> >> + *
> >> + * "High-level state" is anything that is not tied to a concrete processing
> >> + * configuration. E.g., in an API that supports hardware-accelerated encoding
> >> + * and decoding, this struct will (if possible) wrap the state that is common
> >> + * to both encoding and decoding and from which specific instances of encoders
> >> + * or decoders can be derived.
> >> *
> >> * This struct is reference-counted with the AVBuffer mechanism. The
> >> * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field
> >> @@ -103,9 +104,11 @@ typedef struct AVHWDeviceContext {
> >> } AVHWDeviceContext;
> >> 
> >> /**
> >> - * This struct describes a set or pool of "hardware" frames (i.e. those with
> >> - * data not located in normal system memory). All the frames in the pool are
> >> - * assumed to be allocated in the same way and interchangeable.
> >> + * @ref md_doc_2context "context" for a pool of "hardware" frames (those with
> >> + * data not located in normal system memory)
> >> + *
> >> + * All the frames in the pool are assumed to be allocated in the same way and
> >> + * interchangeable.
> >> *
> >> * This struct is reference-counted with the AVBuffer mechanism and tied to a
> >> * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor
> >> diff --git a/libavutil/hwcontext_cuda.h b/libavutil/hwcontext_cuda.h
> >> index cbad434fea..e259892688 100644
> >> --- a/libavutil/hwcontext_cuda.h
> >> +++ b/libavutil/hwcontext_cuda.h
> >> @@ -37,7 +37,7 @@
> >> typedef struct AVCUDADeviceContextInternal AVCUDADeviceContextInternal;
> >> 
> >> /**
> >> - * This struct is allocated as AVHWDeviceContext.hwctx
> >> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >> */
> >> typedef struct AVCUDADeviceContext {
> >> CUcontext cuda_ctx;
> >> diff --git a/libavutil/hwcontext_d3d11va.h b/libavutil/hwcontext_d3d11va.h
> >> index 77d2d72f1b..101d1cb6f8 100644
> >> --- a/libavutil/hwcontext_d3d11va.h
> >> +++ b/libavutil/hwcontext_d3d11va.h
> >> @@ -40,7 +40,7 @@
> >> #include <stdint.h>
> >> 
> >> /**
> >> - * This struct is allocated as AVHWDeviceContext.hwctx
> >> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >> */
> >> typedef struct AVD3D11VADeviceContext {
> >> /**
> >> @@ -126,7 +126,7 @@ typedef struct AVD3D11FrameDescriptor {
> >> } AVD3D11FrameDescriptor;
> >> 
> >> /**
> >> - * This struct is allocated as AVHWFramesContext.hwctx
> >> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
> >> */
> >> typedef struct AVD3D11VAFramesContext {
> >> /**
> >> diff --git a/libavutil/hwcontext_d3d12va.h b/libavutil/hwcontext_d3d12va.h
> >> index ff06e6f2ef..c623914c2b 100644
> >> --- a/libavutil/hwcontext_d3d12va.h
> >> +++ b/libavutil/hwcontext_d3d12va.h
> >> @@ -37,7 +37,7 @@
> >> #include <d3d12video.h>
> >> 
> >> /**
> >> - * @brief This struct is allocated as AVHWDeviceContext.hwctx
> >> + * @brief This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >> *
> >> */
> >> typedef struct AVD3D12VADeviceContext {
> >> @@ -78,7 +78,7 @@ typedef struct AVD3D12VADeviceContext {
> >> } AVD3D12VADeviceContext;
> >> 
> >> /**
> >> - * @brief This struct is used to sync d3d12 execution
> >> + * @brief This @ref md_doc_2context "context" is used to sync d3d12 execution
> >> *
> >> */
> >> typedef struct AVD3D12VASyncContext {
> >> @@ -120,7 +120,7 @@ typedef struct AVD3D12VAFrame {
> >> } AVD3D12VAFrame;
> >> 
> >> /**
> >> - * @brief This struct is allocated as AVHWFramesContext.hwctx
> >> + * @brief This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
> >> *
> >> */
> >> typedef struct AVD3D12VAFramesContext {
> >> diff --git a/libavutil/hwcontext_drm.h b/libavutil/hwcontext_drm.h
> >> index 42709f215e..8329e69966 100644
> >> --- a/libavutil/hwcontext_drm.h
> >> +++ b/libavutil/hwcontext_drm.h
> >> @@ -152,7 +152,7 @@ typedef struct AVDRMFrameDescriptor {
> >> /**
> >> * DRM device.
> >> *
> >> - * Allocated as AVHWDeviceContext.hwctx.
> >> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx.
> >> */
> >> typedef struct AVDRMDeviceContext {
> >> /**
> >> diff --git a/libavutil/hwcontext_dxva2.h b/libavutil/hwcontext_dxva2.h
> >> index e1b79bc0de..c679c16af0 100644
> >> --- a/libavutil/hwcontext_dxva2.h
> >> +++ b/libavutil/hwcontext_dxva2.h
> >> @@ -34,14 +34,14 @@
> >> #include <dxva2api.h>
> >> 
> >> /**
> >> - * This struct is allocated as AVHWDeviceContext.hwctx
> >> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >> */
> >> typedef struct AVDXVA2DeviceContext {
> >> IDirect3DDeviceManager9 *devmgr;
> >> } AVDXVA2DeviceContext;
> >> 
> >> /**
> >> - * This struct is allocated as AVHWFramesContext.hwctx
> >> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
> >> */
> >> typedef struct AVDXVA2FramesContext {
> >> /**
> >> diff --git a/libavutil/hwcontext_mediacodec.h b/libavutil/hwcontext_mediacodec.h
> >> index fc0263cabc..e81193247b 100644
> >> --- a/libavutil/hwcontext_mediacodec.h
> >> +++ b/libavutil/hwcontext_mediacodec.h
> >> @@ -22,7 +22,7 @@
> >> /**
> >> * MediaCodec details.
> >> *
> >> - * Allocated as AVHWDeviceContext.hwctx
> >> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >> */
> >> typedef struct AVMediaCodecDeviceContext {
> >> /**
> >> diff --git a/libavutil/hwcontext_opencl.h b/libavutil/hwcontext_opencl.h
> >> index ef54486c95..7abd97db2b 100644
> >> --- a/libavutil/hwcontext_opencl.h
> >> +++ b/libavutil/hwcontext_opencl.h
> >> @@ -58,7 +58,7 @@ typedef struct AVOpenCLFrameDescriptor {
> >> /**
> >> * OpenCL device details.
> >> *
> >> - * Allocated as AVHWDeviceContext.hwctx
> >> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >> */
> >> typedef struct AVOpenCLDeviceContext {
> >> /**
> >> @@ -84,7 +84,7 @@ typedef struct AVOpenCLDeviceContext {
> >> /**
> >> * OpenCL-specific data associated with a frame pool.
> >> *
> >> - * Allocated as AVHWFramesContext.hwctx.
> >> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
> >> */
> >> typedef struct AVOpenCLFramesContext {
> >> /**
> >> diff --git a/libavutil/hwcontext_qsv.h b/libavutil/hwcontext_qsv.h
> >> index e2dba8ad83..b63ebddaef 100644
> >> --- a/libavutil/hwcontext_qsv.h
> >> +++ b/libavutil/hwcontext_qsv.h
> >> @@ -30,7 +30,7 @@
> >> */
> >> 
> >> /**
> >> - * This struct is allocated as AVHWDeviceContext.hwctx
> >> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >> */
> >> typedef struct AVQSVDeviceContext {
> >> mfxSession session;
> >> @@ -48,7 +48,7 @@ typedef struct AVQSVDeviceContext {
> >> } AVQSVDeviceContext;
> >> 
> >> /**
> >> - * This struct is allocated as AVHWFramesContext.hwctx
> >> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
> >> */
> >> typedef struct AVQSVFramesContext {
> >> mfxFrameSurface1 *surfaces;
> >> diff --git a/libavutil/hwcontext_vaapi.h b/libavutil/hwcontext_vaapi.h
> >> index 0b2e071cb3..4a897eb851 100644
> >> --- a/libavutil/hwcontext_vaapi.h
> >> +++ b/libavutil/hwcontext_vaapi.h
> >> @@ -63,7 +63,7 @@ enum {
> >> /**
> >> * VAAPI connection details.
> >> *
> >> - * Allocated as AVHWDeviceContext.hwctx
> >> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >> */
> >> typedef struct AVVAAPIDeviceContext {
> >> /**
> >> @@ -83,7 +83,7 @@ typedef struct AVVAAPIDeviceContext {
> >> /**
> >> * VAAPI-specific data associated with a frame pool.
> >> *
> >> - * Allocated as AVHWFramesContext.hwctx.
> >> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
> >> */
> >> typedef struct AVVAAPIFramesContext {
> >> /**
> >> @@ -105,7 +105,7 @@ typedef struct AVVAAPIFramesContext {
> >> /**
> >> * VAAPI hardware pipeline configuration details.
> >> *
> >> - * Allocated with av_hwdevice_hwconfig_alloc().
> >> + * This struct is allocated with av_hwdevice_hwconfig_alloc().
> >> */
> >> typedef struct AVVAAPIHWConfig {
> >> /**
> >> diff --git a/libavutil/hwcontext_vdpau.h b/libavutil/hwcontext_vdpau.h
> >> index 1b7ea1e443..e305caa595 100644
> >> --- a/libavutil/hwcontext_vdpau.h
> >> +++ b/libavutil/hwcontext_vdpau.h
> >> @@ -30,7 +30,7 @@
> >> */
> >> 
> >> /**
> >> - * This struct is allocated as AVHWDeviceContext.hwctx
> >> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
> >> */
> >> typedef struct AVVDPAUDeviceContext {
> >> VdpDevice          device;
> >> diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h
> >> index cbbd2390c1..1869870032 100644
> >> --- a/libavutil/hwcontext_vulkan.h
> >> +++ b/libavutil/hwcontext_vulkan.h
> >> @@ -39,7 +39,7 @@ typedef struct AVVkFrame AVVkFrame;
> >> */
> >> 
> >> /**
> >> - * Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
> >> + * Main Vulkan @ref md_doc_2context "context", allocated as AVHWDeviceContext.hwctx.
> >> * All of these can be set before init to change what the context uses
> >> */
> >> typedef struct AVVulkanDeviceContext {
> >> @@ -172,7 +172,7 @@ typedef enum AVVkFrameFlags {
> >> } AVVkFrameFlags;
> >> 
> >> /**
> >> - * Allocated as AVHWFramesContext.hwctx, used to set pool-specific options
> >> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx, used to set pool-specific options
> >> */
> >> typedef struct AVVulkanFramesContext {
> >> /**
> >> diff --git a/libavutil/lfg.h b/libavutil/lfg.h
> >> index e75a986f12..7f4ff5b62f 100644
> >> --- a/libavutil/lfg.h
> >> +++ b/libavutil/lfg.h
> >> @@ -25,7 +25,7 @@
> >> #include <stdint.h>
> >> 
> >> /**
> >> - * Context structure for the Lagged Fibonacci PRNG.
> >> + * @ref md_doc_2context "Context" structure for the Lagged Fibonacci PRNG.
> >> * The exact layout, types and content of this struct may change and should
> >> * not be accessed directly. Only its `sizeof()` is guaranteed to stay the same
> >> * to allow easy instanciation.
> >> 
> > 
> > Could you at least not put "context" in quotation marks?
> > To be honest, I'm not sure this makes documentation any better.
> > A context is an essential term we use in our codebase that's pretty
> > universal. Explaining again and again at every mention is annoying.
> 
> +1. I don’t think “context" is specific to FFmpeg, it’s like common naming conventions.

Ooh, I don't suppose you've got some examples?  I know some other C
projects use similar concepts, but a compatible use of the word
"context" would really help explain things to newbies.
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation
  2024-05-02 13:27                         ` Andrew Sayers
@ 2024-05-02 13:39                           ` Zhao Zhili
  0 siblings, 0 replies; 39+ messages in thread
From: Zhao Zhili @ 2024-05-02 13:39 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



> On May 2, 2024, at 21:27, Andrew Sayers <ffmpeg-devel@pileofstuff.org> wrote:
> 
> On Thu, May 02, 2024 at 09:00:42PM +0800, Zhao Zhili wrote:
>> 
>> 
>>> On May 2, 2024, at 19:01, Lynne <dev@lynne.ee> wrote:
>>> 
>>> Apr 29, 2024, 11:24 by ffmpeg-devel@pileofstuff.org:
>>> 
>>>> Some headings needed to be rewritten to accomodate the text,
>>>> (hopefully) without changing the meaning.
>>>> ---
>>>> libavcodec/aac/aacdec.h            |  2 +-
>>>> libavcodec/aacenc.h                |  2 +-
>>>> libavcodec/ac3enc.h                |  2 +-
>>>> libavcodec/amfenc.h                |  2 +-
>>>> libavcodec/atrac.h                 |  2 +-
>>>> libavcodec/avcodec.h               |  3 ++-
>>>> libavcodec/bsf.h                   |  2 +-
>>>> libavcodec/cbs.h                   |  2 +-
>>>> libavcodec/d3d11va.h               |  3 +--
>>>> libavcodec/h264dsp.h               |  2 +-
>>>> libavcodec/h264pred.h              |  2 +-
>>>> libavcodec/mediacodec.h            |  2 +-
>>>> libavcodec/mpegaudiodec_template.c |  2 +-
>>>> libavcodec/pthread_frame.c         |  4 ++--
>>>> libavcodec/qsv.h                   |  6 ++++--
>>>> libavcodec/sbr.h                   |  2 +-
>>>> libavcodec/smacker.c               |  2 +-
>>>> libavcodec/vdpau.h                 |  3 ++-
>>>> libavcodec/videotoolbox.h          |  5 +++--
>>>> libavfilter/avfilter.h             |  2 +-
>>>> libavformat/avformat.h             |  3 ++-
>>>> libavformat/avio.h                 |  3 ++-
>>>> libavutil/audio_fifo.h             |  2 +-
>>>> libavutil/hwcontext.h              | 21 ++++++++++++---------
>>>> libavutil/hwcontext_cuda.h         |  2 +-
>>>> libavutil/hwcontext_d3d11va.h      |  4 ++--
>>>> libavutil/hwcontext_d3d12va.h      |  6 +++---
>>>> libavutil/hwcontext_drm.h          |  2 +-
>>>> libavutil/hwcontext_dxva2.h        |  4 ++--
>>>> libavutil/hwcontext_mediacodec.h   |  2 +-
>>>> libavutil/hwcontext_opencl.h       |  4 ++--
>>>> libavutil/hwcontext_qsv.h          |  4 ++--
>>>> libavutil/hwcontext_vaapi.h        |  6 +++---
>>>> libavutil/hwcontext_vdpau.h        |  2 +-
>>>> libavutil/hwcontext_vulkan.h       |  4 ++--
>>>> libavutil/lfg.h                    |  2 +-
>>>> 36 files changed, 66 insertions(+), 57 deletions(-)
>>>> 
>>>> diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
>>>> index 4cf764e2e9..71d61813f4 100644
>>>> --- a/libavcodec/aac/aacdec.h
>>>> +++ b/libavcodec/aac/aacdec.h
>>>> @@ -248,7 +248,7 @@ typedef struct AACDecDSP {
>>>> } AACDecDSP;
>>>> 
>>>> /**
>>>> - * main AAC decoding context
>>>> + * main AAC decoding @ref md_doc_2context "context"
>>>> */
>>>> struct AACDecContext {
>>>> const struct AVClass  *class;
>>>> diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
>>>> index d07960620e..1a645f4719 100644
>>>> --- a/libavcodec/aacenc.h
>>>> +++ b/libavcodec/aacenc.h
>>>> @@ -207,7 +207,7 @@ typedef struct AACPCEInfo {
>>>> } AACPCEInfo;
>>>> 
>>>> /**
>>>> - * AAC encoder context
>>>> + * AAC encoder @ref md_doc_2context "context"
>>>> */
>>>> typedef struct AACEncContext {
>>>> AVClass *av_class;
>>>> diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
>>>> index 30812617cc..c725007077 100644
>>>> --- a/libavcodec/ac3enc.h
>>>> +++ b/libavcodec/ac3enc.h
>>>> @@ -152,7 +152,7 @@ typedef struct AC3Block {
>>>> } AC3Block;
>>>> 
>>>> /**
>>>> - * AC-3 encoder private context.
>>>> + * AC-3 encoder private @ref md_doc_2context "context"
>>>> */
>>>> typedef struct AC3EncodeContext {
>>>> AVClass *av_class;                      ///< AVClass used for AVOption
>>>> diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
>>>> index 2dbd378ef8..f142ede63a 100644
>>>> --- a/libavcodec/amfenc.h
>>>> +++ b/libavcodec/amfenc.h
>>>> @@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
>>>> } AmfTraceWriter;
>>>> 
>>>> /**
>>>> -* AMF encoder context
>>>> +* AMF encoder @ref md_doc_2context "context"
>>>> */
>>>> 
>>>> typedef struct AmfContext {
>>>> diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
>>>> index 05208bbee6..1527e376a9 100644
>>>> --- a/libavcodec/atrac.h
>>>> +++ b/libavcodec/atrac.h
>>>> @@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
>>>> } AtracGainInfo;
>>>> 
>>>> /**
>>>> - *  Gain compensation context structure.
>>>> + *  Gain compensation @ref md_doc_2context "context"
>>>> */
>>>> typedef struct AtracGCContext {
>>>> float   gain_tab1[16];  ///< gain compensation level table
>>>> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
>>>> index 968009a192..9180fedca7 100644
>>>> --- a/libavcodec/avcodec.h
>>>> +++ b/libavcodec/avcodec.h
>>>> @@ -430,7 +430,8 @@ typedef struct RcOverride{
>>>> #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
>>>> 
>>>> /**
>>>> - * main external API structure.
>>>> + * @ref md_doc_2context "Context" for an encode or decode session
>>>> + *
>>>> * New fields can be added to the end with minor version bumps.
>>>> * Removal, reordering and changes to existing fields require a major
>>>> * version bump.
>>>> diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
>>>> index a09c69f242..bf79afa7cc 100644
>>>> --- a/libavcodec/bsf.h
>>>> +++ b/libavcodec/bsf.h
>>>> @@ -56,7 +56,7 @@
>>>> */
>>>> 
>>>> /**
>>>> - * The bitstream filter state.
>>>> + * Bitstream filter @ref md_doc_2context "context"
>>>> *
>>>> * This struct must be allocated with av_bsf_alloc() and freed with
>>>> * av_bsf_free().
>>>> diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h
>>>> index d479b1ac2d..0ff64d2fef 100644
>>>> --- a/libavcodec/cbs.h
>>>> +++ b/libavcodec/cbs.h
>>>> @@ -214,7 +214,7 @@ typedef void (*CBSTraceWriteCallback)(void *trace_context,
>>>> int64_t value);
>>>> 
>>>> /**
>>>> - * Context structure for coded bitstream operations.
>>>> + * @ref md_doc_2context "Context" structure for coded bitstream operations.
>>>> */
>>>> typedef struct CodedBitstreamContext {
>>>> /**
>>>> diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
>>>> index 27f40e5519..ec0c472ab9 100644
>>>> --- a/libavcodec/d3d11va.h
>>>> +++ b/libavcodec/d3d11va.h
>>>> @@ -46,8 +46,7 @@
>>>> */
>>>> 
>>>> /**
>>>> - * This structure is used to provides the necessary configurations and data
>>>> - * to the Direct3D11 FFmpeg HWAccel implementation.
>>>> + * @ref md_doc_2context "Context" for the Direct3D11 FFmpeg HWAccel implementation
>>>> *
>>>> * The application must make it available as AVCodecContext.hwaccel_context.
>>>> *
>>>> diff --git a/libavcodec/h264dsp.h b/libavcodec/h264dsp.h
>>>> index e0880c4d88..27256c5605 100644
>>>> --- a/libavcodec/h264dsp.h
>>>> +++ b/libavcodec/h264dsp.h
>>>> @@ -37,7 +37,7 @@ typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src,
>>>> int weightd, int weights, int offset);
>>>> 
>>>> /**
>>>> - * Context for storing H.264 DSP functions
>>>> + * @ref md_doc_2context "Context" for storing H.264 DSP functions
>>>> */
>>>> typedef struct H264DSPContext {
>>>> /* weighted MC */
>>>> diff --git a/libavcodec/h264pred.h b/libavcodec/h264pred.h
>>>> index cb008548fc..2b076f8846 100644
>>>> --- a/libavcodec/h264pred.h
>>>> +++ b/libavcodec/h264pred.h
>>>> @@ -89,7 +89,7 @@
>>>> #define PART_NOT_AVAILABLE -2
>>>> 
>>>> /**
>>>> - * Context for storing H.264 prediction functions
>>>> + * @ref md_doc_2context "Context" for storing H.264 prediction functions
>>>> */
>>>> typedef struct H264PredContext {
>>>> void(*pred4x4[9 + 3 + 3])(uint8_t *src, const uint8_t *topright,
>>>> diff --git a/libavcodec/mediacodec.h b/libavcodec/mediacodec.h
>>>> index 4e9b56a618..9967a7cfb3 100644
>>>> --- a/libavcodec/mediacodec.h
>>>> +++ b/libavcodec/mediacodec.h
>>>> @@ -26,7 +26,7 @@
>>>> #include "libavcodec/avcodec.h"
>>>> 
>>>> /**
>>>> - * This structure holds a reference to a android/view/Surface object that will
>>>> + * @ref md_doc_2context "Context" for the android/view/Surface object that will
>>>> * be used as output by the decoder.
>>>> *
>>>> */
>>>> diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c
>>>> index c73b1e0054..15d63215d1 100644
>>>> --- a/libavcodec/mpegaudiodec_template.c
>>>> +++ b/libavcodec/mpegaudiodec_template.c
>>>> @@ -1691,7 +1691,7 @@ static int decode_frame_adu(AVCodecContext *avctx, AVFrame *frame,
>>>> #if CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER
>>>> 
>>>> /**
>>>> - * Context for MP3On4 decoder
>>>> + * @ref md_doc_2context "Context" for MP3On4 decoder
>>>> */
>>>> typedef struct MP3On4DecodeContext {
>>>> int frames;                     ///< number of mp3 frames per block (number of mp3 decoder instances)
>>>> diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
>>>> index 67f09c1f48..74f05eedcf 100644
>>>> --- a/libavcodec/pthread_frame.c
>>>> +++ b/libavcodec/pthread_frame.c
>>>> @@ -71,7 +71,7 @@ typedef struct ThreadFrameProgress {
>>>> } ThreadFrameProgress;
>>>> 
>>>> /**
>>>> - * Context used by codec threads and stored in their AVCodecInternal thread_ctx.
>>>> + * @ref md_doc_2context "Context" used by codec threads and stored in their AVCodecInternal thread_ctx.
>>>> */
>>>> typedef struct PerThreadContext {
>>>> struct FrameThreadContext *parent;
>>>> @@ -111,7 +111,7 @@ typedef struct PerThreadContext {
>>>> } PerThreadContext;
>>>> 
>>>> /**
>>>> - * Context stored in the client AVCodecInternal thread_ctx.
>>>> + * @ref md_doc_2context "Context" stored in the client AVCodecInternal thread_ctx.
>>>> */
>>>> typedef struct FrameThreadContext {
>>>> PerThreadContext *threads;     ///< The contexts for each thread.
>>>> diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
>>>> index c156b08d07..8b8160a4b1 100644
>>>> --- a/libavcodec/qsv.h
>>>> +++ b/libavcodec/qsv.h
>>>> @@ -26,8 +26,10 @@
>>>> #include "libavutil/buffer.h"
>>>> 
>>>> /**
>>>> - * This struct is used for communicating QSV parameters between libavcodec and
>>>> - * the caller. It is managed by the caller and must be assigned to
>>>> + * @ref md_doc_2context "Context" for communicating QSV parameters between libavcodec
>>>> + * and the caller.
>>>> + *
>>>> + * It is managed by the caller and must be assigned to
>>>> * AVCodecContext.hwaccel_context.
>>>> * - decoding: hwaccel_context must be set on return from the get_format()
>>>> *             callback
>>>> diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
>>>> index fe3a39603a..98ad9024a9 100644
>>>> --- a/libavcodec/sbr.h
>>>> +++ b/libavcodec/sbr.h
>>>> @@ -116,7 +116,7 @@ typedef struct SBRData {
>>>> typedef struct SpectralBandReplication SpectralBandReplication;
>>>> 
>>>> /**
>>>> - * aacsbr functions pointers
>>>> + * aacsbr functions pointer @ref md_doc_2context "context"
>>>> */
>>>> typedef struct AACSBRContext {
>>>> int (*sbr_lf_gen)(SpectralBandReplication *sbr,
>>>> diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
>>>> index 8f198d6957..1ca39a74a0 100644
>>>> --- a/libavcodec/smacker.c
>>>> +++ b/libavcodec/smacker.c
>>>> @@ -68,7 +68,7 @@ typedef struct HuffEntry {
>>>> } HuffEntry;
>>>> 
>>>> /**
>>>> - * Context used for code reconstructing
>>>> + * @ref md_doc_2context "Context" used for code reconstructing
>>>> */
>>>> typedef struct HuffContext {
>>>> int current;
>>>> diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
>>>> index 8021c25761..227b85727d 100644
>>>> --- a/libavcodec/vdpau.h
>>>> +++ b/libavcodec/vdpau.h
>>>> @@ -64,8 +64,9 @@ typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, struct AVFrame *,
>>>> const VdpBitstreamBuffer *);
>>>> 
>>>> /**
>>>> - * This structure is used to share data between the libavcodec library and
>>>> + * @ref md_doc_2context "Context" to share data between the libavcodec library and
>>>> * the client video application.
>>>> + *
>>>> * This structure will be allocated and stored in AVCodecContext.hwaccel_context
>>>> * by av_vdpau_bind_context(). Members can be set by the user once
>>>> * during initialization or through each AVCodecContext.get_buffer()
>>>> diff --git a/libavcodec/videotoolbox.h b/libavcodec/videotoolbox.h
>>>> index d68d76e400..f15e79f325 100644
>>>> --- a/libavcodec/videotoolbox.h
>>>> +++ b/libavcodec/videotoolbox.h
>>>> @@ -49,8 +49,9 @@
>>>> #include "libavutil/attributes.h"
>>>> 
>>>> /**
>>>> - * This struct holds all the information that needs to be passed
>>>> - * between the caller and libavcodec for initializing Videotoolbox decoding.
>>>> + * @ref md_doc_2context "Context" for information passed between the caller and libavcodec
>>>> + * for initializing Videotoolbox decoding.
>>>> + *
>>>> * Its size is not a part of the public ABI, it must be allocated with
>>>> * av_videotoolbox_alloc_context() and freed with av_free().
>>>> */
>>>> diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
>>>> index a34e61f23c..54b5f9dc43 100644
>>>> --- a/libavfilter/avfilter.h
>>>> +++ b/libavfilter/avfilter.h
>>>> @@ -403,7 +403,7 @@ unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output);
>>>> */
>>>> #define AVFILTER_THREAD_SLICE (1 << 0)
>>>> 
>>>> -/** An instance of a filter */
>>>> +/** @ref md_doc_2context "Context" for a filter */
>>>> struct AVFilterContext {
>>>> const AVClass *av_class;        ///< needed for av_log() and filters common options
>>>> 
>>>> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
>>>> index 8afdcd9fd0..28243c06c4 100644
>>>> --- a/libavformat/avformat.h
>>>> +++ b/libavformat/avformat.h
>>>> @@ -1241,7 +1241,8 @@ enum AVDurationEstimationMethod {
>>>> };
>>>> 
>>>> /**
>>>> - * Format I/O context.
>>>> + * Format I/O @ref md_doc_2context "context"
>>>> + *
>>>> * New fields can be added to the end with minor version bumps.
>>>> * Removal, reordering and changes to existing fields require a major
>>>> * version bump.
>>>> diff --git a/libavformat/avio.h b/libavformat/avio.h
>>>> index ebf611187d..b525c93194 100644
>>>> --- a/libavformat/avio.h
>>>> +++ b/libavformat/avio.h
>>>> @@ -146,7 +146,8 @@ enum AVIODataMarkerType {
>>>> };
>>>> 
>>>> /**
>>>> - * Bytestream IO Context.
>>>> + * Bytestream I/O @ref md_doc_2context "context"
>>>> + *
>>>> * New public fields can be added with minor version bumps.
>>>> * Removal, reordering and changes to existing public fields require
>>>> * a major version bump.
>>>> diff --git a/libavutil/audio_fifo.h b/libavutil/audio_fifo.h
>>>> index fa5f59a2be..de29715462 100644
>>>> --- a/libavutil/audio_fifo.h
>>>> +++ b/libavutil/audio_fifo.h
>>>> @@ -39,7 +39,7 @@
>>>> */
>>>> 
>>>> /**
>>>> - * Context for an Audio FIFO Buffer.
>>>> + * @ref md_doc_2context "Context" for an Audio FIFO Buffer.
>>>> *
>>>> * - Operates at the sample level rather than the byte level.
>>>> * - Supports multiple channels with either planar or packed sample format.
>>>> diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
>>>> index bac30debae..60064cf08b 100644
>>>> --- a/libavutil/hwcontext.h
>>>> +++ b/libavutil/hwcontext.h
>>>> @@ -41,12 +41,13 @@ enum AVHWDeviceType {
>>>> };
>>>> 
>>>> /**
>>>> - * This struct aggregates all the (hardware/vendor-specific) "high-level" state,
>>>> - * i.e. state that is not tied to a concrete processing configuration.
>>>> - * E.g., in an API that supports hardware-accelerated encoding and decoding,
>>>> - * this struct will (if possible) wrap the state that is common to both encoding
>>>> - * and decoding and from which specific instances of encoders or decoders can be
>>>> - * derived.
>>>> + * @ref md_doc_2context "Context" for (hardware/vendor-specific) "high-level" state.
>>>> + *
>>>> + * "High-level state" is anything that is not tied to a concrete processing
>>>> + * configuration. E.g., in an API that supports hardware-accelerated encoding
>>>> + * and decoding, this struct will (if possible) wrap the state that is common
>>>> + * to both encoding and decoding and from which specific instances of encoders
>>>> + * or decoders can be derived.
>>>> *
>>>> * This struct is reference-counted with the AVBuffer mechanism. The
>>>> * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field
>>>> @@ -103,9 +104,11 @@ typedef struct AVHWDeviceContext {
>>>> } AVHWDeviceContext;
>>>> 
>>>> /**
>>>> - * This struct describes a set or pool of "hardware" frames (i.e. those with
>>>> - * data not located in normal system memory). All the frames in the pool are
>>>> - * assumed to be allocated in the same way and interchangeable.
>>>> + * @ref md_doc_2context "context" for a pool of "hardware" frames (those with
>>>> + * data not located in normal system memory)
>>>> + *
>>>> + * All the frames in the pool are assumed to be allocated in the same way and
>>>> + * interchangeable.
>>>> *
>>>> * This struct is reference-counted with the AVBuffer mechanism and tied to a
>>>> * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor
>>>> diff --git a/libavutil/hwcontext_cuda.h b/libavutil/hwcontext_cuda.h
>>>> index cbad434fea..e259892688 100644
>>>> --- a/libavutil/hwcontext_cuda.h
>>>> +++ b/libavutil/hwcontext_cuda.h
>>>> @@ -37,7 +37,7 @@
>>>> typedef struct AVCUDADeviceContextInternal AVCUDADeviceContextInternal;
>>>> 
>>>> /**
>>>> - * This struct is allocated as AVHWDeviceContext.hwctx
>>>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>>>> */
>>>> typedef struct AVCUDADeviceContext {
>>>> CUcontext cuda_ctx;
>>>> diff --git a/libavutil/hwcontext_d3d11va.h b/libavutil/hwcontext_d3d11va.h
>>>> index 77d2d72f1b..101d1cb6f8 100644
>>>> --- a/libavutil/hwcontext_d3d11va.h
>>>> +++ b/libavutil/hwcontext_d3d11va.h
>>>> @@ -40,7 +40,7 @@
>>>> #include <stdint.h>
>>>> 
>>>> /**
>>>> - * This struct is allocated as AVHWDeviceContext.hwctx
>>>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>>>> */
>>>> typedef struct AVD3D11VADeviceContext {
>>>> /**
>>>> @@ -126,7 +126,7 @@ typedef struct AVD3D11FrameDescriptor {
>>>> } AVD3D11FrameDescriptor;
>>>> 
>>>> /**
>>>> - * This struct is allocated as AVHWFramesContext.hwctx
>>>> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
>>>> */
>>>> typedef struct AVD3D11VAFramesContext {
>>>> /**
>>>> diff --git a/libavutil/hwcontext_d3d12va.h b/libavutil/hwcontext_d3d12va.h
>>>> index ff06e6f2ef..c623914c2b 100644
>>>> --- a/libavutil/hwcontext_d3d12va.h
>>>> +++ b/libavutil/hwcontext_d3d12va.h
>>>> @@ -37,7 +37,7 @@
>>>> #include <d3d12video.h>
>>>> 
>>>> /**
>>>> - * @brief This struct is allocated as AVHWDeviceContext.hwctx
>>>> + * @brief This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>>>> *
>>>> */
>>>> typedef struct AVD3D12VADeviceContext {
>>>> @@ -78,7 +78,7 @@ typedef struct AVD3D12VADeviceContext {
>>>> } AVD3D12VADeviceContext;
>>>> 
>>>> /**
>>>> - * @brief This struct is used to sync d3d12 execution
>>>> + * @brief This @ref md_doc_2context "context" is used to sync d3d12 execution
>>>> *
>>>> */
>>>> typedef struct AVD3D12VASyncContext {
>>>> @@ -120,7 +120,7 @@ typedef struct AVD3D12VAFrame {
>>>> } AVD3D12VAFrame;
>>>> 
>>>> /**
>>>> - * @brief This struct is allocated as AVHWFramesContext.hwctx
>>>> + * @brief This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
>>>> *
>>>> */
>>>> typedef struct AVD3D12VAFramesContext {
>>>> diff --git a/libavutil/hwcontext_drm.h b/libavutil/hwcontext_drm.h
>>>> index 42709f215e..8329e69966 100644
>>>> --- a/libavutil/hwcontext_drm.h
>>>> +++ b/libavutil/hwcontext_drm.h
>>>> @@ -152,7 +152,7 @@ typedef struct AVDRMFrameDescriptor {
>>>> /**
>>>> * DRM device.
>>>> *
>>>> - * Allocated as AVHWDeviceContext.hwctx.
>>>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx.
>>>> */
>>>> typedef struct AVDRMDeviceContext {
>>>> /**
>>>> diff --git a/libavutil/hwcontext_dxva2.h b/libavutil/hwcontext_dxva2.h
>>>> index e1b79bc0de..c679c16af0 100644
>>>> --- a/libavutil/hwcontext_dxva2.h
>>>> +++ b/libavutil/hwcontext_dxva2.h
>>>> @@ -34,14 +34,14 @@
>>>> #include <dxva2api.h>
>>>> 
>>>> /**
>>>> - * This struct is allocated as AVHWDeviceContext.hwctx
>>>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>>>> */
>>>> typedef struct AVDXVA2DeviceContext {
>>>> IDirect3DDeviceManager9 *devmgr;
>>>> } AVDXVA2DeviceContext;
>>>> 
>>>> /**
>>>> - * This struct is allocated as AVHWFramesContext.hwctx
>>>> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
>>>> */
>>>> typedef struct AVDXVA2FramesContext {
>>>> /**
>>>> diff --git a/libavutil/hwcontext_mediacodec.h b/libavutil/hwcontext_mediacodec.h
>>>> index fc0263cabc..e81193247b 100644
>>>> --- a/libavutil/hwcontext_mediacodec.h
>>>> +++ b/libavutil/hwcontext_mediacodec.h
>>>> @@ -22,7 +22,7 @@
>>>> /**
>>>> * MediaCodec details.
>>>> *
>>>> - * Allocated as AVHWDeviceContext.hwctx
>>>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>>>> */
>>>> typedef struct AVMediaCodecDeviceContext {
>>>> /**
>>>> diff --git a/libavutil/hwcontext_opencl.h b/libavutil/hwcontext_opencl.h
>>>> index ef54486c95..7abd97db2b 100644
>>>> --- a/libavutil/hwcontext_opencl.h
>>>> +++ b/libavutil/hwcontext_opencl.h
>>>> @@ -58,7 +58,7 @@ typedef struct AVOpenCLFrameDescriptor {
>>>> /**
>>>> * OpenCL device details.
>>>> *
>>>> - * Allocated as AVHWDeviceContext.hwctx
>>>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>>>> */
>>>> typedef struct AVOpenCLDeviceContext {
>>>> /**
>>>> @@ -84,7 +84,7 @@ typedef struct AVOpenCLDeviceContext {
>>>> /**
>>>> * OpenCL-specific data associated with a frame pool.
>>>> *
>>>> - * Allocated as AVHWFramesContext.hwctx.
>>>> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
>>>> */
>>>> typedef struct AVOpenCLFramesContext {
>>>> /**
>>>> diff --git a/libavutil/hwcontext_qsv.h b/libavutil/hwcontext_qsv.h
>>>> index e2dba8ad83..b63ebddaef 100644
>>>> --- a/libavutil/hwcontext_qsv.h
>>>> +++ b/libavutil/hwcontext_qsv.h
>>>> @@ -30,7 +30,7 @@
>>>> */
>>>> 
>>>> /**
>>>> - * This struct is allocated as AVHWDeviceContext.hwctx
>>>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>>>> */
>>>> typedef struct AVQSVDeviceContext {
>>>> mfxSession session;
>>>> @@ -48,7 +48,7 @@ typedef struct AVQSVDeviceContext {
>>>> } AVQSVDeviceContext;
>>>> 
>>>> /**
>>>> - * This struct is allocated as AVHWFramesContext.hwctx
>>>> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
>>>> */
>>>> typedef struct AVQSVFramesContext {
>>>> mfxFrameSurface1 *surfaces;
>>>> diff --git a/libavutil/hwcontext_vaapi.h b/libavutil/hwcontext_vaapi.h
>>>> index 0b2e071cb3..4a897eb851 100644
>>>> --- a/libavutil/hwcontext_vaapi.h
>>>> +++ b/libavutil/hwcontext_vaapi.h
>>>> @@ -63,7 +63,7 @@ enum {
>>>> /**
>>>> * VAAPI connection details.
>>>> *
>>>> - * Allocated as AVHWDeviceContext.hwctx
>>>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>>>> */
>>>> typedef struct AVVAAPIDeviceContext {
>>>> /**
>>>> @@ -83,7 +83,7 @@ typedef struct AVVAAPIDeviceContext {
>>>> /**
>>>> * VAAPI-specific data associated with a frame pool.
>>>> *
>>>> - * Allocated as AVHWFramesContext.hwctx.
>>>> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
>>>> */
>>>> typedef struct AVVAAPIFramesContext {
>>>> /**
>>>> @@ -105,7 +105,7 @@ typedef struct AVVAAPIFramesContext {
>>>> /**
>>>> * VAAPI hardware pipeline configuration details.
>>>> *
>>>> - * Allocated with av_hwdevice_hwconfig_alloc().
>>>> + * This struct is allocated with av_hwdevice_hwconfig_alloc().
>>>> */
>>>> typedef struct AVVAAPIHWConfig {
>>>> /**
>>>> diff --git a/libavutil/hwcontext_vdpau.h b/libavutil/hwcontext_vdpau.h
>>>> index 1b7ea1e443..e305caa595 100644
>>>> --- a/libavutil/hwcontext_vdpau.h
>>>> +++ b/libavutil/hwcontext_vdpau.h
>>>> @@ -30,7 +30,7 @@
>>>> */
>>>> 
>>>> /**
>>>> - * This struct is allocated as AVHWDeviceContext.hwctx
>>>> + * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
>>>> */
>>>> typedef struct AVVDPAUDeviceContext {
>>>> VdpDevice          device;
>>>> diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h
>>>> index cbbd2390c1..1869870032 100644
>>>> --- a/libavutil/hwcontext_vulkan.h
>>>> +++ b/libavutil/hwcontext_vulkan.h
>>>> @@ -39,7 +39,7 @@ typedef struct AVVkFrame AVVkFrame;
>>>> */
>>>> 
>>>> /**
>>>> - * Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
>>>> + * Main Vulkan @ref md_doc_2context "context", allocated as AVHWDeviceContext.hwctx.
>>>> * All of these can be set before init to change what the context uses
>>>> */
>>>> typedef struct AVVulkanDeviceContext {
>>>> @@ -172,7 +172,7 @@ typedef enum AVVkFrameFlags {
>>>> } AVVkFrameFlags;
>>>> 
>>>> /**
>>>> - * Allocated as AVHWFramesContext.hwctx, used to set pool-specific options
>>>> + * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx, used to set pool-specific options
>>>> */
>>>> typedef struct AVVulkanFramesContext {
>>>> /**
>>>> diff --git a/libavutil/lfg.h b/libavutil/lfg.h
>>>> index e75a986f12..7f4ff5b62f 100644
>>>> --- a/libavutil/lfg.h
>>>> +++ b/libavutil/lfg.h
>>>> @@ -25,7 +25,7 @@
>>>> #include <stdint.h>
>>>> 
>>>> /**
>>>> - * Context structure for the Lagged Fibonacci PRNG.
>>>> + * @ref md_doc_2context "Context" structure for the Lagged Fibonacci PRNG.
>>>> * The exact layout, types and content of this struct may change and should
>>>> * not be accessed directly. Only its `sizeof()` is guaranteed to stay the same
>>>> * to allow easy instanciation.
>>>> 
>>> 
>>> Could you at least not put "context" in quotation marks?
>>> To be honest, I'm not sure this makes documentation any better.
>>> A context is an essential term we use in our codebase that's pretty
>>> universal. Explaining again and again at every mention is annoying.
>> 
>> +1. I don’t think “context" is specific to FFmpeg, it’s like common naming conventions.
> 
> Ooh, I don't suppose you've got some examples?

Curl, libxml2, libevent.

>  I know some other C
> projects use similar concepts, but a compatible use of the word
> "context" would really help explain things to newbies.
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org <mailto:ffmpeg-devel-request@ffmpeg.org> with subject "unsubscribe".

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v3 1/3] doc: Explain what "context" means
  2024-04-29  9:10                 ` Andrew Sayers
  2024-05-02 10:03                   ` Andrew Sayers
@ 2024-05-05  7:29                   ` Stefano Sabatini
  2024-05-05 21:04                     ` Andrew Sayers
  1 sibling, 1 reply; 39+ messages in thread
From: Stefano Sabatini @ 2024-05-05  7:29 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On date Monday 2024-04-29 10:10:35 +0100, Andrew Sayers wrote:
> On Mon, Apr 22, 2024 at 07:05:12PM +0200, Stefano Sabatini wrote:
[...]
> > I don't have a strong opinion, but I'd probably focus on providing a
> > typical example of a common API (check doc/examples). Also I see here
> > there is a strong focus on OOP, this might be counter-productive in
> > case the reader is not familiar with OOP terminology.
> > 
> > OTOH the content might be useful for readers coming from an OOP
> > background and terminology. I wonder if this content might be isolated
> > in a dedicated section, so that non-OOP readers can simply skip it.
> > 
> > But this is not a strong objection, and can be possibly reworked in a
> > later step.
> > 
> 
> This is really a document for FFmpeg newbies, so we need to assume as
> little prior knowledge as possible.  After a few days to think it
> over, I think we should avoid assuming...
> 
> Knowledge of object-oriented programming.  For example, this should be
> useful to a research mathematician with a project that involves codec
> algorithms.  So the next draft should feel less like "FFmpeg for OOP
> devs" and more like "FFmpeg for newbies (with some optional OOP
> background reading)".
> 
> Knowing that programming doesn't *have* to be object-oriented.
> OOP has become so ubiquitous nowadays, there are plenty of programmers
> who will insist everything is OOP if you just speak loudly and slowly.
> This is a harder problem in some ways, because someone who doesn't
> understand can always re-read until they do, while someone who jumps
> to the wrong conclusion will just keep reading and try to make things
> fit their assumption (e.g. my earlier messages in this thread!).
> So the "how it differs from OOP" stuff needs to stay fairly prominent.
> 

> Knowing anything about FFmpeg (or multimedia in general).  I like the
> idea of tweaking `doc/examples` to better introduce FFmpeg
> fundamentals, but explaining "context" is a steep enough learning
> curve on its own - introducing concepts like "stream" and "codec" at
> the same time seems like too much.

But even if you show the API that does not mean you need to explain
it entirely, you only need to highligth the structural relationships:

    // create an instance context, whatever it is
    c = avcodec_alloc_context3(codec);
    if (!c) {
        fprintf(stderr, "Could not allocate video codec context\n");
        exit(1);
    }

    // set context parametres directly
    c->bit_rate = 400000;
    /* resolution must be a multiple of two */
    c->width = 352;
    c->height = 288;
    /* frames per second */
    c->time_base = (AVRational){1, 25};
    c->framerate = (AVRational){25, 1};

    // use av_opt API to set the options?
    ...

    // open the codec context provided a codec
    ret = avcodec_open2(c, codec, NULL);
    if (ret < 0) {
        fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
        exit(1);
    }

You might even replace avcodec_ with fooblargh_ and get the same
effect, with the addition that with avcodec_ you are already
familiarizing the user with the concrete API rather than with an
hypotetical one.

[...]

> I've also gone through the code looking for edge cases we haven't covered.
> Here are some questions trying to prompt an "oh yeah I forgot to mention
> that"-type answer.  Anything where the answer is more like "that should
> probably be rewritten to be clearer", let me know and I'll avoid confusing
> newbies with it.
> 

> av_ambient_viewing_environment_create_side_data() takes an AVFrame as its
> first argument, and returns a new AVAmbientViewingEnvironment.  What is the
> context object for that function - AVFrame or AVAmbientViewingEnvironment?

But this should be clear from the doxy:

/**
 * Allocate and add an AVAmbientViewingEnvironment structure to an existing
 * AVFrame as side data.
 *
 * @return the newly allocated struct, or NULL on failure
 */
AVAmbientViewingEnvironment *av_ambient_viewing_environment_create_side_data(AVFrame *frame);

Also, you are assuming that all the function should have a
context. That's not the case, as you don't always need to keep track
of a "context" when performing operations.

> 
> av_register_bitstream_filter() (deprecated 4.0, removed 5.0) took an
> `AVBitStreamFilter *` as its first argument, but I don't think you'd say
> the argument provided "context" for the function.  So would I be right in
> saying `AVBitStreamFilter *` is not a context, despite looking like one?

This was finally dropped so this is even missing. But again, it seems
you are assuming that all the functions should take a context, which
is not the case. In that case you had:
av_register_bistream_filter(filter)

which was registering the filter in the program global state.
 
> av_buffersink_*() all take a `const AVFilterContext *` argument.
> What does the difference between av_buffersink prefix and AVFilter type mean?

None, probabily it should have been named avfilter_buffersink since
this is a libavfilter API, seel below.

> av_channel_description_bprint() takes a `struct AVBPrint *` as its first
> argument, then `enum AVChannel`.  Is the context AVBPrint, AVChannel,
> or both?  Does it make sense for a function to have two contexts?

Again, this should be clear from the doxy:
/**
 * Get a human readable string describing a given channel.
 *
 * @param buf pre-allocated buffer where to put the generated string
 * @param buf_size size in bytes of the buffer.
 * @param channel the AVChannel whose description to get
 * @return amount of bytes needed to hold the output string, or a negative AVERROR
 *         on failure. If the returned value is bigger than buf_size, then the
 *         string was truncated.
 */
int av_channel_description(char *buf, size_t buf_size, enum AVChannel channel);

/**
 * bprint variant of av_channel_description().
 *
 * @note the string will be appended to the bprint buffer.
 */
void av_channel_description_bprint(struct AVBPrint *bp, enum AVChannel channel_id);

> Related to the previous question, does `av_cmp_q()` count as a function
> with two contexts?  Or no contexts?

And again, it looks like you are overgeneralizing and require that all
the functions take a context. In general, the C language is procedural
and so is the FFmpeg API. The fact that we are assuming some
constructs which might mimic or resemble OOP does not mean that all
the API was designed in that way.

> 
> Finally, a general question - functions of the form "avfoo" seem like they
> are more consistent than "av_foo".  Does the underscore mean anything?

This is due to the fact that despite the effort, implementing a
consistent API is difficult, also due to different
reviewers/contributors picking different conventions.

In some case we prefer av_ (most of libavutil) for the generic API,
while libavcodec/libavformat/libavfilter tend to use avLIB_, but there
might be exceptions.
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v4 1/4] doc: Explain what "context" means
  2024-04-29  9:24                 ` [FFmpeg-devel] [PATCH v4 1/4] " Andrew Sayers
                                     ` (2 preceding siblings ...)
  2024-04-29  9:24                   ` [FFmpeg-devel] [PATCH v4 4/4] lavf: Add documentation for private "Context" classes Andrew Sayers
@ 2024-05-05  8:31                   ` Andreas Rheinhardt
  2024-05-05 10:34                     ` Andrew Sayers
  3 siblings, 1 reply; 39+ messages in thread
From: Andreas Rheinhardt @ 2024-05-05  8:31 UTC (permalink / raw)
  To: ffmpeg-devel

Andrew Sayers:
> Derived from detailed explanations kindly provided by Stefano Sabatini:
> https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325903.html
> ---
>  doc/context.md | 308 +++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 308 insertions(+)
>  create mode 100644 doc/context.md
> 

Who is the intended audience of this file? (Aspiring) internal
developers or external API users?

- Andreas

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v4 1/4] doc: Explain what "context" means
  2024-05-05  8:31                   ` [FFmpeg-devel] [PATCH v4 1/4] doc: Explain what "context" means Andreas Rheinhardt
@ 2024-05-05 10:34                     ` Andrew Sayers
  0 siblings, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-05-05 10:34 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Sun, May 05, 2024 at 10:31:18AM +0200, Andreas Rheinhardt wrote:
> Andrew Sayers:
> > Derived from detailed explanations kindly provided by Stefano Sabatini:
> > https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325903.html
> > ---
> >  doc/context.md | 308 +++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 308 insertions(+)
> >  create mode 100644 doc/context.md
> > 
> 
> Who is the intended audience of this file? (Aspiring) internal
> developers or external API users?

External API users.  This needs to say e.g. "ignore anything called
`internal` or `priv_data`", whereas a document for new internal devs
would say which one to prefer in new code.  That would be very
useful, but well beyond my current abilities.

(I'm still travelling so have low mental and typing bandwidth, but am
thinking through other responses and should have time to respond in
the coming days)
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v3 1/3] doc: Explain what "context" means
  2024-05-05  7:29                   ` Stefano Sabatini
@ 2024-05-05 21:04                     ` Andrew Sayers
  0 siblings, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-05-05 21:04 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

I'm still travelling, so the following thoughts might be a bit
half-formed.  But I wanted to get some feedback before sitting down
for a proper think.

On Sun, May 05, 2024 at 09:29:10AM +0200, Stefano Sabatini wrote:
> On date Monday 2024-04-29 10:10:35 +0100, Andrew Sayers wrote:
> > On Mon, Apr 22, 2024 at 07:05:12PM +0200, Stefano Sabatini wrote:
> [...]
> > > I don't have a strong opinion, but I'd probably focus on providing a
> > > typical example of a common API (check doc/examples). Also I see here
> > > there is a strong focus on OOP, this might be counter-productive in
> > > case the reader is not familiar with OOP terminology.
> > > 
> > > OTOH the content might be useful for readers coming from an OOP
> > > background and terminology. I wonder if this content might be isolated
> > > in a dedicated section, so that non-OOP readers can simply skip it.
> > > 
> > > But this is not a strong objection, and can be possibly reworked in a
> > > later step.
> > > 
> > 
> > This is really a document for FFmpeg newbies, so we need to assume as
> > little prior knowledge as possible.  After a few days to think it
> > over, I think we should avoid assuming...
> > 
> > Knowledge of object-oriented programming.  For example, this should be
> > useful to a research mathematician with a project that involves codec
> > algorithms.  So the next draft should feel less like "FFmpeg for OOP
> > devs" and more like "FFmpeg for newbies (with some optional OOP
> > background reading)".
> > 
> > Knowing that programming doesn't *have* to be object-oriented.
> > OOP has become so ubiquitous nowadays, there are plenty of programmers
> > who will insist everything is OOP if you just speak loudly and slowly.
> > This is a harder problem in some ways, because someone who doesn't
> > understand can always re-read until they do, while someone who jumps
> > to the wrong conclusion will just keep reading and try to make things
> > fit their assumption (e.g. my earlier messages in this thread!).
> > So the "how it differs from OOP" stuff needs to stay fairly prominent.
> > 
> 
> > Knowing anything about FFmpeg (or multimedia in general).  I like the
> > idea of tweaking `doc/examples` to better introduce FFmpeg
> > fundamentals, but explaining "context" is a steep enough learning
> > curve on its own - introducing concepts like "stream" and "codec" at
> > the same time seems like too much.
> 
> But even if you show the API that does not mean you need to explain
> it entirely, you only need to highligth the structural relationships:
> 
>     // create an instance context, whatever it is
>     c = avcodec_alloc_context3(codec);
>     if (!c) {
>         fprintf(stderr, "Could not allocate video codec context\n");
>         exit(1);
>     }
> 
>     // set context parametres directly
>     c->bit_rate = 400000;
>     /* resolution must be a multiple of two */
>     c->width = 352;
>     c->height = 288;
>     /* frames per second */
>     c->time_base = (AVRational){1, 25};
>     c->framerate = (AVRational){25, 1};
> 
>     // use av_opt API to set the options?
>     ...
> 
>     // open the codec context provided a codec
>     ret = avcodec_open2(c, codec, NULL);
>     if (ret < 0) {
>         fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
>         exit(1);
>     }
> 
> You might even replace avcodec_ with fooblargh_ and get the same
> effect, with the addition that with avcodec_ you are already
> familiarizing the user with the concrete API rather than with an
> hypotetical one.
> 
> [...]
> 
> > I've also gone through the code looking for edge cases we haven't covered.
> > Here are some questions trying to prompt an "oh yeah I forgot to mention
> > that"-type answer.  Anything where the answer is more like "that should
> > probably be rewritten to be clearer", let me know and I'll avoid confusing
> > newbies with it.
> > 
> 
> > av_ambient_viewing_environment_create_side_data() takes an AVFrame as its
> > first argument, and returns a new AVAmbientViewingEnvironment.  What is the
> > context object for that function - AVFrame or AVAmbientViewingEnvironment?
> 
> But this should be clear from the doxy:
> 
> /**
>  * Allocate and add an AVAmbientViewingEnvironment structure to an existing
>  * AVFrame as side data.
>  *
>  * @return the newly allocated struct, or NULL on failure
>  */
> AVAmbientViewingEnvironment *av_ambient_viewing_environment_create_side_data(AVFrame *frame);

I'm afraid it's not clear, at least to me.  I think you're saying the
AVFrame is the context because a "create" function can't have a
context any more than a C++ "new" can be called as a member.  But the
function's prefix points to the other conclusion, and neither signal
is clear enough on its own.

My current thinking is to propose separate patches renaming arguments
to `ctx` whenever I find functions I can't parse.  That's not as good
as a simple rule like "the first argument is always the context", but
better than adding a paragraph or two about how to read the docs.

> Also, you are assuming that all the function should have a
> context. That's not the case, as you don't always need to keep track
> of a "context" when performing operations.

It sounds like there's a subtle distinction to be made here: when a
struct is named "FooContext" or a variable is named `ctx`, the writer
has signalled that "context" is the (only) correct interpretation.
OTOH, when something acts like a context but isn't explicitly
labelled as such, it may or may not have been intended as a context,
and treating it as one may or may not be helpful - it's more "if it
helps" than an objective fact.  That means reasonable people can
disagree about edge cases - for example, it's genuinely unclear
whether av_register_bitstream_filter()'s argument is a context, and
TBH if I weren't writing this doc I would just avoid thinking about
av_ambient_viewing_environment_create_side_data() altogether.

> 
> > 
> > av_register_bitstream_filter() (deprecated 4.0, removed 5.0) took an
> > `AVBitStreamFilter *` as its first argument, but I don't think you'd say
> > the argument provided "context" for the function.  So would I be right in
> > saying `AVBitStreamFilter *` is not a context, despite looking like one?
> 
> This was finally dropped so this is even missing. But again, it seems
> you are assuming that all the functions should take a context, which
> is not the case. In that case you had:
> av_register_bistream_filter(filter)
> 
> which was registering the filter in the program global state.
>  
> > av_buffersink_*() all take a `const AVFilterContext *` argument.
> > What does the difference between av_buffersink prefix and AVFilter type mean?
> 
> None, probabily it should have been named avfilter_buffersink since
> this is a libavfilter API, seel below.
> 
> > av_channel_description_bprint() takes a `struct AVBPrint *` as its first
> > argument, then `enum AVChannel`.  Is the context AVBPrint, AVChannel,
> > or both?  Does it make sense for a function to have two contexts?
> 
> Again, this should be clear from the doxy:
> /**
>  * Get a human readable string describing a given channel.
>  *
>  * @param buf pre-allocated buffer where to put the generated string
>  * @param buf_size size in bytes of the buffer.
>  * @param channel the AVChannel whose description to get
>  * @return amount of bytes needed to hold the output string, or a negative AVERROR
>  *         on failure. If the returned value is bigger than buf_size, then the
>  *         string was truncated.
>  */
> int av_channel_description(char *buf, size_t buf_size, enum AVChannel channel);
> 
> /**
>  * bprint variant of av_channel_description().
>  *
>  * @note the string will be appended to the bprint buffer.
>  */
> void av_channel_description_bprint(struct AVBPrint *bp, enum AVChannel channel_id);

I think you're saying that I should look at which word appears more
often in the doxy ("channel") rather than which word appears first in
the argument list ("buf")?  As above, the solution might be to rename
the variable in a separate patch rather than teach people another
special case.

> 
> > Related to the previous question, does `av_cmp_q()` count as a function
> > with two contexts?  Or no contexts?
> 
> And again, it looks like you are overgeneralizing and require that all
> the functions take a context. In general, the C language is procedural
> and so is the FFmpeg API. The fact that we are assuming some
> constructs which might mimic or resemble OOP does not mean that all
> the API was designed in that way.
> 
> > 
> > Finally, a general question - functions of the form "avfoo" seem like they
> > are more consistent than "av_foo".  Does the underscore mean anything?
> 
> This is due to the fact that despite the effort, implementing a
> consistent API is difficult, also due to different
> reviewers/contributors picking different conventions.
> 
> In some case we prefer av_ (most of libavutil) for the generic API,
> while libavcodec/libavformat/libavfilter tend to use avLIB_, but there
> might be exceptions.

Given all of the above (and Zhao Zhili's useful examples), I think
the document might be better like:

Section 1: context is a good way to think about some code constructs.
If you've ever used a callback function with an arbitrary callback
argument, you've used a context.  <quick example of a hypothetical
callback function with a context variable>.

Section 2: some projects explicitly use "context" as a metaphor.
<comparison of curl and FFmpeg's md5 contexts>.  This should be
understood as a broad metaphor that different people use to mean
slightly different things.

Section 3: FFmpeg has developed various conventions around contexts.
<discussion of a non-AVClass example that follows most patterns but
breaks some others>.

Section 4: user-facing contexts use AVClass+AVOptions.  This is a
common and highly visible special case, but not the inevitable
endpoint of all contexts.  <discussion of an AVClass-enabled object>.
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v4 0/4] Explain what "context" means
  2024-04-18 15:06 [FFmpeg-devel] [PATCH 1/3] doc: Explain what "context" means Andrew Sayers
                   ` (2 preceding siblings ...)
  2024-04-20  7:25 ` [FFmpeg-devel] [PATCH 1/3] doc: Explain what "context" means Stefano Sabatini
@ 2024-05-15 15:54 ` Andrew Sayers
  2024-05-15 15:54   ` [FFmpeg-devel] [PATCH v4 1/4] doc: " Andrew Sayers
                     ` (3 more replies)
  3 siblings, 4 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-05-15 15:54 UTC (permalink / raw)
  To: ffmpeg-devel

This version strongly implies AVClass is only used alongside AVOption.
I'm not sure when or if e.g. AVClass::category would be used by an external
API developer, but happy to change the text if anyone has a use case.

I accept the argument that the previous version was linked more widely
than it was useful, but instead of reducing links I've tried to widen
its usefulness.  The new version discusses how e.g. FFmpeg contexts differ
from curl, which could be useful to developers coming from other projects.
And it goes into more detail about e.g. context lifetime, which could
be useful for even an intermediate developer.

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v4 1/4] doc: Explain what "context" means
  2024-05-15 15:54 ` [FFmpeg-devel] [PATCH v4 0/4] Explain what "context" means Andrew Sayers
@ 2024-05-15 15:54   ` Andrew Sayers
  2024-05-15 15:54   ` [FFmpeg-devel] [PATCH v4 2/4] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-05-15 15:54 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

Derived from detailed explanations kindly provided by Stefano Sabatini:
https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325903.html
---
 doc/context.md | 394 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 394 insertions(+)
 create mode 100644 doc/context.md

diff --git a/doc/context.md b/doc/context.md
new file mode 100644
index 0000000000..fb85b3f366
--- /dev/null
+++ b/doc/context.md
@@ -0,0 +1,394 @@
+# Introduction to contexts
+
+&ldquo;%Context&rdquo; is a name for a widely-used programming idiom.
+This document explains the general idiom and the conventions FFmpeg has built around it.
+
+This document uses object-oriented analogies to help readers familiar with
+[object-oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming)
+learn about contexts.  But contexts can also be used outside of OOP,
+and even in situations where OOP isn't helpful.  So these analogies
+should only be used as a first step towards understanding contexts.
+
+## &ldquo;Context&rdquo; as a way to think about code
+
+A context is any data structure that is passed to several functions
+(or several instances of the same function) that all operate on the same entity.
+For example, [object-oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming)
+languages usually provide member functions with a `this` or `self` value:
+
+```c
+class my_cxx_class {
+  void my_member_function() {
+    // the implicit object parameter provides context for the member function:
+    std::cout << this;
+  }
+};
+```
+
+Contexts are a fundamental building block of OOP, but can also be used in procedural code.
+For example, most callback functions can be understood to use contexts:
+
+```c
+struct MyStruct {
+  int counter;
+};
+
+void my_callback( void *my_var_ ) {
+  // my_var provides context for the callback function:
+  struct MyStruct *my_var = (struct MyStruct *)my_var_;
+  printf("Called %d time(s)", ++my_var->counter);
+}
+
+void init() {
+  struct MyStruct my_var;
+  my_var.counter = 0;
+  register_callback( my_callback, &my_var );
+}
+```
+
+In the broadest sense, &ldquo;context&rdquo; is just a way to think about code.
+You can even use it to think about code written by people who have never
+heard the term, or who would disagree with you about what it means.
+
+## &ldquo;Context&rdquo; as a tool of communication
+
+&ldquo;%Context&ldquo; can just be a word to understand code in your own head,
+but it can also be a term you use to explain your interfaces.
+Here is a version of the callback example that makes the context explicit:
+
+```c
+struct CallbackContext {
+  int counter;
+};
+
+void my_callback( void *ctx_ ) {
+  // ctx provides context for the callback function:
+  struct CallbackContext *ctx = (struct CallbackContext *)ctx_;
+  printf("Called %d time(s)", ++ctx->counter);
+}
+
+void init() {
+  struct CallbackContext ctx;
+  ctx.counter = 0;
+  register_callback( my_callback, &ctx );
+}
+```
+
+The difference here is subtle, but important.  If a piece of code
+*appears compatible with contexts*, then you are *allowed to think
+that way*, but if a piece of code *explicitly states it uses
+contexts*, then you are *required to follow that approach*.
+
+For example, imagine someone modified `MyStruct` in the earlier example
+to count several unrelated events across the whole program.  That would mean
+it contained information about multiple entities, so was not a context.
+But nobody ever *said* it was a context, so that isn't necessarily wrong.
+However, proposing the same change to the `CallbackContext` in the later example
+would violate a guarantee, and should be pointed out in a code review.
+
+@warning Guaranteeing to use contexts does not mean guaranteeing to use
+object-oriented programming.  For example, FFmpeg creates its contexts
+procedurally instead of with constructors.
+
+## Contexts in the real world
+
+To understand how contexts are used in the real world, it might be
+useful to compare [curl's MD5 hash context](https://github.com/curl/curl/blob/bbeeccdea8507ff50efca70a0b33d28aef720267/lib/curl_md5.h#L48)
+with @ref AVMD5 "FFmpeg's equivalent context".
+
+The [MD5 algorithm](https://en.wikipedia.org/wiki/MD5) produces
+a fixed-length digest from arbitrary-length data.  It does this by calculating
+the digest for a prefix of the data, then loading the next part and adding it
+to the previous digest, and so on.  Projects that use MD5 generally use some
+kind of context, so comparing them can reveal differences between projects.
+
+```c
+// Curl's MD5 context looks like this:
+struct MD5_context {
+  const struct MD5_params *md5_hash;    /* Hash function definition */
+  void                  *md5_hashctx;   /* Hash function context */
+};
+
+// FFmpeg's MD5 context looks like this:
+typedef struct AVMD5 {
+    uint64_t len;
+    uint8_t  block[64];
+    uint32_t ABCD[4];
+} AVMD5;
+```
+
+Curl's struct name ends with `_context`, guaranteeing contexts are the correct
+interpretation.  FFmpeg's struct does not explicitly say it's a context, but
+@ref libavutil/md5.c "its functions do" so we can reasonably assume
+it's the intended interpretation.
+
+Curl's struct uses `void *md5_hashctx` to avoid guaranteeing
+implementation details in the public interface, whereas FFmpeg makes
+everything accessible.  This kind of data hiding is an advanced context-oriented
+convention, and is discussed below.  Using it in this case has strengths and
+weaknesses.  On one hand, it means changing the layout in a future version
+of curl won't break downstream programs that used that data.  On the other hand,
+the MD5 algorithm has been stable for 30 years, so it's arguably more important
+to let people dig in when debugging their own code.
+
+Curl's struct is declared as `struct <type> { ... }`, whereas FFmpeg uses
+`typedef struct <type> { ... } <type>`.  These conventions are used with both
+context and non-context structs, so don't say anything about contexts as such.
+Specifically, FFmpeg's convention is a workaround for an issue with C grammar:
+
+```c
+void my_function( ... ) {
+  int                my_var;        // good
+  MD5_context        my_curl_ctx;   // error: C needs you to explicitly say "struct"
+  struct MD5_context my_curl_ctx;   // good: added "struct"
+  AVMD5              my_ffmpeg_ctx; // good: typedef's avoid the need for "struct"
+}
+```
+
+Both MD5 implementations are long-tested, widely-used examples of contexts
+in the real world.  They show how contexts can solve the same problem
+in different ways.
+
+## FFmpeg's advanced context-oriented conventions
+
+Projects that make heavy use of contexts tend to develop conventions
+to make them more useful.  This section discusses conventions used in FFmpeg,
+some of which are used in other projects, others are unique to this project.
+
+### Naming: &ldquo;Context&rdquo; and &ldquo;ctx&rdquo;
+
+```c
+// Context struct names usually end with `Context`:
+struct AVSomeContext {
+  ...
+};
+
+// Functions are usually named after their context,
+// context parameters usually come first and are often called `ctx`:
+void av_some_function( AVSomeContext *ctx, ... );
+```
+
+If an FFmpeg struct is intended for use as a context, its name usually
+makes that clear.  Exceptions to this rule include AVMD5 (discussed above),
+which is only identified as a context by the functions that call it.
+
+If a function is associated with a context, its name usually
+begins with some variant of the context name (e.g. av_md5_alloc()
+or avcodec_alloc_context3()).  Exceptions to this rule include
+@ref avformat.h "AVFormatContext's functions", many of which
+begin with just `av_`.
+
+If a function has a context parameter, it usually comes first and its name
+often contains `ctx`.  Exceptions include av_bsf_alloc(), which puts the
+context argument second to emphasise it's an out variable.
+
+### Data hiding: private contexts
+
+```c
+// Context structs often hide private context:
+struct AVSomeContext {
+  void *priv_data; // sometimes just called "internal"
+};
+```
+
+Contexts usually present a public interface, so changing a context's members
+forces everyone that uses the library to at least recompile their program,
+if not rewrite it to remain compatible.  Hiding information in a private context
+ensures it can be modified without affecting downstream software.
+
+Object-oriented programmers may be tempted to compare private contexts to
+*private class members*.  That's often accurate, but for example it can also
+be used like a *virtual function table* - a list of functions that are
+guaranteed to exist, but may be implemented differently for different
+sub-classes.  When thinking about private contexts, remember that FFmpeg
+isn't *large enough* to need some common OOP techniques, even though it's
+solving a problem that's *complex enough* to benefit from some rarer techniques.
+
+### Manage lifetime: allocate, initialize and free
+
+```c
+void my_function( ... ) {
+
+    // Context structs are allocated then initialized with associated functions:
+
+    AVSomeContext *ctx = av_some_context_alloc( ... );
+
+    // ... configure ctx ...
+
+    av_some_context_init( ctx, ... );
+
+    // ... use ctx ...
+
+    // Context structs are freed with associated functions:
+
+    av_some_context_free( ctx );
+
+}
+```
+
+FFmpeg contexts go through the following stages of life:
+
+1. allocation (often a function that ends with `_alloc`)
+   * a range of memory is allocated for use by the structure
+   * memory is allocated on boundaries that improve caching
+   * memory is reset to zeroes, some internal structures may be initialized
+2. configuration (implemented by setting values directly on the object)
+   * no function for this - calling code populates the structure directly
+   * memory is populated with useful values
+   * simple contexts can skip this stage
+3. initialization (often a function that ends with `_init`)
+   * setup actions are performed based on the configuration (e.g. opening files)
+5. normal usage
+   * most functions are called in this stage
+   * documentation implies some members are now read-only (or not used at all)
+   * some contexts allow re-initialization
+6. closing (often a function that ends with `_close()`)
+   * teardown actions are performed (e.g. closing files)
+7. deallocation (often a function that ends with `_free()`)
+   * memory is returned to the pool of available memory
+
+This can mislead object-oriented programmers, who expect something more like:
+
+1. allocation (usually a `new` keyword)
+   * a range of memory is allocated for use by the structure
+   * memory *may* be reset (e.g. for security reasons)
+2. initialization (usually a constructor)
+   * memory is populated with useful values
+   * related setup actions are performed based on arguments (e.g. opening files)
+3. normal usage
+   * most functions are called in this stage
+   * compiler enforces that some members are read-only (or private)
+   * no going back to the previous stage
+4. finalization (usually a destructor)
+   * teardown actions are performed (e.g. closing files)
+5. deallocation (usually a `delete` keyword)
+   * memory is returned to the pool of available memory
+
+FFmpeg's allocation stage is broadly similar to OOP, but can do some higher-level
+operations.  For example, AVOptions-enabled structs (discussed below) contain an
+AVClass member that is set during allocation.
+
+FFmpeg's "configuration" and "initialization" stages combine to resemble OOP's
+"initialization" stage.  This can mislead object-oriented developers,
+who are used to doing both at once.  This means FFmpeg contexts don't have
+a direct equivalent of OOP constructors, as they would be doing
+two jobs in one function.
+
+FFmpeg's three-stage creation process is useful for complicated structures.
+For example, AVCodecContext contains many members that *can* be set before
+initialization, but in practice most programs set few if any of them.
+Implementing this with a constructor would involve a function with a list
+of arguments that was extremely long and changed whenever the struct was
+updated.  For contexts that don't need the extra flexibility, FFmpeg usually
+provides a combined allocator and initializer function.  For historical reasons,
+suffixes like `_alloc`, `_init`, `_alloc_context` and even `_open` can indicate
+the function does any combination of allocation and initialization.
+
+FFmpeg's "closing" stage is broadly similar to OOP's "finalization" stage,
+but some contexts allow re-initialization after finalization.  For example,
+SwrContext lets you call swr_close() then swr_init() to reuse a context.
+
+FFmpeg's "deallocation" stage is broadly similar to OOP, but can perform some
+higher-level functions (similar to the allocation stage).
+
+Very few contexts need the flexibility of separate "closing" and
+"deallocation" stages, so these are usually combined into a single function.
+Closing functions usually end with "_close", while deallocation
+functions usually end with "_free".
+
+### Reflection: AVOptions-enabled structs
+
+Object-oriented programming puts more focus on data hiding than FFmpeg needs,
+but it also puts less focus on
+[reflection](https://en.wikipedia.org/wiki/Reflection_(computer_programming)).
+
+To understand FFmpeg's reflection requirements, run `ffmpeg -h full` on the
+command-line, then ask yourself how you would implement all those options
+with the C standard [`getopt` function](https://en.wikipedia.org/wiki/Getopt).
+You can also ask the same question for any other programming languages you know.
+[Python's argparse module](https://docs.python.org/3/library/argparse.html)
+is a good example - its approach works well with far more complex programs
+than `getopt`, but would you like to maintain an argparse implementation
+with 15,000 options and growing?
+
+Most solutions assume you can just put all options in a single block,
+which is unworkable at FFmpeg's scale.  Instead, we split configuration
+across many *AVOptions-enabled structs*, which use the @ref avoptions
+"AVOptions API" to reflect information about their user-configurable members,
+including members in private contexts.
+
+An *AVOptions-enabled struct* is a struct that contains an AVClass element as
+its first member, and uses that element to provide access to instances of
+AVOption, each of which provides information about a single option.
+The AVClass can also include more @ref AVClass "AVClasses" for private contexts,
+making it possible to set options through the API that aren't
+accessible directly.
+
+AVOptions-accessible members of a context should be accessed through the
+AVOptions API whenever possible, even if they're not hidden away in a private
+context.  That ensures values are validated as they're set, and means you won't
+have to do as much work if a future version of FFmpeg changes the layout.
+
+AVClass was created very early in FFmpeg's history, long before AVOptions.
+Its name suggests some kind of relationship to an OOP
+base [class](https://en.wikipedia.org/wiki/Class_(computer_programming)),
+but the name has become less accurate as FFmpeg evolved, to the point where
+AVClass and AVOption are largely synonymous in modern usage.  The difference
+might still matter if you need to support old versions of FFmpeg,
+where you might find *AVClass context structures* (contain an AVClass element
+as their first member) that are not *AVOptions-enabled* (don't use that element
+to provide access to instances of AVOption).
+
+Object-oriented programmers may be tempted to compare @ref avoptions "AVOptions"
+to OOP getters and setters.  There is some overlap in functionality, but OOP
+getters and setters are usually specific to a single member and don't provide
+metadata about the member; whereas AVOptions has a single API that covers
+every option, and provides help text etc. as well.
+
+Object-oriented programmers may be tempted to compare AVOptions-accessible
+members of a public context to protected members of a class.  Both provide
+global access through an API, and unrestricted access for trusted friends.
+But this is just a happy accident, not a guarantee.
+
+## Final example: context for a codec
+
+AVCodecContext is an AVOptions-enabled struct that contains information
+about encoding or decoding one stream of data (e.g. the video in a movie).
+It's a good example of many of the issues above.
+
+The name "AVCodecContext" tells us this is a context.  Many of
+@ref libavcodec/avcodec.h "its functions" start with an `avctx` parameter,
+indicating this object provides context for that function.
+
+AVCodecContext::internal contains the private context.  For example,
+codec-specific information might be stored here.
+
+AVCodecContext is allocated with avcodec_alloc_context3(), initialized with
+avcodec_open2(), and freed with avcodec_free_context().  Most of its members
+are configured with the @ref avoptions "AVOptions API", but for example you
+can set AVCodecContext::opaque or AVCodecContext::draw_horiz_band() if your
+program happens to need them.
+
+AVCodecContext provides an abstract interface to many different *codecs*.
+Options supported by many codecs (e.g. "bitrate") are kept in AVCodecContext
+and reflected as AVOptions.  Options that are specific to one codec are
+stored in the internal context, and reflected from there.
+
+To support a specific codec, AVCodecContext's private context is set to
+an encoder-specific data type.  For example, the video codec
+[H.264](https://en.wikipedia.org/wiki/Advanced_Video_Coding) is supported via
+[the x264 library](https://www.videolan.org/developers/x264.html), and
+implemented in X264Context.  Although included in the documentation, X264Context
+is not part of the public API.  Whereas there are strict rules about
+changing AVCodecContext, a version of FFmpeg could modify X264Context or
+replace it with another type altogether.  An adverse legal ruling or security
+problem could even force us to switch to a completely different library
+without a major version bump.
+
+The design of AVCodecContext provides several important guarantees:
+
+- lets you use the same interface for any codec
+- supports common encoder options like "bitrate" without duplicating code
+- supports encoder-specific options like "profile" without bulking out the public interface
+- reflects both types of options to users, with help text and detection of missing options
+- hides implementation details (e.g. its encoding buffer)
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v4 2/4] lavu: Clarify relationship between AVClass, AVOption and context
  2024-05-15 15:54 ` [FFmpeg-devel] [PATCH v4 0/4] Explain what "context" means Andrew Sayers
  2024-05-15 15:54   ` [FFmpeg-devel] [PATCH v4 1/4] doc: " Andrew Sayers
@ 2024-05-15 15:54   ` Andrew Sayers
  2024-05-15 15:54   ` [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation Andrew Sayers
  2024-05-15 15:54   ` [FFmpeg-devel] [PATCH v4 4/4] lavf: Add documentation for private "Context" classes Andrew Sayers
  3 siblings, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-05-15 15:54 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

---
 libavutil/log.h | 11 ++++++++---
 libavutil/opt.h |  7 ++++---
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/libavutil/log.h b/libavutil/log.h
index ab7ceabe22..cfbf416679 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -59,9 +59,14 @@ typedef enum {
 struct AVOptionRanges;
 
 /**
- * Describe the class of an AVClass context structure. That is an
- * arbitrary struct of which the first field is a pointer to an
- * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).
+ * Metadata about an arbitrary data structure
+ *
+ * A @ref md_doc_2context "context struct" whose first member is a pointer
+ * to an AVClass object is called an "AVClass context structure"
+ * (e.g. AVCodecContext, AVFormatContext etc.).
+ *
+ * AVClass is often combined with @ref avoptions "AVOptions" to create
+ * "AVOptions-enabled structs" that can be easily configured by users.
  */
 typedef struct AVClass {
     /**
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 07e27a9208..e314e134c2 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -39,9 +39,10 @@
  * @defgroup avoptions AVOptions
  * @ingroup lavu_data
  * @{
- * AVOptions provide a generic system to declare options on arbitrary structs
- * ("objects"). An option can have a help text, a type and a range of possible
- * values. Options may then be enumerated, read and written to.
+ * Builds on AVClass, adding a generic system to declare options.
+ *
+ * An option can have a help text, a type and a range of possible values.
+ * Options may then be enumerated, read and written to.
  *
  * There are two modes of access to members of AVOption and its child structs.
  * One is called 'native access', and refers to access from the code that
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation
  2024-05-15 15:54 ` [FFmpeg-devel] [PATCH v4 0/4] Explain what "context" means Andrew Sayers
  2024-05-15 15:54   ` [FFmpeg-devel] [PATCH v4 1/4] doc: " Andrew Sayers
  2024-05-15 15:54   ` [FFmpeg-devel] [PATCH v4 2/4] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
@ 2024-05-15 15:54   ` Andrew Sayers
  2024-05-15 16:46     ` Lynne via ffmpeg-devel
  2024-05-15 15:54   ` [FFmpeg-devel] [PATCH v4 4/4] lavf: Add documentation for private "Context" classes Andrew Sayers
  3 siblings, 1 reply; 39+ messages in thread
From: Andrew Sayers @ 2024-05-15 15:54 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

Some headings needed to be rewritten to accomodate the text,
(hopefully) without changing the meaning.
---
 libavcodec/aac/aacdec.h            |  2 +-
 libavcodec/aacenc.h                |  2 +-
 libavcodec/ac3enc.h                |  2 +-
 libavcodec/amfenc.h                |  2 +-
 libavcodec/atrac.h                 |  2 +-
 libavcodec/avcodec.h               |  3 ++-
 libavcodec/bsf.h                   |  2 +-
 libavcodec/cbs.h                   |  2 +-
 libavcodec/d3d11va.h               |  3 +--
 libavcodec/h264dsp.h               |  2 +-
 libavcodec/h264pred.h              |  2 +-
 libavcodec/mediacodec.h            |  2 +-
 libavcodec/mpegaudiodec_template.c |  2 +-
 libavcodec/pthread_frame.c         |  4 ++--
 libavcodec/qsv.h                   |  6 ++++--
 libavcodec/sbr.h                   |  2 +-
 libavcodec/smacker.c               |  2 +-
 libavcodec/vdpau.h                 |  3 ++-
 libavcodec/videotoolbox.h          |  5 +++--
 libavfilter/avfilter.h             |  2 +-
 libavformat/avformat.h             |  3 ++-
 libavformat/avio.h                 |  3 ++-
 libavutil/audio_fifo.h             |  2 +-
 libavutil/hwcontext.h              | 21 ++++++++++++---------
 libavutil/hwcontext_cuda.h         |  2 +-
 libavutil/hwcontext_d3d11va.h      |  4 ++--
 libavutil/hwcontext_d3d12va.h      |  6 +++---
 libavutil/hwcontext_drm.h          |  2 +-
 libavutil/hwcontext_dxva2.h        |  4 ++--
 libavutil/hwcontext_mediacodec.h   |  2 +-
 libavutil/hwcontext_opencl.h       |  4 ++--
 libavutil/hwcontext_qsv.h          |  4 ++--
 libavutil/hwcontext_vaapi.h        |  6 +++---
 libavutil/hwcontext_vdpau.h        |  2 +-
 libavutil/hwcontext_vulkan.h       |  4 ++--
 libavutil/lfg.h                    |  2 +-
 36 files changed, 66 insertions(+), 57 deletions(-)

diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
index eed53c6c96..1d991a3c63 100644
--- a/libavcodec/aac/aacdec.h
+++ b/libavcodec/aac/aacdec.h
@@ -253,7 +253,7 @@ typedef struct AACDecDSP {
 } AACDecDSP;
 
 /**
- * main AAC decoding context
+ * main AAC decoding @ref md_doc_2context "context"
  */
 struct AACDecContext {
     const struct AVClass  *class;
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index d07960620e..1a645f4719 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -207,7 +207,7 @@ typedef struct AACPCEInfo {
 } AACPCEInfo;
 
 /**
- * AAC encoder context
+ * AAC encoder @ref md_doc_2context "context"
  */
 typedef struct AACEncContext {
     AVClass *av_class;
diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
index 30812617cc..c725007077 100644
--- a/libavcodec/ac3enc.h
+++ b/libavcodec/ac3enc.h
@@ -152,7 +152,7 @@ typedef struct AC3Block {
 } AC3Block;
 
 /**
- * AC-3 encoder private context.
+ * AC-3 encoder private @ref md_doc_2context "context"
  */
 typedef struct AC3EncodeContext {
     AVClass *av_class;                      ///< AVClass used for AVOption
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..f142ede63a 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
 } AmfTraceWriter;
 
 /**
-* AMF encoder context
+* AMF encoder @ref md_doc_2context "context"
 */
 
 typedef struct AmfContext {
diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
index 05208bbee6..1527e376a9 100644
--- a/libavcodec/atrac.h
+++ b/libavcodec/atrac.h
@@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
 } AtracGainInfo;
 
 /**
- *  Gain compensation context structure.
+ *  Gain compensation @ref md_doc_2context "context"
  */
 typedef struct AtracGCContext {
     float   gain_tab1[16];  ///< gain compensation level table
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 2da63c87ea..4f7a5aa80d 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -430,7 +430,8 @@ typedef struct RcOverride{
 #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
 
 /**
- * main external API structure.
+ * @ref md_doc_2context "Context" for an encode or decode session
+ *
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
index a09c69f242..bf79afa7cc 100644
--- a/libavcodec/bsf.h
+++ b/libavcodec/bsf.h
@@ -56,7 +56,7 @@
  */
 
 /**
- * The bitstream filter state.
+ * Bitstream filter @ref md_doc_2context "context"
  *
  * This struct must be allocated with av_bsf_alloc() and freed with
  * av_bsf_free().
diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h
index d479b1ac2d..0ff64d2fef 100644
--- a/libavcodec/cbs.h
+++ b/libavcodec/cbs.h
@@ -214,7 +214,7 @@ typedef void (*CBSTraceWriteCallback)(void *trace_context,
                                       int64_t value);
 
 /**
- * Context structure for coded bitstream operations.
+ * @ref md_doc_2context "Context" structure for coded bitstream operations.
  */
 typedef struct CodedBitstreamContext {
     /**
diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
index 27f40e5519..ec0c472ab9 100644
--- a/libavcodec/d3d11va.h
+++ b/libavcodec/d3d11va.h
@@ -46,8 +46,7 @@
  */
 
 /**
- * This structure is used to provides the necessary configurations and data
- * to the Direct3D11 FFmpeg HWAccel implementation.
+ * @ref md_doc_2context "Context" for the Direct3D11 FFmpeg HWAccel implementation
  *
  * The application must make it available as AVCodecContext.hwaccel_context.
  *
diff --git a/libavcodec/h264dsp.h b/libavcodec/h264dsp.h
index e0880c4d88..27256c5605 100644
--- a/libavcodec/h264dsp.h
+++ b/libavcodec/h264dsp.h
@@ -37,7 +37,7 @@ typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src,
                                    int weightd, int weights, int offset);
 
 /**
- * Context for storing H.264 DSP functions
+ * @ref md_doc_2context "Context" for storing H.264 DSP functions
  */
 typedef struct H264DSPContext {
     /* weighted MC */
diff --git a/libavcodec/h264pred.h b/libavcodec/h264pred.h
index cb008548fc..2b076f8846 100644
--- a/libavcodec/h264pred.h
+++ b/libavcodec/h264pred.h
@@ -89,7 +89,7 @@
 #define PART_NOT_AVAILABLE -2
 
 /**
- * Context for storing H.264 prediction functions
+ * @ref md_doc_2context "Context" for storing H.264 prediction functions
  */
 typedef struct H264PredContext {
     void(*pred4x4[9 + 3 + 3])(uint8_t *src, const uint8_t *topright,
diff --git a/libavcodec/mediacodec.h b/libavcodec/mediacodec.h
index 4e9b56a618..9967a7cfb3 100644
--- a/libavcodec/mediacodec.h
+++ b/libavcodec/mediacodec.h
@@ -26,7 +26,7 @@
 #include "libavcodec/avcodec.h"
 
 /**
- * This structure holds a reference to a android/view/Surface object that will
+ * @ref md_doc_2context "Context" for the android/view/Surface object that will
  * be used as output by the decoder.
  *
  */
diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c
index c73b1e0054..15d63215d1 100644
--- a/libavcodec/mpegaudiodec_template.c
+++ b/libavcodec/mpegaudiodec_template.c
@@ -1691,7 +1691,7 @@ static int decode_frame_adu(AVCodecContext *avctx, AVFrame *frame,
 #if CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER
 
 /**
- * Context for MP3On4 decoder
+ * @ref md_doc_2context "Context" for MP3On4 decoder
  */
 typedef struct MP3On4DecodeContext {
     int frames;                     ///< number of mp3 frames per block (number of mp3 decoder instances)
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index 67f09c1f48..74f05eedcf 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -71,7 +71,7 @@ typedef struct ThreadFrameProgress {
 } ThreadFrameProgress;
 
 /**
- * Context used by codec threads and stored in their AVCodecInternal thread_ctx.
+ * @ref md_doc_2context "Context" used by codec threads and stored in their AVCodecInternal thread_ctx.
  */
 typedef struct PerThreadContext {
     struct FrameThreadContext *parent;
@@ -111,7 +111,7 @@ typedef struct PerThreadContext {
 } PerThreadContext;
 
 /**
- * Context stored in the client AVCodecInternal thread_ctx.
+ * @ref md_doc_2context "Context" stored in the client AVCodecInternal thread_ctx.
  */
 typedef struct FrameThreadContext {
     PerThreadContext *threads;     ///< The contexts for each thread.
diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
index c156b08d07..8b8160a4b1 100644
--- a/libavcodec/qsv.h
+++ b/libavcodec/qsv.h
@@ -26,8 +26,10 @@
 #include "libavutil/buffer.h"
 
 /**
- * This struct is used for communicating QSV parameters between libavcodec and
- * the caller. It is managed by the caller and must be assigned to
+ * @ref md_doc_2context "Context" for communicating QSV parameters between libavcodec
+ * and the caller.
+ *
+ * It is managed by the caller and must be assigned to
  * AVCodecContext.hwaccel_context.
  * - decoding: hwaccel_context must be set on return from the get_format()
  *             callback
diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
index fe3a39603a..98ad9024a9 100644
--- a/libavcodec/sbr.h
+++ b/libavcodec/sbr.h
@@ -116,7 +116,7 @@ typedef struct SBRData {
 typedef struct SpectralBandReplication SpectralBandReplication;
 
 /**
- * aacsbr functions pointers
+ * aacsbr functions pointer @ref md_doc_2context "context"
  */
 typedef struct AACSBRContext {
     int (*sbr_lf_gen)(SpectralBandReplication *sbr,
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
index 8f198d6957..1ca39a74a0 100644
--- a/libavcodec/smacker.c
+++ b/libavcodec/smacker.c
@@ -68,7 +68,7 @@ typedef struct HuffEntry {
 } HuffEntry;
 
 /**
- * Context used for code reconstructing
+ * @ref md_doc_2context "Context" used for code reconstructing
  */
 typedef struct HuffContext {
     int current;
diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
index 8021c25761..227b85727d 100644
--- a/libavcodec/vdpau.h
+++ b/libavcodec/vdpau.h
@@ -64,8 +64,9 @@ typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, struct AVFrame *,
                                const VdpBitstreamBuffer *);
 
 /**
- * This structure is used to share data between the libavcodec library and
+ * @ref md_doc_2context "Context" to share data between the libavcodec library and
  * the client video application.
+ *
  * This structure will be allocated and stored in AVCodecContext.hwaccel_context
  * by av_vdpau_bind_context(). Members can be set by the user once
  * during initialization or through each AVCodecContext.get_buffer()
diff --git a/libavcodec/videotoolbox.h b/libavcodec/videotoolbox.h
index d68d76e400..f15e79f325 100644
--- a/libavcodec/videotoolbox.h
+++ b/libavcodec/videotoolbox.h
@@ -49,8 +49,9 @@
 #include "libavutil/attributes.h"
 
 /**
- * This struct holds all the information that needs to be passed
- * between the caller and libavcodec for initializing Videotoolbox decoding.
+ * @ref md_doc_2context "Context" for information passed between the caller and libavcodec
+ * for initializing Videotoolbox decoding.
+ *
  * Its size is not a part of the public ABI, it must be allocated with
  * av_videotoolbox_alloc_context() and freed with av_free().
  */
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index a34e61f23c..54b5f9dc43 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -403,7 +403,7 @@ unsigned avfilter_filter_pad_count(const AVFilter *filter, int is_output);
  */
 #define AVFILTER_THREAD_SLICE (1 << 0)
 
-/** An instance of a filter */
+/** @ref md_doc_2context "Context" for a filter */
 struct AVFilterContext {
     const AVClass *av_class;        ///< needed for av_log() and filters common options
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 8afdcd9fd0..28243c06c4 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1241,7 +1241,8 @@ enum AVDurationEstimationMethod {
 };
 
 /**
- * Format I/O context.
+ * Format I/O @ref md_doc_2context "context"
+ *
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
diff --git a/libavformat/avio.h b/libavformat/avio.h
index ebf611187d..b525c93194 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -146,7 +146,8 @@ enum AVIODataMarkerType {
 };
 
 /**
- * Bytestream IO Context.
+ * Bytestream I/O @ref md_doc_2context "context"
+ *
  * New public fields can be added with minor version bumps.
  * Removal, reordering and changes to existing public fields require
  * a major version bump.
diff --git a/libavutil/audio_fifo.h b/libavutil/audio_fifo.h
index fa5f59a2be..de29715462 100644
--- a/libavutil/audio_fifo.h
+++ b/libavutil/audio_fifo.h
@@ -39,7 +39,7 @@
  */
 
 /**
- * Context for an Audio FIFO Buffer.
+ * @ref md_doc_2context "Context" for an Audio FIFO Buffer.
  *
  * - Operates at the sample level rather than the byte level.
  * - Supports multiple channels with either planar or packed sample format.
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index bac30debae..60064cf08b 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -41,12 +41,13 @@ enum AVHWDeviceType {
 };
 
 /**
- * This struct aggregates all the (hardware/vendor-specific) "high-level" state,
- * i.e. state that is not tied to a concrete processing configuration.
- * E.g., in an API that supports hardware-accelerated encoding and decoding,
- * this struct will (if possible) wrap the state that is common to both encoding
- * and decoding and from which specific instances of encoders or decoders can be
- * derived.
+ * @ref md_doc_2context "Context" for (hardware/vendor-specific) "high-level" state.
+ *
+ * "High-level state" is anything that is not tied to a concrete processing
+ * configuration. E.g., in an API that supports hardware-accelerated encoding
+ * and decoding, this struct will (if possible) wrap the state that is common
+ * to both encoding and decoding and from which specific instances of encoders
+ * or decoders can be derived.
  *
  * This struct is reference-counted with the AVBuffer mechanism. The
  * av_hwdevice_ctx_alloc() constructor yields a reference, whose data field
@@ -103,9 +104,11 @@ typedef struct AVHWDeviceContext {
 } AVHWDeviceContext;
 
 /**
- * This struct describes a set or pool of "hardware" frames (i.e. those with
- * data not located in normal system memory). All the frames in the pool are
- * assumed to be allocated in the same way and interchangeable.
+ * @ref md_doc_2context "context" for a pool of "hardware" frames (those with
+ * data not located in normal system memory)
+ *
+ * All the frames in the pool are assumed to be allocated in the same way and
+ * interchangeable.
  *
  * This struct is reference-counted with the AVBuffer mechanism and tied to a
  * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor
diff --git a/libavutil/hwcontext_cuda.h b/libavutil/hwcontext_cuda.h
index cbad434fea..e259892688 100644
--- a/libavutil/hwcontext_cuda.h
+++ b/libavutil/hwcontext_cuda.h
@@ -37,7 +37,7 @@
 typedef struct AVCUDADeviceContextInternal AVCUDADeviceContextInternal;
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVCUDADeviceContext {
     CUcontext cuda_ctx;
diff --git a/libavutil/hwcontext_d3d11va.h b/libavutil/hwcontext_d3d11va.h
index 77d2d72f1b..101d1cb6f8 100644
--- a/libavutil/hwcontext_d3d11va.h
+++ b/libavutil/hwcontext_d3d11va.h
@@ -40,7 +40,7 @@
 #include <stdint.h>
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVD3D11VADeviceContext {
     /**
@@ -126,7 +126,7 @@ typedef struct AVD3D11FrameDescriptor {
 } AVD3D11FrameDescriptor;
 
 /**
- * This struct is allocated as AVHWFramesContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
  */
 typedef struct AVD3D11VAFramesContext {
     /**
diff --git a/libavutil/hwcontext_d3d12va.h b/libavutil/hwcontext_d3d12va.h
index ff06e6f2ef..c623914c2b 100644
--- a/libavutil/hwcontext_d3d12va.h
+++ b/libavutil/hwcontext_d3d12va.h
@@ -37,7 +37,7 @@
 #include <d3d12video.h>
 
 /**
- * @brief This struct is allocated as AVHWDeviceContext.hwctx
+ * @brief This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  *
  */
 typedef struct AVD3D12VADeviceContext {
@@ -78,7 +78,7 @@ typedef struct AVD3D12VADeviceContext {
 } AVD3D12VADeviceContext;
 
 /**
- * @brief This struct is used to sync d3d12 execution
+ * @brief This @ref md_doc_2context "context" is used to sync d3d12 execution
  *
  */
 typedef struct AVD3D12VASyncContext {
@@ -120,7 +120,7 @@ typedef struct AVD3D12VAFrame {
 } AVD3D12VAFrame;
 
 /**
- * @brief This struct is allocated as AVHWFramesContext.hwctx
+ * @brief This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
  *
  */
 typedef struct AVD3D12VAFramesContext {
diff --git a/libavutil/hwcontext_drm.h b/libavutil/hwcontext_drm.h
index 42709f215e..8329e69966 100644
--- a/libavutil/hwcontext_drm.h
+++ b/libavutil/hwcontext_drm.h
@@ -152,7 +152,7 @@ typedef struct AVDRMFrameDescriptor {
 /**
  * DRM device.
  *
- * Allocated as AVHWDeviceContext.hwctx.
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx.
  */
 typedef struct AVDRMDeviceContext {
     /**
diff --git a/libavutil/hwcontext_dxva2.h b/libavutil/hwcontext_dxva2.h
index e1b79bc0de..c679c16af0 100644
--- a/libavutil/hwcontext_dxva2.h
+++ b/libavutil/hwcontext_dxva2.h
@@ -34,14 +34,14 @@
 #include <dxva2api.h>
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVDXVA2DeviceContext {
     IDirect3DDeviceManager9 *devmgr;
 } AVDXVA2DeviceContext;
 
 /**
- * This struct is allocated as AVHWFramesContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
  */
 typedef struct AVDXVA2FramesContext {
     /**
diff --git a/libavutil/hwcontext_mediacodec.h b/libavutil/hwcontext_mediacodec.h
index fc0263cabc..e81193247b 100644
--- a/libavutil/hwcontext_mediacodec.h
+++ b/libavutil/hwcontext_mediacodec.h
@@ -22,7 +22,7 @@
 /**
  * MediaCodec details.
  *
- * Allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVMediaCodecDeviceContext {
     /**
diff --git a/libavutil/hwcontext_opencl.h b/libavutil/hwcontext_opencl.h
index ef54486c95..7abd97db2b 100644
--- a/libavutil/hwcontext_opencl.h
+++ b/libavutil/hwcontext_opencl.h
@@ -58,7 +58,7 @@ typedef struct AVOpenCLFrameDescriptor {
 /**
  * OpenCL device details.
  *
- * Allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVOpenCLDeviceContext {
     /**
@@ -84,7 +84,7 @@ typedef struct AVOpenCLDeviceContext {
 /**
  * OpenCL-specific data associated with a frame pool.
  *
- * Allocated as AVHWFramesContext.hwctx.
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
  */
 typedef struct AVOpenCLFramesContext {
     /**
diff --git a/libavutil/hwcontext_qsv.h b/libavutil/hwcontext_qsv.h
index e2dba8ad83..b63ebddaef 100644
--- a/libavutil/hwcontext_qsv.h
+++ b/libavutil/hwcontext_qsv.h
@@ -30,7 +30,7 @@
  */
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVQSVDeviceContext {
     mfxSession session;
@@ -48,7 +48,7 @@ typedef struct AVQSVDeviceContext {
 } AVQSVDeviceContext;
 
 /**
- * This struct is allocated as AVHWFramesContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx
  */
 typedef struct AVQSVFramesContext {
     mfxFrameSurface1 *surfaces;
diff --git a/libavutil/hwcontext_vaapi.h b/libavutil/hwcontext_vaapi.h
index 0b2e071cb3..4a897eb851 100644
--- a/libavutil/hwcontext_vaapi.h
+++ b/libavutil/hwcontext_vaapi.h
@@ -63,7 +63,7 @@ enum {
 /**
  * VAAPI connection details.
  *
- * Allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVVAAPIDeviceContext {
     /**
@@ -83,7 +83,7 @@ typedef struct AVVAAPIDeviceContext {
 /**
  * VAAPI-specific data associated with a frame pool.
  *
- * Allocated as AVHWFramesContext.hwctx.
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx.
  */
 typedef struct AVVAAPIFramesContext {
     /**
@@ -105,7 +105,7 @@ typedef struct AVVAAPIFramesContext {
 /**
  * VAAPI hardware pipeline configuration details.
  *
- * Allocated with av_hwdevice_hwconfig_alloc().
+ * This struct is allocated with av_hwdevice_hwconfig_alloc().
  */
 typedef struct AVVAAPIHWConfig {
     /**
diff --git a/libavutil/hwcontext_vdpau.h b/libavutil/hwcontext_vdpau.h
index 1b7ea1e443..e305caa595 100644
--- a/libavutil/hwcontext_vdpau.h
+++ b/libavutil/hwcontext_vdpau.h
@@ -30,7 +30,7 @@
  */
 
 /**
- * This struct is allocated as AVHWDeviceContext.hwctx
+ * This @ref md_doc_2context "context" is allocated as AVHWDeviceContext.hwctx
  */
 typedef struct AVVDPAUDeviceContext {
     VdpDevice          device;
diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h
index cbbd2390c1..1869870032 100644
--- a/libavutil/hwcontext_vulkan.h
+++ b/libavutil/hwcontext_vulkan.h
@@ -39,7 +39,7 @@ typedef struct AVVkFrame AVVkFrame;
  */
 
 /**
- * Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
+ * Main Vulkan @ref md_doc_2context "context", allocated as AVHWDeviceContext.hwctx.
  * All of these can be set before init to change what the context uses
  */
 typedef struct AVVulkanDeviceContext {
@@ -172,7 +172,7 @@ typedef enum AVVkFrameFlags {
 } AVVkFrameFlags;
 
 /**
- * Allocated as AVHWFramesContext.hwctx, used to set pool-specific options
+ * This @ref md_doc_2context "context" is allocated as AVHWFramesContext.hwctx, used to set pool-specific options
  */
 typedef struct AVVulkanFramesContext {
     /**
diff --git a/libavutil/lfg.h b/libavutil/lfg.h
index e75a986f12..7f4ff5b62f 100644
--- a/libavutil/lfg.h
+++ b/libavutil/lfg.h
@@ -25,7 +25,7 @@
 #include <stdint.h>
 
 /**
- * Context structure for the Lagged Fibonacci PRNG.
+ * @ref md_doc_2context "Context" structure for the Lagged Fibonacci PRNG.
  * The exact layout, types and content of this struct may change and should
  * not be accessed directly. Only its `sizeof()` is guaranteed to stay the same
  * to allow easy instanciation.
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [FFmpeg-devel] [PATCH v4 4/4] lavf: Add documentation for private "Context" classes
  2024-05-15 15:54 ` [FFmpeg-devel] [PATCH v4 0/4] Explain what "context" means Andrew Sayers
                     ` (2 preceding siblings ...)
  2024-05-15 15:54   ` [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation Andrew Sayers
@ 2024-05-15 15:54   ` Andrew Sayers
  3 siblings, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-05-15 15:54 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andrew Sayers

Doxygen thinks any text like "Context for foo" is a link to a struct called "Context".
Add a description and a better link, to avoid confusing readers.
---
 libavformat/async.c | 3 +++
 libavformat/cache.c | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/libavformat/async.c b/libavformat/async.c
index e096b0bc6f..3c28d418ae 100644
--- a/libavformat/async.c
+++ b/libavformat/async.c
@@ -53,6 +53,9 @@ typedef struct RingBuffer
     int           read_pos;
 } RingBuffer;
 
+/**
+ * @brief @ref md_doc_2context "Context" for testing async
+ */
 typedef struct Context {
     AVClass        *class;
     URLContext     *inner;
diff --git a/libavformat/cache.c b/libavformat/cache.c
index 5f78adba9d..3cc0edec82 100644
--- a/libavformat/cache.c
+++ b/libavformat/cache.c
@@ -52,6 +52,9 @@ typedef struct CacheEntry {
     int size;
 } CacheEntry;
 
+/**
+ * @brief @ref md_doc_2context "Context" for a cache
+ */
 typedef struct Context {
     AVClass *class;
     int fd;
-- 
2.43.0

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation
  2024-05-15 15:54   ` [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation Andrew Sayers
@ 2024-05-15 16:46     ` Lynne via ffmpeg-devel
  2024-05-16 11:25       ` Andrew Sayers
  0 siblings, 1 reply; 39+ messages in thread
From: Lynne via ffmpeg-devel @ 2024-05-15 16:46 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Lynne


[-- Attachment #1.1.1.1: Type: text/plain, Size: 2139 bytes --]

On 15/05/2024 17:54, Andrew Sayers wrote:
> Some headings needed to be rewritten to accomodate the text,
> (hopefully) without changing the meaning.
> ---
>   libavcodec/aac/aacdec.h            |  2 +-
>   libavcodec/aacenc.h                |  2 +-
>   libavcodec/ac3enc.h                |  2 +-
>   libavcodec/amfenc.h                |  2 +-
>   libavcodec/atrac.h                 |  2 +-
>   libavcodec/avcodec.h               |  3 ++-
>   libavcodec/bsf.h                   |  2 +-
>   libavcodec/cbs.h                   |  2 +-
>   libavcodec/d3d11va.h               |  3 +--
>   libavcodec/h264dsp.h               |  2 +-
>   libavcodec/h264pred.h              |  2 +-
>   libavcodec/mediacodec.h            |  2 +-
>   libavcodec/mpegaudiodec_template.c |  2 +-
>   libavcodec/pthread_frame.c         |  4 ++--
>   libavcodec/qsv.h                   |  6 ++++--
>   libavcodec/sbr.h                   |  2 +-
>   libavcodec/smacker.c               |  2 +-
>   libavcodec/vdpau.h                 |  3 ++-
>   libavcodec/videotoolbox.h          |  5 +++--
>   libavfilter/avfilter.h             |  2 +-
>   libavformat/avformat.h             |  3 ++-
>   libavformat/avio.h                 |  3 ++-
>   libavutil/audio_fifo.h             |  2 +-
>   libavutil/hwcontext.h              | 21 ++++++++++++---------
>   libavutil/hwcontext_cuda.h         |  2 +-
>   libavutil/hwcontext_d3d11va.h      |  4 ++--
>   libavutil/hwcontext_d3d12va.h      |  6 +++---
>   libavutil/hwcontext_drm.h          |  2 +-
>   libavutil/hwcontext_dxva2.h        |  4 ++--
>   libavutil/hwcontext_mediacodec.h   |  2 +-
>   libavutil/hwcontext_opencl.h       |  4 ++--
>   libavutil/hwcontext_qsv.h          |  4 ++--
>   libavutil/hwcontext_vaapi.h        |  6 +++---
>   libavutil/hwcontext_vdpau.h        |  2 +-
>   libavutil/hwcontext_vulkan.h       |  4 ++--
>   libavutil/lfg.h                    |  2 +-
>   36 files changed, 66 insertions(+), 57 deletions(-)

I still don't like this part. There's no reason to link this everywhere 
when no one will be bothered to. The document alone is enough IMO.

[-- Attachment #1.1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 637 bytes --]

[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 236 bytes --]

[-- Attachment #2: Type: text/plain, Size: 251 bytes --]

_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation
  2024-05-15 16:46     ` Lynne via ffmpeg-devel
@ 2024-05-16 11:25       ` Andrew Sayers
  0 siblings, 0 replies; 39+ messages in thread
From: Andrew Sayers @ 2024-05-16 11:25 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Wed, May 15, 2024 at 06:46:19PM +0200, Lynne via ffmpeg-devel wrote:
> On 15/05/2024 17:54, Andrew Sayers wrote:
> > Some headings needed to be rewritten to accomodate the text,
> > (hopefully) without changing the meaning.
> > ---
> >   libavcodec/aac/aacdec.h            |  2 +-
> >   libavcodec/aacenc.h                |  2 +-
> >   libavcodec/ac3enc.h                |  2 +-
> >   libavcodec/amfenc.h                |  2 +-
> >   libavcodec/atrac.h                 |  2 +-
> >   libavcodec/avcodec.h               |  3 ++-
> >   libavcodec/bsf.h                   |  2 +-
> >   libavcodec/cbs.h                   |  2 +-
> >   libavcodec/d3d11va.h               |  3 +--
> >   libavcodec/h264dsp.h               |  2 +-
> >   libavcodec/h264pred.h              |  2 +-
> >   libavcodec/mediacodec.h            |  2 +-
> >   libavcodec/mpegaudiodec_template.c |  2 +-
> >   libavcodec/pthread_frame.c         |  4 ++--
> >   libavcodec/qsv.h                   |  6 ++++--
> >   libavcodec/sbr.h                   |  2 +-
> >   libavcodec/smacker.c               |  2 +-
> >   libavcodec/vdpau.h                 |  3 ++-
> >   libavcodec/videotoolbox.h          |  5 +++--
> >   libavfilter/avfilter.h             |  2 +-
> >   libavformat/avformat.h             |  3 ++-
> >   libavformat/avio.h                 |  3 ++-
> >   libavutil/audio_fifo.h             |  2 +-
> >   libavutil/hwcontext.h              | 21 ++++++++++++---------
> >   libavutil/hwcontext_cuda.h         |  2 +-
> >   libavutil/hwcontext_d3d11va.h      |  4 ++--
> >   libavutil/hwcontext_d3d12va.h      |  6 +++---
> >   libavutil/hwcontext_drm.h          |  2 +-
> >   libavutil/hwcontext_dxva2.h        |  4 ++--
> >   libavutil/hwcontext_mediacodec.h   |  2 +-
> >   libavutil/hwcontext_opencl.h       |  4 ++--
> >   libavutil/hwcontext_qsv.h          |  4 ++--
> >   libavutil/hwcontext_vaapi.h        |  6 +++---
> >   libavutil/hwcontext_vdpau.h        |  2 +-
> >   libavutil/hwcontext_vulkan.h       |  4 ++--
> >   libavutil/lfg.h                    |  2 +-
> >   36 files changed, 66 insertions(+), 57 deletions(-)
> 
> I still don't like this part. There's no reason to link this everywhere when
> no one will be bothered to. The document alone is enough IMO.

Readers who don't already know the word "context" need a sign that it's a word
they need to pay attention to.  For example, I come from an OOP background
where the word "object" is used so widely, it simply never comes up.

In fact, I'm probably not the only person who followed the link to AVClass
instead, which just makes FFmpeg look like a failed attempt at OOP if you don't
know about contexts.

Linking widely lets an attentive reader see this *before* they get the wrong
end of the stick, and gives an overwhelmed newbie enough hints that this is a
word they need to pay attention to.

To underline the previous point - an attentive reader could probably make do
with e.g. just links from AVClass and a handful of the most popular contexts.
But newbies are often inefficient learners who need many reminders before
they stop paying attention to random things.  So linking as widely as possible
makes the project more accessible to people with less experience.
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2024-05-16 11:25 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-18 15:06 [FFmpeg-devel] [PATCH 1/3] doc: Explain what "context" means Andrew Sayers
2024-04-18 15:06 ` [FFmpeg-devel] [PATCH 2/3] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
2024-04-18 15:06 ` [FFmpeg-devel] [PATCH 3/3] all: Link to "context" from all contexts with documentation Andrew Sayers
2024-04-20  7:25 ` [FFmpeg-devel] [PATCH 1/3] doc: Explain what "context" means Stefano Sabatini
2024-04-20 12:18   ` Andrew Sayers
2024-04-20 16:13     ` Stefano Sabatini
2024-04-20 12:19   ` [FFmpeg-devel] [PATCH v2 " Andrew Sayers
2024-04-20 12:19     ` [FFmpeg-devel] [PATCH v2 2/3] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
2024-04-20 12:19     ` [FFmpeg-devel] [PATCH v2 3/3] all: Link to "context" from all contexts with documentation Andrew Sayers
2024-04-20 16:48     ` [FFmpeg-devel] [PATCH v2 1/3] doc: Explain what "context" means Stefano Sabatini
2024-04-20 22:17       ` Andrew Sayers
2024-04-22  8:02         ` Stefano Sabatini
2024-04-22 15:56           ` [FFmpeg-devel] [PATCH v3 0/3] all: Link to "context" from all contexts with documentation Andrew Sayers
2024-04-22 15:56             ` [FFmpeg-devel] [PATCH v3 1/3] doc: Explain what "context" means Andrew Sayers
2024-04-22 17:05               ` Stefano Sabatini
2024-04-29  9:10                 ` Andrew Sayers
2024-05-02 10:03                   ` Andrew Sayers
2024-05-05  7:29                   ` Stefano Sabatini
2024-05-05 21:04                     ` Andrew Sayers
2024-04-29  9:24                 ` [FFmpeg-devel] [PATCH v4 1/4] " Andrew Sayers
2024-04-29  9:24                   ` [FFmpeg-devel] [PATCH v4 2/4] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
2024-04-29  9:24                   ` [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation Andrew Sayers
2024-05-02 11:01                     ` Lynne
2024-05-02 11:14                       ` Andrew Sayers
2024-05-02 13:00                       ` Zhao Zhili
2024-05-02 13:27                         ` Andrew Sayers
2024-05-02 13:39                           ` Zhao Zhili
2024-04-29  9:24                   ` [FFmpeg-devel] [PATCH v4 4/4] lavf: Add documentation for private "Context" classes Andrew Sayers
2024-05-05  8:31                   ` [FFmpeg-devel] [PATCH v4 1/4] doc: Explain what "context" means Andreas Rheinhardt
2024-05-05 10:34                     ` Andrew Sayers
2024-04-22 15:56             ` [FFmpeg-devel] [PATCH v3 2/3] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
2024-04-22 15:56             ` [FFmpeg-devel] [PATCH v3 3/3] all: Link to "context" from all contexts with documentation Andrew Sayers
2024-05-15 15:54 ` [FFmpeg-devel] [PATCH v4 0/4] Explain what "context" means Andrew Sayers
2024-05-15 15:54   ` [FFmpeg-devel] [PATCH v4 1/4] doc: " Andrew Sayers
2024-05-15 15:54   ` [FFmpeg-devel] [PATCH v4 2/4] lavu: Clarify relationship between AVClass, AVOption and context Andrew Sayers
2024-05-15 15:54   ` [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation Andrew Sayers
2024-05-15 16:46     ` Lynne via ffmpeg-devel
2024-05-16 11:25       ` Andrew Sayers
2024-05-15 15:54   ` [FFmpeg-devel] [PATCH v4 4/4] lavf: Add documentation for private "Context" classes Andrew Sayers

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