Skip to content

Commit e49d314

Browse files
authored
Merge pull request qualcomm-linux#198 from smuppand/camera-yavta
Camera RDI capture: dynamic media graph config + robust yavta fallbacks
2 parents 5ab3bb2 + 14b5980 commit e49d314

File tree

2 files changed

+341
-121
lines changed

2 files changed

+341
-121
lines changed

Runner/suites/Multimedia/Camera/Camera_RDI_FrameCapture/run.sh

Lines changed: 158 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,37 @@
22
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
33
# SPDX-License-Identifier: BSD-3-Clause-Clear
44
# --- Robustly find and source init_env ---------------------------
5-
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
5+
# ---------- Repo env + helpers ----------
6+
SCRIPT_DIR="$(
7+
cd "$(dirname "$0")" || exit 1
8+
pwd
9+
)"
610
INIT_ENV=""
711
SEARCH="$SCRIPT_DIR"
12+
813
while [ "$SEARCH" != "/" ]; do
914
if [ -f "$SEARCH/init_env" ]; then
10-
INIT_ENV="$SEARCH/init_env"; break
15+
INIT_ENV="$SEARCH/init_env"
16+
break
1117
fi
1218
SEARCH=$(dirname "$SEARCH")
1319
done
14-
[ -z "$INIT_ENV" ] && echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2 && exit 1
20+
21+
if [ -z "$INIT_ENV" ]; then
22+
echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2
23+
exit 1
24+
fi
25+
26+
# Only source once (idempotent)
27+
if [ -z "${__INIT_ENV_LOADED:-}" ]; then
28+
# shellcheck disable=SC1090
29+
. "$INIT_ENV"
30+
__INIT_ENV_LOADED=1
31+
fi
1532

1633
# shellcheck disable=SC1090
17-
[ -z "$__INIT_ENV_LOADED" ] && . "$INIT_ENV"
18-
# shellcheck disable=SC1090,SC1091
34+
. "$INIT_ENV"
35+
# shellcheck disable=SC1091
1936
. "$TOOLS/functestlib.sh"
2037

2138
TESTNAME="Camera_RDI_FrameCapture"
@@ -46,71 +63,16 @@ while [ $# -gt 0 ]; do
4663
--format) shift; USER_FORMAT="$1" ;;
4764
--frames) shift; FRAMES="$1" ;;
4865
--help) print_usage; exit 0 ;;
49-
*) log_error "Unknown argument: $1"; print_usage; exit 1 ;;
66+
*) log_error "Unknown argument: $1"; print_usage; echo "$TESTNAME FAIL" >"$RES_FILE"; exit 1 ;;
5067
esac
5168
shift
5269
done
5370

54-
# Helper: print planned media-ctl / yavta sequence for CI logs
55-
print_planned_commands() {
56-
media_node="$1"
57-
pixfmt="$2"
58-
59-
log_info "[CI] Planned sequence:"
60-
log_info " media-ctl -d $media_node --reset"
61-
62-
# media-ctl -V (show with possible TARGET_FORMAT substitution exactly like configure helper does)
63-
if [ -n "$MEDIA_CTL_V_LIST" ]; then
64-
printf '%s\n' "$MEDIA_CTL_V_LIST" | while IFS= read -r vline; do
65-
[ -z "$vline" ] && continue
66-
vline_out="$(printf '%s' "$vline" | sed -E "s/fmt:[^/]+\/([0-9]+x[0-9]+)/fmt:${pixfmt}\/\1/g")"
67-
log_info " media-ctl -d $media_node -V '$vline_out'"
68-
done
69-
fi
70-
# media-ctl -l
71-
if [ -n "$MEDIA_CTL_L_LIST" ]; then
72-
printf '%s\n' "$MEDIA_CTL_L_LIST" | while IFS= read -r lline; do
73-
[ -z "$lline" ] && continue
74-
log_info " media-ctl -d $media_node -l '$lline'"
75-
done
76-
fi
77-
# yavta control writes (pre)
78-
if [ -n "$YAVTA_CTRL_PRE_LIST" ]; then
79-
printf '%s\n' "$YAVTA_CTRL_PRE_LIST" | while IFS= read -r ctrl; do
80-
[ -z "$ctrl" ] && continue
81-
dev="$(printf '%s' "$ctrl" | awk '{print $1}')"
82-
reg="$(printf '%s' "$ctrl" | awk '{print $2}')"
83-
val="$(printf '%s' "$ctrl" | awk '{print $3}')"
84-
[ -n "$dev" ] && [ -n "$reg" ] && [ -n "$val" ] && \
85-
log_info " yavta --no-query -w '$reg $val' $dev"
86-
done
87-
fi
88-
# main yavta capture (dimensions may be empty occasionally)
89-
size_arg=""
90-
if [ -n "$YAVTA_W" ] && [ -n "$YAVTA_H" ]; then
91-
size_arg="-s ${YAVTA_W}x${YAVTA_H}"
92-
fi
93-
if [ -n "$YAVTA_DEV" ]; then
94-
log_info " yavta -B capture-mplane -c -I -n $FRAMES -f $pixfmt $size_arg -F $YAVTA_DEV --capture=$FRAMES --file='frame-#.bin'"
95-
fi
96-
# yavta control writes (post)
97-
if [ -n "$YAVTA_CTRL_POST_LIST" ]; then
98-
printf '%s\n' "$YAVTA_CTRL_POST_LIST" | while IFS= read -r ctrl; do
99-
[ -z "$ctrl" ] && continue
100-
dev="$(printf '%s' "$ctrl" | awk '{print $1}')"
101-
reg="$(printf '%s' "$ctrl" | awk '{print $2}')"
102-
val="$(printf '%s' "$ctrl" | awk '{print $3}')"
103-
[ -n "$dev" ] && [ -n "$reg" ] && [ -n "$val" ] && \
104-
log_info " yavta --no-query -w '$reg $val' $dev"
105-
done
106-
fi
107-
}
108-
10971
# --------- DT Precheck ---------
11072
if ! dt_confirm_node_or_compatible "isp" "cam" "camss"; then
11173
log_skip "$TESTNAME SKIP – No ISP/camera node/compatible found in DT"
11274
echo "$TESTNAME SKIP" >"$RES_FILE"
113-
exit 0
75+
exit 2
11476
fi
11577

11678
# --------- Kernel config sanity (MANDATORY bits only gate if totally absent) ---------
@@ -150,7 +112,7 @@ elif printf '%s\n' "$DMESG_CACHE" | grep -qiE 'qcom[-_]camss'; then
150112
else
151113
log_skip "Camera_RDI_FrameCapture SKIP – CAMSS driver not present (module or built-in)"
152114
echo "$TESTNAME SKIP" >"$RES_FILE"
153-
exit 0
115+
exit 2
154116
fi
155117

156118
# --------- Module inventory (visibility only; no gating) ---------
@@ -193,22 +155,22 @@ DMESG_EXCLUDE='dummy regulator|supply [^ ]+ not found|using dummy regulator|Fail
193155
if scan_dmesg_errors "$SCRIPT_DIR" "$DMESG_MODULES" "$DMESG_EXCLUDE"; then
194156
log_skip "$TESTNAME SKIP – $DRIVER_MOD probe errors detected in dmesg"
195157
echo "$TESTNAME SKIP" >"$RES_FILE"
196-
exit 0
158+
exit 2
197159
fi
198160

199161
# --------- Dependency Checks ---------
200162
check_dependencies media-ctl yavta python3 v4l2-ctl || {
201163
log_skip "$TESTNAME SKIP – Required tools missing"
202164
echo "$TESTNAME SKIP" >"$RES_FILE"
203-
exit 0
165+
exit 2
204166
}
205167

206168
# --------- Media Node Detection ---------
207169
MEDIA_NODE="$(detect_media_node)"
208170
if [ -z "$MEDIA_NODE" ]; then
209171
log_skip "$TESTNAME SKIP – Media node not found"
210172
echo "$TESTNAME SKIP" >"$RES_FILE"
211-
exit 0
173+
exit 2
212174
fi
213175
log_info "Detected media node: $MEDIA_NODE"
214176

@@ -227,7 +189,7 @@ PYTHON_PIPELINES="$(run_camera_pipeline_parser "$TOPO_FILE")"
227189
if [ -z "$PYTHON_PIPELINES" ]; then
228190
log_skip "$TESTNAME SKIP – No valid pipelines found"
229191
echo "$TESTNAME SKIP" >"$RES_FILE"
230-
exit 0
192+
exit 2
231193
fi
232194
printf '%s\n' "$PYTHON_PIPELINES" >"$TMP_PIPELINES_FILE"
233195

@@ -287,6 +249,132 @@ while IFS= read -r line || [ -n "$line" ]; do
287249
RET=$?
288250
fi
289251

252+
######################## Format/Resolution fallbacks ########################
253+
if [ "$RET" -ne 0 ]; then
254+
if printf '%s' "$TARGET_FORMAT" | grep -q 'P$'; then
255+
ALT_FMT_A="$(printf '%s' "$TARGET_FORMAT" | sed 's/P$//')"
256+
257+
SAVE_V="$MEDIA_CTL_V_LIST"; SAVE_W="$YAVTA_W"; SAVE_H="$YAVTA_H"
258+
MEDIA_CTL_V_LIST="$(printf '%s\n' "$MEDIA_CTL_V_LIST" | sed -E "s/fmt:[^/]+\//fmt:${ALT_FMT_A}\//g")"
259+
260+
log_info "Applying format fallback (A1): $TARGET_FORMAT$ALT_FMT_A"
261+
print_planned_commands "$MEDIA_NODE" "$ALT_FMT_A"
262+
configure_pipeline_block "$MEDIA_NODE" "$ALT_FMT_A"
263+
execute_capture_block "$FRAMES" "$ALT_FMT_A"
264+
RET=$?
265+
266+
if [ "$RET" -ne 0 ] && [ -n "$SAVE_W" ] && [ -n "$SAVE_H" ]; then
267+
NEW_W=$(( (SAVE_W/2)*2 ))
268+
NEW_H=$(( (SAVE_H/2)*2 ))
269+
MEDIA_CTL_V_LIST="$(printf '%s\n' "$MEDIA_CTL_V_LIST" | sed -E "s/([0-9]+x[0-9]+)/${NEW_W}x${NEW_H}/g")"
270+
YAVTA_W="$NEW_W"; YAVTA_H="$NEW_H"
271+
log_info "Applying resolution fallback (A2): ${SAVE_W}x${SAVE_H}${NEW_W}x${NEW_H} (format $ALT_FMT_A)"
272+
print_planned_commands "$MEDIA_NODE" "$ALT_FMT_A"
273+
configure_pipeline_block "$MEDIA_NODE" "$ALT_FMT_A"
274+
execute_capture_block "$FRAMES" "$ALT_FMT_A"
275+
RET=$?
276+
fi
277+
278+
MEDIA_CTL_V_LIST="$SAVE_V"; YAVTA_W="$SAVE_W"; YAVTA_H="$SAVE_H"
279+
fi
280+
fi
281+
###################### end ###############################################
282+
283+
######################## Try other RDI/Video indices #####################
284+
if [ "$RET" -ne 0 ]; then
285+
CUR_RDI="$(printf '%s\n%s\n' "$MEDIA_CTL_V_LIST" "$MEDIA_CTL_L_LIST" \
286+
| sed -n 's/.*msm_vfe[0-9]_rdi\([0-9]\).*/\1/p' | head -n1)"
287+
CUR_VIDIDX="$(printf '%s\n%s\n' "$MEDIA_CTL_V_LIST" "$MEDIA_CTL_L_LIST" \
288+
| sed -n 's/.*msm_vfe[0-9]_video\([0-9]\).*/\1/p' | head -n1)"
289+
[ -z "$CUR_VIDIDX" ] && CUR_VIDIDX="$(printf '%s' "$YAVTA_DEV" | sed -n 's#.*/video\([0-9]\+\)$#\1#p')"
290+
291+
if [ -n "$CUR_RDI" ] && [ -n "$CUR_VIDIDX" ]; then
292+
for ALT_IDX in 0 1 2; do
293+
[ "$ALT_IDX" = "$CUR_RDI" ] && continue
294+
295+
SAVE_V="$MEDIA_CTL_V_LIST"
296+
SAVE_L="$MEDIA_CTL_L_LIST"
297+
SAVE_DEV="$YAVTA_DEV"
298+
SAVE_W="$YAVTA_W"
299+
SAVE_H="$YAVTA_H"
300+
301+
MEDIA_CTL_V_LIST="$(printf '%s\n' "$MEDIA_CTL_V_LIST" \
302+
| sed -E "s/(msm_vfe[0-9]_rdi)[0-2]/\1${ALT_IDX}/g; s/(msm_vfe[0-9]_video)[0-2]/\1${ALT_IDX}/g")"
303+
MEDIA_CTL_L_LIST="$(printf '%s\n' "$MEDIA_CTL_L_LIST" \
304+
| sed -E "s/(msm_vfe[0-9]_rdi)[0-2]/\1${ALT_IDX}/g; s/(msm_vfe[0-9]_video)[0-2]/\1${ALT_IDX}/g")"
305+
306+
if printf '%s' "$YAVTA_DEV" | grep -qE '/dev/video[0-9]+$'; then
307+
YAVTA_DEV="$(printf '%s' "$YAVTA_DEV" | sed -E "s#/dev/video[0-9]+#/dev/video${ALT_IDX}#")"
308+
fi
309+
310+
log_info "Applying path fallback (B1): switch to RDI/video index ${ALT_IDX} with format $TARGET_FORMAT"
311+
print_planned_commands "$MEDIA_NODE" "$TARGET_FORMAT"
312+
configure_pipeline_block "$MEDIA_NODE" "$TARGET_FORMAT"
313+
execute_capture_block "$FRAMES" "$TARGET_FORMAT"
314+
RET=$?
315+
316+
if [ "$RET" -ne 0 ] && [ -n "$SAVE_W" ] && [ -n "$SAVE_H" ]; then
317+
YAVTA_W=""; YAVTA_H=""
318+
log_info "Retrying (B2) letting driver choose size on index ${ALT_IDX}"
319+
print_planned_commands "$MEDIA_NODE" "$TARGET_FORMAT"
320+
configure_pipeline_block "$MEDIA_NODE" "$TARGET_FORMAT"
321+
execute_capture_block "$FRAMES" "$TARGET_FORMAT"
322+
RET=$?
323+
fi
324+
325+
MEDIA_CTL_V_LIST="$SAVE_V"
326+
MEDIA_CTL_L_LIST="$SAVE_L"
327+
YAVTA_DEV="$SAVE_DEV"
328+
YAVTA_W="$SAVE_W"
329+
YAVTA_H="$SAVE_H"
330+
331+
[ "$RET" -eq 0 ] && break
332+
done
333+
fi
334+
fi
335+
###################### end ###############################################
336+
337+
############### Inline device-supported format fallback ##################
338+
if [ "$RET" -ne 0 ]; then
339+
SUP_FMTS="$(v4l2-ctl -d "$YAVTA_DEV" --list-formats 2>/dev/null \
340+
| sed -n "s/^[[:space:]]*'\([^']*\)'.*/\1/p")"
341+
342+
if [ -n "$SUP_FMTS" ]; then
343+
ALT_FMT_C=""
344+
if printf '%s\n' "$SUP_FMTS" | grep -qx "$TARGET_FORMAT"; then
345+
ALT_FMT_C="$TARGET_FORMAT"
346+
elif printf '%s\n' "$TARGET_FORMAT" | grep -q 'P$' && \
347+
printf '%s\n' "$SUP_FMTS" | grep -qx "$(printf '%s' "$TARGET_FORMAT" | sed 's/P$//')"; then
348+
ALT_FMT_C="$(printf '%s' "$TARGET_FORMAT" | sed 's/P$//')"
349+
else
350+
ALT_FMT_C="$(printf '%s\n' "$SUP_FMTS" | grep -E '^S[RGB]+[0-9]{2}P?$' | head -n1)"
351+
[ -z "$ALT_FMT_C" ] && ALT_FMT_C="$(printf '%s\n' "$SUP_FMTS" | head -n1)"
352+
fi
353+
354+
if [ -n "$ALT_FMT_C" ]; then
355+
SAVE_V="$MEDIA_CTL_V_LIST"
356+
SAVE_W="$YAVTA_W"
357+
SAVE_H="$YAVTA_H"
358+
359+
MEDIA_CTL_V_LIST="$(printf '%s\n' "$MEDIA_CTL_V_LIST" \
360+
| sed -E "s/fmt:[^/]+\//fmt:${ALT_FMT_C}\//g")"
361+
YAVTA_W=""
362+
YAVTA_H=""
363+
364+
log_info "Applying device-supported format fallback (C): $TARGET_FORMAT$ALT_FMT_C (letting driver choose size)"
365+
print_planned_commands "$MEDIA_NODE" "$ALT_FMT_C"
366+
configure_pipeline_block "$MEDIA_NODE" "$ALT_FMT_C"
367+
execute_capture_block "$FRAMES" "$ALT_FMT_C"
368+
RET=$?
369+
370+
MEDIA_CTL_V_LIST="$SAVE_V"
371+
YAVTA_W="$SAVE_W"
372+
YAVTA_H="$SAVE_H"
373+
fi
374+
fi
375+
fi
376+
###################### end ###############################################
377+
290378
case "$RET" in
291379
0) log_pass "$SENSOR $VIDEO $TARGET_FORMAT PASS"; PASS=$((PASS+1)) ;;
292380
1) log_fail "$SENSOR $VIDEO $TARGET_FORMAT FAIL (capture failed)"; FAIL=$((FAIL+1)) ;;
@@ -305,9 +393,11 @@ done < "$TMP_PIPELINES_FILE"
305393
log_info "Test Summary: Passed: $PASS, Failed: $FAIL, Skipped: $SKIP"
306394
if [ "$PASS" -gt 0 ]; then
307395
echo "$TESTNAME PASS" >"$RES_FILE"
396+
exit 0
308397
elif [ "$FAIL" -gt 0 ]; then
309398
echo "$TESTNAME FAIL" >"$RES_FILE"
399+
exit 1
310400
else
311401
echo "$TESTNAME SKIP" >"$RES_FILE"
402+
exit 0
312403
fi
313-
exit 0

0 commit comments

Comments
 (0)