Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions changelog.d/added/libvmaf-public-header-doc-comments-round2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
## Added

- **Doxygen comments on under-documented public libvmaf C-API entry points**
(`core/include/libvmaf/feature.h`, `model.h`, `dnn.h`): round-2 follow-on
to PR #302's targeted gap-close. Adds `@brief`, `@param`, `@return`, and
ownership/lifetime contracts to 15 public surfaces that the ffmpeg patch
stack, the Go/Rust bindings, and downstream MCP consumers depend on:

- `feature.h`: `VmafFeatureDictionary` (struct), `vmaf_feature_dictionary_set`,
`vmaf_feature_dictionary_free` (full file was undocumented).
- `model.h`: `VmafModelFlags`, `VmafModelConfig`, `vmaf_model_load`,
`vmaf_model_load_from_path`, `vmaf_model_feature_overload`,
`vmaf_model_destroy`, `VmafModelCollection`,
`VmafModelCollectionScoreType`, `VmafModelCollectionScore`,
`vmaf_model_collection_load`, `vmaf_model_collection_load_from_path`,
`vmaf_model_collection_feature_overload`,
`vmaf_model_collection_destroy`.
- `dnn.h`: `vmaf_dnn_session_close`.

Each block documents return semantics (negative errno convention),
ownership-transfer rules for dictionaries that pass into the library, and
the `vmaf_model_destroy` / `vmaf_model_collection_destroy` pairing
required to avoid double-free of collection-owned sub-models.

- **NOLINT citations on upstream-mirror include guards**: the three touched
Netflix-copyright headers retain their `__VMAF_*_H__` include guards
verbatim for rebase parity with Netflix/vmaf master. Each `#ifndef` /
`#define` carries an inline NOLINT for `bugprone-reserved-identifier`
citing CLAUDE.md §10 (Upstream sync) and §12 r12 (touched-file
lint-clean rule per ADR-0278). No identifier changes; no ABI impact.

No semantic or ABI change. Doc-only comment additions plus the NOLINT
annotations required to leave the touched files lint-clean.
15 changes: 15 additions & 0 deletions core/include/libvmaf/dnn.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@
* returns 0 and every other entry point returns -ENOSYS.
*/

/* Pre-2026 internal scaffold name kept for ABI/source-compat with the first
* fork consumers of this header (ffmpeg-patches/0008-add-libv*.patch +
* mcp-server/vmaf-mcp/). A future audit may rename to VMAF_DNN_H_; this lints
* stays cited until that lands. See CLAUDE.md §12 r12 / ADR-0278. */
/* NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) */
#ifndef __VMAF_DNN_H__
/* NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) */
#define __VMAF_DNN_H__

#include <stdbool.h>
Expand Down Expand Up @@ -285,6 +291,15 @@ typedef struct VmafDnnOutput {
VMAF_EXPORT int vmaf_dnn_session_run(VmafDnnSession *sess, const VmafDnnInput *inputs,
size_t n_inputs, VmafDnnOutput *outputs, size_t n_outputs);

/**
* Close a standalone DNN session and release all owned resources. Tears down
* the ONNX Runtime session, releases input/output binding caches, and frees
* the handle. Safe to call with a NULL @p sess. After this call any pointer
* cached from @ref vmaf_dnn_session_attached_ep is invalidated. Pair with
* every successful @ref vmaf_dnn_session_open.
*
* @param sess Session handle from @ref vmaf_dnn_session_open. NULL is a no-op.
*/
VMAF_EXPORT void vmaf_dnn_session_close(VmafDnnSession *sess);

/**
Expand Down
68 changes: 68 additions & 0 deletions core/include/libvmaf/feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@
*
*/

/* Upstream Netflix include guard preserved verbatim for rebase parity.
* Renaming would diverge from Netflix/vmaf master and break port-only sync.
* See CLAUDE.md §10 "Upstream sync" and docs/rebase-notes.md. */
/* NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) */
#ifndef __VMAF_FEATURE_H__
/* NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) */
#define __VMAF_FEATURE_H__

#include "libvmaf/macros.h"
Expand All @@ -25,11 +30,74 @@
extern "C" {
#endif

/**
* @typedef VmafFeatureDictionary
* @brief Opaque key/value dictionary used to override feature-extractor options.
*
* Built incrementally via @ref vmaf_feature_dictionary_set and consumed by
* @ref vmaf_use_feature and @ref vmaf_model_feature_overload. Numeric values
* are detected at set-time and stored in a normalised form so that
* `"1"` / `"1.0"` / `" 1 "` compare equal downstream.
*
* Ownership transfer rules:
* - On success of @ref vmaf_use_feature / @ref vmaf_model_feature_overload,
* ownership of the dictionary passes to the VmafContext / VmafModel and
* the caller MUST NOT free it.
* - On failure of those calls (non-zero return), the caller still owns the
* dictionary and is responsible for releasing it with
* @ref vmaf_feature_dictionary_free.
*/
typedef struct VmafFeatureDictionary VmafFeatureDictionary;

/**
* @brief Set (or replace) a key/value pair in a feature-extractor options dictionary.
*
* On the first call against an empty dictionary, pass `*dict == NULL` and the
* function allocates a fresh dictionary in place. Subsequent calls add or
* overwrite entries. Values that parse as a decimal integer or float are
* normalised internally (whitespace stripped, canonical numeric form stored)
* so `"1"` and `" 1.0 "` compare equal across feature-extractor option
* resolution.
*
* Both @p key and @p val are copied; the caller retains ownership of the
* input strings and may free them after this call returns.
*
* @param dict In/out: address of a `VmafFeatureDictionary *`. The first call
* must point at a NULL handle; on success @p *dict is updated to
* the allocated dictionary. The caller owns @p *dict on failure
* and must release it via @ref vmaf_feature_dictionary_free.
* Must not be NULL.
* @param key NUL-terminated option name (e.g. `"adm_enhn_gain_limit"`).
* Must not be NULL or empty.
* @param val NUL-terminated option value. May be a number, boolean, or
* arbitrary string; the feature extractor decides interpretation.
*
* @return 0 on success, or a negative errno code on error:
* `-EINVAL` for NULL arguments, `-ENOMEM` if allocation fails.
*
* @since libvmaf 3.0.0 (upstream).
*/
VMAF_EXPORT int vmaf_feature_dictionary_set(VmafFeatureDictionary **dict, const char *key,
const char *val);

/**
* @brief Release a feature-extractor options dictionary and clear the handle.
*
* Safe to call on a NULL @p dict or with `*dict == NULL`; both are no-ops.
* On success @p *dict is set to NULL so the handle cannot be reused.
*
* Only call this on dictionaries the caller still owns - once ownership has
* passed to a VmafContext via @ref vmaf_use_feature, or to a VmafModel via
* @ref vmaf_model_feature_overload, calling this is a double-free. See the
* `VmafFeatureDictionary` ownership-transfer rules above.
*
* @param dict In/out: address of the dictionary handle to free. NULL is a
* no-op; on a non-NULL @p dict, @p *dict is reset to NULL.
*
* @return 0 on success, or a negative errno code on internal failure.
*
* @since libvmaf 3.0.0 (upstream).
*/
VMAF_EXPORT int vmaf_feature_dictionary_free(VmafFeatureDictionary **dict);

#ifdef __cplusplus
Expand Down
Loading
Loading