Merge branch 'mobile_face' of https://github.com/ente-io/auth into mobile_face

This commit is contained in:
Neeraj Gupta 2024-04-30 14:48:28 +05:30
commit b1cbf8526b
3 changed files with 34 additions and 16 deletions

View file

@ -261,21 +261,21 @@ class _PersonClustersState extends State<PersonReviewClusterSuggestion> {
],
);
// Precompute face thumbnails for next suggestions, in case there are
const precompute = 6;
const maxComputations = 10;
const precomputeSuggestions = 6;
const maxPrecomputations = 10;
int compCount = 0;
if (allSuggestions.length > currentSuggestionIndex + 1) {
for (final suggestion in allSuggestions.sublist(
currentSuggestionIndex + 1,
min(allSuggestions.length, currentSuggestionIndex + precompute),
min(allSuggestions.length, currentSuggestionIndex + precomputeSuggestions),
)) {
final files = suggestion.filesInCluster;
final clusterID = suggestion.clusterIDToMerge;
for (final file in files.sublist(0, min(files.length, 8))) {
unawaited(PersonFaceWidget.precomputeFaceCrops(file, clusterID));
unawaited(PersonFaceWidget.precomputeNextFaceCrops(file, clusterID));
compCount++;
if (compCount >= maxComputations) {
if (compCount >= maxPrecomputations) {
break;
}
}
@ -300,6 +300,7 @@ class _PersonClustersState extends State<PersonReviewClusterSuggestion> {
child: PersonFaceWidget(
files[start + index],
clusterID: cluserId,
useFullFile: false,
),
),
),

View file

@ -19,6 +19,7 @@ class PersonFaceWidget extends StatelessWidget {
final EnteFile file;
final String? personId;
final int? clusterID;
final bool useFullFile;
// PersonFaceWidget constructor checks that both personId and clusterID are not null
// and that the file is not null
@ -26,6 +27,7 @@ class PersonFaceWidget extends StatelessWidget {
this.file, {
this.personId,
this.clusterID,
this.useFullFile = true,
Key? key,
}) : assert(
personId != null || clusterID != null,
@ -33,7 +35,7 @@ class PersonFaceWidget extends StatelessWidget {
),
super(key: key);
static Future<void> precomputeFaceCrops(file, clusterID) async {
static Future<void> precomputeNextFaceCrops(file, clusterID) async {
try {
final Face? face = await FaceMLDataDB.instance.getCoverFaceForPerson(
recentFileID: file.uploadedFileID!,
@ -176,6 +178,13 @@ class PersonFaceWidget extends StatelessWidget {
faceCropCache.put(face.faceID, data);
return data;
}
if (!useFullFile) {
final Uint8List? cachedFaceThumbnail =
faceCropThumbnailCache.get(face.faceID);
if (cachedFaceThumbnail != null) {
return cachedFaceThumbnail;
}
}
EnteFile? fileForFaceCrop = file;
if (face.fileID != file.uploadedFileID!) {
fileForFaceCrop =
@ -191,12 +200,17 @@ class PersonFaceWidget extends StatelessWidget {
{
face.faceID: face.detection.box,
},
useFullFile: useFullFile,
),
);
final Uint8List? computedCrop = result?[face.faceID];
if (computedCrop != null) {
if (useFullFile) {
faceCropCache.put(face.faceID, computedCrop);
faceCropCacheFile.writeAsBytes(computedCrop).ignore();
} else {
faceCropThumbnailCache.put(face.faceID, computedCrop);
}
}
return computedCrop;
} catch (e, s) {

View file

@ -1,4 +1,4 @@
import "dart:io";
import "dart:io" show File;
import "package:flutter/foundation.dart";
import "package:photos/core/cache/lru_map.dart";
@ -12,13 +12,16 @@ import "package:photos/utils/thumbnail_util.dart";
import "package:pool/pool.dart";
final LRUMap<String, Uint8List?> faceCropCache = LRUMap(1000);
final LRUMap<String, Uint8List?> faceCropThumbnailCache = LRUMap(1000);
final pool = Pool(10, timeout: const Duration(seconds: 15));
Future<Map<String, Uint8List>?> getFaceCrops(
EnteFile file,
Map<String, FaceBox> faceBoxeMap,
Map<String, FaceBox> faceBoxeMap, {
bool useFullFile = true,
}
) async {
late String? imagePath;
if (file.fileType != FileType.video) {
if (useFullFile && file.fileType != FileType.video) {
final File? ioFile = await getFile(file);
if (ioFile == null) {
return null;