Initial commit

This commit is contained in:
Martijn Braam 2020-06-30 17:38:35 +02:00
commit bbee468ba9
No known key found for this signature in database
GPG Key ID: C4280ACB000B060F
1 changed files with 192 additions and 0 deletions

192
camera.py Executable file
View File

@ -0,0 +1,192 @@
#!/usr/bin/env python3
import subprocess
import os
import glob
def get_orientation():
for device in glob.glob('/sys/bus/iio/devices/iio:device*'):
if os.path.isfile(os.path.join(device, 'in_accel_x_raw')):
break
else:
return 0
with open(os.path.join(device, 'in_accel_x_raw')) as handle:
x = int(handle.read().strip())
with open(os.path.join(device, 'in_accel_y_raw')) as handle:
y = int(handle.read().strip())
with open(os.path.join(device, 'in_accel_z_raw')) as handle:
z = int(handle.read().strip())
max_abs = max(abs(x), abs(y), abs(z))
if x == max_abs:
# portrait
return "portrait"
if -x == max_abs:
# upside down portrait
return "portrait"
if y == max_abs:
# landscale counterclockwise
return "ccw"
if -y == max_abs:
# landscape clockwise
return "cw"
if z == max_abs:
# flat on back
return "flat"
if -z == max_abs:
# flat on screen
return "flat"
return "cw"
def setup(node, res, debug=False):
speed = 30
if '@' in res:
res, speed = res.split('@')
command = ['sudo', 'media-ctl', '-d', '/dev/media1', '--set-v4l2',
'"{}":0[fmt:UYVY8_2X8/{}@1/{}]'.format(node, res, speed)]
if debug:
print(command)
p = subprocess.run(command, timeout=5)
if p.returncode != 0:
return False
width, height = res.split('x')
fmt = ['width=' + width, 'height=' + height, 'pixelformat=UYVY']
command = ['sudo', 'v4l2-ctl', '--device', '/dev/video1', '--set-fmt-video={}'.format(','.join(fmt))]
if debug:
print(command)
p = subprocess.run(command, timeout=5)
if p.returncode != 0:
return False
def take_snapshot(node, res, name, rotate, skip=5, debug=False):
setup(node, res, debug=debug)
speed = 30
if '@' in res:
res, speed = res.split('@')
command = ['sudo', 'v4l2-ctl', '--device', '/dev/video1', '--stream-mmap', '--stream-to=/tmp/frame.raw',
'--stream-count=1', '--stream-skip={}'.format(skip)]
if debug:
print(command)
p = subprocess.run(command, timeout=10)
if p.returncode != 0:
return False
command = ['convert', '-size', res, 'uyvy:/tmp/frame.raw', '-rotate', rotate, name]
if debug:
print(command)
p = subprocess.run(command, timeout=15)
if p.returncode != 0:
return False
command = ['sudo', 'rm', '-rf', '/tmp/frame.raw']
if debug:
print(command)
subprocess.run(command, timeout=5)
return True
def record(node, res, name, rotate, debug=False):
setup(node, res, debug=debug)
speed = 30
if '@' in res:
res, speed = res.split('@')
command = ['ffmpeg', '-f', 'v4l2', '-framerate', str(speed), '-video_size', res, '-i', '/dev/video1', '-preset',
'ultrafast', name]
if debug:
print(command)
p = subprocess.run(command)
if p.returncode != 0:
return False
def set_route(camera):
if camera == 'ov5640':
links = [
'"gc2145 3-003c":0->"sun6i-csi":0[0]',
'"ov5640 3-004c":0->"sun6i-csi":0[1]'
]
elif camera == 'gc2145':
links = [
'"ov5640 3-004c":0->"sun6i-csi":0[0]',
'"gc2145 3-003c":0->"sun6i-csi":0[1]'
]
else:
raise Exception("Something wrong")
for link in links:
subprocess.run(['sudo', 'media-ctl', '-d', '/dev/media1', '--links', link])
def main():
import argparse
modes_ov5640 = {
'max': '1920x1080@20',
'1080p': '1920x1080@20',
'1080p20': '1920x1080@20',
'1080p15': '1920x1080@15',
'720p': '1280x720@30',
'720p60': '1280x720@60',
'720p50': '1280x720@50',
'720p30': '1280x720@30',
'720p25': '1280x720@25',
'720p24': '1280x720@24',
}
modes_gc2145 = {
'1080p': '1920x1080@30',
'720p': '1280x720@30',
'1080p15': '1920x1080@15',
}
options = set(modes_ov5640.keys())
options.update(modes_gc2145.keys())
parser = argparse.ArgumentParser(description="PinePhone camera tool")
parser.add_argument('action', choices=['still', 'movie'])
parser.add_argument('--resolution', '-r', choices=options, default='1080p')
parser.add_argument('--camera', '-c', choices=['rear', 'front'], default='rear')
parser.add_argument('--debug', '-d', action="store_true")
parser.add_argument('filename')
args = parser.parse_args()
orientation = get_orientation()
if args.camera == "rear":
set_route("ov5640")
node = 'ov5640 3-004c'
if orientation == "portrait":
angle = '90'
elif orientation == "cw":
angle = '0'
elif orientation == "ccw":
angle = '180'
else:
angle = '0'
modes = modes_ov5640
else:
set_route("gc2145")
node = 'gc2145 3-003c'
angle = '270'
modes = modes_gc2145
mode = modes[args.resolution]
if args.action == "still":
take_snapshot(node, mode, args.filename, angle, debug=args.debug)
elif args.action == "movie":
record(node, mode, args.filename, angle, debug=args.debug)
else:
print("Unsupported action")
exit(1)
if __name__ == "__main__":
main()