#!/bin/sh #补充 文件使用:./[文件名].sh clean,如./v4l2test.sh clean 清理文件;./v4l2test.sh mod 修改volatile变量 ROM_CAPTURE_PATH="./rom_camcache"#数据暂存路径,SELECT_CACHE_LOC值选择实际数据存放的位置 SELECT_CACHE_LOC=0 #可选值0 or 1,0:选择内存盘;1:选择ROM_CAPTURE_PATH指定地址 RAM_DIR_NAME="user.camcap_cache"#RAM临时文件文件名 IS_HARDCODE=1 #值为1时使用程序中硬编码的摄像头捕获参数 ### Volatile parameter DEVICE_LOC=2 CAP_WIDTH=2560 CAP_HEIGHT=720 CAP_PIXFMT=MJPG CAP_SUFFIX=jpeg #jpeg/raw depends on CAP_PIXFMT is MJPEG/YUYV etc.此处需要修改!!我后来发现如果是仅YUYV的摄像头而这里还是jpeg就会报错没有找到raw文件 ### PIX_FMT_FFMPEG="yuyv422"#ffmpeg需要原像素格式的信息,我的设备只有这一种,所以我的代码就不对其他格式适配了。 #摄像头初始化处也需要制定像素格式,但是参数拼写不一样,需要进一步完善代码可以从这里做起。 start=`date +%s.%N` echo"\nROM_CAPTURE_PATH=${ROM_CAPTURE_PATH}\t#数据暂存路径,SELECT_CACHE_LOC值选择实际数据存放的位置\nSELECT_CACHE_LOC=${SELECT_CACHE_LOC}\t#可选值0 or 1,0:选择内存盘;1:选择ROM_CAPTURE_PATH指定地址\nRAM_DIR_NAME=${RAM_DIR_NAME}\t\t#RAM临时文件文件名\nIS_HARDCODE=${IS_HARDCODE}\t\t#值为1时使用程序中硬编码的摄像头捕获参数\n###Volatile parameter###\nDEVICE_LOC=${DEVICE_LOC}\nCAP_WIDTH=${CAP_WIDTH}\nCAP_HEIGHT=${CAP_HEIGHT}\nCAP_PIXFMT=${CAP_PIXFMT}\n###\nPIX_FMT_FFMPEG=${PIX_FMT_FFMPEG}" if [ -n "$1" ] then if [ $1 = "clean" ] then echo"Cleaning the dir in RAM:" rm -ir /dev/shm/${RAM_DIR_NAME} echo"Cleaning the link to the dir in RAM:" rm ${RAM_DIR_NAME}_link echo"Cleaning the dir in ROM:" rm -ir ${ROM_CAPTURE_PATH} echo"Process Done." return fi if [ $1 = "mod" ] then IS_HARDCODE=0 fi fi
if [ ${SELECT_CACHE_LOC} -eq 0 ] #选择内存盘 then echo"creating RAM disk" if [ ! -d /dev/shm/${RAM_DIR_NAME} ] then mkdir /dev/shm/${RAM_DIR_NAME}#创建内存盘,需要确认df -h显示/dev/shm挂载方式为tmpfs fi if [ ! -d ./${RAM_DIR_NAME}_link ] then ln -s /dev/shm/${RAM_DIR_NAME} ./${RAM_DIR_NAME}_link #在当前目录下创建软链接方便使用 fi else#选择ROM_CAPTURE_PATH指定地址 if [ ! -d ./${ROM_CAPTURE_PATH} ] then mkdir ${ROM_CAPTURE_PATH} fi fi v4l2-ctl --list-devices #显示当前连接的摄像头设备 if [ ${IS_HARDCODE} -eq 1 ] then echo"using the hardcode now" echo"Choose:/dev/video${DEVICE_LOC}" echo"resolution:${CAP_WIDTH}x${CAP_HEIGHT} in ${CAP_PIXFMT}" else if [ -n "$2" ] then DEVICE_LOC=$2 else echo"选择设备(格式:若选择/dev/video0,则输入0。没有检查输入所以自己注意):" read DEVICE_LOC fi echo"Choose:/dev/video${DEVICE_LOC}" echo"在如下信息中选择摄像头参数" v4l2-ctl -d${DEVICE_LOC} --list-formats-ext #注意⚠️返回值写着摄像头支持的所有输出模式,如YUYV if [ -n "$3" ] then CAP_WIDTH=$3 else echo"请输入捕捉宽度" read CAP_WIDTH fi if [ -n "$4" ] then CAP_HEIGHT=$4 else echo"请输入捕捉高度" read CAP_HEIGHT fi if [ -n "$5" ] then CAP_PIXFMT=$5 else echo"请输入像素格式" read CAP_PIXFMT fi fi if [ ${CAP_PIXFMT} = "YUYV" ] #捕获格式不为YUYV时不进行转码 then CAP_SUFFIX=raw #为之前出现的bug作修补即前面volatile的警告 fi if [ ${SELECT_CACHE_LOC} -eq 0 ] #选择内存盘 then v4l2-ctl --verbose \ -d${DEVICE_LOC} \ --set-fmt-video=width=${CAP_WIDTH},height=${CAP_HEIGHT},pixelformat=${CAP_PIXFMT} \ --stream-mmap \ --stream-count=1 \ --stream-to=./${RAM_DIR_NAME}_link/output.${CAP_SUFFIX} if [ ${CAP_PIXFMT} = "YUYV" ] #捕获格式不为YUYV时不进行转码 then ffmpeg -y -s:v ${CAP_WIDTH}x${CAP_HEIGHT} -pix_fmt ${PIX_FMT_FFMPEG} -i ./${RAM_DIR_NAME}_link/output.raw ./${RAM_DIR_NAME}_link/output.jpeg fi else#选择ROM_CAPTURE_PATH指定地址 v4l2-ctl --verbose \ -d${DEVICE_LOC} \ --set-fmt-video=width=${CAP_WIDTH},height=${CAP_HEIGHT},pixelformat=${CAP_PIXFMT} \ --stream-mmap \ --stream-count=1 \ --stream-to=${ROM_CAPTURE_PATH}/output.${CAP_SUFFIX} if [ ${CAP_PIXFMT} = "YUYV" ] #捕获格式不为YUYV时不进行转码 then ffmpeg -y -s:v ${CAP_WIDTH}x${CAP_HEIGHT} -pix_fmt ${PIX_FMT_FFMPEG} -i ${ROM_CAPTURE_PATH}/output.raw ${ROM_CAPTURE_PATH}/output.jpeg fi fi end=`date +%s.%N` getTiming(){ #https://blog.csdn.net/bowenlaw/article/details/103789158 start=$1 end=$2 start_s=$(echo$start | cut -d '.' -f 1) start_ns=$(echo$start | cut -d '.' -f 2) end_s=$(echo$end | cut -d '.' -f 1) end_ns=$(echo$end | cut -d '.' -f 2) time=`expr $end_s \* 1000 - $start_s \* 1000 + $end_ns / 1000000 - $start_ns / 1000000` echo"$time ms" } result=$(getTiming $start$end) echo$result