#!/bin/bash #### v4l2 control library #### crowsnest - A webcam Service for multiple Cams and Stream Services. #### #### Written by Stephan Wendel aka KwadFan #### Copyright 2021 #### https://github.com/mainsail-crew/crowsnest #### #### This File is distributed under GPLv3 #### #### Description: Configure Cam with v4l2-ctl options #### ex.: v4l2-ctl -c brightness=100 # shellcheck enable=require-variable-braces # Exit upon Errors set -Ee function v4l2_control { v4c_log_msg() { log_msg "V4L2 Control: ${1}" } function main { local device v4l2ctl valueless opt_avail for cam in $(configured_cams); do # get device from cam section device="$(get_param "cam ${cam}" device)" # get v4l2ctl parameters v4l2ctl="$(get_param "cam ${cam}" v4l2ctl)" # if not empty do if [[ -n "${v4l2ctl}" ]]; then # Write configured options to Log v4c_log_msg "Device: [cam ${cam}]" v4c_log_msg "Options: ${v4l2ctl}" # Split options to array IFS="," read -ra opt < <(echo "${v4l2ctl}" | tr -d " "); unset IFS # loop through options for param in "${opt[@]}"; do # parameter available for device # needs || true to prevent script to exit valueless="$(echo "${param}" | cut -d "=" -f1)" opt_avail="$(v4l2-ctl -d "${device}" -L | \ grep -c "${valueless}" || true)" if [[ "${opt_avail}" -eq "0" ]]; then v4c_log_msg "Parameter '${param}' not available for '${device}'. Skipped." else v4l2-ctl -d "${device}" -c "${param}" 2> /dev/null || v4c_log_msg "Failed to set parameter: '${param}' ..." fi done if [[ "${CROWSNEST_LOG_LEVEL}" == "debug" ]]; then v4l2-ctl -d "${device}" -L | log_output "v4l2ctl" fi else v4c_log_msg "No parameters set for [cam ${cam}]. Skipped." fi done } ### MAIN main } function brokenfocus { # checks if "focus_absolute" is configured # call if_focus_absolute # returns 1 = true, 0 = false function if_focus_absolute { local cam cam="${1}" get_param "cam ${cam}" v4l2ctl | grep -c "focus_absolute" } # checks if device has "focus_absolute" # call has_focus_absolute # returns 1 if true, 0 if false function has_focus_absolute { v4l2-ctl -d "${1}" -C "focus_absolute" &> /dev/null \ && echo "1" || echo "0" } # call get_conf_value # spits out value from config file function get_conf_value { local cam conf_val local -a params cam="${1}" conf_val="$(get_param "cam ${cam}" v4l2ctl)" if [ -n "${conf_val}" ]; then IFS=','; read -ra params <<< "${conf_val}" unset IFS for i in "${params[@]}"; do grep "focus_absolute" <<< "${i}" || true done fi } # call get_current_value # ex.: get_current_value /dev/video0 # spits out focus_absolute=20 ( if set to 20 ) function get_current_value { v4l2-ctl -d "${1}" -C "focus_absolute" 2> /dev/null | sed 's/:[[:space:]]/=/' } # call set_current_value # ex.: set_current_value /dev/video0 focus_absolute=30 function set_focus_absolute { local device value device="${1}" value="${2}" v4l2-ctl -d "${device}" -c "${value}" } function main { local cur_val conf_val device for cam in ${1}; do device="$(get_param "cam ${cam}" device)" cur_val="$(get_current_value "${device}")" conf_val="$(get_conf_value "${cam}")" if [ "$(has_focus_absolute "${device}")" == "1" ] && [ "$(if_focus_absolute "${cam}")" == "1" ] && [ "${cur_val}" != "${conf_val}" ]; then detected_broken_dev_msg set_focus_absolute "${device}" "${conf_val}" fi if [[ "${CROWSNEST_LOG_LEVEL}" == "debug" ]] && [[ -n "${cur_val}" ]]; then debug_focus_val_msg "$(get_current_value "${device}")" fi done } ### MAIN main "${1}" } # This function is to set bitrate on raspicams. # If raspicams set to variable bitrate, they tend to show # a "block-like" view after reboots # To prevent that blockyfix should apply constant bitrate befor start of ustreamer # See https://github.com/mainsail-crew/crowsnest/issues/33 function blockyfix { local dev v4l2ctl # call set_bitrate function set_bitrate { v4l2-ctl -d "${1}" -c video_bitrate_mode=1 2> /dev/null v4l2-ctl -d "${1}" -c video_bitrate=15000000 2> /dev/null } for cam in $(configured_cams); do dev="$(get_param "cam ${cam}" device)" v4l2ctl="$(get_param "cam ${cam}" v4l2ctl)" if [ "${dev}" = "$(dev_is_legacy)" ]; then if [ -z "${v4l2ctl}" ] || [ "$(grep -c "video_bitrate" <<< "${v4l2ctl}")" == "0" ]; then set_bitrate "${dev}" blockyfix_msg_1 fi fi done }