[mob][perf] Avoid XMP extraction on main thread (#3787)

This commit is contained in:
Neeraj Gupta
2024-10-21 20:07:14 +05:30
committed by GitHub
7 changed files with 36 additions and 9 deletions

View File

@@ -1,6 +1,7 @@
import "dart:io";
import "dart:typed_data";
import "package:logging/logging.dart";
import "package:photos/core/event_bus.dart";
import "package:photos/db/ml/db.dart";
import "package:photos/db/ml/db_fields.dart";
@@ -19,6 +20,7 @@ extension ClipDB on MLDataDB {
}
Future<List<EmbeddingVector>> getAllClipVectors() async {
Logger("ClipDB").info("reading all embeddings from DB");
final db = await MLDataDB.instance.asyncDB;
final results = await db.getAll('SELECT * FROM $clipTable');
return _convertToVectors(results);

View File

@@ -30,6 +30,8 @@ class MLDataDB {
static const _databaseName = "ente.ml.db";
static Logger get logger => _logger;
// static const _databaseVersion = 1;
MLDataDB._privateConstructor();

View File

@@ -2,7 +2,6 @@ import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:logging/logging.dart';
import "package:motion_photos/src/xmp_extractor.dart";
import 'package:path/path.dart';
import 'package:photo_manager/photo_manager.dart';
import 'package:photos/core/configuration.dart';
@@ -185,8 +184,7 @@ class EnteFile {
if (mediaUploadData.isPanorama != true) {
try {
final xmpData = XMPExtractor()
.extract(mediaUploadData.sourceFile!.readAsBytesSync());
final xmpData = await getXmp(mediaUploadData.sourceFile!);
mediaUploadData.isPanorama = checkPanoramaFromXMP(xmpData);
} catch (_) {}

View File

@@ -108,8 +108,12 @@ class SemanticSearchService {
}
Future<List<EmbeddingVector>> getClipVectors() async {
_logger.info("Pulling cached clip embeddings");
if (_cachedImageEmbeddingVectors != null) {
return _cachedImageEmbeddingVectors!;
}
_cachedImageEmbeddingVectors ??= MLDataDB.instance.getAllClipVectors();
_logger.info("read all embeddings from DB");
return _cachedImageEmbeddingVectors!;
}

View File

@@ -10,6 +10,7 @@ import "package:ffmpeg_kit_flutter_min/media_information_session.dart";
import "package:flutter/foundation.dart";
import 'package:intl/intl.dart';
import 'package:logging/logging.dart';
import "package:motion_photos/src/xmp_extractor.dart";
import "package:photos/models/ffmpeg/ffprobe_props.dart";
import 'package:photos/models/file/file.dart';
import "package:photos/models/location/location.dart";
@@ -56,6 +57,19 @@ Future<Map<String, IfdTag>?> getExifFromSourceFile(File originFile) async {
}
}
Future<Map<String, dynamic>> getXmp(File file) async {
return Computer.shared().compute(
_getXMPComputer,
param: {"file": file},
taskName: "getXMPAsync",
);
}
Map<String, dynamic> _getXMPComputer(Map<String, dynamic> args) {
final File originalFile = args["file"] as File;
return XMPExtractor().extract(originalFile.readAsBytesSync());
}
Future<FFProbeProps?> getVideoPropsAsync(File originalFile) async {
try {
final stopwatch = Stopwatch()..start();

View File

@@ -160,8 +160,11 @@ Future<MediaUploadData> _getMediaUploadDataFromAssetFile(EnteFile file) async {
int? motionPhotoStartingIndex;
if (Platform.isAndroid && asset.type == AssetType.image) {
try {
motionPhotoStartingIndex =
(await MotionPhotos(sourceFile.path).getMotionVideoIndex())?.start;
motionPhotoStartingIndex = await Computer.shared().compute(
motionVideoIndex,
param: {'path': sourceFile.path},
taskName: 'motionPhotoIndex',
);
} catch (e) {
_logger.severe('error while detecthing motion photo start index', e);
}
@@ -177,6 +180,11 @@ Future<MediaUploadData> _getMediaUploadDataFromAssetFile(EnteFile file) async {
);
}
Future<int?> motionVideoIndex(Map<String, dynamic> args) async {
final String path = args['path'];
return (await MotionPhotos(path).getMotionVideoIndex())?.start;
}
Future<void> _computeZip(Map<String, dynamic> args) async {
final String zipPath = args['zipPath'];
final String imagePath = args['imagePath'];

View File

@@ -18,8 +18,7 @@ Future<bool> checkIfPanorama(EnteFile enteFile) async {
}
try {
final result = XMPExtractor().extract(file.readAsBytesSync());
if (result["GPano:ProjectionType"] == "cylindrical" ||
result["GPano:ProjectionType"] == "equirectangular") {
if (checkPanoramaFromXMP(result)) {
return true;
}
} catch (_) {}
@@ -30,7 +29,7 @@ Future<bool> checkIfPanorama(EnteFile enteFile) async {
return element?.printable == "6";
}
bool? checkPanoramaFromXMP(Map<String, dynamic> xmpData) {
bool checkPanoramaFromXMP(Map<String, dynamic> xmpData) {
if (xmpData["GPano:ProjectionType"] == "cylindrical" ||
xmpData["GPano:ProjectionType"] == "equirectangular") {
return true;