|
|
@@ -33,9 +33,17 @@ import com.grkj.shared.widget.FaceOverlayView
|
|
|
import com.sik.sikcore.thread.ThreadUtils
|
|
|
import com.sik.sikimage.ImageConvertUtils
|
|
|
import com.sik.sikimage.ImageUtils
|
|
|
-import kotlinx.coroutines.*
|
|
|
+import kotlinx.coroutines.CoroutineScope
|
|
|
+import kotlinx.coroutines.Dispatchers
|
|
|
+import kotlinx.coroutines.Job
|
|
|
+import kotlinx.coroutines.SupervisorJob
|
|
|
+import kotlinx.coroutines.asCoroutineDispatcher
|
|
|
+import kotlinx.coroutines.delay
|
|
|
+import kotlinx.coroutines.launch
|
|
|
+import kotlinx.coroutines.runBlocking
|
|
|
import kotlinx.coroutines.sync.Mutex
|
|
|
import kotlinx.coroutines.sync.withLock
|
|
|
+import kotlinx.coroutines.withContext
|
|
|
import org.json.JSONObject
|
|
|
import org.slf4j.Logger
|
|
|
import org.slf4j.LoggerFactory
|
|
|
@@ -44,9 +52,9 @@ import java.lang.ref.WeakReference
|
|
|
import java.util.concurrent.Executors
|
|
|
import java.util.concurrent.atomic.AtomicBoolean
|
|
|
import java.util.concurrent.atomic.AtomicLong
|
|
|
+import java.util.concurrent.locks.ReentrantLock
|
|
|
import java.util.zip.CRC32
|
|
|
import kotlin.coroutines.CoroutineContext
|
|
|
-import java.util.concurrent.locks.ReentrantLock
|
|
|
|
|
|
/**
|
|
|
* FaceUtil 人脸:兼容 HLK 模组;对外 API 不变
|
|
|
@@ -550,14 +558,17 @@ object FaceUtil {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 尝试次数
|
|
|
+ private var retryCheckCount = 0
|
|
|
+
|
|
|
// ================= checkCamera:命中即停 =================
|
|
|
fun checkCamera(
|
|
|
preview: View,
|
|
|
faceOverlayView: FaceOverlayView? = null,
|
|
|
callBack: (Bitmap?, face: Rect?, Long?) -> Unit
|
|
|
) {
|
|
|
+ retryCheckCount = 3
|
|
|
stashAppContext(preview.context)
|
|
|
-
|
|
|
// 进入 checkCamera 时重置“命中即停”标记
|
|
|
stopAfterHit.set(false)
|
|
|
|
|
|
@@ -654,11 +665,7 @@ object FaceUtil {
|
|
|
val alive = liveList.any { it.liveness == LivenessInfo.ALIVE }
|
|
|
if (!alive) {
|
|
|
if (shouldEmit(lastCheckCbTs)) ThreadUtils.runOnMain {
|
|
|
- callBack(
|
|
|
- null,
|
|
|
- null,
|
|
|
- null
|
|
|
- )
|
|
|
+ callBack(null, null, null)
|
|
|
}
|
|
|
return@launch
|
|
|
}
|
|
|
@@ -679,34 +686,24 @@ object FaceUtil {
|
|
|
if (stopAfterHit.compareAndSet(false, true)) {
|
|
|
if (shouldEmit(lastCheckCbTs)) {
|
|
|
val bmp = withContext(Dispatchers.IO) {
|
|
|
- ImageConvertUtils.nv21ToBitmap(
|
|
|
- data,
|
|
|
- p.width,
|
|
|
- p.height
|
|
|
- )
|
|
|
+ ImageConvertUtils.nv21ToBitmap(data, p.width, p.height)
|
|
|
}
|
|
|
ThreadUtils.runOnMain {
|
|
|
- callBack(
|
|
|
- bmp,
|
|
|
- faces[0].rect,
|
|
|
- searchResult?.faceFeatureInfo?.searchId?.toLong()
|
|
|
- )
|
|
|
+ callBack(bmp, faces[0].rect, searchResult?.faceFeatureInfo?.searchId?.toLong())
|
|
|
}
|
|
|
}
|
|
|
requestStop = true // 解锁之后再 stop()
|
|
|
}
|
|
|
return@launch
|
|
|
}
|
|
|
-
|
|
|
// 未命中:按原逻辑回调空
|
|
|
if (shouldEmit(lastCheckCbTs)) ThreadUtils.runOnMain {
|
|
|
- callBack(
|
|
|
- null,
|
|
|
- null,
|
|
|
- null
|
|
|
- )
|
|
|
+ if (retryCheckCount == 0) {
|
|
|
+ callBack(null, null, null)
|
|
|
+ requestStop = true
|
|
|
+ }
|
|
|
+ retryCheckCount--
|
|
|
}
|
|
|
-
|
|
|
} catch (e: Throwable) {
|
|
|
logger.warn("ARC check error: ${e.message}", e)
|
|
|
} finally {
|
|
|
@@ -770,7 +767,7 @@ object FaceUtil {
|
|
|
fun registerFace(faceData: List<Pair<Long, String>>) {
|
|
|
if (backend == FaceBackend.HLK) {
|
|
|
ThreadUtils.runOnIO {
|
|
|
- faceData.forEach { (uid, b64) ->
|
|
|
+ faceData.forEach { (uid, b64) ->
|
|
|
val jpegBytes = ImageCompress.base64ToJpegUnderMB(b64)
|
|
|
// val jpegBytes = Base64.decode(b64, Base64.DEFAULT)
|
|
|
val crc32 = CRC32().apply { update(jpegBytes) }.value
|