Skip to content
Open
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
50 changes: 49 additions & 1 deletion Runner/suites/Multimedia/Video/Video_V4L2_Runner/README_Video.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,55 @@ The suite includes a **reboot-free video stack switcher** (upstream ↔ downstre

---

## Shikra Platform Support

**Shikra** is an upstream-only platform. The sole video driver is `qcom_iris`, which may be
modular (visible in `lsmod`) or compiled in as a built-in (bound under
`/sys/bus/platform/drivers/qcom_iris`). Both cases are detected automatically.

| Property | Value |
|---|---|
| Supported stack | `upstream` only (`--stack upstream` or `--stack auto`) |
| Downstream stack | Not supported — rejected with a clear error |
| Video driver | `qcom_iris` (modular or built-in) |
| Max H.264/HEVC encode Level | **4.0** (automatically applied to bundled fixtures) |

### Automatic Level cap for bundled encoder fixtures

On Shikra, Level 4.0 is the maximum supported H.264 and HEVC encode level.
The runner automatically rewrites the `Level` control to `4.0` in the four
bundled encoder configs before execution:

- `base_h264Encoder.json`
- `base_h265Encoder.json`
- `overlay_h264Encoder.json`
- `overlay_h265Encoder.json`

User-supplied configs passed via `--config` are **not** modified by default.
Set `VIDEO_POLICY_SCOPE=all` to apply the rewrite to every config.

### Extending the policy table

Additional per-platform control overrides can be injected at runtime without
modifying any source file:

```sh
# Apply a Profile override for Shikra H.264 encode in addition to the built-in Level cap
export VIDEO_POLICY_EXTRA="shikra|encode|h264|Profile|High"
./run-test.sh Video_V4L2_Runner --app /path/to/iris_v4l2_test --stack upstream
```

Format: `platform|mode|codec|control|value` (one row per line, pipe-separated).

### Example: run all configs on Shikra

```sh
# From the Runner/ directory on the device:
./run-test.sh Video_V4L2_Runner --app /path/to/iris_v4l2_test --stack upstream
```

---

## What’s New (since 2025‑10‑03)

- **Network stabilization delay (post-connect)**
Expand Down Expand Up @@ -350,4 +399,3 @@ export VIDEO_INTER_TEST_SLEEP=3
Ensure time is sane (TLS), network is reachable, and provide Wi‑Fi creds via env or `ssid_list.txt`. The downloader uses BusyBox‑compatible flags with retries and a final TLS‑lenient attempt if needed. When the network remains unreachable, the runner **SKIPs** decode cases.

---

Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
metadata:
name: video-v4l2-runner
format: "Lava-Test Test Definition 1.0"
description: "These scripts automate validation of video **encoding** and **decoding** on Qualcomm Linux platforms running a Yocto-based rootfs."
description: >
Automates V4L2 video encoding and decoding validation on Qualcomm Linux
platforms (LeMans, Monaco, Kodiak, Shikra) using iris_v4l2_test.
Shikra is upstream-only (qcom_iris driver); set VIDEO_STACK=upstream.
Level 4.0 is automatically applied to bundled Shikra encoder fixtures.
Set VIDEO_POLICY_SCOPE=all to extend the rewrite to user-supplied configs.
os:
- linux
scope:
Expand All @@ -10,10 +15,19 @@ metadata:
params:
# path to iris_v4l2_test binary
APP_PATH: "/usr/bin/iris_v4l2_test"
# specific config can be selected. Available: h264Decoder.json, h264Encoder.json, h265Decoder.json, h265Encoder.json, vp9Decoder.json. Default is to use all of them
# specific config can be selected. Available: base_h264Decoder.json,
# base_h264Encoder.json, base_h265Decoder.json, base_h265Encoder.json,
# base_vp9Decoder.json, overlay_*.json. Default is to use all of them.
CONFIG_PATH: "./"
# platform is autodetected by the test script
# platform is autodetected by the test script (lemans|monaco|kodiak|shikra)
PLATFORM: ""
# stack selection: auto|upstream|downstream|base|overlay|both
# Shikra supports upstream only; use VIDEO_STACK=upstream or leave as auto.
VIDEO_STACK: "auto"
# policy scope: bundled (default) | all
# 'bundled' restricts Level-4.0 rewrite to the four bundled encoder fixtures.
# 'all' applies the rewrite to every config including user-supplied ones.
VIDEO_POLICY_SCOPE: "bundled"
LOGLEVEL: 15
RETRY_ON_FAIL: 5
POST_TEST_SLEEP: 10
Expand All @@ -22,5 +36,5 @@ run:
steps:
- REPO_PATH=$PWD
- cd Runner/suites/Multimedia/Video/Video_V4L2_Runner/
- ./run.sh --app "${APP_PATH}" --config "${CONFIG_PATH}" --platform "${PLATFORM}" --loglevel "${LOGLEVEL}" --retry-on-fail "${RETRY_ON_FAIL}" --post-test-sleep "${POST_TEST_SLEEP}" || true
- VIDEO_POLICY_SCOPE="${VIDEO_POLICY_SCOPE}" ./run.sh --app "${APP_PATH}" --config "${CONFIG_PATH}" --platform "${PLATFORM}" --stack "${VIDEO_STACK}" --loglevel "${LOGLEVEL}" --retry-on-fail "${RETRY_ON_FAIL}" --post-test-sleep "${POST_TEST_SLEEP}" || true
- $REPO_PATH/Runner/utils/send-to-lava.sh Video_V4L2_Runner.res || true
118 changes: 113 additions & 5 deletions Runner/suites/Multimedia/Video/Video_V4L2_Runner/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ Usage: $0 [--config path.json|/path/dir] [--dir DIR] [--pattern GLOB]
[--repeat N] [--repeat-delay S] [--repeat-policy all|any]
[--junit FILE] [--dry-run] [--verbose]
[--stack auto|upstream|downstream|base|overlay|up|down|both]
[--platform lemans|monaco|kodiak]
[--platform lemans|monaco|kodiak|shikra]
[--downstream-fw PATH] [--force]
[--app /path/to/iris_v4l2_test]
[--ssid SSID] [--password PASS]
Expand All @@ -120,6 +120,23 @@ Usage: $0 [--config path.json|/path/dir] [--dir DIR] [--pattern GLOB]
# --- Media bundle (opt-in, local tar) ---
[--clips-tar /path/to/clips.tar.gz] # extract locally even if --dir/--config is used
[--clips-dest DIR] # extraction destination (defaults to cfg/dir root or testcase dir)

Platform notes:
shikra Upstream-only platform (qcom_iris driver, modular or built-in).
Downstream stack is not supported. --stack upstream (or auto) is
the only valid choice. Level 4.0 is the maximum supported H.264/HEVC
encode level and is automatically applied to the bundled encoder
fixtures (base_h264Encoder.json, base_h265Encoder.json,
overlay_h264Encoder.json, overlay_h265Encoder.json).

Environment variables:
VIDEO_POLICY_SCOPE bundled (default) | all
Controls which configs receive automatic platform policy rewrites.
'bundled' restricts rewrites to the bundled fixture configs above.
'all' applies the policy to every config, including user-supplied ones.
VIDEO_POLICY_EXTRA Additional policy rows in pipe-separated format:
platform|mode|codec|control|value (one row per line).
Example: VIDEO_POLICY_EXTRA="shikra|encode|h264|Profile|High"
EOF
}

Expand Down Expand Up @@ -933,6 +950,15 @@ case "$plat" in
fi
fi
;;
shikra)
if [ "$post_stack" = "upstream" ]; then
if video_qcom_iris_active; then
log_pass "Upstream validated: qcom_iris present (Shikra)"
else
log_warn "Upstream expected but qcom_iris not present (Shikra)"
fi
fi
;;
*)
log_warn "Unknown platform; skipping strict module validation"
;;
Expand Down Expand Up @@ -1157,6 +1183,88 @@ while IFS= read -r cfg; do
continue
fi

# -----------------------------------------------------------------------
# Stage the effective config once per test case, before the repeat loop.
# Both normal runs and retries use the same staged path so they cannot
# diverge. Platforms with no matching policy row use the original config
# unchanged (no-op path through video_policy_lookup).
#
# Policy rewrites are restricted to the bundled fixture configs by default
# (base_*.json and overlay_*.json) so that user-supplied configs passed via
# --config are not silently modified. Set VIDEO_POLICY_SCOPE=all to apply
# the policy to every config regardless of filename.
# -----------------------------------------------------------------------
effective_cfg="$cfg"
vpl_policy_file="$LOG_DIR/.policy_${id}.$$.txt"
# Resolve the config to an absolute path and compare against the actual
# bundled fixture paths in the suite directory. A config that merely has
# the same basename as a bundled fixture (e.g. /data/base_h264Encoder.json)
# is treated as user-supplied and is not rewritten by default.
vpl_cfg_resolved="$(cd "$(dirname "$cfg")" 2>/dev/null && pwd)/$(basename "$cfg")"
vpl_apply_policy=0
case "$vpl_cfg_resolved" in
"$SCRIPT_DIR/base_h264Encoder.json"|\
"$SCRIPT_DIR/base_h265Encoder.json"|\
"$SCRIPT_DIR/overlay_h264Encoder.json"|\
"$SCRIPT_DIR/overlay_h265Encoder.json")
vpl_apply_policy=1
;;
*)
if [ "${VIDEO_POLICY_SCOPE:-bundled}" = "all" ]; then
vpl_apply_policy=1
fi
;;
esac
if [ "$vpl_apply_policy" -eq 1 ]; then
video_policy_lookup "$plat" "$mode" "$codec" > "$vpl_policy_file" 2>/dev/null || true
fi

if [ -s "$vpl_policy_file" ]; then
vpl_staged="$cfg"
vpl_stage_ok=1
while IFS='|' read -r vpl_ctrl vpl_val; do
[ -z "$vpl_ctrl" ] && continue
vpl_result="$(video_stage_control_override \
"$vpl_staged" "$vpl_ctrl" "$vpl_val" "$LOG_DIR")"
vpl_rc=$?
if [ "$vpl_rc" -eq 2 ]; then
# Policy requires this control but the config does not declare it.
# Running the original config would silently use the platform default
# (potentially unsupported) value — fail preparation instead.
log_warn "[$id] Required control '$vpl_ctrl' is absent from config '$vpl_staged'; aborting preparation"
vpl_stage_ok=0
break
fi
if [ "$vpl_rc" -ne 0 ]; then
log_warn "[$id] Config staging failed for control '$vpl_ctrl'; aborting preparation"
vpl_stage_ok=0
break
fi
if [ -n "$vpl_result" ] && [ -f "$vpl_result" ]; then
vpl_staged="$vpl_result"
fi
done < "$vpl_policy_file"

if [ "$vpl_stage_ok" -eq 0 ]; then
rm -f "$vpl_policy_file" 2>/dev/null || true
log_fail "[$id] FAIL - config preparation failed"
printf '%s\n' "$id FAIL $pretty" >> "$LOG_DIR/summary.txt"
printf '%s\n' "$mode,$id,FAIL,$pretty,0,0,0" >> "$LOG_DIR/results.csv"
fail=$((fail + 1))
suite_rc=1
if [ "$STOP_ON_FAIL" -eq 1 ]; then
break
fi
continue
fi

if [ "$vpl_staged" != "$cfg" ]; then
effective_cfg="$vpl_staged"
log_info "[$id] Using staged config: $effective_cfg"
fi
fi
rm -f "$vpl_policy_file" 2>/dev/null || true

pass_runs="0"
fail_runs="0"
rep="1"
Expand All @@ -1169,7 +1277,7 @@ while IFS= read -r cfg; do
fi

video_step "$id" "Execute app"
log_info "[$id] CMD: $VIDEO_APP --config \"$cfg\" --loglevel $LOGLEVEL"
log_info "[$id] CMD: $VIDEO_APP --config \"$effective_cfg\" --loglevel $LOGLEVEL"

case "$APP_LAUNCH_SLEEP" in
''|*[!0-9]* )
Expand All @@ -1184,7 +1292,7 @@ while IFS= read -r cfg; do
;;
esac

if video_run_once "$cfg" "$logf" "$TIMEOUT" "$SUCCESS_RE" "$LOGLEVEL"; then
if video_run_once "$effective_cfg" "$logf" "$TIMEOUT" "$SUCCESS_RE" "$LOGLEVEL"; then
pass_runs=$((pass_runs + 1))
else
rc_val="$(awk -F'=' '/^END-RUN rc=/{print $2}' "$logf" 2>/dev/null | tail -n1 | tr -d ' ')"
Expand Down Expand Up @@ -1238,7 +1346,7 @@ while IFS= read -r cfg; do
fi

# (2) Retry on final failure (extra attempts outside REPEAT loop, before recording results)
if [ "$final" = "FAIL" ] && [ "$RETRY_ON_FAIL" -gt 0 ] 2>/dev/null; then
if [ "$final" = "FAIL" ] && [ "$RETRY_ON_FAIL" -gt 0 ] 2>/dev/null; then
r=1
log_info "[$id] RETRY_ON_FAIL: up to $RETRY_ON_FAIL additional attempt(s)"
while [ "$r" -le "$RETRY_ON_FAIL" ]; do
Expand All @@ -1247,7 +1355,7 @@ while IFS= read -r cfg; do
fi

log_info "[$id] retry attempt $r/$RETRY_ON_FAIL"
if video_run_once "$cfg" "$logf" "$TIMEOUT" "$SUCCESS_RE" "$LOGLEVEL"; then
if video_run_once "$effective_cfg" "$logf" "$TIMEOUT" "$SUCCESS_RE" "$LOGLEVEL"; then
pass_runs=$((pass_runs + 1))
final="PASS"
log_pass "[$id] RETRY succeeded — marking PASS"
Expand Down
38 changes: 6 additions & 32 deletions Runner/utils/audio_common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2779,39 +2779,13 @@ audio_remoteproc_is_modem() {
}

# Return success when runtime platform evidence identifies a Shikra target.
# The preflight runs before the suites call detect_platform, so inspect both
# any already-populated platform variables and the standard runtime DT paths.
#
# All repository callers source functestlib.sh before audio_common.sh,
# including child user-session paths. platform_identity_matches() from
# functestlib.sh is therefore always available and is the single contract.
# If standalone sourcing is required, source functestlib.sh explicitly first.
audio_platform_is_shikra() {
apis_identity="${PLATFORM_MACHINE:-} ${PLATFORM_TARGET:-}"
apis_identity="$apis_identity ${PLATFORM_SOC_MACHINE:-}"
apis_identity="$apis_identity ${PLATFORM_DT_MODEL:-}"
apis_identity="$apis_identity ${PLATFORM_DT_COMPAT:-}"

for apis_file in \
/proc/device-tree/model \
/proc/device-tree/compatible \
/sys/firmware/devicetree/base/model \
/sys/firmware/devicetree/base/compatible
do
if [ -r "$apis_file" ]; then
apis_value="$(tr '\000' ' ' <"$apis_file" 2>/dev/null || true)"
apis_identity="$apis_identity $apis_value"
fi
done

apis_identity="$(
printf '%s\n' "$apis_identity" |
tr '[:upper:]' '[:lower:]'
)"

case "$apis_identity" in
*shikra*)
return 0
;;
*)
return 1
;;
esac
platform_identity_matches "shikra"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

platform_identity_matches is not defined in functestlib.sh or anywhere else at this PR head. Add the shared platform identity helpers to functestlib.sh in this PR and test both matching and non-matching platforms, or retain the previous working runtime-DT implementation.

}

# Reorder an inventory so a modem-hosted audio path is considered before DSP
Expand Down
55 changes: 55 additions & 0 deletions Runner/utils/functestlib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8580,6 +8580,61 @@ detect_platform() {
return 0
}

# -----------------------------------------------------------------------------
# platform_runtime_identity
#
# Prints a lowercased, space-joined identity string built from all available
# platform evidence (soc0 sysfs, device-tree model/compatible, and any vars
# already exported by detect_platform). Callers treat an empty result as
# "no match" rather than falling back to a name heuristic.
# This is the single source of truth for board identity shared by audio,
# video, and any other subsystem library.
# -----------------------------------------------------------------------------
platform_runtime_identity() {
pri_identity="${PLATFORM_MACHINE:-} ${PLATFORM_TARGET:-}"
pri_identity="$pri_identity ${PLATFORM_SOC_MACHINE:-}"
pri_identity="$pri_identity ${PLATFORM_DT_MODEL:-}"
pri_identity="$pri_identity ${PLATFORM_DT_COMPAT:-}"

for pri_dtf in \
/proc/device-tree/model \
/proc/device-tree/compatible \
/sys/firmware/devicetree/base/model \
/sys/firmware/devicetree/base/compatible
do
if [ -r "$pri_dtf" ]; then
pri_dtv="$(tr '\000' ' ' <"$pri_dtf" 2>/dev/null || true)"
pri_identity="$pri_identity $pri_dtv"
fi
done

printf '%s\n' "$pri_identity" | tr '[:upper:]' '[:lower:]'
}

# -----------------------------------------------------------------------------
# platform_identity_matches <substr>
#
# Returns 0 when <substr> (case-insensitive) appears anywhere in the runtime
# platform identity string produced by platform_runtime_identity().
# Returns 1 when there is no match or the identity string is empty.
# -----------------------------------------------------------------------------
platform_identity_matches() {
pim_tok="$1"
[ -n "$pim_tok" ] || return 1

pim_identity="$(platform_runtime_identity)"
pim_tok_l="$(printf '%s' "$pim_tok" | tr '[:upper:]' '[:lower:]')"

case "$pim_identity" in
*"$pim_tok_l"*)
return 0
;;
*)
return 1
;;
esac
}

# ---------- minimal root / FS helpers (Yocto-safe, no underscores) ----------
isroot() { uid="$(id -u 2>/dev/null || echo 1)"; [ "$uid" -eq 0 ]; }

Expand Down
Loading
Loading