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+ ) "
610INIT_ENV=" "
711SEARCH=" $SCRIPT_DIR "
12+
813while [ " $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 " )
1319done
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
2138TESTNAME=" 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
5269done
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 ---------
11072if ! 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
11476fi
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
150112else
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
154116fi
155117
156118# --------- Module inventory (visibility only; no gating) ---------
@@ -193,22 +155,22 @@ DMESG_EXCLUDE='dummy regulator|supply [^ ]+ not found|using dummy regulator|Fail
193155if 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
197159fi
198160
199161# --------- Dependency Checks ---------
200162check_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 ---------
207169MEDIA_NODE=" $( detect_media_node) "
208170if [ -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
212174fi
213175log_info " Detected media node: $MEDIA_NODE "
214176
@@ -227,7 +189,7 @@ PYTHON_PIPELINES="$(run_camera_pipeline_parser "$TOPO_FILE")"
227189if [ -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
231193fi
232194printf ' %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"
305393log_info " Test Summary: Passed: $PASS , Failed: $FAIL , Skipped: $SKIP "
306394if [ " $PASS " -gt 0 ]; then
307395 echo " $TESTNAME PASS" > " $RES_FILE "
396+ exit 0
308397elif [ " $FAIL " -gt 0 ]; then
309398 echo " $TESTNAME FAIL" > " $RES_FILE "
399+ exit 1
310400else
311401 echo " $TESTNAME SKIP" > " $RES_FILE "
402+ exit 0
312403fi
313- exit 0
0 commit comments