Release Vulpes OS 2.7-preview.24
This commit is contained in:
parent
49572b6b45
commit
97ef99f827
135 changed files with 7717 additions and 2524 deletions
72
tundra/runtime/beatles-camera-client.py
Normal file
72
tundra/runtime/beatles-camera-client.py
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/python3.11
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
"""Narrow stdio-to-socket adapter for the Android CameraService broker."""
|
||||
import os
|
||||
import json
|
||||
import socket
|
||||
import sys
|
||||
|
||||
SOCKET = '/work/camera-ipc/camera.sock'
|
||||
|
||||
def read_exact(stream, size):
|
||||
data = bytearray()
|
||||
while len(data) < size:
|
||||
chunk = stream.recv(size - len(data))
|
||||
if not chunk:
|
||||
raise EOFError('Camera broker closed the session')
|
||||
data.extend(chunk)
|
||||
return bytes(data)
|
||||
|
||||
def forward(sock, target, size):
|
||||
header = read_exact(sock, size)
|
||||
target.write(header); target.flush()
|
||||
return header
|
||||
|
||||
def packet(sock, output):
|
||||
header = read_exact(sock, 4)
|
||||
size = int.from_bytes(header, 'little')
|
||||
if size > 65536:
|
||||
raise ValueError('Camera broker sent an oversized response')
|
||||
payload = read_exact(sock, size)
|
||||
output.write(header + payload); output.flush()
|
||||
return json.loads(payload.decode('utf-8'))
|
||||
|
||||
def main():
|
||||
client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
client.connect(SOCKET)
|
||||
output = os.fdopen(os.dup(1), 'wb', buffering=0)
|
||||
try:
|
||||
client.sendall(b'start\n')
|
||||
header = forward(client, output, 4)
|
||||
length = int.from_bytes(header, 'little')
|
||||
if not 0 < length <= 65536:
|
||||
return 2
|
||||
forward(client, output, length)
|
||||
while True:
|
||||
command = sys.stdin.buffer.readline(2049)
|
||||
if not command or len(command) > 2048:
|
||||
break
|
||||
client.sendall(command)
|
||||
if command.strip() == b'frame':
|
||||
header = forward(client, output, 8)
|
||||
length = int.from_bytes(header[4:], 'little')
|
||||
if length > 320 * 240 * 3 // 2:
|
||||
return 3
|
||||
if length:
|
||||
forward(client, output, length)
|
||||
elif command.strip() == b'stop':
|
||||
packet(client, output)
|
||||
break
|
||||
else:
|
||||
response = packet(client, output)
|
||||
jpeg = response.get('jpegLength', 0)
|
||||
if isinstance(jpeg, int) and 0 < jpeg <= 32 * 1024 * 1024:
|
||||
forward(client, output, jpeg)
|
||||
except (BrokenPipeError, ConnectionError, EOFError):
|
||||
return 0
|
||||
finally:
|
||||
client.close(); output.close()
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
Loading…
Reference in a new issue