Skip to content

media sdk overlay factory

Andre Lafleur edited this page Oct 8, 2026 · 7 revisions

About OverlayFactory

OverlayFactory is the entry point for Media SDK overlays. Use it to initialize overlay support, get or create an Overlay stream for a camera, and remove an overlay stream when an integration needs to retire it.

You do not construct Overlay or Layer directly. OverlayFactory.Get returns an Overlay for a camera, and Overlay.CreateLayer returns a Layer inside that overlay. The Layer is where you draw text, lines, rectangles, ellipses, and images.

How overlays are organized

An overlay belongs to one camera and one overlay stream name. The stream name is the application-owned name that appears in the camera metadata stream list.

OverlayFactory.Get(camera, name) returns the same Overlay instance for the same camera-and-name pair within the process. Use a stable name per overlay purpose, such as AnalyticsOverlay or OperatorAnnotations, and reuse it across application runs.

An overlay contains one or more layers. Each layer has a LayerIdentifier GUID. The player uses this GUID to update that layer over time, so use a stable GUID for each drawing concept, such as object boxes, alarm regions, status text, or a logo. Layers cannot be listed later through the overlay API, so the application must own and preserve its layer ID scheme.

For dynamic content, use a bounded pool of deterministic layer IDs. For example, if an analytics integration tracks up to 50 objects, use a predictable set of 50 layer IDs, clear those IDs when the application starts, and reuse them while objects appear and disappear.

OverlayFactory

using Genetec.Sdk.Media.Overlay;

OverlayFactory.Initialize(engine);

Overlay overlay = OverlayFactory.Get(cameraGuid, "AnalyticsOverlay");

The Engine must be connected to the Directory, and the Security Center license must include the Media SDK option. Calling Get before Initialize throws InvalidOperationException.

Member Description
OverlayFactory.Initialize(IEngine engine) Initialize overlay support. Call once during application startup.
OverlayFactory.Get(Guid cameraGuid, string overlayName) Get or create an Overlay for the camera and name. Overloads also accept a Camera, a list of camera GUIDs, or an integer logical ID.
OverlayFactory.Remove(Guid cameraGuid, string overlayName, bool deleteFiles) Remove the overlay stream. Pass true to delete associated recorded overlay files. Pass false to remove the live stream registration while keeping archived overlay data available for playback. Use this for cleanup or upgrade workflows, not to clear routine drawings.

Use Camera.IsOverlaySupported before creating overlays when your application selects cameras dynamically. Ghost and federated cameras do not support creating overlay streams.

Overlay

After getting the overlay, initialize its drawing surface, and then create layers.

overlay.StateChange += OnOverlayStateChanged;

overlay.Initialize(
    drawingSurfaceHeight: 1080,
    drawingSurfaceWidth: 1920);

Layer layer = overlay.CreateLayer(
    Guid.Parse("525dbe6e-5579-4b36-ac88-761a646a5410"),
    "Vehicle count");
Member Description
Initialize(double drawingSurfaceHeight, double drawingSurfaceWidth) Set the logical drawing surface dimensions. Call before creating layers. The dimensions must be numbers greater than zero.
DrawingSurfaceHeight, DrawingSurfaceWidth The initialized surface size. These values are 0 until Initialize succeeds.
CreateLayer(Guid layerIdentifier, string displayName) Create a layer with a stable GUID and display name. The overlay must be initialized first.
IsReadyForUpdate true when the overlay recorder is started and can propagate layer updates.
StateChange Raised when overlay update readiness changes. Use OverlayStatusEventArgs.CanPropagateUpdate to check the new state.
Dispose() Release the overlay object and recorder resources. This does not remove the overlay stream and does not dispose layers created from the overlay.

Call Initialize once per overlay. Calling it again with different dimensions is not supported. If the camera resolution or the application coordinate system changes, create a new overlay and layer setup rather than resizing the existing overlay.

Drawing surface and coordinates

The drawing surface is a logical canvas. Coordinates start at the top-left corner of that canvas:

  • x = 0, y = 0 is the top-left corner.
  • x increases to the right.
  • y increases downward.
  • Drawing outside 0..DrawingSurfaceWidth and 0..DrawingSurfaceHeight is clipped.

Use a drawing surface that matches the coordinate system you use to calculate overlay positions. For a typical video overlay, initialize the surface to the video frame size that your application targets, such as 1080, 1920 for 1920 by 1080 video.

Image positions are used as supplied. DrawImage takes an image and the destination rectangle on the overlay canvas; the destination rectangle is not independently scaled. If you initialize the overlay to a surface that does not match the video coordinate system, image overlays can appear at unexpected positions or sizes.

Layer

A Layer carries drawing commands. Drawing calls buffer content on the layer until an Update overload publishes the layer.

layer.Duration = TimeSpan.FromSeconds(5);
layer.DepthIndex = 10;

layer.DrawText(
    "Vehicle detected",
    "Calibri",
    emSize: 32,
    color: "#FFFF0000",
    x: 50,
    y: 50);

bool updated = layer.Update();
Member Description
LayerIdentifier The stable GUID that identifies this layer in the overlay stream. Reuse the same GUID to update or clear the same logical layer.
DisplayName The layer display name supplied to CreateLayer. It is descriptive metadata, not the layer identity.
IsReady true after the layer drawing surface and drawing context are ready.
IsRecorderInitialized true when the layer has an initialized recorder. Returns false after the layer is disposed.
Duration How long the published layer remains active. Milliseconds are ignored. A duration of TimeSpan.Zero is treated as 24 hours, not as infinite. For long-lived layers, refresh the duration before it elapses; use Clear() followed by Update() when the application must remove the layer at a precise time.
DepthIndex Visual stacking value used by MediaPlayer. When layers overlap, higher values render in front of lower values. Use distinct values when order matters.
IsDisplayedByDefault true by default. When set to false, the layer is not rendered by default by the player.
DrawText(...) Draw text at a point.
DrawLine(...) Draw a line between two points.
DrawRectangle(...) Draw a rectangle with fill and outline values.
DrawEllipse(...) Draw an ellipse with fill and outline values.
DrawImage(...) Draw a BitmapImage at a destination rectangle.
Clear() Clear the buffered drawing content. Call Update() after Clear() to publish the cleared layer.
Dispose() Release layer resources. Disposing the parent overlay does not dispose the layer.

When you pass WPF Brush or Pen objects to drawing methods, freeze them before calling the method. The string color overloads create their own brushes and pens.

Color values

String color overloads accept 8-digit hexadecimal ARGB color values in the form #AARRGGBB. This form is recommended because it includes the alpha value. Standard WPF color names, such as Red, are also accepted.

layer.DrawRectangle(
    fillColor: "#80FF0000",
    outlineColor: "#FFFF0000",
    x: 100,
    y: 100,
    width: 300,
    height: 120);

In #AARRGGBB, AA is alpha, RR is red, GG is green, and BB is blue. For example, #FFFF0000 is opaque red, and #80FF0000 is semi-transparent red.

Empty or invalid color strings fail before the drawing command is queued. The failed draw call does not add content to the layer.

Images

DrawImage accepts a non-null WPF BitmapImage and a destination rectangle:

layer.DrawImage(
    bitmapImage,
    xCoordinate: 40,
    yCoordinate: 40,
    width: 160,
    height: 90);

The image data is included in the layer update. The viewer does not load the original image file path. If the same BitmapImage instance is drawn more than once before an update, the update can reference that image at multiple locations.

No numeric maximum image width, height, or byte size is defined for DrawImage. Large images increase the overlay update payload and must be decoded and rendered by viewers. Prefer images that are already close to the displayed size, and avoid resending large images at high frequency.

Publishing updates

Each Update call publishes the drawing commands currently buffered on the layer and then resets the drawing buffer for the next update. Redraw content before the next Update if it should remain visible with new timing or new geometry.

Member Description
Update() Publish using the current UTC time.
Update(DateTime frameTime) Publish with an explicit frame time. The time is converted to UTC before recording unless it is DateTime.MinValue.
Update(DateTime frameTime, uint rtpTimestamp) Publish with both an explicit frame time and RTP timestamp.
Update(uint rtpTimestamp) Publish with an RTP timestamp when that is the timing value your application has.

Update returns true when the update is recorded. It returns false when the overlay is not ready for updates, the layer is disposed, or the update cannot be recorded. The first update can return false while the overlay starts up. Use Overlay.IsReadyForUpdate or Overlay.StateChange when the application needs to wait for update readiness.

Important

Update(DateTime) does not draw in the past. It does not edit an existing archive or insert an overlay into video that Security Center already recorded.

The supplied time becomes timing metadata for the update being sent through the current overlay stream. It does not backfill overlays, repair delayed analysis, or make the overlay appear on earlier video.

Use Update() for normal live annotations. Use the timestamp overloads only when the application already has the correct frame time or RTP timestamp for the overlay update it is sending.

Clearing layers

Clear a layer by publishing an empty update for the same LayerIdentifier:

layer.Clear();
layer.Update();

This is the right way to remove drawings during normal operation. Do not use OverlayFactory.Remove to clear routine content; that removes the overlay stream itself.

If a layer has a finite Duration, the player keeps the layer active until that duration expires. Since milliseconds are ignored, use Clear() followed by Update() when the application needs precise removal.

Displaying overlays in MediaPlayer

Overlay streams are camera metadata streams. A MediaPlayer discovers available overlay stream IDs while it plays video. Subscribe from the availability event instead of assuming the list is complete during initialization:

player.AvailableMetadataStreamChange += (_, _) =>
{
    foreach (Guid streamId in player.AvailableMetadataStreams)
    {
        if (!player.MetadataStreamsSubscriptions.Contains(streamId))
        {
            player.SubscribeMetadataStream(streamId);
        }
    }
};
Member Description
AvailableMetadataStreams Overlay metadata stream IDs the player can subscribe to.
MetadataStreamsSubscriptions Metadata stream IDs the player is currently subscribed to.
AvailableMetadataStreamChange Raised when overlay metadata streams are discovered, added, or removed.
SubscribeMetadataStream(Guid) Display the selected overlay metadata stream.
UnsubscribeMetadataStream(Guid) Stop displaying the selected metadata stream.
MediaPlayer.AutomaticallyStartOverlayStream Process-wide setting that makes players subscribe to overlay streams automatically as they are discovered. Set it explicitly for the behavior your application wants.

To subscribe to one named overlay stream, match the stream name on the camera, then subscribe when the player reports that stream as available:

MetadataStreamInfo overlayStream = camera.MetadataStreams
    .FirstOrDefault(stream => stream.Name == "AnalyticsOverlay" && !stream.IsGhost);

if (overlayStream != null &&
    player.AvailableMetadataStreams.Contains(overlayStream.StreamId) &&
    !player.MetadataStreamsSubscriptions.Contains(overlayStream.StreamId))
{
    player.SubscribeMetadataStream(overlayStream.StreamId);
}

The user must have the privilege to display video overlays for overlay subscription to succeed.

ShowSpecialOverlay(OverlayType) is unrelated to application overlay streams. It displays built-in player diagnostic overlays such as statistics and status.

Update volume and lifecycle

No numeric maximum update frequency, layer count, or image size is defined for overlays. Each layer uses drawing resources, each update serializes the current layer content into a metadata update, and image updates include image data. Keep the layer set bounded, update only layers that changed, and dispose layers that are no longer used.

For recurring drawings, prefer stable layers with stable IDs. For temporary drawings, clear the layer and publish the clear update before disposing it. Dispose layers before disposing the parent overlay when shutting down an overlay workflow.

Use OverlayFactory.Remove only when the integration needs to remove the overlay stream itself, such as uninstall, migration, or cleanup. Pass deleteFiles: false when archived overlay data should remain available for playback. Pass deleteFiles: true only when the recorded overlay data should also be deleted.

See also

  • About MediaPlayer: MediaPlayer WPF control for live, recorded, and local-file playback.

Platform SDK

Plugin SDK

Workspace SDK

Media SDK

Macro SDK

Web SDK

Synergis RIO

Media Gateway

Genetec Web Player

Clone this wiki locally