batch calls to raptor check for better memory behavior.

It will still OOM because the barcode scanner will fill up memomry with unprocessed codes, so need to turn the cam off to let it drain.
This commit is contained in:
Joe Ardent 2023-08-27 09:46:43 -07:00
parent 85c60913d5
commit d8ed7acddd
5 changed files with 44 additions and 28 deletions

View file

@ -44,10 +44,9 @@ Currently, the following is done in terms of functionality:
The desktop app (unix-ish only; developed on linux, untested on anything else, but should run on macos) The desktop app (unix-ish only; developed on linux, untested on anything else, but should run on macos)
is closer to its final form in terms of UI/UX, though it currently can only transmit. The Android is closer to its final form in terms of UI/UX, though it currently can only transmit. The Android
app is about halfway done in terms of functionality, but the UI is, shall we say, "hideous": app is about halfway done in terms of functionality, but the UI is, shall we say, "bad":
![cuttle mobile app receiving data](./mobile_receiving.png) ![cuttle mobile app done receiving ![cuttle mobile app receiving data](./mobile_receiving.png)
data](./mobile_finished.png)
I might take a crack at making it less hideous before I start on the mobile transmitting/desktop I might take a crack at making it less hideous before I start on the mobile transmitting/desktop
receiving side of the functionality, but maybe not! I often want to transfer a file or text from my receiving side of the functionality, but maybe not! I often want to transfer a file or text from my

View file

@ -5,9 +5,16 @@ gen:
flutter_rust_bridge_codegen flutter_rust_bridge_codegen
lint: lint:
cd native && cargo fmt
dart format . dart format .
native: native-debug native-release
native-release:
cd android && ./gradlew :app:cargoBuildRelease
native-debug:
cd android && ./gradlew :app:cargoBuildDebug
clean: clean:
flutter clean flutter clean
cd native && cargo clean cd native && cargo clean

View file

@ -1,10 +1,12 @@
import 'dart:async'; import 'dart:async';
import 'dart:collection';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:camerawesome/camerawesome_plugin.dart'; import 'package:camerawesome/camerawesome_plugin.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_mlkit_barcode_scanning/google_mlkit_barcode_scanning.dart'; import 'package:google_mlkit_barcode_scanning/google_mlkit_barcode_scanning.dart';
import 'package:intl/intl.dart';
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
import 'ffi.dart'; import 'ffi.dart';
import 'utils/mlkit_utils.dart'; import 'utils/mlkit_utils.dart';
@ -45,12 +47,14 @@ class _MyHomePageState extends State<MyHomePage> {
final _barcodeScanner = BarcodeScanner(formats: [BarcodeFormat.qrCode]); final _barcodeScanner = BarcodeScanner(formats: [BarcodeFormat.qrCode]);
final _rxTextController = BehaviorSubject<String>(); final _rxTextController = BehaviorSubject<String>();
late final Stream<String> _rxTextStream = _rxTextController.stream; late final Stream<String> _rxTextStream = _rxTextController.stream;
final _scrollController = ScrollController();
TxConfig? _txConfig; TxConfig? _txConfig;
var _cuttleState = CuttleState.unitialized; var _cuttleState = CuttleState.unitialized;
final List<RaptorPacket> _rxData = []; final HashSet<RaptorPacket> _rxData = HashSet();
String _rxText = ''; String _rxText = '';
int _rxCount = 1;
final _formatter = NumberFormat('###,###,###');
@override @override
void dispose() { void dispose() {
@ -65,15 +69,14 @@ class _MyHomePageState extends State<MyHomePage> {
onImageForAnalysis: (img) => _processImageBarcode(img), onImageForAnalysis: (img) => _processImageBarcode(img),
imageAnalysisConfig: AnalysisConfig( imageAnalysisConfig: AnalysisConfig(
androidOptions: const AndroidAnalysisOptions.nv21( androidOptions: const AndroidAnalysisOptions.nv21(
width: 1024, width: 600,
), ),
maxFramesPerSecond: 30, maxFramesPerSecond: 20,
autoStart: false, autoStart: false,
), ),
builder: (cameraModeState, previewSize, previewRect) { builder: (cameraModeState, previewSize, previewRect) {
return _RxTextDisplayWidget( return _RxTextDisplayWidget(
rxTextStream: _rxTextStream, rxTextStream: _rxTextStream,
scrollController: _scrollController,
analysisController: cameraModeState.analysisController!, analysisController: cameraModeState.analysisController!,
); );
}, },
@ -103,7 +106,8 @@ class _MyHomePageState extends State<MyHomePage> {
_txConfig!.filename ?? "large text on the command line"; _txConfig!.filename ?? "large text on the command line";
final desc = _txConfig!.description; final desc = _txConfig!.description;
final text = 'Receiving $fname, ${_txConfig!.len} bytes: $desc'; final text =
'Receiving $fname, ${_formatter.format(_txConfig!.len)} bytes ($desc)';
_rxText = text; _rxText = text;
_rxTextController.add(text); _rxTextController.add(text);
continue; continue;
@ -121,25 +125,32 @@ class _MyHomePageState extends State<MyHomePage> {
case CuttleState.receiving: case CuttleState.receiving:
{ {
var txconf = await api.getTxConfig(bytes: dbytes); var txconf = await api.getTxConfig(bytes: dbytes);
if (txconf != null || barcode.rawValue != null) { if (txconf != null) {
await api.dropTxConfig(txc: txconf!); await api.dropTxConfig(txc: txconf);
continue; continue;
} }
final packet = RaptorPacket(field0: dbytes); final packet = RaptorPacket(field0: dbytes);
_rxData.add(packet); _rxData.add(packet);
final content = _rxCount += 1;
await api.decodePackets(packets: _rxData, txconf: _txConfig!); if (_rxCount % 40 == 0) {
_rxCount = 1;
final content = await api.decodePackets(
packets: _rxData.toList(), txconf: _txConfig!);
if (content != null) { if (content != null) {
_rxData.clear(); _rxData.clear();
_barcodeScanner.close(); _barcodeScanner.close();
_cuttleState = CuttleState.received; _cuttleState = CuttleState.received;
_rxTextController.add("DONE RECEIVING $_rxText"); _rxTextController.add("DONE RECEIVING $_rxText");
final f = await _saveReceivedFile(_txConfig!.filename, content); final f =
await _saveReceivedFile(_txConfig!.filename, content);
_rxTextController.add("Saved content to $f"); _rxTextController.add("Saved content to $f");
continue; continue;
} }
_rxTextController }
.add("$_rxText -- ${_rxData.length} bytes so far"); final bytesTotal = _rxData.length * dbytes.length;
final pct = (100.0 * bytesTotal / _txConfig!.len).floor();
_rxTextController.add(
"$_rxText -- $pct% received (${_formatter.format(bytesTotal)} bytes)");
} }
case CuttleState.received: case CuttleState.received:
@ -164,7 +175,6 @@ class _MyHomePageState extends State<MyHomePage> {
class _RxTextDisplayWidget extends StatefulWidget { class _RxTextDisplayWidget extends StatefulWidget {
final Stream<String> rxTextStream; final Stream<String> rxTextStream;
final ScrollController scrollController;
final AnalysisController analysisController; final AnalysisController analysisController;
@ -172,7 +182,6 @@ class _RxTextDisplayWidget extends StatefulWidget {
// ignore: unused_element // ignore: unused_element
super.key, super.key,
required this.rxTextStream, required this.rxTextStream,
required this.scrollController,
required this.analysisController, required this.analysisController,
}); });
@ -186,8 +195,8 @@ class _RxTextDisplayWidgetState extends State<_RxTextDisplayWidget> {
return Align( return Align(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
child: Container( child: Container(
decoration: BoxDecoration( decoration: const BoxDecoration(
color: Colors.tealAccent.withOpacity(0.7), color: Colors.white,
), ),
child: Column(mainAxisSize: MainAxisSize.min, children: [ child: Column(mainAxisSize: MainAxisSize.min, children: [
Material( Material(

View file

@ -45,6 +45,7 @@ dependencies:
path_provider: ^2.1.0 path_provider: ^2.1.0
rxdart: ^0.27.7 rxdart: ^0.27.7
uuid: ^3.0.7 uuid: ^3.0.7
intl: ^0.18.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 698 KiB

After

Width:  |  Height:  |  Size: 708 KiB