Post Processing Blocks allow writing custom logic which will be hooked into when a certain process starts. More precisely, URM listens to proc events using a Netlink socket, when an event of the type: PROC_EVENT_EXEC is received, URM checks if a post processing callback has been registered for that particular process, if it has been, it gets executed.
| Process Name | Callback | Source File |
|---|---|---|
| gst-launch-1.0 | WorkloadPostprocessCallback | CamPostProcessing.cpp |
| gst-camera-per-port-example | WorkloadPostprocessCallback | CamPostProcessing.cpp |
| genie-t2t-run | workloadPostprocessCallback | GenieT2T.cpp |
WorkloadPostprocessCallback is triggered for gst-launch-1.0 and gst-camera-per-port-example.
/proc/<pid>/cmdline and sanitize null bytes to spaces.Scan the command line for GStreamer element identifiers:
Encoder elements (checked first):
v4l2h264enc — hardware H.264 encoderqtic2venc — Qualcomm C2 encoderDecoder elements:
v4l2h264dec — hardware H.264 decoderqtic2vdec — Qualcomm C2 decoderPreview source:
qtiqmmfsrc — Qualcomm multimedia sourceframerate=N[/D] value found (integer division)height=N value foundwidth=N value foundClassify the workload and set SigId + SigType:
| Detected | SigId | SigType | Logic |
|---|---|---|---|
| Single encoder | URM_SIG_CAMERA_ENCODE | 0 | exactly 1 encoder element |
| Multi-stream encode | URM_SIG_CAMERA_ENCODE_MULTI_STREAMS | 0 or 13 | >1 encoder; SigType=0 if ≤12, 13 if >12 |
| Decoder | URM_SIG_VIDEO_DECODE | 0, 5, or 21 | thread count: <5→0, 5–20→5, >20→21 |
| Preview | URM_SIG_CAMERA_PREVIEW | 0 | qtiqmmfsrc present, no encoder/decoder |
acquireSignal(sigId, sigType, pid, pid, SIGNAL_EXTRA_ATTRS_COUNT, extraArgs) directly and store the handle in cbData->mHandleAcq.For decoder workloads, the callback counts threads under /proc/<pid>/task/ whose /comm file contains the decoder element name (case-insensitive substring match). This count drives the SigType selection.
For encoder workloads, the callback counts occurrences of the matched encoder string in the full cmdline buffer. More than one occurrence indicates a multi-stream pipeline.
workloadPostprocessCallback is triggered for genie-t2t-run.
The callback unconditionally sets:
cbData->mSigId = CONSTRUCT_SIG_CODE(0xf1, 0x0123) → GENIE_T2T_RUNcbData->mSigType = DEFAULT_SIGNAL_TYPEThis routes the process to the GENIE_T2T_RUN signal, which affinizes IRQs to cores 0–5 and applies CPU affinity for inference threads.
Let’s say we need to write a simple post-processing callback for the process: “gst-launch-1.0”, so that whenever a process with that command name is launched the callback is triggered.
static void workloadPostprocessCallback(void* context) {
if(context == nullptr) {
return;
}
PostProcessCBData* cbData = static_cast<PostProcessCBData*>(context);
if(cbData == nullptr) {
return;
}
// Main selection logic
// Get the sigId and sigType for the signal which needs to be configured.
// ........
// Relay the information back to URM
cbData->mSigId = sigId;
cbData->mSigType = sigType;
}
__attribute__((constructor))
static void registerWithUrm() {
// Post Processing Callback for process: "gst-launch-1.0"
URM_REGISTER_POST_PROCESS_CB("gst-launch-1.0", workloadPostprocessCallback)
}
For callbacks that need to pass extra attributes (FPS, resolution) or call acquireSignal() directly, see the advanced pattern in 06-extension-api-guide.md.