# `Dala.Media.Clock`
[🔗](https://github.com/manhvu/dala/blob/main/lib/dala/media/clock.ex#L1)

Realtime frame-clock for AV sync and animation.

Uses audio clock as master (audio glitches are more noticeable than video drops).
Drives the animation system and frame pacing.

Architecture:
    Audio Clock (master)
        ↓
    Frame Pacer
        ↓
    Video Frame Selection
        ↓
    Frame Presentation

# `clock_ref`

```elixir
@type clock_ref() :: pid()
```

# `timestamp_us`

```elixir
@type timestamp_us() :: integer()
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `drift`

```elixir
@spec drift(clock_ref()) :: integer()
```

Get current AV drift in microseconds.

# `report_video_frame`

```elixir
@spec report_video_frame(clock_ref(), timestamp_us()) :: :ok
```

Report a video frame presentation (called by video renderer).

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

Start the frame clock.

# `start_ticking`

```elixir
@spec start_ticking(clock_ref()) :: :ok
```

Start ticking at the target FPS.

# `stats`

```elixir
@spec stats(clock_ref()) :: %{
  frame_count: non_neg_integer(),
  dropped_frames: non_neg_integer(),
  drift_us: integer(),
  target_fps: pos_integer()
}
```

Get frame statistics.

# `stop_ticking`

```elixir
@spec stop_ticking(clock_ref()) :: :ok
```

Stop ticking.

# `subscribe`

```elixir
@spec subscribe(clock_ref(), pid()) :: :ok
```

Register a listener process that receives `{:clock, :tick, %{frame: n, timestamp_us: us}}`.

# `unsubscribe`

```elixir
@spec unsubscribe(clock_ref(), pid()) :: :ok
```

Unsubscribe a listener.

# `update_audio_clock`

```elixir
@spec update_audio_clock(clock_ref(), timestamp_us()) :: :ok
```

Update the audio master clock (called by audio output callback).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
