From 463cd2c58328e8df6e08e54a4dae7b0f5c779129 Mon Sep 17 00:00:00 2001 From: nitinn Date: Thu, 30 Apr 2026 07:55:13 +0530 Subject: [PATCH 1/2] camera: enhance camera tests with snapshot support for qtiqmmfsrc and libcamerasrc Signed-off-by: nitinn --- .../Camera/Camera_Tests/Camera_Tests.yaml | 10 +- .../GSTreamer/Camera/Camera_Tests/README.md | 15 +- .../GSTreamer/Camera/Camera_Tests/run.sh | 317 ++++++++++++++++-- 3 files changed, 309 insertions(+), 33 deletions(-) diff --git a/Runner/suites/Multimedia/GSTreamer/Camera/Camera_Tests/Camera_Tests.yaml b/Runner/suites/Multimedia/GSTreamer/Camera/Camera_Tests/Camera_Tests.yaml index 9de2b4cb..017d3dde 100644 --- a/Runner/suites/Multimedia/GSTreamer/Camera/Camera_Tests/Camera_Tests.yaml +++ b/Runner/suites/Multimedia/GSTreamer/Camera/Camera_Tests/Camera_Tests.yaml @@ -3,10 +3,10 @@ metadata: format: "Lava-Test Test Definition 1.0" description: > Comprehensive camera validation using GStreamer with qtiqmmfsrc or libcamerasrc. - Auto-detects available plugin (qtiqmmfsrc: 10 tests, libcamerasrc: 7 tests). - Tests run in sequence: Fakesink -> Preview -> Encode. - qtiqmmfsrc supports NV12 (linear) and UBWC (Qualcomm compressed) formats. - libcamerasrc supports NV12 only. + Auto-detects available plugin (qtiqmmfsrc: 12 tests, libcamerasrc: 9 tests). + Tests run in sequence: Fakesink -> Preview -> Encode -> Snapshot. + qtiqmmfsrc supports NV12 (linear) and UBWC (Qualcomm compressed) formats, plus snapshot tests (1080p, 4K). + libcamerasrc supports NV12 only and includes snapshot tests (1080p, 4K). os: - linux scope: @@ -15,7 +15,7 @@ metadata: params: CAMERA_ID: "0" CAMERA_PLUGIN: "auto" - CAMERA_TEST_MODES: "fakesink,preview,encode" + CAMERA_TEST_MODES: "fakesink,preview,encode,snapshot" CAMERA_FORMATS: "nv12,ubwc" CAMERA_RESOLUTIONS: "720p,1080p,4k" CAMERA_FRAMERATE: "30" diff --git a/Runner/suites/Multimedia/GSTreamer/Camera/Camera_Tests/README.md b/Runner/suites/Multimedia/GSTreamer/Camera/Camera_Tests/README.md index 9787d897..61319b0c 100644 --- a/Runner/suites/Multimedia/GSTreamer/Camera/Camera_Tests/README.md +++ b/Runner/suites/Multimedia/GSTreamer/Camera/Camera_Tests/README.md @@ -34,29 +34,33 @@ Auto-detects available plugin (prioritizes qtiqmmfsrc). Use `--plugin` to explic ## Test Matrix -### qtiqmmfsrc Tests (10 Total) +### qtiqmmfsrc Tests (12 Total) | Category | Tests | Formats | Resolutions | Description | |----------|-------|---------|-------------|-------------| | Fakesink | 2 | NV12, UBWC | 720p | Basic capture validation | | Preview | 2 | NV12, UBWC | 4K | Display on Weston | | Encode | 6 | NV12, UBWC | 720p, 1080p, 4K | H.264 encoding to MP4 | +| Snapshot | 2 | NV12 | 1080p, 4K | JPEG still image capture | **Format Notes:** - **NV12**: Standard linear format (universal support) - **UBWC**: Qualcomm compressed format (Qualcomm optimized) +- **Snapshot**: Uses NV12 format only -### libcamerasrc Tests (7 Total) +### libcamerasrc Tests (9 Total) | Category | Tests | Resolutions | Description | |----------|-------|-------------|-------------| | Fakesink | 2 | 720p, 1080p | Basic capture validation | | Preview | 2 | 720p, 1080p | Display on Weston | | Encode | 3 | 720p, 1080p, 4K | H.264 encoding to MP4 | +| Snapshot | 2 | 1080p, 4K | Still image capture (JPEG) | **Format Notes:** - Only supports NV12 format - Requires `videoconvert` element +- Snapshot tests use `src_1::stream-role=still-capture` for high-quality stills ## Parameters @@ -67,7 +71,7 @@ Auto-detects available plugin (prioritizes qtiqmmfsrc). Use `--plugin` to explic --camera-id Camera device ID (qtiqmmfsrc only, default: 0) --plugin Plugin: qtiqmmfsrc, libcamerasrc, auto (default: auto) ---test-modes Modes: fakesink,preview,encode (default: all) +--test-modes Modes: fakesink,preview,encode,snapshot (default: all) --formats Formats: nv12,ubwc (qtiqmmfsrc only, default: both) --resolutions Resolutions: 720p,1080p,4k (default: all) --framerate Framerate (default: 30) @@ -82,7 +86,7 @@ Auto-detects available plugin (prioritizes qtiqmmfsrc). Use `--plugin` to explic |----------|-------------|---------| | `CAMERA_ID` | Camera device ID (qtiqmmfsrc only) | 0 | | `CAMERA_PLUGIN` | Plugin: qtiqmmfsrc, libcamerasrc, auto | auto | -| `CAMERA_TEST_MODES` | Test modes (comma-separated) | fakesink,preview,encode | +| `CAMERA_TEST_MODES` | Test modes (comma-separated) | fakesink,preview,encode,snapshot | | `CAMERA_FORMATS` | Formats (qtiqmmfsrc only) | nv12,ubwc | | `CAMERA_RESOLUTIONS` | Resolutions | 720p,1080p,4k | | `CAMERA_FRAMERATE` | Framerate (fps) | 30 | @@ -103,6 +107,9 @@ Auto-detects available plugin (prioritizes qtiqmmfsrc). Use `--plugin` to explic ./run.sh --plugin qtiqmmfsrc --test-modes fakesink ./run.sh --plugin libcamerasrc --test-modes preview,encode +# Run libcamerasrc snapshot tests (2 tests: 1080p and 4K) +./run.sh --plugin libcamerasrc --test-modes snapshot + # Test specific formats/resolutions ./run.sh --plugin qtiqmmfsrc --formats nv12 --resolutions 720p,1080p ./run.sh --plugin libcamerasrc --resolutions 4k --duration 20 diff --git a/Runner/suites/Multimedia/GSTreamer/Camera/Camera_Tests/run.sh b/Runner/suites/Multimedia/GSTreamer/Camera/Camera_Tests/run.sh index 7b42f9d6..598ec550 100755 --- a/Runner/suites/Multimedia/GSTreamer/Camera/Camera_Tests/run.sh +++ b/Runner/suites/Multimedia/GSTreamer/Camera/Camera_Tests/run.sh @@ -70,12 +70,13 @@ total_tests=0 # -------------------- Defaults -------------------- cameraId="${CAMERA_ID:-0}" cameraPlugin="${CAMERA_PLUGIN:-auto}" -testModeList="${CAMERA_TEST_MODES:-fakesink,preview,encode}" +testModeList="${CAMERA_TEST_MODES:-fakesink,preview,encode,snapshot}" formatList="${CAMERA_FORMATS:-nv12,ubwc}" resolutionList="${CAMERA_RESOLUTIONS:-720p,1080p,4k}" framerate="${CAMERA_FRAMERATE:-30}" duration="${CAMERA_DURATION:-10}" gstDebugLevel="${CAMERA_GST_DEBUG:-${GST_DEBUG_LEVEL:-2}}" +SNAPSHOT_MIN_BYTES="${CAMERA_SNAPSHOT_MIN_BYTES:-10000}" # Validate environment variables if set (POSIX-safe; no indirect expansion) for param in CAMERA_DURATION CAMERA_FRAMERATE CAMERA_GST_DEBUG GST_DEBUG_LEVEL; do @@ -247,22 +248,24 @@ Camera Tests - Comprehensive GStreamer Camera Validation OVERVIEW: This test suite validates camera functionality using GStreamer with two camera source plugins: - - qtiqmmfsrc (Qualcomm CAMX downstream) - 10 tests - - libcamerasrc (upstream) - 7 tests + - qtiqmmfsrc (Qualcomm CAMX downstream) - 12 tests + - libcamerasrc (upstream) - 9 tests Tests run in sequence to progressively validate different camera capabilities. TEST SEQUENCES: - qtiqmmfsrc (10 Total Tests): + qtiqmmfsrc (12 Total Tests): 1. Fakesink (2 tests) - Basic camera capture validation (no encoding) 2. Preview (2 tests) - Camera preview on Weston display (4K) 3. Encode (6 tests) - Camera capture with H.264 encoding (720p/1080p/4K) + 4. Snapshot (2 tests) - Still image capture to JPEG (1080p/4K) - libcamerasrc (7 Total Tests): + libcamerasrc (9 Total Tests): 1. Fakesink (2 tests) - Basic camera capture validation (no encoding, 720p/1080p) 2. Preview (2 tests) - Camera preview on Weston (720p/1080p) 3. Encode (3 tests) - Camera capture with H.264 encoding (720p/1080p/4K) + 4. Snapshot (2 tests) - Still image capture to JPEG (1080p/4K) USAGE: $0 [OPTIONS] @@ -274,11 +277,11 @@ OPTIONS: --plugin Camera plugin to use (default: auto) Options: qtiqmmfsrc, libcamerasrc, auto auto - Auto-detect (prioritizes qtiqmmfsrc if both available) - qtiqmmfsrc - Use CAMX downstream camera (10 tests) - libcamerasrc - Use upstream camera (7 tests) + qtiqmmfsrc - Use CAMX downstream camera (12 tests) + libcamerasrc - Use upstream camera (9 tests) - --test-modes Test modes to run (default: fakesink,preview,encode) - Options: fakesink, preview, encode + --test-modes Test modes to run (default: fakesink,preview,encode,snapshot) + Options: fakesink, preview, encode, snapshot Use comma-separated list to run specific modes --formats Formats to test (qtiqmmfsrc only, default: nv12,ubwc) @@ -316,10 +319,10 @@ EXAMPLES: # Run all tests with auto-detected camera plugin $0 - # Explicitly test qtiqmmfsrc (10 tests) + # Explicitly test qtiqmmfsrc (12 tests) $0 --plugin qtiqmmfsrc - # Explicitly test libcamerasrc (7 tests) + # Explicitly test libcamerasrc (9 tests) $0 --plugin libcamerasrc # Run only fakesink tests with qtiqmmfsrc @@ -360,7 +363,7 @@ EXAMPLES: TEST DETAILS: - qtiqmmfsrc Tests (10): + qtiqmmfsrc Tests (12): Fakesink (2): - fakesink_nv12 : NV12 format, 720p, no encoding - fakesink_ubwc : UBWC format, 720p, no encoding @@ -376,8 +379,12 @@ TEST DETAILS: - encode_ubwc_720p : UBWC, 1280x720, H.264 encode - encode_ubwc_1080p : UBWC, 1920x1080, H.264 encode - encode_ubwc_4k : UBWC, 3840x2160, H.264 encode + + Snapshot (2): + - snapshot_1080p : NV12, 1920x1080, JPEG still capture (2 images) + - snapshot_4k : NV12, 3840x2160, JPEG still capture (2 images) - libcamerasrc Tests (7): + libcamerasrc Tests (9): Fakesink (2): - libcam_720p_Fakesink : 720p, no encoding - libcam_1080p_Fakesink : 1080p, no encoding @@ -390,6 +397,10 @@ TEST DETAILS: - libcam_720p_NV12_Encode : NV12, 1280x720, H.264 encode - libcam_1080p_NV12_Encode : NV12, 1920x1080, H.264 encode - libcam_4k_NV12_Encode : NV12, 3840x2160, H.264 encode + + Snapshot (2): + - libcam_1080p_Snapshot : 1920x1080, JPEG still capture (2 images) + - libcam_4k_Snapshot : 3840x2160, JPEG still capture (5 images) FORMAT DETAILS: NV12 (Linear): @@ -417,12 +428,12 @@ PREREQUISITES: - gst-inspect-1.0 (GStreamer plugin inspector) Required Plugins: - For qtiqmmfsrc (10 tests): + For qtiqmmfsrc (12 tests): - qtiqmmfsrc (Qualcomm camera source) - v4l2h264enc (V4L2 H.264 encoder, for encode) - waylandsink (Wayland display, for preview) - For libcamerasrc (7 tests): + For libcamerasrc (9 tests): - libcamerasrc (Upstream camera source) - videoconvert (Video format converter, required) - v4l2h264enc (V4L2 H.264 encoder, for encode) @@ -507,7 +518,7 @@ case "$cameraPlugin" in if [ "$qtiqmmfsrc_available" -eq 1 ]; then camera_source="qtiqmmfsrc" log_info "Using qtiqmmfsrc (CAMX downstream camera) - explicitly requested" - log_info "Will run 10 qtiqmmfsrc tests: fakesink(2) + preview(2) + encode(6)" + log_info "Will run 12 qtiqmmfsrc tests: fakesink(2) + preview(2) + encode(6) + snapshot(2)" else log_skip "qtiqmmfsrc explicitly requested but not available" echo "$RESULT_TESTNAME SKIP" >"$RES_FILE" @@ -518,7 +529,7 @@ case "$cameraPlugin" in if [ "$libcamerasrc_available" -eq 1 ]; then camera_source="libcamerasrc" log_info "Using libcamerasrc (upstream camera) - explicitly requested" - log_info "Will run 7 libcamerasrc tests: fakesink(2) + preview(2) + encode(3)" + log_info "Will run 9 libcamerasrc tests: fakesink(2) + preview(2) + encode(3) + snapshot(2)" else log_skip "libcamerasrc explicitly requested but not available" echo "$RESULT_TESTNAME SKIP" >"$RES_FILE" @@ -534,11 +545,11 @@ case "$cameraPlugin" in log_info "Note: Both qtiqmmfsrc and libcamerasrc detected, prioritizing qtiqmmfsrc" log_info "Use --plugin libcamerasrc to explicitly test libcamerasrc instead" fi - log_info "Will run 10 qtiqmmfsrc tests: fakesink(2) + preview(2) + encode(6)" + log_info "Will run 12 qtiqmmfsrc tests: fakesink(2) + preview(2) + encode(6) + snapshot(2)" elif [ "$libcamerasrc_available" -eq 1 ]; then camera_source="libcamerasrc" log_info "Using libcamerasrc (upstream camera) for tests" - log_info "Will run 7 libcamerasrc tests: fakesink(2) + preview(2) + encode(3)" + log_info "Will run 9 libcamerasrc tests: fakesink(2) + preview(2) + encode(3) + snapshot(2)" else log_skip "No camera source plugin available (neither qtiqmmfsrc nor libcamerasrc detected)" echo "$RESULT_TESTNAME SKIP" >"$RES_FILE" @@ -560,7 +571,7 @@ camera_preflight_checks() { checks_failed=0 # Check 1: GStreamer plugin validation (CRITICAL) - log_info "[1/2] GStreamer plugin validation..." + log_info "[1/3] GStreamer plugin validation..." if has_element "$camera_source"; then log_pass " ✓ GStreamer plugin available: $camera_source" checks_passed=$((checks_passed + 1)) @@ -571,7 +582,7 @@ camera_preflight_checks() { # Check 2: Required encoder plugin (only if encode tests are requested) if echo "$testModeList" | grep -q "encode"; then - log_info "[2/2] H.264 encoder plugin check..." + log_info "[2/3] H.264 encoder plugin check..." if has_element v4l2h264enc; then log_pass " ✓ v4l2h264enc available" checks_passed=$((checks_passed + 1)) @@ -579,7 +590,46 @@ camera_preflight_checks() { log_warn " ⚠ v4l2h264enc not available (encode tests will be skipped)" fi else - log_info "[2/2] H.264 encoder plugin check... skipped (encode tests not requested)" + log_info "[2/3] H.264 encoder plugin check... skipped (encode tests not requested)" + checks_passed=$((checks_passed + 1)) + fi + + # Check 3: Required snapshot plugins (only if snapshot tests are requested) + if echo "$testModeList" | grep -q "snapshot"; then + log_info "[3/3] Snapshot plugin checks..." + snapshot_checks_failed=0 + + if has_element jpegenc; then + log_pass " ✓ jpegenc available" + else + log_fail " ✗ jpegenc not available (required for snapshot tests)" + snapshot_checks_failed=$((snapshot_checks_failed + 1)) + fi + + if has_element multifilesink; then + log_pass " ✓ multifilesink available" + else + log_fail " ✗ multifilesink not available (required for snapshot tests)" + snapshot_checks_failed=$((snapshot_checks_failed + 1)) + fi + + # For libcamerasrc, also check videoconvert + if [ "$camera_source" = "libcamerasrc" ]; then + if has_element videoconvert; then + log_pass " ✓ videoconvert available (libcamerasrc)" + else + log_fail " ✗ videoconvert not available (required for libcamerasrc snapshot tests)" + snapshot_checks_failed=$((snapshot_checks_failed + 1)) + fi + fi + + if [ "$snapshot_checks_failed" -eq 0 ]; then + checks_passed=$((checks_passed + 1)) + else + checks_failed=$((checks_failed + 1)) + fi + else + log_info "[3/3] Snapshot plugin checks... skipped (snapshot tests not requested)" checks_passed=$((checks_passed + 1)) fi @@ -868,6 +918,92 @@ run_qtiqmmf_encode_test() { run_camera_test "$testname" "$pipeline" "$output_file" "yes" } +# qtiqmmfsrc Snapshot test +run_qtiqmmf_snapshot_test() { + resolution="$1" + width="$2" + height="$3" + max_files="${4:-2}" + + if ! has_element jpegenc; then + log_fail "jpegenc not available - required for snapshot test" + fail_count=$((fail_count + 1)); return 1 + fi + + if ! has_element multifilesink; then + log_fail "multifilesink not available - required for snapshot test" + fail_count=$((fail_count + 1)); return 1 + fi + + testname="snapshot_${resolution}" + output_pattern="$ENCODED_DIR/camera${cameraId}_${resolution}_image%d.jpg" + + log_info "Resolution: $resolution (${width}x${height})" + log_info "Max snapshots: $max_files" + + # Clean up old snapshot files from previous runs to avoid false positives + if ls "$ENCODED_DIR"/camera"${cameraId}"_"${resolution}"_image*.jpg >/dev/null 2>&1; then + log_info "Cleaning up old snapshot files..." + rm -f "$ENCODED_DIR"/camera"${cameraId}"_"${resolution}"_image*.jpg + fi + + pipeline=$(camera_build_qtiqmmfsrc_snapshot_pipeline "$cameraId" "$width" "$height" "$framerate" "$output_pattern" "$max_files") + + # For snapshot tests, we check if at least one snapshot file was created + # Run the test with a shorter timeout since we're only capturing a few frames + snapshot_timeout=$((max_files + 5)) + + log_info "=========================================="; log_info "Running: $testname"; log_info "==========================================" + + # Restart cam-server before snapshot test (qtiqmmfsrc only) + log_info "Restarting cam-server..." + systemctl restart cam-server >/dev/null 2>&1 || log_warn "Failed to restart cam-server (may not be critical)" + sleep 1 + + test_log="$OUTDIR/${testname}.log" + : >"$test_log" + + if [ -z "$pipeline" ]; then + log_warn "$testname: Failed to build pipeline"; skip_count=$((skip_count + 1)); return 1 + fi + + log_info "Pipeline: gst-launch-1.0 -e $pipeline" + + # Run pipeline with timeout + gstreamer_run_gstlaunch_timeout "$snapshot_timeout" "$pipeline" >>"$test_log" 2>&1 + + # Wait for filesystem to sync + sleep 5 + + # Validate log + if ! gstreamer_validate_log "$test_log" "$testname"; then + diagnose_camera_failure "$testname" "$test_log" + log_fail "$testname: FAIL"; fail_count=$((fail_count + 1)); return 1 + fi + + # Check if at least one snapshot file was created (any number, not just 0) + # multifilesink may continue numbering from previous runs + snapshot_files=$(find "$ENCODED_DIR" -name "camera${cameraId}_${resolution}_image*.jpg" -type f 2>/dev/null) + snapshot_count=$(printf '%s\n' "$snapshot_files" | grep -c .) + + if [ "$snapshot_count" -gt 0 ]; then + # Get the first file found (any number) + first_snapshot=$(printf '%s\n' "$snapshot_files" | head -n 1) + file_size=$(gstreamer_file_size_bytes "$first_snapshot") + log_info "Found snapshot file: $(basename "$first_snapshot")" + + # Check if file size is reasonable for a JPEG + if [ "$file_size" -gt "$SNAPSHOT_MIN_BYTES" ]; then + log_info "Snapshots created: $snapshot_count (file size: $file_size bytes)" + log_pass "$testname: PASS"; pass_count=$((pass_count + 1)); return 0 + else + log_fail "$testname: FAIL (snapshot file too small: $file_size bytes, minimum: $SNAPSHOT_MIN_BYTES)"; fail_count=$((fail_count + 1)); return 1 + fi + else + log_fail "$testname: FAIL (no snapshot files created)"; fail_count=$((fail_count + 1)); return 1 + fi +} + # -------------------- libcamerasrc Test Functions -------------------- # Fakesink test (parameterized) @@ -951,9 +1087,95 @@ run_libcam_encode_test() { run_camera_test "$testname" "$pipeline" "$output_file" } +# Snapshot test (parameterized) +run_libcam_snapshot_test() { + width="$1" + height="$2" + resolution_name="$3" + max_files="${4:-5}" + + if ! has_element videoconvert; then + log_fail "videoconvert not available - required for snapshot test" + fail_count=$((fail_count + 1)); return 1 + fi + + if ! has_element jpegenc; then + log_fail "jpegenc not available - required for snapshot test" + fail_count=$((fail_count + 1)); return 1 + fi + + if ! has_element multifilesink; then + log_fail "multifilesink not available - required for snapshot test" + fail_count=$((fail_count + 1)); return 1 + fi + + testname="libcam_${resolution_name}_Snapshot" + output_pattern="$ENCODED_DIR/snapshot_${resolution_name}_%d.jpg" + + log_info "Resolution: $resolution_name (${width}x${height})" + log_info "Max snapshots: $max_files" + + # Clean up old snapshot files from previous runs to avoid false positives + if ls "$ENCODED_DIR"/snapshot_"${resolution_name}"_*.jpg >/dev/null 2>&1; then + log_info "Cleaning up old snapshot files..." + rm -f "$ENCODED_DIR"/snapshot_"${resolution_name}"_*.jpg + fi + + pipeline=$(camera_build_libcamera_snapshot_pipeline "$width" "$height" "$output_pattern" "$max_files") + + # For snapshot tests, we check if at least one snapshot file was created + # Run the test with a shorter timeout since we're only capturing a few frames + snapshot_timeout=$((max_files + 5)) + + log_info "=========================================="; log_info "Running: $testname"; log_info "==========================================" + + test_log="$OUTDIR/${testname}.log" + : >"$test_log" + + if [ -z "$pipeline" ]; then + log_warn "$testname: Failed to build pipeline"; skip_count=$((skip_count + 1)); return 1 + fi + + log_info "Pipeline: gst-launch-1.0 -e $pipeline" + + # Run pipeline with timeout + gstreamer_run_gstlaunch_timeout "$snapshot_timeout" "$pipeline" >>"$test_log" 2>&1 + + # Wait for filesystem to sync + sleep 5 + + # Validate log + if ! gstreamer_validate_log "$test_log" "$testname"; then + diagnose_camera_failure "$testname" "$test_log" + log_fail "$testname: FAIL"; fail_count=$((fail_count + 1)); return 1 + fi + + # Check if at least one snapshot file was created (any number, not just 0) + # multifilesink may continue numbering from previous runs + snapshot_files=$(find "$ENCODED_DIR" -name "snapshot_${resolution_name}_*.jpg" -type f 2>/dev/null) + snapshot_count=$(printf '%s\n' "$snapshot_files" | grep -c .) + + if [ "$snapshot_count" -gt 0 ]; then + # Get the first file found (any number) + first_snapshot=$(printf '%s\n' "$snapshot_files" | head -n 1) + file_size=$(gstreamer_file_size_bytes "$first_snapshot") + log_info "Found snapshot file: $(basename "$first_snapshot")" + + # Check if file size is reasonable for a JPEG + if [ "$file_size" -gt "$SNAPSHOT_MIN_BYTES" ]; then + log_info "Snapshots created: $snapshot_count (file size: $file_size bytes)" + log_pass "$testname: PASS"; pass_count=$((pass_count + 1)); return 0 + else + log_fail "$testname: FAIL (snapshot file too small: $file_size bytes, minimum: $SNAPSHOT_MIN_BYTES)"; fail_count=$((fail_count + 1)); return 1 + fi + else + log_fail "$testname: FAIL (no snapshot files created)"; fail_count=$((fail_count + 1)); return 1 + fi +} + # -------------------- Main test execution -------------------- if [ "$camera_source" = "libcamerasrc" ]; then - log_info "Starting libcamerasrc tests: fakesink -> preview -> encode" + log_info "Starting libcamerasrc tests: fakesink -> preview -> encode -> snapshot" # Parse test modes and resolutions for libcamerasrc test_modes=$(printf '%s' "$testModeList" | tr ',' ' ') @@ -1060,6 +1282,30 @@ if [ "$camera_source" = "libcamerasrc" ]; then done ;; + snapshot) + log_info "==========================================" + log_info "LIBCAMERA SNAPSHOT TESTS" + log_info "==========================================" + + # Run snapshot tests for 1080p and 4K only + for res in $resolutions; do + case "$res" in + 1080p) + total_tests=$((total_tests + 1)) + run_libcam_snapshot_test 1920 1080 "1080p" 2 || true + ;; + 4k) + total_tests=$((total_tests + 1)) + run_libcam_snapshot_test 3840 2160 "4k" 5 || true + ;; + 720p|default|*) + # Only 1080p and 4K snapshot supported for libcamerasrc - skip without counting + log_warn "libcamerasrc snapshot: Resolution '$res' not enabled in this suite (only 1080p and 4k are supported)" + ;; + esac + done + ;; + *) log_warn "Unknown test mode for libcamerasrc: $mode" ;; @@ -1068,7 +1314,7 @@ if [ "$camera_source" = "libcamerasrc" ]; then else # qtiqmmfsrc tests - log_info "Starting camera tests in sequence: fakesink -> preview -> encode" + log_info "Starting camera tests in sequence: fakesink -> preview -> encode -> snapshot" test_modes=$(printf '%s' "$testModeList" | tr ',' ' ') formats=$(printf '%s' "$formatList" | tr ',' ' ') @@ -1130,6 +1376,29 @@ else done done ;; + snapshot) + log_info "==========================================" + log_info "QTIQMMFSRC SNAPSHOT TESTS" + log_info "==========================================" + + # Run snapshot tests for 1080p and 4K only + for res in $resolutions; do + case "$res" in + 1080p) + total_tests=$((total_tests + 1)) + run_qtiqmmf_snapshot_test "1080p" 1920 1080 2 || true + ;; + 4k) + total_tests=$((total_tests + 1)) + run_qtiqmmf_snapshot_test "4k" 3840 2160 2 || true + ;; + 720p|default|*) + # Only 1080p and 4K snapshot supported for qtiqmmfsrc - skip without counting + log_warn "qtiqmmfsrc snapshot: Resolution '$res' not enabled in this suite (only 1080p and 4k are supported)" + ;; + esac + done + ;; *) log_warn "Unknown test mode: $mode" ;; From 2da7a808f7210dc92cf0c4cbf5494af1e79895d9 Mon Sep 17 00:00:00 2001 From: nitinn Date: Thu, 30 Apr 2026 15:39:10 +0530 Subject: [PATCH 2/2] camera: extend gstreamer helper for snapshot support in qtiqmmfsrc Signed-off-by: nitinn --- Runner/utils/lib_gstreamer.sh | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Runner/utils/lib_gstreamer.sh b/Runner/utils/lib_gstreamer.sh index cc9a2a48..8796469a 100755 --- a/Runner/utils/lib_gstreamer.sh +++ b/Runner/utils/lib_gstreamer.sh @@ -1512,6 +1512,28 @@ camera_build_qtiqmmfsrc_encode_pipeline() { fi } +# camera_build_qtiqmmfsrc_snapshot_pipeline +# Builds qtiqmmfsrc snapshot pipeline for still image capture +# Uses NV12 format with jpegenc for JPEG output +# Parameters: +# camera_id: Camera device ID +# width: Image width +# height: Image height +# framerate: Framerate in fps +# output_location: Output file pattern (e.g., /path/to/camera0_4k_image%d.jpg) +# max_files: Maximum number of snapshots to capture +# Prints: pipeline string +camera_build_qtiqmmfsrc_snapshot_pipeline() { + camera_id="$1" + width="$2" + height="$3" + framerate="$4" + output_location="$5" + max_files="${6:-2}" + + printf '%s\n' "qtiqmmfsrc camera=${camera_id} name=camsrc ! capsfilter caps=\"video/x-raw,format=NV12,width=${width},height=${height},framerate=${framerate}/1\" ! jpegenc ! multifilesink location=\"${output_location}\ max-files=${max_files}" +} + # -------------------- libcamerasrc pipeline builders -------------------- # camera_build_libcamera_fakesink_pipeline # Builds libcamerasrc fakesink pipeline with optional resolution caps (uses timeout for duration control) @@ -1570,6 +1592,24 @@ camera_build_libcamera_encode_pipeline() { printf '%s\n' "libcamerasrc ! videoconvert ! video/x-raw,format=NV12,width=${width},height=${height},framerate=${framerate}/1 ! v4l2h264enc capture-io-mode=4 output-io-mode=4 ! h264parse ! mp4mux ! filesink location=${output_file}" } +# camera_build_libcamera_snapshot_pipeline +# Builds libcamerasrc snapshot pipeline for still image capture +# Uses src_1::stream-role=still-capture for high-quality still images +# Parameters: +# width: Image width +# height: Image height +# output_location: Output file pattern (e.g., /path/to/snapshot%d.jpg) +# max_files: Maximum number of snapshots to capture +# Prints: pipeline string +camera_build_libcamera_snapshot_pipeline() { + width="$1" + height="$2" + output_location="$3" + max_files="${4:-5}" + + printf '%s\n' "libcamerasrc name=camsrc src_1::stream-role=still-capture ! video/x-raw,width=${width},height=${height} ! videoconvert ! jpegenc ! multifilesink location=\"${output_location}\ max-files=${max_files}" +} + # -------------------- Wayland/Weston setup helper -------------------- # camera_setup_wayland_environment # Sets up Wayland/Weston environment for camera preview tests