Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions docs/Tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,20 @@ watch -n 1 -p ./mxl-info mxl:///dev/shm/mxl?id=5fbec3b1-1b0f-417d-9059-8b94a4719

A binary that uses the gstreamer 'videotestsrc' and 'audiotestsrc' elements to produce video grains and/or audio samples which will be pushed to a MXL Flow. The flow is configured from a NMOS Flow json file. Here's an example of such file :

  **Note** Don't forget to provide valid description, label and grouphint tag.


```json
{
"description": "MXL Test Flow, 1080p29",
"description": "___CHANGE ME___ Long description of the video flow",
"id": "5fbec3b1-1b0f-417d-9059-8b94a47197ed",
"tags": {
"urn:x-nmos:tag:grouphint/v1.0": [
"My Media Function Unique Name (Change Me):Video"
"___CHANGE ME FOR A NAME UNIQUE TO YOUR MEDIA FUNCTION INSTANCE___:Video"
Copy link
Contributor

@jonasohland jonasohland Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could print a warning from the SDK if we detect a string like ^__CHANGE ME.*$ in one of those fields.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels dirty but maybe it's worth it. @KimonHoffmann what do you think about hard coding a check for '___CHANGE ME'?

]
},
"format": "urn:x-nmos:format:video",
"label": "MXL Test Flow, 1080p29",
"label": "___CHANGE ME___ Short description of the video flow",
"parents": [],
"media_type": "video/v210",
"grain_rate": {
Expand Down Expand Up @@ -142,18 +145,21 @@ A binary that uses the gstreamer 'videotestsrc' and 'audiotestsrc' elements to p
}
```
Below is an example of an **augmented NMOS Flow JSON** for audio.
  **Note:** The *channel_count* property is a mandatory MXL requirement (not found in standard NMOS definition). To adjust the number of audio channels, simply update the *channel_count* value.
  **Note 1:** The *channel_count* property is a mandatory MXL requirement (not found in standard NMOS definition). To adjust the number of audio channels, simply update the *channel_count* value.

  **Note 2:** Don't forget to provide valid description, label and grouphint tag.


```json
{
"description": "MXL Audio Flow",
"description": "___CHANGE ME___ Long description of the audio flow",
"format": "urn:x-nmos:format:audio",
"tags": {
"urn:x-nmos:tag:grouphint/v1.0": [
"My Media Function Unique Name (Change Me):Audio"
"___CHANGE ME FOR A NAME UNIQUE TO YOUR MEDIA FUNCTION INSTANCE___:Audio #1"
]
},
"label": "MXL Audio Flow",
"label": "___CHANGE ME___ Short description of the audio flow",
"version": "1441812152:154331951",
"id": "b3bb5be7-9fe9-4324-a5bb-4c70e1084449",
"media_type": "audio/float32",
Expand Down
35 changes: 34 additions & 1 deletion lib/include/mxl/flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,43 @@ extern "C"
typedef struct mxlFlowSynchronizationGroup_t* mxlFlowSynchronizationGroup;

/**
* Attempt to create a flow writer for a given flow definition. If the flow does not exist already, it is created and 'created' will be set to
* Attempts to create a flow writer for a given flow definition. If the flow does not exist already, it is created and 'created' will be set to
* true. If the flow exists, it will be opened and 'created' will be set to false. If the flow exists already it is not guaranteed that the flow
* definition of the existing flow is exactly equal to the flow definition supplied in flowDef. The definition of the existing flow can be
* retrieved using mxlGetFlowDef().
*
* <span style="color: red;">IMPORTANT NOTE</span><br/>
* The flow definition (flowDef) is expected to have well defined fields such as label,
* description and grouphint tag. This is a responsibility of the media function implementer. These fields should refer to the <b>media function instance name</b>. For example, on a large system with
* mutliple software defined decoders running simultaneously, <b>each decoder instance should use a unique name in the grouphint tag to identify
* itself.</b> Please read carefully the 'natural groups' section of the <a
* href="https://specs.amwa.tv/nmos-parameter-registers/branches/main/tags/grouphint.html#natural-groups">group hint tag specification</a>.
*
* Example fields for an hypothetical video decoder media function instance named "Decoder 1":
* <ul>
* <li>label: "Decoder 1 Video Output"</li>
* <li>description: "Decoder 1 MXL Flow Video Output"</li>
* <li>grouphint tag: "Decoder 1:Video"</li>
* </ul>
*
* Example fields for a multi-flow audio receiver media function instance named "Audio Receiver A":
* Flow 1:
* <ul>
* <li>label: "Audio Receiver A Audio Output #1"</li>
* <li>description: "Audio Receiver A MXL Flow Audio Output #1"</li>
* <li>grouphint tag: "Audio Receiver A:Audio #1"</li>
* </ul>
*
* Flow 2:
* <ul>
* <li>label: "Audio Receiver A Audio Output #2"</li>
* <li>description: "Audio Receiver A MXL Flow Audio Output #2"</li>
* <li>grouphint tag: "Audio Receiver A:Audio #2"</li>
* </ul>
*
* <b>Having a well formed grouphint tag refering to the <b>media function instance name</b> is essential to ensure proper flow discovery and
* management by higher level applications using MXL.</b>
*
* \param[in] instance The mxl instance created using mxlCreateInstance
* \param[in] flowDef The flow definition from which a flow should be created if there is not already a flow with the same flow id.
* \param[in] options (optional) Additional options, can be NULL
Expand Down
8 changes: 4 additions & 4 deletions lib/tests/data/audio_flow.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"$copyright": "SPDX-FileCopyrightText: 2025 Contributors to the Media eXchange Layer project.",
"$license": "SPDX-License-Identifier: Apache-2.0",
"description": "MXL Audio Flow",
"description": "___CHANGE ME___ Long description of the audio flow",
"format": "urn:x-nmos:format:audio",
"tags": {
"urn:x-nmos:tag:grouphint/v1.0": [
"Media Function XYZ:Audio"
"___CHANGE ME FOR A NAME UNIQUE TO YOUR MEDIA FUNCTION INSTANCE___:Audio"
]
},
"label": "MXL Audio Flow",
"label": "___CHANGE ME___ Short description of the audio flow",
"version": "1441812152:154331951",
"id": "b3bb5be7-9fe9-4324-a5bb-4c70e1084449",
"media_type": "audio/float32",
Expand All @@ -20,4 +20,4 @@
"parents": [],
"source_id": "2aa143ac-0ab7-4d75-bc32-5c00c13d186f",
"device_id": "169feb2c-3fae-42a5-ae2e-f6f8cbce29cf"
}
}
6 changes: 3 additions & 3 deletions lib/tests/data/data_flow.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"$copyright": "SPDX-FileCopyrightText: 2025 Contributors to the Media eXchange Layer project.",
"$license": "SPDX-License-Identifier: Apache-2.0",
"description": "MXL VANC Data",
"description": "___CHANGE ME___ Long description of the data flow",
"tags": {
"urn:x-nmos:tag:grouphint/v1.0": [
"Media Function XYZ:Ancillary Data"
"___CHANGE ME FOR A NAME UNIQUE TO YOUR MEDIA FUNCTION INSTANCE___:Ancillary Data"
]
},
"format": "urn:x-nmos:format:data",
"label": "MXL VANC Data",
"label": "___CHANGE ME___ Short description of the data flow",
"version": "1453880607:123995943",
"parents": [],
"source_id": "0e635152-e501-4d4e-bb87-9f3fe05eb79a",
Expand Down
6 changes: 3 additions & 3 deletions lib/tests/data/v210_flow.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"$copyright": "SPDX-FileCopyrightText: 2025 Contributors to the Media eXchange Layer project.",
"$license": "SPDX-License-Identifier: Apache-2.0",
"description": "MXL Test Flow, 1080p29",
"description": "___CHANGE ME___ Long description of the video flow",
"id": "5fbec3b1-1b0f-417d-9059-8b94a47197ed",
"tags": {
"urn:x-nmos:tag:grouphint/v1.0": [
"Media Function XYZ:Video"
"___CHANGE ME FOR A NAME UNIQUE TO YOUR MEDIA FUNCTION INSTANCE___:Video"
]
},
"format": "urn:x-nmos:format:video",
"label": "MXL Test Flow, 1080p29",
"label": "___CHANGE ME___ Short description of the video flow",
"parents": [],
"media_type": "video/v210",
"grain_rate": {
Expand Down
6 changes: 3 additions & 3 deletions lib/tests/data/v210a_flow.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"$copyright": "SPDX-FileCopyrightText: 2025 Contributors to the Media eXchange Layer project.",
"$license": "SPDX-License-Identifier: Apache-2.0",
"description": "MXL Test Flow, 1080p29 with alpha",
"description": "___CHANGE ME___ Long description of the video flow",
"id": "5fbec3b1-1b0f-417d-9059-8b94a47197ed",
"tags": {
"urn:x-nmos:tag:grouphint/v1.0": [
"Media Function XYZ:Video"
"___CHANGE ME FOR A NAME UNIQUE TO YOUR MEDIA FUNCTION INSTANCE___:Video"
]
},
"format": "urn:x-nmos:format:video",
"label": "MXL Test Flow, 1080p29 with alpha",
"label": "___CHANGE ME___ Short description of the video flow",
"parents": [],
"media_type": "video/v210a",
"grain_rate": {
Expand Down
Loading