Dala.Media.Scene (dala v0.2.0)

Copy Markdown View Source

Realtime scene graph compositor.

Composites multiple media sources (video, overlays, text, effects) into a single GPU-rendered output. Frame-clock driven for smooth 60fps.

Scene graph:

Scene
  VideoNode      hardware-decoded video texture
  OverlayNode    image/UI overlay layers
  TextNode       GPU-rendered text
  EffectNode     GPU compute filters (blur, LUT, etc.)
  AnimationNode  frame-clock driven animations

Example

{:ok, scene} = Dala.Media.Scene.new(1920, 1080)

# Add a video layer
{:ok, video_node} = Dala.Media.Scene.add_node(scene, :video, %{
  stream: video_stream,
  position: {0, 0},
  size: {1920, 1080},
  z_index: 0
})

# Add an overlay
{:ok, overlay_node} = Dala.Media.Scene.add_node(scene, :overlay, %{
  texture: overlay_texture,
  position: {100, 100},
  size: {200, 50},
  opacity: 0.8,
  z_index: 10
})

# Add a blur effect
{:ok, effect_node} = Dala.Media.Scene.add_node(scene, :effect, %{
  type: :blur,
  radius: 5.0,
  input: video_node,
  z_index: 5
})

# Composite and render
Dala.Media.Scene.render(scene)

Summary

Functions

Add an image node to the scene.

Add a node to the scene.

Add a video node to the scene with optional PiP (picture-in-picture) transform.

Returns a specification to start this module under a supervisor.

Destroy the scene and release all GPU resources.

Get current FPS.

Get current frame count.

Create a new scene with the given dimensions.

Remove a node from the scene.

Composite all nodes and render to the GPU surface.

Update a node's PiP (picture-in-picture) transform.

Set target FPS (default 60).

Update a node's transform.

Update a node's properties.

Types

node_id()

@type node_id() :: reference()

node_type()

@type node_type() :: :video | :image | :overlay | :text | :effect | :animation

opacity()

@type opacity() :: float()

position()

@type position() :: {non_neg_integer(), non_neg_integer()}

scene_ref()

@type scene_ref() :: pid()

size()

@type size() :: {non_neg_integer(), non_neg_integer()}

transform()

@type transform() :: %{
  position: position(),
  scale: {float(), float()},
  rotation: float(),
  opacity: opacity(),
  z_index: z_index()
}

z_index()

@type z_index() :: integer()

Functions

add_image(pid, opts)

@spec add_image(
  scene_ref(),
  keyword()
) :: {:ok, node_id()} | {:error, term()}

Add an image node to the scene.

Convenience wrapper around add_node/3 for image sources.

Options

  • :image_id — The GPU image ID (from Dala.Gpu.load_image/4)
  • :position{x, y} tuple (default: {0, 0})
  • :size{w, h} tuple (default: {100, 100})
  • :z_index — Layer order (default: 0)
  • :opacity0.0 to 1.0 (default: 1.0)

Example

{:ok, img_node} = Dala.Media.Scene.add_image(scene, image_id: 1, position: {540, 20}, size: {120, 90}, z_index: 100)

add_node(pid, type, props)

@spec add_node(scene_ref(), node_type(), map()) :: {:ok, node_id()} | {:error, term()}

Add a node to the scene.

add_video(pid, opts)

@spec add_video(
  scene_ref(),
  keyword()
) :: {:ok, node_id()} | {:error, term()}

Add a video node to the scene with optional PiP (picture-in-picture) transform.

Convenience wrapper around add_node/3 for video streams.

Options

  • :stream — A Dala.Media.Video pid (required)
  • :position{x, y} tuple (default: {0, 0})
  • :size{w, h} tuple (default: {1920, 1080})
  • :z_index — Layer order (default: 0)
  • :pip — If true, applies a PiP transform (small overlay in top-right corner)
  • :pip_position — Custom PiP position {x, y} (default: auto-calculated)
  • :pip_size — Custom PiP size {w, h} (default: {200, 150})

Example

# Full-screen video
{:ok, vid} = Dala.Media.Scene.add_video(scene, stream: video_stream, size: {1920, 1080})

# PiP video overlay
{:ok, pip} = Dala.Media.Scene.add_video(scene, stream: pip_stream, pip: true, z_index: 100)

# Custom PiP position
{:ok, pip} = Dala.Media.Scene.add_video(scene, stream: pip_stream, pip: true, pip_position: {50, 50}, pip_size: {300, 200})

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

destroy(pid)

@spec destroy(scene_ref()) :: :ok

Destroy the scene and release all GPU resources.

fps(pid)

@spec fps(scene_ref()) :: float()

Get current FPS.

frame_count(pid)

@spec frame_count(scene_ref()) :: non_neg_integer()

Get current frame count.

new(width, height, opts \\ [])

@spec new(non_neg_integer(), non_neg_integer(), keyword()) ::
  {:ok, scene_ref()} | {:error, term()}

Create a new scene with the given dimensions.

remove_node(pid, node_id)

@spec remove_node(scene_ref(), node_id()) :: :ok

Remove a node from the scene.

render(pid)

@spec render(scene_ref()) :: :ok

Composite all nodes and render to the GPU surface.

set_pip_transform(pid, node_id, opts)

@spec set_pip_transform(scene_ref(), node_id(), keyword()) :: :ok

Update a node's PiP (picture-in-picture) transform.

Convenience function to move/resize a PiP node.

Example

Dala.Media.Scene.set_pip_transform(scene, pip_node_id, position: {100, 50}, size: {250, 180})

set_target_fps(pid, fps)

@spec set_target_fps(scene_ref(), pos_integer()) :: :ok

Set target FPS (default 60).

set_transform(pid, node_id, transform)

@spec set_transform(scene_ref(), node_id(), transform()) :: :ok

Update a node's transform.

update_node(pid, node_id, props)

@spec update_node(scene_ref(), node_id(), map()) :: :ok

Update a node's properties.