Skip to content
CAI
Software that uses CAICheck a score

membraneframework/membrane_core

70.3

Strong · 23 September 2026

17.7k

lines of production code

Elixir

primary language

5

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is the core framework for building and orchestrating media processing pipelines in Elixir. It provides the foundational abstractions for defining pipeline topologies, managing element lifecycles, and handling data flow through buffers and events. The framework includes built-in mechanisms for performance benchmarking, distributed demand tracking, and comprehensive testing utilities to validate pipeline behavior.

How it got here

2016–2018 — Core framework refactoring and testing

18 changes.

The project underwent a significant architectural overhaul, removing legacy OTP supervision and hardcoded constants to introduce a modular, component-based framework with strict error handling and telemetry. This period focused on restructuring core elements into specialized controllers, implementing diamond detection for pipeline stability, and establishing comprehensive test coverage with new utilities for pipeline simulation and assertion.

2019–2020 — core architecture refactoring and test expansion

14 changes.

This period focused on restructuring the internal architecture of Membrane's core components, specifically refactoring the bin, pipeline, and parent-child lifecycle management into modular controllers. Concurrently, extensive integration and unit tests were added to validate these changes, covering complex scenarios such as crash groups, dynamic pads, and pipeline demand handling.

2021–2023 — core refactoring and test infrastructure

14 changes.

This period focused on refactoring core lifecycle and demand management logic into dedicated utility modules while significantly expanding the test suite with specialized support helpers. The work also introduced performance benchmarking, debugging elements, and automation scripts to improve ecosystem maintenance and developer tooling.

2024–2026 — Developer tooling and flow control enhancements

5 changes.

This period focused on improving the developer experience by introducing Mix tasks for scaffolding Membrane components and downloading demo projects, alongside expanded documentation. Concurrently, the core library was enhanced to support timestamp-based demand units in the manual flow controller, enabling more precise playback timing and buffer management.

Features

Add Discontinuity and Underrun event types

New event types for Discontinuity and Underrun have been added to the library. The Discontinuity event signals that the flow of buffers in a stream was interrupted (e.g., due to soundcard drops or network loss) while the stream continues, optionally including a duration. The Underrun event notifies upstream elements that a consumer is ready for more buffers but none are currently available.

lib/membrane/event · high confidence

Added demo and tutorial submodules to guides

The guides section now includes two new submodules: 'membrane\_demo' and 'membrane\_tutorials'. This change integrates external demo and tutorial content into the documentation structure, allowing users to access these resources directly within the guides area.

guides · high confidence

Added performance benchmarking suite for Membrane Core

A new benchmarking infrastructure has been added to the \benchmark/\ directory, enabling developers to measure and compare performance metrics such as execution time, in-progress memory usage, and message queue lengths. The suite includes scripts to run tests on linear and branched pipeline topologies, define custom metrics via the \Benchmark.Metric\ behavior, and compare results against reference files to detect regressions.

benchmark · high confidence

Automated maintenance of the Elixir package ecosystem list

The scripts/elixir directory now includes a new automation script (update\_packages\_list.exs) that fetches repository metadata from GitHub and package information from Hex.pm to automatically generate and validate the official list of Membrane ecosystem packages. This script produces two key outputs: a structured data file (packages.exs) that categorizes packages into sections like Plugins, Formats, and Utils, and a filtered list (hex\_packages.exs) containing only packages with available HexDocs. The update process also enforces data integrity by checking for unlisted repositories and maintaining a blacklist to exclude non-package repositories, ensuring the documentation remains accurate and up-to-date without manual intervention.

scripts/elixir · high confidence

Initial project scaffolding and configuration

The repository is initialized with essential configuration files, including a Credo linter setup (.credo.exs) and an Elixir code formatter configuration (.formatter.exs) that defines local macro names and export rules. Standard project metadata and documentation are added, such as the Apache 2.0 License, a detailed README, and a CHANGELOG starting at version 1.3.5. The project structure is further defined by a CONTRIBUTING guide, a .gitignore file, and Git submodules for tutorials and demos.

(repo-wide) · high confidence

Introduction of core Membrane framework modules

The \lib/membrane\ directory now contains the foundational modules for the Membrane framework, including \Membrane.Bin\ for containerizing elements, \Membrane.Element\ and its specific behaviors (\Source\, \Filter\, \Sink\, \Endpoint\) for defining processing units, and \Membrane.Pipeline\ for orchestration. This change introduces the \Membrane.Clock\ for time synchronization, \Membrane.Buffer\ for data transport with PTS/DTS metadata, and \Membrane.ChildrenSpec\ for defining pipeline topologies. It also adds utility components like \Membrane.Connector\ (renamed from \ForwardingFilter\) for dynamic pad forwarding, \Membrane.Funnel\ and \Membrane.Tee\ for stream distribution/combination, and \Membrane.Fake.Sink\ for testing. The framework now enforces strict error handling via new exception types (\PipelineError\, \BinError\, \CallbackError\, etc.) and provides a \Membrane.EventProtocol\ for standardized event behavior.

lib/membrane · high confidence

New Mix tasks for generating component templates and downloading demos

Developers can now use \mix membrane.gen.\*\ (e.g., \mix membrane.gen.source\) to scaffold new Membrane component files from templates, and \mix membrane.demo\ to download example projects from the membrane\_demo repository. The demo task supports listing available demos, cloning all of them, or selectively checking out specific demos using Git sparse-checkout, while the generator tasks validate module names and create files in the appropriate \lib\ directory structure.

lib/mix · high confidence

New component templates for Membrane pipelines

Added new Mix task-generated templates for Membrane components, including Bin, Endpoint, Filter, Pipeline, Sink, and Source. These templates provide a structured starting point for building media processing pipelines, featuring pre-configured input/output pads, state structs, and commented-out lifecycle callbacks (such as handle\_init, handle\_buffer, and handle\_terminate\_request) to guide implementation.

templates · high confidence

New debug filter and sink elements for pipeline inspection

Added Membrane.Debug.Filter and Membrane.Debug.Sink elements to help users inspect data flowing through a pipeline. The Filter element forwards data to the opposite side while invoking configurable callback functions for buffers, events, stream formats, and start/end-of-stream signals. The Sink element stops data flow and similarly allows custom callbacks for debugging purposes, enabling users to log or inspect specific pipeline events without altering the main processing logic.

lib/membrane/debug · high confidence

New scripts to identify PR author origin and retrieve ticket IDs

Added two new Python scripts to support GitHub workflow automation. The \get\_author\_origin.py\ script determines whether a pull request author is a core team member or from the community by checking their login against a provided JSON list of team members. The \get\_ticket\_id.py\ script searches a provided JSON payload of project items to find and return the ID of the ticket associated with a specific PR URL.

scripts/python · high confidence

Removals

Removal of Helpers.Time and Helpers.Formatting modules

The \Membrane.Helpers.Time\ and \Membrane.Helpers.Formatting\ modules have been removed from the codebase. This eliminates the \ticks\_per\_sec/0\ function (which returned the Erlang VM clock resolution) and the \ip/1\ function (which formatted IP addresses). Users relying on these helper utilities for time resolution queries or IP address string formatting will need to implement alternative solutions or use standard library functions.

_lib/membrane\core/helpers · high confidence

Removal of Membrane.Mixins.Log module

The \Membrane.Mixins.Log\ mixin, which previously provided \info/1\, \warn/1\, and \debug/1\ helper functions for logging within other modules, has been removed from the codebase.

_lib/membrane\core/mixins · high confidence

Removal of hardcoded audio constants and Caps conversion logic

The \Membrane.Caps\ module and the \Membrane.Const\ module have been removed from the core library. This eliminates the previous hardcoded audio configuration (48kHz, 16-bit, stereo) and the specific \to\_gstreamer\ conversion logic that relied on these constants, requiring users to define their own caps structures and conversion methods.

_lib/membrane\core · high confidence

Architecture

Refactored parent-child lifecycle and linking into modular components

The parent component's internal architecture has been restructured to improve maintainability and clarity. The monolithic parent logic is now split into dedicated modules: \ChildLifeController\ manages the full lifecycle of children (initialization, linking, and termination), \ChildEntryParser\ handles the parsing of child specifications, \ChildrenModel\ provides a standardized interface for child state management, \ClockHandler\ centralizes clock selection and proxying, \CrashGroup\ defines the data structure for crash groups, \DiamondDetectionController\ handles diamond pattern detection, \LifecycleController\ orchestrates high-level state transitions (setup, playing, termination), and \SpecificationParser\ parses the \ChildrenSpec\ into links and children definitions. This refactoring isolates concerns, making the parent's behavior easier to understand and modify.

lib/membrane/core/parent · high confidence

Behavioural changes

Atomic demand counter now supports distributed access via a background worker

The AtomicDemand implementation has been updated to safely handle atomic counters accessed from multiple nodes. A new DistributedAtomic module and its associated GenServer worker now manage the underlying :atomics counter, routing cross-node operations through GenServer calls while keeping same-node access direct. This ensures that demand tracking remains consistent and error-logged even in distributed scenarios.

_lib/membrane/core/element/atomic\demand · high confidence

Configure JUnit formatter and Membrane Core telemetry flags for the test environment

A new configuration file for the test environment enables the JUnit test formatter to include filenames in its output and activates comprehensive telemetry tracking for Membrane Core elements, bins, and pipelines. This setup ensures that specific lifecycle callbacks (such as init, playing, setup, terminate, and parent notifications) are monitored and that all data points are reported during testing, facilitating better observability and debugging of media processing pipelines.

config · high confidence

Deprecate public Buffer.Metric implementations

The \Membrane.Buffer.Metric.ByteSize\ and \Membrane.Buffer.Metric.Count\ modules are now deprecated. These modules, which previously provided public metric functionality for calculating buffer sizes in bytes and counts, have been moved to the internal API of the Membrane Framework and are no longer accessible via the public \Membrane.Buffer.Metric\ behaviour. Users relying on these modules will see deprecation warnings, as the functionality is now handled internally.

lib/membrane/buffer/metric · high confidence

Deprecation of Buffer.Metric module

The Membrane.Buffer.Metric module, which previously defined callbacks for buffer size approximation and demand units, is now deprecated. The metric functionality has been moved to the internal API of the Membrane Framework, and users should no longer rely on these callbacks.

lib/membrane/buffer · high confidence

Introduce explicit action types and callback context for Membrane Bins

This change introduces three new modules in the \lib/membrane/bin\ area to formalize bin behavior: \Membrane.Bin.Action\ defines the specific return types (actions) that bin callbacks can yield, including \{:setup, :incomplete \| :complete}\, \{:spec, ...}\, \{:remove\_link, ...}\, and timer management actions (\start\_timer\, \timer\_interval\, \stop\_timer\); \Membrane.Bin.CallbackContext\ defines the structure of the context map passed to bin callbacks, adding fields like \:crash\_initiator\, \:crash\_reason\, \:members\, \:exit\_reason\, and \:group\_name\ to support crash group handling and detailed child termination info; and \Membrane.Bin.PadData\ defines the struct for pad state, explicitly exposing \max\_instances\ for dynamic pads and enforcing a set of private fields. These changes provide a stricter, more documented interface for bin developers to manage child lifecycle, linking, and internal state.

lib/membrane/bin · high confidence

Introduce structured pipeline actions and callback contexts

This change introduces the \Membrane.Pipeline.Action\ module, which defines the specific action types (such as \setup\, \spec\, \remove\_link\, \start\_timer\, and \terminate\) that pipeline callbacks can return to control the pipeline's behavior. It also adds the \Membrane.Pipeline.CallbackContext\ module to formally define the context map passed to these callbacks, including fields like \:from\ for synchronous calls, \:crash\_initiator\ for crash handling, and \:group\_name\ for child groups. This provides a clearer, type-safe interface for interacting with the pipeline's lifecycle and topology.

lib/membrane/pipeline · high confidence

Major refactor of element core: new modular controllers and auto-flow control

The element core implementation has been restructured into distinct, specialized modules to improve maintainability and performance. The previous monolithic handling logic is now split into \ActionHandler\ (validating and executing element actions), \BufferController\ (managing incoming buffers), \EventController\ (handling stream events), \DemandController\ (managing output pad demand snapshots and redemands), and separate \AutoFlowController\ and \ManualFlowController\ modules for different flow control strategies. A new \AtomicDemand\ module introduces distributed atomic counters for precise demand tracking, while \EffectiveFlowController\ dynamically resolves whether auto pads operate in push or pull mode. Additionally, a \DiamondDetectionController\ is introduced to detect and warn about potential pipeline deadlocks caused by diamond-shaped topologies in pull-mode streams. These changes fundamentally alter how elements process data, manage state, and interact with their pads, requiring users to ensure their custom elements are compatible with the new callback contexts and action handling mechanisms.

lib/membrane/core/element · high confidence

Manual flow control now supports timestamp-based demand units

The manual flow controller has been refactored to support demand measured in timestamps (PTS, DTS, or DTS/PTS) in addition to the existing buffer count and byte size units. This change introduces a new \BufferMetric\ module to handle metric calculations and a rewritten \InputQueue\ that tracks consumed buffer timestamps to accurately determine how much data satisfies a timestamp-based demand. Users relying on manual flow control can now specify demand units based on time, allowing for more precise control over playback timing and buffer management, while the system also includes warnings for non-monotonic timestamps and demands that are smaller than the elapsed time of consumed buffers.

_lib/membrane/core/element/manual\_flow\controller · high confidence

Pipeline lifecycle and action handling refactored into dedicated modules

The internal structure of the pipeline has been reorganized to improve clarity and maintainability. A new \ActionHandler\ module now centralizes the processing of pipeline actions (such as setup, spec loading, timer management, and termination), replacing the previous inline logic. The pipeline's internal state is now managed by a dedicated \State\ struct, which includes explicit fields for crash groups, synchronization, and setup completion status. Additionally, a \CallbackContext\ module standardizes how context data is passed to callbacks, and a \Zombie\ module handles the behavior of a pipeline after it has requested termination, ensuring callbacks are no longer invoked on the user's implementation. These changes streamline how pipelines manage their lifecycle, errors, and interactions with child elements.

lib/membrane/core/pipeline · high confidence

Refactor child lifecycle management into dedicated utility modules

The internal logic for managing child element lifecycles has been reorganized into three new dedicated modules: \CrashGroupUtils\ for handling crash group membership and detonation, \LinkUtils\ for managing pad links and unlinks, and \StartupUtils\ for child initialization and synchronization. This refactoring centralizes these responsibilities, improving code maintainability and clarity for the pipeline's core lifecycle controller without changing external behavior.

_lib/membrane/core/parent/child\_life\controller · high confidence

Refactored FilterAggregator internal action handling and context management

The FilterAggregator now uses a dedicated InternalAction module to manage internal state transitions (such as setup, playing, and start\_of\_stream) and a new Context module to handle the encapsulation of element states. This change introduces stricter validation, ensuring that only filters with pads in \:auto\ flow-control mode are supported, and updates how pad data and context links are built and updated during playback.

_lib/membrane/core/filter\aggregator · high confidence

Refactored bin internal architecture with dedicated action and pad controllers

The internal implementation of bins has been restructured to improve modularity and maintainability. A new \ActionHandler\ module now centralizes the processing of bin actions (such as spec updates, child management, and timer control), replacing previous inline logic. Pad linking and unlinking responsibilities have been moved to a dedicated \PadController\, which handles both internal and external link requests with clearer state management. Additionally, a \CallbackContext\ module was introduced to standardize how callback contexts are constructed from the bin's state, and a \Zombie\ module was added to handle post-termination behavior for bins. These changes refine the internal mechanics of bin lifecycle and communication without altering the public API surface.

lib/membrane/core/bin · high confidence

Refactored child pad management and lifecycle handling

The internal structure for managing child components (elements and bins) has been reorganized to improve code clarity and maintainability. Pad-related logic, including validation, model data structures, and specification handling, has been extracted into dedicated modules (\PadController\, \PadModel\, \PadSpecHandler\, \PadsSpecs\) within the \lib/membrane/core/child\ directory. Additionally, a new \LifecycleController\ module has been introduced to centralize the handling of parent notifications. These changes streamline how pad options are parsed, how pad instances are validated, and how lifecycle events are processed, without altering the external API for defining or linking pads.

lib/membrane/core/child · high confidence

Refactored core component architecture and added diamond detection

The core library has been restructured to improve modularity and observability. Bin, Element, and Pipeline logic has been separated into distinct modules under the \Membrane.Core\ namespace, with a new \Membrane.Core.Component\ module providing unified state and context helpers. A new diamond detection mechanism has been added to identify and warn about potential flow-control deadlocks in pull-mode pipelines. Additionally, the internal message system has been standardized via \Membrane.Core.Message\, and the legacy telemetry system has been preserved in \Membrane.Core.LegacyTelemetry\ for backward compatibility while the new telemetry infrastructure is adopted.

lib/membrane/core · high confidence

Refactored element callback architecture and action types

The element implementation has been restructured to use a unified \CallbackContext\ struct for passing state to callbacks, replacing previous ad-hoc context passing. A new \Membrane.Element.Action\ module centralizes the type specifications for all actions elements can return (such as \:demand\, \:buffer\, \:event\, and \:redemand\), making the API more explicit. The callback behaviors in \WithInputPads\ and \WithOutputPads\ have been updated to accept this new context, and \PadData\ has been refined to better track pad state including auto-demand pausing and instance limits. This change standardizes how elements interact with the framework and manage their internal state.

lib/membrane/element · high confidence

Removal of the main Membrane application supervisor

The \lib/membrane\_core.ex\ file, which previously defined the \Membrane\ module as an OTP application with a \:one\_for\_one\ supervisor strategy, has been deleted. This change removes the default top-level supervision tree that was automatically started when the application launched, shifting responsibility for process management to other parts of the system (such as the new \Membrane.Log.Supervisor\ and router structures mentioned in the commit history).

lib · high confidence

Test coverage

Added integration tests for pipeline lifecycle, crash groups, and element behavior; Added test coverage for core Membrane components; Added test suite for FilterAggregator; Added test support elements for Membrane pipeline testing; Added test support for log metadata verification; Added test support helpers for child crash scenarios; Added test support helpers for synchronization testing; Added test support infrastructure for child removal scenarios; Added test support module for Bin components; Added test support modules for accepted format validation; Added test support modules for distributed pipelines, dynamic filtering, and stream formats; Added test support modules for pipeline demand testing; Added tests for BufferMetric byte size, count, and timestamp handling; Added tests for Membrane demo and component generation tasks; Added tests for RCPipeline event subscription and await functionality; Added tests for the Parent Specification Parser; Added unit tests for Membrane.Testing components; Added unit tests for core element subsystems; Configure ExUnit for distributed testing and parallel execution; New testing utilities and assertions for Membrane pipelines.

Dependencies

Major dependency overhaul and Elixir version upgrade

The project has been upgraded to require Elixir \~\> 1.17 and bumped to version 1.3.4. The dependency list has been significantly expanded and modernized: the legacy \porcelain\ dependency has been removed, while new dependencies such as \bunch\, \credo\, \dialyxir\, \ex\_doc\, \excoveralls\, \mox\, and \telemetry\ have been added to support improved static analysis, documentation generation, test coverage, mocking, and runtime telemetry. The \mix.lock\ file has been regenerated to reflect these changes.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 53 → 70 (+17.1)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 99 → 99 (+0.4)
  • Architecture 91 → 96 (+5.2)
  • Maturity 65 → 65 (-0.1)
  • Readiness 38 → 66 (+28.1)
  • Security 54 → 70 (+15.8)

Resolved (18)

  • Change coupling: pad_controller.ex ↔ demand_controller.ex (lib/membrane/core/child/pad_controller.ex)
  • Change coupling: pad_controller.ex ↔ pad_data.ex (lib/membrane/core/child/pad_controller.ex)
  • Change coupling: pad_controller.ex ↔ pad_model.ex (lib/membrane/core/child/pad_controller.ex)
  • Coverage not included — suite not readable by the collector
  • Dependency hygiene not measured — no supported dependency manifest was read
  • Duplicated block (13 lines × 2) (lib/membrane/core/bin.ex)
  • Duplicated block (5 lines × 2) (lib/membrane/buffer/metric/byte_size.ex)
  • Duplicated block (7 lines × 2) (lib/membrane/testing/endpoint.ex)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • No exposed public API
  • Off-boarding risk: anonymized user #1
  • Test reliability not included

New (41)

  • Change coupling: action_handler.ex ↔ exceptions.ex (lib/membrane/core/element/action_handler.ex)
  • Change coupling: bin.ex ↔ element.ex (lib/membrane/core/bin.ex)
  • Change coupling: metric.ex ↔ input_queue.ex (lib/membrane/buffer/metric.ex)
  • Documentation: no contributor guidance (README.md)
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (README.md)
  • Duplicated block (15–17 lines × 2) (lib/membrane/core/bin.ex)
  • Duplicated block (5 lines × 2) (lib/membrane/buffer/metric/byte_size.ex)
  • Duplicated block (7 lines × 2) (lib/membrane/buffer/metric/byte_size.ex)
  • Duplicated block (8 lines × 2) (lib/membrane/core/bin.ex)
  • Duplicated block (8 lines × 2) (lib/membrane/testing/endpoint.ex)
  • Duplicated block (8 lines × 2) (lib/membrane/testing/endpoint.ex)
  • Fork-triggerable workflow runs with an unscoped write token
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • …and 21 more

Changes since last survey

  • 2 commits — 2 feature/other, 0 fixes

By area

  • (repo) — 1 commit
  • .github/workflows — 1 commit

Notable commits

  • change: Merge pull request #1171 from membraneframework/gha-on-prs
  • change: Restrict CI push trigger to main/master, run on pull_request too

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

membraneframework/membrane_core was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 23 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 3aca29d537ae7f49f2bc792c48fd68d16420ec61 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-955b9cee9818.