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 animationsExample
{: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
@type node_id() :: reference()
@type node_type() :: :video | :image | :overlay | :text | :effect | :animation
@type opacity() :: float()
@type position() :: {non_neg_integer(), non_neg_integer()}
@type scene_ref() :: pid()
@type size() :: {non_neg_integer(), non_neg_integer()}
@type z_index() :: integer()
Functions
Add an image node to the scene.
Convenience wrapper around add_node/3 for image sources.
Options
:image_id— The GPU image ID (fromDala.Gpu.load_image/4):position—{x, y}tuple (default:{0, 0}):size—{w, h}tuple (default:{100, 100}):z_index— Layer order (default:0):opacity—0.0to1.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 a node to the scene.
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— ADala.Media.Videopid (required):position—{x, y}tuple (default:{0, 0}):size—{w, h}tuple (default:{1920, 1080}):z_index— Layer order (default:0):pip— Iftrue, 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})
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec destroy(scene_ref()) :: :ok
Destroy the scene and release all GPU resources.
Get current FPS.
@spec frame_count(scene_ref()) :: non_neg_integer()
Get current frame count.
@spec new(non_neg_integer(), non_neg_integer(), keyword()) :: {:ok, scene_ref()} | {:error, term()}
Create a new scene with the given dimensions.
Remove a node from the scene.
@spec render(scene_ref()) :: :ok
Composite all nodes and render to the GPU surface.
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})
@spec set_target_fps(scene_ref(), pos_integer()) :: :ok
Set target FPS (default 60).
Update a node's transform.
Update a node's properties.