[
  {
    "path": ".github/workflows/release-apk.yml",
    "content": "name: release-apk\non: workflow_dispatch\n\nenv:\n  NCNN_VERSION: 20260113\n  OPENCV_VERSION: 4.13.0\n  OPENCV_MOBILE_TAG: v35\n  BUILD_TOOLS_VERSION: 36.0.0\n\njobs:\n  release-apk:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v4\n    - uses: actions/setup-java@v4\n      with:\n        distribution: 'temurin'\n        java-version: '21'\n\n    - name: ncnn\n      run: |\n        wget -q https://github.com/Tencent/ncnn/releases/download/${NCNN_VERSION}/ncnn-${NCNN_VERSION}-android-vulkan.zip\n        unzip -q ncnn-${NCNN_VERSION}-android-vulkan.zip -d app/src/main/jni\n\n    - name: opencv-mobile\n      run: |\n        wget -q https://github.com/nihui/opencv-mobile/releases/download/${OPENCV_MOBILE_TAG}/opencv-mobile-${OPENCV_VERSION}-android.zip\n        unzip -q opencv-mobile-${OPENCV_VERSION}-android.zip -d app/src/main/jni\n\n    - name: modify-jni-cmakelists\n      run: |\n        sed -i \"s@ncnn-[^-]*-android-vulkan@ncnn-${NCNN_VERSION}-android-vulkan@g\" app/src/main/jni/CMakeLists.txt\n        sed -i \"s@opencv-mobile-[^-]*-android@opencv-mobile-${OPENCV_VERSION}-android@g\" app/src/main/jni/CMakeLists.txt\n\n    - name: build-apk\n      run: |\n        bash ./gradlew assembleRelease --stacktrace\n\n    - name: sign-apk\n      id: signapk\n      run: |\n        DATE=`date +'%Y%m%d'`\n        SHA_SHORT=`git rev-parse --short HEAD`\n        UNSIGNED_APK=`find app/build/outputs/apk/release -type f -name \"*-release-unsigned.apk\" | head -n 1`\n        ALIGNED_APK=${UNSIGNED_APK//-release-unsigned.apk/-release-unsigned-aligned.apk}\n        SIGNED_APK=${{ github.event.repository.name }}-${DATE}.${SHA_SHORT}.apk\n        keytool -genkey -noprompt -alias ncnn \\\n            -dname \"CN=mqttserver.ibm.com, OU=ID, O=IBM, L=Hursley, S=Hants, C=GB\"\\\n            -keystore ncnn.keystore -storepass 7767517 -keypass 7767517 \\\n            -keyalg RSA -keysize 2048 -validity 10000\n        ${ANDROID_HOME}/build-tools/${BUILD_TOOLS_VERSION}/zipalign -f -v 4 ${UNSIGNED_APK} ${SIGNED_APK}\n        ${ANDROID_HOME}/build-tools/${BUILD_TOOLS_VERSION}/apksigner sign --ks ncnn.keystore --ks-key-alias ncnn \\\n            --ks-pass pass:7767517 --key-pass pass:7767517 --out ${SIGNED_APK} ${SIGNED_APK}\n        ${ANDROID_HOME}/build-tools/${BUILD_TOOLS_VERSION}/apksigner verify ${SIGNED_APK}\n        echo \"SIGNED_APK=${SIGNED_APK}\" >> $GITHUB_OUTPUT\n        echo \"APK_VERSION=${DATE}.${SHA_SHORT}\" >> $GITHUB_OUTPUT\n\n    - name: create-release\n      uses: softprops/action-gh-release@v1\n      with:\n        token: ${{ secrets.GITHUB_TOKEN }}\n        tag_name: ${{ steps.signapk.outputs.APK_VERSION }}\n        name: Release ${{ steps.signapk.outputs.APK_VERSION }}\n        files: ${{ steps.signapk.outputs.SIGNED_APK }}\n"
  },
  {
    "path": "README.md",
    "content": "# ncnn-android-scrfd\n\nThe SCRFD face detection\n\nThis is a sample ncnn android project, it depends on ncnn library and opencv\n\nhttps://github.com/Tencent/ncnn\n\nhttps://github.com/nihui/opencv-mobile\n\n## android apk file download\nhttps://github.com/nihui/ncnn-android-scrfd/releases/latest\n\n## how to build and run\n### step1\nhttps://github.com/Tencent/ncnn/releases\n\n* Download ncnn-YYYYMMDD-android-vulkan.zip or build ncnn for android yourself\n* Extract ncnn-YYYYMMDD-android-vulkan.zip into **app/src/main/jni** and change the **ncnn_DIR** path to yours in **app/src/main/jni/CMakeLists.txt**\n\n### step2\nhttps://github.com/nihui/opencv-mobile\n\n* Download opencv-mobile-XYZ-android.zip\n* Extract opencv-mobile-XYZ-android.zip into **app/src/main/jni** and change the **OpenCV_DIR** path to yours in **app/src/main/jni/CMakeLists.txt**\n\n### step3\n* Open this project with Android Studio, build it and enjoy!\n\n## some notes\n* Android ndk camera is used for best efficiency\n* Crash may happen on very old devices for lacking HAL3 camera interface\n* All models are manually modified to accept dynamic input shape\n* Most small models run slower on GPU than on CPU, this is common\n* FPS may be lower in dark environment because of longer camera exposure time\n\n## screenshot\n![](screenshot.jpg)\n\n"
  },
  {
    "path": "app/build.gradle",
    "content": "plugins {\n    id 'com.android.application'\n}\n\nandroid {\n    namespace 'com.tencent.scrfdncnn'\n    compileSdk 33\n    ndkVersion \"29.0.14206865\"\n\n    defaultConfig {\n        applicationId \"com.tencent.scrfdncnn\"\n        archivesBaseName = \"$applicationId\"\n\n        minSdkVersion 24\n        targetSdkVersion 35\n\n        externalNativeBuild {\n            cmake {\n                arguments \"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON\"\n            }\n        }\n    }\n\n    externalNativeBuild {\n        cmake {\n            version \"3.31.5\"\n            path file('src/main/jni/CMakeLists.txt')\n        }\n    }\n\n    dependencies {\n        implementation 'com.android.support:support-v4:24.0.0'\n    }\n\n    packaging {\n        jniLibs {\n            useLegacyPackaging true\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      android:versionCode=\"1\"\n      android:versionName=\"1.1\">\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-feature android:name=\"android.hardware.camera2.full\" />\n    <uses-feature android:name=\"android.hardware.camera\" android:required=\"false\" />\n\n    <application android:label=\"@string/app_name\">\n        <activity android:name=\"MainActivity\" android:label=\"@string/app_name\" android:exported=\"true\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n</manifest> \n"
  },
  {
    "path": "app/src/main/assets/scrfd_10g-opt2.param",
    "content": "7767517\n133 154\nInput                    input.1                  0 1 input.1\nConvolution              Conv_0                   1 1 input.1 220 0=28 1=3 3=2 4=1 5=1 6=756 9=1\nConvolution              Conv_2                   1 1 220 223 0=28 1=3 4=1 5=1 6=7056 9=1\nConvolution              Conv_4                   1 1 223 226 0=56 1=3 4=1 5=1 6=14112 9=1\nPooling                  MaxPool_6                1 1 226 227 1=2 2=2 5=1\nSplit                    splitncnn_0              1 2 227 227_splitncnn_0 227_splitncnn_1\nConvolution              Conv_7                   1 1 227_splitncnn_1 230 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_9                   1 1 230 532 0=56 1=3 4=1 5=1 6=28224\nBinaryOp                 Add_10                   2 1 532 227_splitncnn_0 233\nReLU                     Relu_11                  1 1 233 234\nSplit                    splitncnn_1              1 2 234 234_splitncnn_0 234_splitncnn_1\nConvolution              Conv_12                  1 1 234_splitncnn_1 237 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_14                  1 1 237 538 0=56 1=3 4=1 5=1 6=28224\nBinaryOp                 Add_15                   2 1 538 234_splitncnn_0 240\nReLU                     Relu_16                  1 1 240 241\nSplit                    splitncnn_2              1 2 241 241_splitncnn_0 241_splitncnn_1\nConvolution              Conv_17                  1 1 241_splitncnn_1 244 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_19                  1 1 244 544 0=56 1=3 4=1 5=1 6=28224\nBinaryOp                 Add_20                   2 1 544 241_splitncnn_0 247\nReLU                     Relu_21                  1 1 247 248\nSplit                    splitncnn_3              1 2 248 248_splitncnn_0 248_splitncnn_1\nConvolution              Conv_22                  1 1 248_splitncnn_1 251 0=88 1=3 3=2 4=1 5=1 6=44352 9=1\nConvolution              Conv_24                  1 1 251 550 0=88 1=3 4=1 5=1 6=69696\nPooling                  AveragePool_25           1 1 248_splitncnn_0 254 0=1 1=2 2=2\nConvolution              Conv_26                  1 1 254 553 0=88 1=1 5=1 6=4928\nBinaryOp                 Add_27                   2 1 550 553 257\nReLU                     Relu_28                  1 1 257 258\nSplit                    splitncnn_4              1 2 258 258_splitncnn_0 258_splitncnn_1\nConvolution              Conv_29                  1 1 258_splitncnn_1 261 0=88 1=3 4=1 5=1 6=69696 9=1\nConvolution              Conv_31                  1 1 261 559 0=88 1=3 4=1 5=1 6=69696\nBinaryOp                 Add_32                   2 1 559 258_splitncnn_0 264\nReLU                     Relu_33                  1 1 264 265\nSplit                    splitncnn_5              1 2 265 265_splitncnn_0 265_splitncnn_1\nConvolution              Conv_34                  1 1 265_splitncnn_1 268 0=88 1=3 4=1 5=1 6=69696 9=1\nConvolution              Conv_36                  1 1 268 565 0=88 1=3 4=1 5=1 6=69696\nBinaryOp                 Add_37                   2 1 565 265_splitncnn_0 271\nReLU                     Relu_38                  1 1 271 272\nSplit                    splitncnn_6              1 2 272 272_splitncnn_0 272_splitncnn_1\nConvolution              Conv_39                  1 1 272_splitncnn_1 275 0=88 1=3 4=1 5=1 6=69696 9=1\nConvolution              Conv_41                  1 1 275 571 0=88 1=3 4=1 5=1 6=69696\nBinaryOp                 Add_42                   2 1 571 272_splitncnn_0 278\nReLU                     Relu_43                  1 1 278 279\nSplit                    splitncnn_7              1 3 279 279_splitncnn_0 279_splitncnn_1 279_splitncnn_2\nConvolution              Conv_44                  1 1 279_splitncnn_2 282 0=88 1=3 3=2 4=1 5=1 6=69696 9=1\nConvolution              Conv_46                  1 1 282 577 0=88 1=3 4=1 5=1 6=69696\nPooling                  AveragePool_47           1 1 279_splitncnn_1 285 0=1 1=2 2=2\nConvolution              Conv_48                  1 1 285 580 0=88 1=1 5=1 6=7744\nBinaryOp                 Add_49                   2 1 577 580 288\nReLU                     Relu_50                  1 1 288 289\nSplit                    splitncnn_8              1 2 289 289_splitncnn_0 289_splitncnn_1\nConvolution              Conv_51                  1 1 289_splitncnn_1 292 0=88 1=3 4=1 5=1 6=69696 9=1\nConvolution              Conv_53                  1 1 292 586 0=88 1=3 4=1 5=1 6=69696\nBinaryOp                 Add_54                   2 1 586 289_splitncnn_0 295\nReLU                     Relu_55                  1 1 295 296\nSplit                    splitncnn_9              1 3 296 296_splitncnn_0 296_splitncnn_1 296_splitncnn_2\nConvolution              Conv_56                  1 1 296_splitncnn_2 299 0=224 1=3 3=2 4=1 5=1 6=177408 9=1\nConvolution              Conv_58                  1 1 299 592 0=224 1=3 4=1 5=1 6=451584\nPooling                  AveragePool_59           1 1 296_splitncnn_1 302 0=1 1=2 2=2\nConvolution              Conv_60                  1 1 302 595 0=224 1=1 5=1 6=19712\nBinaryOp                 Add_61                   2 1 592 595 305\nReLU                     Relu_62                  1 1 305 306\nSplit                    splitncnn_10             1 2 306 306_splitncnn_0 306_splitncnn_1\nConvolution              Conv_63                  1 1 306_splitncnn_1 309 0=224 1=3 4=1 5=1 6=451584 9=1\nConvolution              Conv_65                  1 1 309 601 0=224 1=3 4=1 5=1 6=451584\nBinaryOp                 Add_66                   2 1 601 306_splitncnn_0 312\nReLU                     Relu_67                  1 1 312 313\nSplit                    splitncnn_11             1 2 313 313_splitncnn_0 313_splitncnn_1\nConvolution              Conv_68                  1 1 313_splitncnn_1 316 0=224 1=3 4=1 5=1 6=451584 9=1\nConvolution              Conv_70                  1 1 316 607 0=224 1=3 4=1 5=1 6=451584\nBinaryOp                 Add_71                   2 1 607 313_splitncnn_0 319\nReLU                     Relu_72                  1 1 319 320\nConvolution              Conv_73                  1 1 279_splitncnn_0 321 0=56 1=1 5=1 6=4928\nConvolution              Conv_74                  1 1 296_splitncnn_0 322 0=56 1=1 5=1 6=4928\nConvolution              Conv_75                  1 1 320 323 0=56 1=1 5=1 6=12544\nSplit                    splitncnn_12             1 2 323 323_splitncnn_0 323_splitncnn_1\nInterp                   Resize_94                1 1 323_splitncnn_1 342 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_95                   2 1 322 342 343\nSplit                    splitncnn_13             1 2 343 343_splitncnn_0 343_splitncnn_1\nInterp                   Resize_114               1 1 343_splitncnn_1 362 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_115                  2 1 321 362 363\nConvolution              Conv_116                 1 1 363 364 0=56 1=3 4=1 5=1 6=28224\nSplit                    splitncnn_14             1 2 364 364_splitncnn_0 364_splitncnn_1\nConvolution              Conv_117                 1 1 343_splitncnn_0 365 0=56 1=3 4=1 5=1 6=28224\nConvolution              Conv_118                 1 1 323_splitncnn_0 366 0=56 1=3 4=1 5=1 6=28224\nConvolution              Conv_119                 1 1 364_splitncnn_1 367 0=56 1=3 3=2 4=1 5=1 6=28224\nBinaryOp                 Add_120                  2 1 365 367 368\nSplit                    splitncnn_15             1 2 368 368_splitncnn_0 368_splitncnn_1\nConvolution              Conv_121                 1 1 368_splitncnn_1 369 0=56 1=3 3=2 4=1 5=1 6=28224\nBinaryOp                 Add_122                  2 1 366 369 370\nConvolution              Conv_123                 1 1 368_splitncnn_0 371 0=56 1=3 4=1 5=1 6=28224\nConvolution              Conv_124                 1 1 370 372 0=56 1=3 4=1 5=1 6=28224\nConvolution              Conv_125                 1 1 364_splitncnn_0 373 0=80 1=3 4=1 6=40320\nGroupNorm                Add_134                  1 1 373 384 0=16 1=80 2=1.000000e-05\nReLU                     Relu_135                 1 1 384 385\nConvolution              Conv_136                 1 1 385 386 0=80 1=3 4=1 6=57600\nGroupNorm                Add_145                  1 1 386 397 0=16 1=80 2=1.000000e-05\nReLU                     Relu_146                 1 1 397 398\nConvolution              Conv_147                 1 1 398 399 0=80 1=3 4=1 6=57600\nGroupNorm                Add_156                  1 1 399 410 0=16 1=80 2=1.000000e-05\nReLU                     Relu_157                 1 1 410 411\nSplit                    splitncnn_16             1 2 411 411_splitncnn_0 411_splitncnn_1\nConvolution              Conv_158                 1 1 411_splitncnn_1 417 0=2 1=3 4=1 5=1 6=1440\nConvolution              Conv_159                 1 1 411_splitncnn_0 413 0=8 1=3 4=1 5=1 6=5760\nBinaryOp                 Mul_160                  1 1 413 bbox_8 0=2 1=1 2=8.170338e-01\nSigmoid                  Sigmoid_164              1 1 417 score_8\nConvolution              Conv_168                 1 1 371 422 0=80 1=3 4=1 6=40320\nGroupNorm                Add_177                  1 1 422 433 0=16 1=80 2=1.000000e-05\nReLU                     Relu_178                 1 1 433 434\nConvolution              Conv_179                 1 1 434 435 0=80 1=3 4=1 6=57600\nGroupNorm                Add_188                  1 1 435 446 0=16 1=80 2=1.000000e-05\nReLU                     Relu_189                 1 1 446 447\nConvolution              Conv_190                 1 1 447 448 0=80 1=3 4=1 6=57600\nGroupNorm                Add_199                  1 1 448 459 0=16 1=80 2=1.000000e-05\nReLU                     Relu_200                 1 1 459 460\nSplit                    splitncnn_17             1 2 460 460_splitncnn_0 460_splitncnn_1\nConvolution              Conv_201                 1 1 460_splitncnn_1 466 0=2 1=3 4=1 5=1 6=1440\nConvolution              Conv_202                 1 1 460_splitncnn_0 462 0=8 1=3 4=1 5=1 6=5760\nBinaryOp                 Mul_203                  1 1 462 bbox_16 0=2 1=1 2=1.195922e+00\nSigmoid                  Sigmoid_207              1 1 466 score_16\nConvolution              Conv_211                 1 1 372 471 0=80 1=3 4=1 6=40320\nGroupNorm                Add_220                  1 1 471 482 0=16 1=80 2=1.000000e-05\nReLU                     Relu_221                 1 1 482 483\nConvolution              Conv_222                 1 1 483 484 0=80 1=3 4=1 6=57600\nGroupNorm                Add_231                  1 1 484 495 0=16 1=80 2=1.000000e-05\nReLU                     Relu_232                 1 1 495 496\nConvolution              Conv_233                 1 1 496 497 0=80 1=3 4=1 6=57600\nGroupNorm                Add_242                  1 1 497 508 0=16 1=80 2=1.000000e-05\nReLU                     Relu_243                 1 1 508 509\nSplit                    splitncnn_18             1 2 509 509_splitncnn_0 509_splitncnn_1\nConvolution              Conv_244                 1 1 509_splitncnn_1 515 0=2 1=3 4=1 5=1 6=1440\nConvolution              Conv_245                 1 1 509_splitncnn_0 511 0=8 1=3 4=1 5=1 6=5760\nBinaryOp                 Mul_246                  1 1 511 bbox_32 0=2 1=1 2=1.814443e+00\nSigmoid                  Sigmoid_250              1 1 515 score_32\n"
  },
  {
    "path": "app/src/main/assets/scrfd_10g_kps-opt2.param",
    "content": "7767517\n118 142\nInput                    input.1                  0 1 input.1\nConvolution              Conv_0                   1 1 input.1 279 0=28 1=3 3=2 4=1 5=1 6=756 9=1\nConvolution              Conv_2                   1 1 279 282 0=28 1=3 4=1 5=1 6=7056 9=1\nConvolution              Conv_4                   1 1 282 285 0=56 1=3 4=1 5=1 6=14112 9=1\nPooling                  MaxPool_6                1 1 285 286 1=2 2=2 5=1\nSplit                    splitncnn_0              1 2 286 286_splitncnn_0 286_splitncnn_1\nConvolution              Conv_7                   1 1 286_splitncnn_1 289 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_9                   1 1 289 513 0=56 1=3 4=1 5=1 6=28224\nBinaryOp                 Add_10                   2 1 513 286_splitncnn_0 292\nReLU                     Relu_11                  1 1 292 293\nSplit                    splitncnn_1              1 2 293 293_splitncnn_0 293_splitncnn_1\nConvolution              Conv_12                  1 1 293_splitncnn_1 296 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_14                  1 1 296 519 0=56 1=3 4=1 5=1 6=28224\nBinaryOp                 Add_15                   2 1 519 293_splitncnn_0 299\nReLU                     Relu_16                  1 1 299 300\nSplit                    splitncnn_2              1 2 300 300_splitncnn_0 300_splitncnn_1\nConvolution              Conv_17                  1 1 300_splitncnn_1 303 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_19                  1 1 303 525 0=56 1=3 4=1 5=1 6=28224\nBinaryOp                 Add_20                   2 1 525 300_splitncnn_0 306\nReLU                     Relu_21                  1 1 306 307\nSplit                    splitncnn_3              1 2 307 307_splitncnn_0 307_splitncnn_1\nConvolution              Conv_22                  1 1 307_splitncnn_1 310 0=88 1=3 3=2 4=1 5=1 6=44352 9=1\nConvolution              Conv_24                  1 1 310 531 0=88 1=3 4=1 5=1 6=69696\nPooling                  AveragePool_25           1 1 307_splitncnn_0 313 0=1 1=2 2=2\nConvolution              Conv_26                  1 1 313 534 0=88 1=1 5=1 6=4928\nBinaryOp                 Add_27                   2 1 531 534 316\nReLU                     Relu_28                  1 1 316 317\nSplit                    splitncnn_4              1 2 317 317_splitncnn_0 317_splitncnn_1\nConvolution              Conv_29                  1 1 317_splitncnn_1 320 0=88 1=3 4=1 5=1 6=69696 9=1\nConvolution              Conv_31                  1 1 320 540 0=88 1=3 4=1 5=1 6=69696\nBinaryOp                 Add_32                   2 1 540 317_splitncnn_0 323\nReLU                     Relu_33                  1 1 323 324\nSplit                    splitncnn_5              1 2 324 324_splitncnn_0 324_splitncnn_1\nConvolution              Conv_34                  1 1 324_splitncnn_1 327 0=88 1=3 4=1 5=1 6=69696 9=1\nConvolution              Conv_36                  1 1 327 546 0=88 1=3 4=1 5=1 6=69696\nBinaryOp                 Add_37                   2 1 546 324_splitncnn_0 330\nReLU                     Relu_38                  1 1 330 331\nSplit                    splitncnn_6              1 2 331 331_splitncnn_0 331_splitncnn_1\nConvolution              Conv_39                  1 1 331_splitncnn_1 334 0=88 1=3 4=1 5=1 6=69696 9=1\nConvolution              Conv_41                  1 1 334 552 0=88 1=3 4=1 5=1 6=69696\nBinaryOp                 Add_42                   2 1 552 331_splitncnn_0 337\nReLU                     Relu_43                  1 1 337 338\nSplit                    splitncnn_7              1 3 338 338_splitncnn_0 338_splitncnn_1 338_splitncnn_2\nConvolution              Conv_44                  1 1 338_splitncnn_2 341 0=88 1=3 3=2 4=1 5=1 6=69696 9=1\nConvolution              Conv_46                  1 1 341 558 0=88 1=3 4=1 5=1 6=69696\nPooling                  AveragePool_47           1 1 338_splitncnn_1 344 0=1 1=2 2=2\nConvolution              Conv_48                  1 1 344 561 0=88 1=1 5=1 6=7744\nBinaryOp                 Add_49                   2 1 558 561 347\nReLU                     Relu_50                  1 1 347 348\nSplit                    splitncnn_8              1 2 348 348_splitncnn_0 348_splitncnn_1\nConvolution              Conv_51                  1 1 348_splitncnn_1 351 0=88 1=3 4=1 5=1 6=69696 9=1\nConvolution              Conv_53                  1 1 351 567 0=88 1=3 4=1 5=1 6=69696\nBinaryOp                 Add_54                   2 1 567 348_splitncnn_0 354\nReLU                     Relu_55                  1 1 354 355\nSplit                    splitncnn_9              1 3 355 355_splitncnn_0 355_splitncnn_1 355_splitncnn_2\nConvolution              Conv_56                  1 1 355_splitncnn_2 358 0=224 1=3 3=2 4=1 5=1 6=177408 9=1\nConvolution              Conv_58                  1 1 358 573 0=224 1=3 4=1 5=1 6=451584\nPooling                  AveragePool_59           1 1 355_splitncnn_1 361 0=1 1=2 2=2\nConvolution              Conv_60                  1 1 361 576 0=224 1=1 5=1 6=19712\nBinaryOp                 Add_61                   2 1 573 576 364\nReLU                     Relu_62                  1 1 364 365\nSplit                    splitncnn_10             1 2 365 365_splitncnn_0 365_splitncnn_1\nConvolution              Conv_63                  1 1 365_splitncnn_1 368 0=224 1=3 4=1 5=1 6=451584 9=1\nConvolution              Conv_65                  1 1 368 582 0=224 1=3 4=1 5=1 6=451584\nBinaryOp                 Add_66                   2 1 582 365_splitncnn_0 371\nReLU                     Relu_67                  1 1 371 372\nSplit                    splitncnn_11             1 2 372 372_splitncnn_0 372_splitncnn_1\nConvolution              Conv_68                  1 1 372_splitncnn_1 375 0=224 1=3 4=1 5=1 6=451584 9=1\nConvolution              Conv_70                  1 1 375 588 0=224 1=3 4=1 5=1 6=451584\nBinaryOp                 Add_71                   2 1 588 372_splitncnn_0 378\nReLU                     Relu_72                  1 1 378 379\nConvolution              Conv_73                  1 1 338_splitncnn_0 380 0=56 1=1 5=1 6=4928\nConvolution              Conv_74                  1 1 355_splitncnn_0 381 0=56 1=1 5=1 6=4928\nConvolution              Conv_75                  1 1 379 382 0=56 1=1 5=1 6=12544\nSplit                    splitncnn_12             1 2 382 382_splitncnn_0 382_splitncnn_1\nInterp                   Resize_94                1 1 382_splitncnn_1 401 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_95                   2 1 381 401 402\nSplit                    splitncnn_13             1 2 402 402_splitncnn_0 402_splitncnn_1\nInterp                   Resize_114               1 1 402_splitncnn_1 421 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_115                  2 1 380 421 422\nConvolution              Conv_116                 1 1 422 423 0=56 1=3 4=1 5=1 6=28224\nSplit                    splitncnn_14             1 2 423 423_splitncnn_0 423_splitncnn_1\nConvolution              Conv_117                 1 1 402_splitncnn_0 424 0=56 1=3 4=1 5=1 6=28224\nConvolution              Conv_118                 1 1 382_splitncnn_0 425 0=56 1=3 4=1 5=1 6=28224\nConvolution              Conv_119                 1 1 423_splitncnn_1 426 0=56 1=3 3=2 4=1 5=1 6=28224\nBinaryOp                 Add_120                  2 1 424 426 427\nSplit                    splitncnn_15             1 2 427 427_splitncnn_0 427_splitncnn_1\nConvolution              Conv_121                 1 1 427_splitncnn_1 428 0=56 1=3 3=2 4=1 5=1 6=28224\nBinaryOp                 Add_122                  2 1 425 428 429\nConvolution              Conv_123                 1 1 427_splitncnn_0 430 0=56 1=3 4=1 5=1 6=28224\nConvolution              Conv_124                 1 1 429 431 0=56 1=3 4=1 5=1 6=28224\nConvolution              Conv_125                 1 1 423_splitncnn_0 434 0=80 1=3 4=1 5=1 6=40320 9=1\nConvolution              Conv_127                 1 1 434 437 0=80 1=3 4=1 5=1 6=57600 9=1\nConvolution              Conv_129                 1 1 437 440 0=80 1=3 4=1 5=1 6=57600 9=1\nSplit                    splitncnn_16             1 3 440 440_splitncnn_0 440_splitncnn_1 440_splitncnn_2\nConvolution              Conv_131                 1 1 440_splitncnn_2 447 0=2 1=3 4=1 5=1 6=1440\nConvolution              Conv_132                 1 1 440_splitncnn_1 442 0=8 1=3 4=1 5=1 6=5760\nBinaryOp                 Mul_133                  1 1 442 bbox_8 0=2 1=1 2=8.463594e-01\nConvolution              Conv_134                 1 1 440_splitncnn_0 kps_8 0=20 1=3 4=1 5=1 6=14400\nSigmoid                  Sigmoid_138              1 1 447 score_8\nConvolution              Conv_145                 1 1 430 457 0=80 1=3 4=1 5=1 6=40320 9=1\nConvolution              Conv_147                 1 1 457 460 0=80 1=3 4=1 5=1 6=57600 9=1\nConvolution              Conv_149                 1 1 460 463 0=80 1=3 4=1 5=1 6=57600 9=1\nSplit                    splitncnn_17             1 3 463 463_splitncnn_0 463_splitncnn_1 463_splitncnn_2\nConvolution              Conv_151                 1 1 463_splitncnn_2 470 0=2 1=3 4=1 5=1 6=1440\nConvolution              Conv_152                 1 1 463_splitncnn_1 465 0=8 1=3 4=1 5=1 6=5760\nBinaryOp                 Mul_153                  1 1 465 bbox_16 0=2 1=1 2=8.996264e-01\nConvolution              Conv_154                 1 1 463_splitncnn_0 kps_16 0=20 1=3 4=1 5=1 6=14400\nSigmoid                  Sigmoid_158              1 1 470 score_16\nConvolution              Conv_165                 1 1 431 480 0=80 1=3 4=1 5=1 6=40320 9=1\nConvolution              Conv_167                 1 1 480 483 0=80 1=3 4=1 5=1 6=57600 9=1\nConvolution              Conv_169                 1 1 483 486 0=80 1=3 4=1 5=1 6=57600 9=1\nSplit                    splitncnn_18             1 3 486 486_splitncnn_0 486_splitncnn_1 486_splitncnn_2\nConvolution              Conv_171                 1 1 486_splitncnn_2 493 0=2 1=3 4=1 5=1 6=1440\nConvolution              Conv_172                 1 1 486_splitncnn_1 488 0=8 1=3 4=1 5=1 6=5760\nBinaryOp                 Mul_173                  1 1 488 bbox_32 0=2 1=1 2=1.081209e+00\nConvolution              Conv_174                 1 1 486_splitncnn_0 kps_32 0=20 1=3 4=1 5=1 6=14400\nSigmoid                  Sigmoid_178              1 1 493 score_32\n"
  },
  {
    "path": "app/src/main/assets/scrfd_1g-opt2.param",
    "content": "7767517\n99 108\nInput                    input.1                  0 1 input.1\nConvolution              Conv_0                   1 1 input.1 193 0=32 1=3 3=2 4=1 5=1 6=864 9=1\nConvolutionDepthWise     Conv_2                   1 1 193 196 0=32 1=3 4=1 5=1 6=288 7=32 9=1\nConvolution              Conv_4                   1 1 196 199 0=48 1=1 5=1 6=1536 9=1\nConvolutionDepthWise     Conv_6                   1 1 199 202 0=48 1=3 3=2 4=1 5=1 6=432 7=48 9=1\nConvolution              Conv_8                   1 1 202 205 0=48 1=1 5=1 6=2304 9=1\nConvolutionDepthWise     Conv_10                  1 1 205 208 0=48 1=3 4=1 5=1 6=432 7=48 9=1\nConvolution              Conv_12                  1 1 208 211 0=48 1=1 5=1 6=2304 9=1\nConvolutionDepthWise     Conv_14                  1 1 211 214 0=48 1=3 4=1 5=1 6=432 7=48 9=1\nConvolution              Conv_16                  1 1 214 217 0=48 1=1 5=1 6=2304 9=1\nConvolutionDepthWise     Conv_18                  1 1 217 220 0=48 1=3 3=2 4=1 5=1 6=432 7=48 9=1\nConvolution              Conv_20                  1 1 220 223 0=160 1=1 5=1 6=7680 9=1\nConvolutionDepthWise     Conv_22                  1 1 223 226 0=160 1=3 4=1 5=1 6=1440 7=160 9=1\nConvolution              Conv_24                  1 1 226 229 0=160 1=1 5=1 6=25600 9=1\nSplit                    splitncnn_0              1 2 229 229_splitncnn_0 229_splitncnn_1\nConvolutionDepthWise     Conv_26                  1 1 229_splitncnn_1 232 0=160 1=3 3=2 4=1 5=1 6=1440 7=160 9=1\nConvolution              Conv_28                  1 1 232 235 0=216 1=1 5=1 6=34560 9=1\nSplit                    splitncnn_1              1 2 235 235_splitncnn_0 235_splitncnn_1\nConvolutionDepthWise     Conv_30                  1 1 235_splitncnn_1 238 0=216 1=3 3=2 4=1 5=1 6=1944 7=216 9=1\nConvolution              Conv_32                  1 1 238 241 0=312 1=1 5=1 6=67392 9=1\nConvolutionDepthWise     Conv_34                  1 1 241 244 0=312 1=3 4=1 5=1 6=2808 7=312 9=1\nConvolution              Conv_36                  1 1 244 247 0=312 1=1 5=1 6=97344 9=1\nConvolutionDepthWise     Conv_38                  1 1 247 250 0=312 1=3 4=1 5=1 6=2808 7=312 9=1\nConvolution              Conv_40                  1 1 250 253 0=312 1=1 5=1 6=97344 9=1\nConvolutionDepthWise     Conv_42                  1 1 253 256 0=312 1=3 4=1 5=1 6=2808 7=312 9=1\nConvolution              Conv_44                  1 1 256 259 0=312 1=1 5=1 6=97344 9=1\nConvolutionDepthWise     Conv_46                  1 1 259 262 0=312 1=3 4=1 5=1 6=2808 7=312 9=1\nConvolution              Conv_48                  1 1 262 265 0=312 1=1 5=1 6=97344 9=1\nConvolution              Conv_50                  1 1 229_splitncnn_0 266 0=24 1=1 5=1 6=3840\nConvolution              Conv_51                  1 1 235_splitncnn_0 267 0=24 1=1 5=1 6=5184\nConvolution              Conv_52                  1 1 265 268 0=24 1=1 5=1 6=7488\nSplit                    splitncnn_2              1 2 268 268_splitncnn_0 268_splitncnn_1\nInterp                   Resize_71                1 1 268_splitncnn_1 287 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_72                   2 1 267 287 288\nSplit                    splitncnn_3              1 2 288 288_splitncnn_0 288_splitncnn_1\nInterp                   Resize_91                1 1 288_splitncnn_1 307 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_92                   2 1 266 307 308\nConvolution              Conv_93                  1 1 308 309 0=24 1=3 4=1 5=1 6=5184\nSplit                    splitncnn_4              1 2 309 309_splitncnn_0 309_splitncnn_1\nConvolution              Conv_94                  1 1 288_splitncnn_0 310 0=24 1=3 4=1 5=1 6=5184\nConvolution              Conv_95                  1 1 268_splitncnn_0 311 0=24 1=3 4=1 5=1 6=5184\nConvolution              Conv_96                  1 1 309_splitncnn_1 312 0=24 1=3 3=2 4=1 5=1 6=5184\nBinaryOp                 Add_97                   2 1 310 312 313\nSplit                    splitncnn_5              1 2 313 313_splitncnn_0 313_splitncnn_1\nConvolution              Conv_98                  1 1 313_splitncnn_1 314 0=24 1=3 3=2 4=1 5=1 6=5184\nBinaryOp                 Add_99                   2 1 311 314 315\nConvolution              Conv_100                 1 1 313_splitncnn_0 316 0=24 1=3 4=1 5=1 6=5184\nConvolution              Conv_101                 1 1 315 317 0=24 1=3 4=1 5=1 6=5184\nConvolutionDepthWise     Conv_102                 1 1 309_splitncnn_0 318 0=24 1=3 4=1 6=216 7=24\nGroupNorm                Add_111                  1 1 318 329 0=8 1=24 2=1.000000e-05\nReLU                     Relu_112                 1 1 329 330\nConvolution              Conv_113                 1 1 330 331 0=96 1=1 6=2304\nGroupNorm                Add_122                  1 1 331 342 0=8 1=96 2=1.000000e-05\nReLU                     Relu_123                 1 1 342 343\nConvolutionDepthWise     Conv_124                 1 1 343 344 0=96 1=3 4=1 6=864 7=96\nGroupNorm                Add_133                  1 1 344 355 0=8 1=96 2=1.000000e-05\nReLU                     Relu_134                 1 1 355 356\nConvolution              Conv_135                 1 1 356 357 0=96 1=1 6=9216\nGroupNorm                Add_144                  1 1 357 368 0=8 1=96 2=1.000000e-05\nReLU                     Relu_145                 1 1 368 369\nSplit                    splitncnn_6              1 2 369 369_splitncnn_0 369_splitncnn_1\nConvolution              Conv_146                 1 1 369_splitncnn_1 375 0=2 1=3 4=1 5=1 6=1728\nConvolution              Conv_147                 1 1 369_splitncnn_0 371 0=8 1=3 4=1 5=1 6=6912\nBinaryOp                 Mul_148                  1 1 371 bbox_8 0=2 1=1 2=8.200800e-01\nSigmoid                  Sigmoid_152              1 1 375 score_8\nConvolutionDepthWise     Conv_156                 1 1 316 380 0=24 1=3 4=1 6=216 7=24\nGroupNorm                Add_165                  1 1 380 391 0=8 1=24 2=1.000000e-05\nReLU                     Relu_166                 1 1 391 392\nConvolution              Conv_167                 1 1 392 393 0=96 1=1 6=2304\nGroupNorm                Add_176                  1 1 393 404 0=8 1=96 2=1.000000e-05\nReLU                     Relu_177                 1 1 404 405\nConvolutionDepthWise     Conv_178                 1 1 405 406 0=96 1=3 4=1 6=864 7=96\nGroupNorm                Add_187                  1 1 406 417 0=8 1=96 2=1.000000e-05\nReLU                     Relu_188                 1 1 417 418\nConvolution              Conv_189                 1 1 418 419 0=96 1=1 6=9216\nGroupNorm                Add_198                  1 1 419 430 0=8 1=96 2=1.000000e-05\nReLU                     Relu_199                 1 1 430 431\nSplit                    splitncnn_7              1 2 431 431_splitncnn_0 431_splitncnn_1\nConvolution              Conv_200                 1 1 431_splitncnn_1 437 0=2 1=3 4=1 5=1 6=1728\nConvolution              Conv_201                 1 1 431_splitncnn_0 433 0=8 1=3 4=1 5=1 6=6912\nBinaryOp                 Mul_202                  1 1 433 bbox_16 0=2 1=1 2=1.225648e+00\nSigmoid                  Sigmoid_206              1 1 437 score_16\nConvolutionDepthWise     Conv_210                 1 1 317 442 0=24 1=3 4=1 6=216 7=24\nGroupNorm                Add_219                  1 1 442 453 0=8 1=24 2=1.000000e-05\nReLU                     Relu_220                 1 1 453 454\nConvolution              Conv_221                 1 1 454 455 0=96 1=1 6=2304\nGroupNorm                Add_230                  1 1 455 466 0=8 1=96 2=1.000000e-05\nReLU                     Relu_231                 1 1 466 467\nConvolutionDepthWise     Conv_232                 1 1 467 468 0=96 1=3 4=1 6=864 7=96\nGroupNorm                Add_241                  1 1 468 479 0=8 1=96 2=1.000000e-05\nReLU                     Relu_242                 1 1 479 480\nConvolution              Conv_243                 1 1 480 481 0=96 1=1 6=9216\nGroupNorm                Add_252                  1 1 481 492 0=8 1=96 2=1.000000e-05\nReLU                     Relu_253                 1 1 492 493\nSplit                    splitncnn_8              1 2 493 493_splitncnn_0 493_splitncnn_1\nConvolution              Conv_254                 1 1 493_splitncnn_1 499 0=2 1=3 4=1 5=1 6=1728\nConvolution              Conv_255                 1 1 493_splitncnn_0 495 0=8 1=3 4=1 5=1 6=6912\nBinaryOp                 Mul_256                  1 1 495 bbox_32 0=2 1=1 2=1.842380e+00\nSigmoid                  Sigmoid_260              1 1 499 score_32\n"
  },
  {
    "path": "app/src/main/assets/scrfd_2.5g-opt2.param",
    "content": "7767517\n129 151\nInput                    input.1                  0 1 input.1\nConvolution              Conv_0                   1 1 input.1 229 0=12 1=3 3=2 4=1 5=1 6=324 9=1\nConvolution              Conv_2                   1 1 229 232 0=12 1=3 4=1 5=1 6=1296 9=1\nConvolution              Conv_4                   1 1 232 235 0=24 1=3 4=1 5=1 6=2592 9=1\nPooling                  MaxPool_6                1 1 235 236 1=2 2=2 5=1\nSplit                    splitncnn_0              1 2 236 236_splitncnn_0 236_splitncnn_1\nConvolution              Conv_7                   1 1 236_splitncnn_1 239 0=24 1=3 4=1 5=1 6=5184 9=1\nConvolution              Conv_9                   1 1 239 509 0=24 1=3 4=1 5=1 6=5184\nBinaryOp                 Add_10                   2 1 509 236_splitncnn_0 242\nReLU                     Relu_11                  1 1 242 243\nSplit                    splitncnn_1              1 2 243 243_splitncnn_0 243_splitncnn_1\nConvolution              Conv_12                  1 1 243_splitncnn_1 246 0=24 1=3 4=1 5=1 6=5184 9=1\nConvolution              Conv_14                  1 1 246 515 0=24 1=3 4=1 5=1 6=5184\nBinaryOp                 Add_15                   2 1 515 243_splitncnn_0 249\nReLU                     Relu_16                  1 1 249 250\nSplit                    splitncnn_2              1 2 250 250_splitncnn_0 250_splitncnn_1\nConvolution              Conv_17                  1 1 250_splitncnn_1 253 0=24 1=3 4=1 5=1 6=5184 9=1\nConvolution              Conv_19                  1 1 253 521 0=24 1=3 4=1 5=1 6=5184\nBinaryOp                 Add_20                   2 1 521 250_splitncnn_0 256\nReLU                     Relu_21                  1 1 256 257\nSplit                    splitncnn_3              1 2 257 257_splitncnn_0 257_splitncnn_1\nConvolution              Conv_22                  1 1 257_splitncnn_1 260 0=48 1=3 3=2 4=1 5=1 6=10368 9=1\nConvolution              Conv_24                  1 1 260 527 0=48 1=3 4=1 5=1 6=20736\nPooling                  AveragePool_25           1 1 257_splitncnn_0 263 0=1 1=2 2=2\nConvolution              Conv_26                  1 1 263 530 0=48 1=1 5=1 6=1152\nBinaryOp                 Add_27                   2 1 527 530 266\nReLU                     Relu_28                  1 1 266 267\nSplit                    splitncnn_4              1 2 267 267_splitncnn_0 267_splitncnn_1\nConvolution              Conv_29                  1 1 267_splitncnn_1 270 0=48 1=3 4=1 5=1 6=20736 9=1\nConvolution              Conv_31                  1 1 270 536 0=48 1=3 4=1 5=1 6=20736\nBinaryOp                 Add_32                   2 1 536 267_splitncnn_0 273\nReLU                     Relu_33                  1 1 273 274\nSplit                    splitncnn_5              1 2 274 274_splitncnn_0 274_splitncnn_1\nConvolution              Conv_34                  1 1 274_splitncnn_1 277 0=48 1=3 4=1 5=1 6=20736 9=1\nConvolution              Conv_36                  1 1 277 542 0=48 1=3 4=1 5=1 6=20736\nBinaryOp                 Add_37                   2 1 542 274_splitncnn_0 280\nReLU                     Relu_38                  1 1 280 281\nSplit                    splitncnn_6              1 2 281 281_splitncnn_0 281_splitncnn_1\nConvolution              Conv_39                  1 1 281_splitncnn_1 284 0=48 1=3 4=1 5=1 6=20736 9=1\nConvolution              Conv_41                  1 1 284 548 0=48 1=3 4=1 5=1 6=20736\nBinaryOp                 Add_42                   2 1 548 281_splitncnn_0 287\nReLU                     Relu_43                  1 1 287 288\nSplit                    splitncnn_7              1 2 288 288_splitncnn_0 288_splitncnn_1\nConvolution              Conv_44                  1 1 288_splitncnn_1 291 0=48 1=3 4=1 5=1 6=20736 9=1\nConvolution              Conv_46                  1 1 291 554 0=48 1=3 4=1 5=1 6=20736\nBinaryOp                 Add_47                   2 1 554 288_splitncnn_0 294\nReLU                     Relu_48                  1 1 294 295\nSplit                    splitncnn_8              1 3 295 295_splitncnn_0 295_splitncnn_1 295_splitncnn_2\nConvolution              Conv_49                  1 1 295_splitncnn_2 298 0=48 1=3 3=2 4=1 5=1 6=20736 9=1\nConvolution              Conv_51                  1 1 298 560 0=48 1=3 4=1 5=1 6=20736\nPooling                  AveragePool_52           1 1 295_splitncnn_1 301 0=1 1=2 2=2\nConvolution              Conv_53                  1 1 301 563 0=48 1=1 5=1 6=2304\nBinaryOp                 Add_54                   2 1 560 563 304\nReLU                     Relu_55                  1 1 304 305\nSplit                    splitncnn_9              1 2 305 305_splitncnn_0 305_splitncnn_1\nConvolution              Conv_56                  1 1 305_splitncnn_1 308 0=48 1=3 4=1 5=1 6=20736 9=1\nConvolution              Conv_58                  1 1 308 569 0=48 1=3 4=1 5=1 6=20736\nBinaryOp                 Add_59                   2 1 569 305_splitncnn_0 311\nReLU                     Relu_60                  1 1 311 312\nSplit                    splitncnn_10             1 2 312 312_splitncnn_0 312_splitncnn_1\nConvolution              Conv_61                  1 1 312_splitncnn_1 315 0=48 1=3 4=1 5=1 6=20736 9=1\nConvolution              Conv_63                  1 1 315 575 0=48 1=3 4=1 5=1 6=20736\nBinaryOp                 Add_64                   2 1 575 312_splitncnn_0 318\nReLU                     Relu_65                  1 1 318 319\nSplit                    splitncnn_11             1 3 319 319_splitncnn_0 319_splitncnn_1 319_splitncnn_2\nConvolution              Conv_66                  1 1 319_splitncnn_2 322 0=80 1=3 3=2 4=1 5=1 6=34560 9=1\nConvolution              Conv_68                  1 1 322 581 0=80 1=3 4=1 5=1 6=57600\nPooling                  AveragePool_69           1 1 319_splitncnn_1 325 0=1 1=2 2=2\nConvolution              Conv_70                  1 1 325 584 0=80 1=1 5=1 6=3840\nBinaryOp                 Add_71                   2 1 581 584 328\nReLU                     Relu_72                  1 1 328 329\nSplit                    splitncnn_12             1 2 329 329_splitncnn_0 329_splitncnn_1\nConvolution              Conv_73                  1 1 329_splitncnn_1 332 0=80 1=3 4=1 5=1 6=57600 9=1\nConvolution              Conv_75                  1 1 332 590 0=80 1=3 4=1 5=1 6=57600\nBinaryOp                 Add_76                   2 1 590 329_splitncnn_0 335\nReLU                     Relu_77                  1 1 335 336\nConvolution              Conv_78                  1 1 295_splitncnn_0 337 0=24 1=1 5=1 6=1152\nConvolution              Conv_79                  1 1 319_splitncnn_0 338 0=24 1=1 5=1 6=1152\nConvolution              Conv_80                  1 1 336 339 0=24 1=1 5=1 6=1920\nSplit                    splitncnn_13             1 2 339 339_splitncnn_0 339_splitncnn_1\nInterp                   Resize_99                1 1 339_splitncnn_1 358 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_100                  2 1 338 358 359\nSplit                    splitncnn_14             1 2 359 359_splitncnn_0 359_splitncnn_1\nInterp                   Resize_119               1 1 359_splitncnn_1 378 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_120                  2 1 337 378 379\nConvolution              Conv_121                 1 1 379 380 0=24 1=3 4=1 5=1 6=5184\nSplit                    splitncnn_15             1 2 380 380_splitncnn_0 380_splitncnn_1\nConvolution              Conv_122                 1 1 359_splitncnn_0 381 0=24 1=3 4=1 5=1 6=5184\nConvolution              Conv_123                 1 1 339_splitncnn_0 382 0=24 1=3 4=1 5=1 6=5184\nConvolution              Conv_124                 1 1 380_splitncnn_1 383 0=24 1=3 3=2 4=1 5=1 6=5184\nBinaryOp                 Add_125                  2 1 381 383 384\nSplit                    splitncnn_16             1 2 384 384_splitncnn_0 384_splitncnn_1\nConvolution              Conv_126                 1 1 384_splitncnn_1 385 0=24 1=3 3=2 4=1 5=1 6=5184\nBinaryOp                 Add_127                  2 1 382 385 386\nConvolution              Conv_128                 1 1 384_splitncnn_0 387 0=24 1=3 4=1 5=1 6=5184\nConvolution              Conv_129                 1 1 386 388 0=24 1=3 4=1 5=1 6=5184\nConvolution              Conv_130                 1 1 380_splitncnn_0 389 0=64 1=3 4=1 6=13824\nGroupNorm                Add_139                  1 1 389 400 0=16 1=64 2=1.000000e-05\nReLU                     Relu_140                 1 1 400 401\nConvolution              Conv_141                 1 1 401 402 0=64 1=3 4=1 6=36864\nGroupNorm                Add_150                  1 1 402 413 0=16 1=64 2=1.000000e-05\nReLU                     Relu_151                 1 1 413 414\nSplit                    splitncnn_17             1 2 414 414_splitncnn_0 414_splitncnn_1\nConvolution              Conv_152                 1 1 414_splitncnn_1 420 0=2 1=3 4=1 5=1 6=1152\nConvolution              Conv_153                 1 1 414_splitncnn_0 416 0=8 1=3 4=1 5=1 6=4608\nBinaryOp                 Mul_154                  1 1 416 bbox_8 0=2 1=1 2=8.394209e-01\nSigmoid                  Sigmoid_158              1 1 420 score_8\nConvolution              Conv_162                 1 1 387 425 0=64 1=3 4=1 6=13824\nGroupNorm                Add_171                  1 1 425 436 0=16 1=64 2=1.000000e-05\nReLU                     Relu_172                 1 1 436 437\nConvolution              Conv_173                 1 1 437 438 0=64 1=3 4=1 6=36864\nGroupNorm                Add_182                  1 1 438 449 0=16 1=64 2=1.000000e-05\nReLU                     Relu_183                 1 1 449 450\nSplit                    splitncnn_18             1 2 450 450_splitncnn_0 450_splitncnn_1\nConvolution              Conv_184                 1 1 450_splitncnn_1 456 0=2 1=3 4=1 5=1 6=1152\nConvolution              Conv_185                 1 1 450_splitncnn_0 452 0=8 1=3 4=1 5=1 6=4608\nBinaryOp                 Mul_186                  1 1 452 bbox_16 0=2 1=1 2=1.251327e+00\nSigmoid                  Sigmoid_190              1 1 456 score_16\nConvolution              Conv_194                 1 1 388 461 0=64 1=3 4=1 6=13824\nGroupNorm                Add_203                  1 1 461 472 0=16 1=64 2=1.000000e-05\nReLU                     Relu_204                 1 1 472 473\nConvolution              Conv_205                 1 1 473 474 0=64 1=3 4=1 6=36864\nGroupNorm                Add_214                  1 1 474 485 0=16 1=64 2=1.000000e-05\nReLU                     Relu_215                 1 1 485 486\nSplit                    splitncnn_19             1 2 486 486_splitncnn_0 486_splitncnn_1\nConvolution              Conv_216                 1 1 486_splitncnn_1 492 0=2 1=3 4=1 5=1 6=1152\nConvolution              Conv_217                 1 1 486_splitncnn_0 488 0=8 1=3 4=1 5=1 6=4608\nBinaryOp                 Mul_218                  1 1 488 bbox_32 0=2 1=1 2=1.961941e+00\nSigmoid                  Sigmoid_222              1 1 492 score_32\n"
  },
  {
    "path": "app/src/main/assets/scrfd_2.5g_kps-opt2.param",
    "content": "7767517\n120 145\nInput                    input.1                  0 1 input.1\nConvolution              Conv_0                   1 1 input.1 273 0=12 1=3 3=2 4=1 5=1 6=324 9=1\nConvolution              Conv_2                   1 1 273 276 0=12 1=3 4=1 5=1 6=1296 9=1\nConvolution              Conv_4                   1 1 276 279 0=24 1=3 4=1 5=1 6=2592 9=1\nPooling                  MaxPool_6                1 1 279 280 1=2 2=2 5=1\nSplit                    splitncnn_0              1 2 280 280_splitncnn_0 280_splitncnn_1\nConvolution              Conv_7                   1 1 280_splitncnn_1 283 0=24 1=3 4=1 5=1 6=5184 9=1\nConvolution              Conv_9                   1 1 283 505 0=24 1=3 4=1 5=1 6=5184\nBinaryOp                 Add_10                   2 1 505 280_splitncnn_0 286\nReLU                     Relu_11                  1 1 286 287\nSplit                    splitncnn_1              1 2 287 287_splitncnn_0 287_splitncnn_1\nConvolution              Conv_12                  1 1 287_splitncnn_1 290 0=24 1=3 4=1 5=1 6=5184 9=1\nConvolution              Conv_14                  1 1 290 511 0=24 1=3 4=1 5=1 6=5184\nBinaryOp                 Add_15                   2 1 511 287_splitncnn_0 293\nReLU                     Relu_16                  1 1 293 294\nSplit                    splitncnn_2              1 2 294 294_splitncnn_0 294_splitncnn_1\nConvolution              Conv_17                  1 1 294_splitncnn_1 297 0=24 1=3 4=1 5=1 6=5184 9=1\nConvolution              Conv_19                  1 1 297 517 0=24 1=3 4=1 5=1 6=5184\nBinaryOp                 Add_20                   2 1 517 294_splitncnn_0 300\nReLU                     Relu_21                  1 1 300 301\nSplit                    splitncnn_3              1 2 301 301_splitncnn_0 301_splitncnn_1\nConvolution              Conv_22                  1 1 301_splitncnn_1 304 0=48 1=3 3=2 4=1 5=1 6=10368 9=1\nConvolution              Conv_24                  1 1 304 523 0=48 1=3 4=1 5=1 6=20736\nPooling                  AveragePool_25           1 1 301_splitncnn_0 307 0=1 1=2 2=2\nConvolution              Conv_26                  1 1 307 526 0=48 1=1 5=1 6=1152\nBinaryOp                 Add_27                   2 1 523 526 310\nReLU                     Relu_28                  1 1 310 311\nSplit                    splitncnn_4              1 2 311 311_splitncnn_0 311_splitncnn_1\nConvolution              Conv_29                  1 1 311_splitncnn_1 314 0=48 1=3 4=1 5=1 6=20736 9=1\nConvolution              Conv_31                  1 1 314 532 0=48 1=3 4=1 5=1 6=20736\nBinaryOp                 Add_32                   2 1 532 311_splitncnn_0 317\nReLU                     Relu_33                  1 1 317 318\nSplit                    splitncnn_5              1 2 318 318_splitncnn_0 318_splitncnn_1\nConvolution              Conv_34                  1 1 318_splitncnn_1 321 0=48 1=3 4=1 5=1 6=20736 9=1\nConvolution              Conv_36                  1 1 321 538 0=48 1=3 4=1 5=1 6=20736\nBinaryOp                 Add_37                   2 1 538 318_splitncnn_0 324\nReLU                     Relu_38                  1 1 324 325\nSplit                    splitncnn_6              1 2 325 325_splitncnn_0 325_splitncnn_1\nConvolution              Conv_39                  1 1 325_splitncnn_1 328 0=48 1=3 4=1 5=1 6=20736 9=1\nConvolution              Conv_41                  1 1 328 544 0=48 1=3 4=1 5=1 6=20736\nBinaryOp                 Add_42                   2 1 544 325_splitncnn_0 331\nReLU                     Relu_43                  1 1 331 332\nSplit                    splitncnn_7              1 2 332 332_splitncnn_0 332_splitncnn_1\nConvolution              Conv_44                  1 1 332_splitncnn_1 335 0=48 1=3 4=1 5=1 6=20736 9=1\nConvolution              Conv_46                  1 1 335 550 0=48 1=3 4=1 5=1 6=20736\nBinaryOp                 Add_47                   2 1 550 332_splitncnn_0 338\nReLU                     Relu_48                  1 1 338 339\nSplit                    splitncnn_8              1 3 339 339_splitncnn_0 339_splitncnn_1 339_splitncnn_2\nConvolution              Conv_49                  1 1 339_splitncnn_2 342 0=48 1=3 3=2 4=1 5=1 6=20736 9=1\nConvolution              Conv_51                  1 1 342 556 0=48 1=3 4=1 5=1 6=20736\nPooling                  AveragePool_52           1 1 339_splitncnn_1 345 0=1 1=2 2=2\nConvolution              Conv_53                  1 1 345 559 0=48 1=1 5=1 6=2304\nBinaryOp                 Add_54                   2 1 556 559 348\nReLU                     Relu_55                  1 1 348 349\nSplit                    splitncnn_9              1 2 349 349_splitncnn_0 349_splitncnn_1\nConvolution              Conv_56                  1 1 349_splitncnn_1 352 0=48 1=3 4=1 5=1 6=20736 9=1\nConvolution              Conv_58                  1 1 352 565 0=48 1=3 4=1 5=1 6=20736\nBinaryOp                 Add_59                   2 1 565 349_splitncnn_0 355\nReLU                     Relu_60                  1 1 355 356\nSplit                    splitncnn_10             1 2 356 356_splitncnn_0 356_splitncnn_1\nConvolution              Conv_61                  1 1 356_splitncnn_1 359 0=48 1=3 4=1 5=1 6=20736 9=1\nConvolution              Conv_63                  1 1 359 571 0=48 1=3 4=1 5=1 6=20736\nBinaryOp                 Add_64                   2 1 571 356_splitncnn_0 362\nReLU                     Relu_65                  1 1 362 363\nSplit                    splitncnn_11             1 3 363 363_splitncnn_0 363_splitncnn_1 363_splitncnn_2\nConvolution              Conv_66                  1 1 363_splitncnn_2 366 0=80 1=3 3=2 4=1 5=1 6=34560 9=1\nConvolution              Conv_68                  1 1 366 577 0=80 1=3 4=1 5=1 6=57600\nPooling                  AveragePool_69           1 1 363_splitncnn_1 369 0=1 1=2 2=2\nConvolution              Conv_70                  1 1 369 580 0=80 1=1 5=1 6=3840\nBinaryOp                 Add_71                   2 1 577 580 372\nReLU                     Relu_72                  1 1 372 373\nSplit                    splitncnn_12             1 2 373 373_splitncnn_0 373_splitncnn_1\nConvolution              Conv_73                  1 1 373_splitncnn_1 376 0=80 1=3 4=1 5=1 6=57600 9=1\nConvolution              Conv_75                  1 1 376 586 0=80 1=3 4=1 5=1 6=57600\nBinaryOp                 Add_76                   2 1 586 373_splitncnn_0 379\nReLU                     Relu_77                  1 1 379 380\nConvolution              Conv_78                  1 1 339_splitncnn_0 381 0=24 1=1 5=1 6=1152\nConvolution              Conv_79                  1 1 363_splitncnn_0 382 0=24 1=1 5=1 6=1152\nConvolution              Conv_80                  1 1 380 383 0=24 1=1 5=1 6=1920\nSplit                    splitncnn_13             1 2 383 383_splitncnn_0 383_splitncnn_1\nInterp                   Resize_99                1 1 383_splitncnn_1 402 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_100                  2 1 382 402 403\nSplit                    splitncnn_14             1 2 403 403_splitncnn_0 403_splitncnn_1\nInterp                   Resize_119               1 1 403_splitncnn_1 422 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_120                  2 1 381 422 423\nConvolution              Conv_121                 1 1 423 424 0=24 1=3 4=1 5=1 6=5184\nSplit                    splitncnn_15             1 2 424 424_splitncnn_0 424_splitncnn_1\nConvolution              Conv_122                 1 1 403_splitncnn_0 425 0=24 1=3 4=1 5=1 6=5184\nConvolution              Conv_123                 1 1 383_splitncnn_0 426 0=24 1=3 4=1 5=1 6=5184\nConvolution              Conv_124                 1 1 424_splitncnn_1 427 0=24 1=3 3=2 4=1 5=1 6=5184\nBinaryOp                 Add_125                  2 1 425 427 428\nSplit                    splitncnn_16             1 2 428 428_splitncnn_0 428_splitncnn_1\nConvolution              Conv_126                 1 1 428_splitncnn_1 429 0=24 1=3 3=2 4=1 5=1 6=5184\nBinaryOp                 Add_127                  2 1 426 429 430\nConvolution              Conv_128                 1 1 428_splitncnn_0 431 0=24 1=3 4=1 5=1 6=5184\nConvolution              Conv_129                 1 1 430 432 0=24 1=3 4=1 5=1 6=5184\nConvolution              Conv_130                 1 1 424_splitncnn_0 435 0=64 1=3 4=1 5=1 6=13824 9=1\nConvolution              Conv_132                 1 1 435 438 0=64 1=3 4=1 5=1 6=36864 9=1\nSplit                    splitncnn_17             1 3 438 438_splitncnn_0 438_splitncnn_1 438_splitncnn_2\nConvolution              Conv_134                 1 1 438_splitncnn_2 445 0=2 1=3 4=1 5=1 6=1152\nConvolution              Conv_135                 1 1 438_splitncnn_1 440 0=8 1=3 4=1 5=1 6=4608\nBinaryOp                 Mul_136                  1 1 440 bbox_8 0=2 1=1 2=8.807251e-01\nConvolution              Conv_137                 1 1 438_splitncnn_0 kps_8 0=20 1=3 4=1 5=1 6=11520\nSigmoid                  Sigmoid_141              1 1 445 score_8\nConvolution              Conv_148                 1 1 431 455 0=64 1=3 4=1 5=1 6=13824 9=1\nConvolution              Conv_150                 1 1 455 458 0=64 1=3 4=1 5=1 6=36864 9=1\nSplit                    splitncnn_18             1 3 458 458_splitncnn_0 458_splitncnn_1 458_splitncnn_2\nConvolution              Conv_152                 1 1 458_splitncnn_2 465 0=2 1=3 4=1 5=1 6=1152\nConvolution              Conv_153                 1 1 458_splitncnn_1 460 0=8 1=3 4=1 5=1 6=4608\nBinaryOp                 Mul_154                  1 1 460 bbox_16 0=2 1=1 2=9.315465e-01\nConvolution              Conv_155                 1 1 458_splitncnn_0 kps_16 0=20 1=3 4=1 5=1 6=11520\nSigmoid                  Sigmoid_159              1 1 465 score_16\nConvolution              Conv_166                 1 1 432 475 0=64 1=3 4=1 5=1 6=13824 9=1\nConvolution              Conv_168                 1 1 475 478 0=64 1=3 4=1 5=1 6=36864 9=1\nSplit                    splitncnn_19             1 3 478 478_splitncnn_0 478_splitncnn_1 478_splitncnn_2\nConvolution              Conv_170                 1 1 478_splitncnn_2 485 0=2 1=3 4=1 5=1 6=1152\nConvolution              Conv_171                 1 1 478_splitncnn_1 480 0=8 1=3 4=1 5=1 6=4608\nBinaryOp                 Mul_172                  1 1 480 bbox_32 0=2 1=1 2=1.142366e+00\nConvolution              Conv_173                 1 1 478_splitncnn_0 kps_32 0=20 1=3 4=1 5=1 6=11520\nSigmoid                  Sigmoid_177              1 1 485 score_32\n"
  },
  {
    "path": "app/src/main/assets/scrfd_34g-opt2.param",
    "content": "7767517\n323 375\nInput                    input.1                  0 1 input.1\nConvolution              Conv_0                   1 1 input.1 853 0=28 1=3 3=2 4=1 5=1 6=756 9=1\nConvolution              Conv_2                   1 1 853 856 0=28 1=3 4=1 5=1 6=7056 9=1\nConvolution              Conv_4                   1 1 856 859 0=56 1=3 4=1 5=1 6=14112 9=1\nPooling                  MaxPool_6                1 1 859 860 1=2 2=2 5=1\nSplit                    splitncnn_0              1 2 860 869 860_splitncnn_1\nConvolution              Conv_7                   1 1 860_splitncnn_1 863 0=56 1=1 5=1 6=3136 9=1\nConvolution              Conv_9                   1 1 863 866 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_11                  1 1 866 1478 0=224 1=1 5=1 6=12544\nConvolution              Conv_13                  1 1 869 1481 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_14                   2 1 1478 1481 872\nReLU                     Relu_15                  1 1 872 873\nSplit                    splitncnn_1              1 2 873 873_splitncnn_0 873_splitncnn_1\nConvolution              Conv_16                  1 1 873_splitncnn_1 876 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_18                  1 1 876 879 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_20                  1 1 879 1490 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_21                   2 1 1490 873_splitncnn_0 882\nReLU                     Relu_22                  1 1 882 883\nSplit                    splitncnn_2              1 2 883 883_splitncnn_0 883_splitncnn_1\nConvolution              Conv_23                  1 1 883_splitncnn_1 886 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_25                  1 1 886 889 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_27                  1 1 889 1499 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_28                   2 1 1499 883_splitncnn_0 892\nReLU                     Relu_29                  1 1 892 893\nSplit                    splitncnn_3              1 2 893 893_splitncnn_0 893_splitncnn_1\nConvolution              Conv_30                  1 1 893_splitncnn_1 896 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_32                  1 1 896 899 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_34                  1 1 899 1508 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_35                   2 1 1508 893_splitncnn_0 902\nReLU                     Relu_36                  1 1 902 903\nSplit                    splitncnn_4              1 2 903 903_splitncnn_0 903_splitncnn_1\nConvolution              Conv_37                  1 1 903_splitncnn_1 906 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_39                  1 1 906 909 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_41                  1 1 909 1517 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_42                   2 1 1517 903_splitncnn_0 912\nReLU                     Relu_43                  1 1 912 913\nSplit                    splitncnn_5              1 2 913 913_splitncnn_0 913_splitncnn_1\nConvolution              Conv_44                  1 1 913_splitncnn_1 916 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_46                  1 1 916 919 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_48                  1 1 919 1526 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_49                   2 1 1526 913_splitncnn_0 922\nReLU                     Relu_50                  1 1 922 923\nSplit                    splitncnn_6              1 2 923 923_splitncnn_0 923_splitncnn_1\nConvolution              Conv_51                  1 1 923_splitncnn_1 926 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_53                  1 1 926 929 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_55                  1 1 929 1535 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_56                   2 1 1535 923_splitncnn_0 932\nReLU                     Relu_57                  1 1 932 933\nSplit                    splitncnn_7              1 2 933 933_splitncnn_0 933_splitncnn_1\nConvolution              Conv_58                  1 1 933_splitncnn_1 936 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_60                  1 1 936 939 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_62                  1 1 939 1544 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_63                   2 1 1544 933_splitncnn_0 942\nReLU                     Relu_64                  1 1 942 943\nSplit                    splitncnn_8              1 2 943 943_splitncnn_0 943_splitncnn_1\nConvolution              Conv_65                  1 1 943_splitncnn_1 946 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_67                  1 1 946 949 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_69                  1 1 949 1553 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_70                   2 1 1553 943_splitncnn_0 952\nReLU                     Relu_71                  1 1 952 953\nSplit                    splitncnn_9              1 2 953 953_splitncnn_0 953_splitncnn_1\nConvolution              Conv_72                  1 1 953_splitncnn_1 956 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_74                  1 1 956 959 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_76                  1 1 959 1562 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_77                   2 1 1562 953_splitncnn_0 962\nReLU                     Relu_78                  1 1 962 963\nSplit                    splitncnn_10             1 2 963 963_splitncnn_0 963_splitncnn_1\nConvolution              Conv_79                  1 1 963_splitncnn_1 966 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_81                  1 1 966 969 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_83                  1 1 969 1571 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_84                   2 1 1571 963_splitncnn_0 972\nReLU                     Relu_85                  1 1 972 973\nSplit                    splitncnn_11             1 2 973 973_splitncnn_0 973_splitncnn_1\nConvolution              Conv_86                  1 1 973_splitncnn_1 976 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_88                  1 1 976 979 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_90                  1 1 979 1580 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_91                   2 1 1580 973_splitncnn_0 982\nReLU                     Relu_92                  1 1 982 983\nSplit                    splitncnn_12             1 2 983 983_splitncnn_0 983_splitncnn_1\nConvolution              Conv_93                  1 1 983_splitncnn_1 986 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_95                  1 1 986 989 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_97                  1 1 989 1589 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_98                   2 1 1589 983_splitncnn_0 992\nReLU                     Relu_99                  1 1 992 993\nSplit                    splitncnn_13             1 2 993 993_splitncnn_0 993_splitncnn_1\nConvolution              Conv_100                 1 1 993_splitncnn_1 996 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_102                 1 1 996 999 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_104                 1 1 999 1598 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_105                  2 1 1598 993_splitncnn_0 1002\nReLU                     Relu_106                 1 1 1002 1003\nSplit                    splitncnn_14             1 2 1003 1003_splitncnn_0 1003_splitncnn_1\nConvolution              Conv_107                 1 1 1003_splitncnn_1 1006 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_109                 1 1 1006 1009 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_111                 1 1 1009 1607 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_112                  2 1 1607 1003_splitncnn_0 1012\nReLU                     Relu_113                 1 1 1012 1013\nSplit                    splitncnn_15             1 2 1013 1013_splitncnn_0 1013_splitncnn_1\nConvolution              Conv_114                 1 1 1013_splitncnn_1 1016 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_116                 1 1 1016 1019 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_118                 1 1 1019 1616 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_119                  2 1 1616 1013_splitncnn_0 1022\nReLU                     Relu_120                 1 1 1022 1023\nSplit                    splitncnn_16             1 2 1023 1023_splitncnn_0 1023_splitncnn_1\nConvolution              Conv_121                 1 1 1023_splitncnn_1 1026 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_123                 1 1 1026 1029 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_125                 1 1 1029 1625 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_126                  2 1 1625 1023_splitncnn_0 1032\nReLU                     Relu_127                 1 1 1032 1033\nSplit                    splitncnn_17             1 2 1033 1033_splitncnn_0 1033_splitncnn_1\nConvolution              Conv_128                 1 1 1033_splitncnn_1 1036 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_130                 1 1 1036 1039 0=56 1=3 3=2 4=1 5=1 6=28224 9=1\nConvolution              Conv_132                 1 1 1039 1634 0=224 1=1 5=1 6=12544\nPooling                  AveragePool_133          1 1 1033_splitncnn_0 1042 0=1 1=2 2=2\nConvolution              Conv_134                 1 1 1042 1637 0=224 1=1 5=1 6=50176\nBinaryOp                 Add_135                  2 1 1634 1637 1045\nReLU                     Relu_136                 1 1 1045 1046\nSplit                    splitncnn_18             1 2 1046 1046_splitncnn_0 1046_splitncnn_1\nConvolution              Conv_137                 1 1 1046_splitncnn_1 1049 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_139                 1 1 1049 1052 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_141                 1 1 1052 1646 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_142                  2 1 1646 1046_splitncnn_0 1055\nReLU                     Relu_143                 1 1 1055 1056\nSplit                    splitncnn_19             1 2 1056 1056_splitncnn_0 1056_splitncnn_1\nConvolution              Conv_144                 1 1 1056_splitncnn_1 1059 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_146                 1 1 1059 1062 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_148                 1 1 1062 1655 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_149                  2 1 1655 1056_splitncnn_0 1065\nReLU                     Relu_150                 1 1 1065 1066\nSplit                    splitncnn_20             1 2 1066 1066_splitncnn_0 1066_splitncnn_1\nConvolution              Conv_151                 1 1 1066_splitncnn_1 1069 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_153                 1 1 1069 1072 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_155                 1 1 1072 1664 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_156                  2 1 1664 1066_splitncnn_0 1075\nReLU                     Relu_157                 1 1 1075 1076\nSplit                    splitncnn_21             1 2 1076 1076_splitncnn_0 1076_splitncnn_1\nConvolution              Conv_158                 1 1 1076_splitncnn_1 1079 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_160                 1 1 1079 1082 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_162                 1 1 1082 1673 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_163                  2 1 1673 1076_splitncnn_0 1085\nReLU                     Relu_164                 1 1 1085 1086\nSplit                    splitncnn_22             1 2 1086 1086_splitncnn_0 1086_splitncnn_1\nConvolution              Conv_165                 1 1 1086_splitncnn_1 1089 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_167                 1 1 1089 1092 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_169                 1 1 1092 1682 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_170                  2 1 1682 1086_splitncnn_0 1095\nReLU                     Relu_171                 1 1 1095 1096\nSplit                    splitncnn_23             1 2 1096 1096_splitncnn_0 1096_splitncnn_1\nConvolution              Conv_172                 1 1 1096_splitncnn_1 1099 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_174                 1 1 1099 1102 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_176                 1 1 1102 1691 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_177                  2 1 1691 1096_splitncnn_0 1105\nReLU                     Relu_178                 1 1 1105 1106\nSplit                    splitncnn_24             1 2 1106 1106_splitncnn_0 1106_splitncnn_1\nConvolution              Conv_179                 1 1 1106_splitncnn_1 1109 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_181                 1 1 1109 1112 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_183                 1 1 1112 1700 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_184                  2 1 1700 1106_splitncnn_0 1115\nReLU                     Relu_185                 1 1 1115 1116\nSplit                    splitncnn_25             1 2 1116 1116_splitncnn_0 1116_splitncnn_1\nConvolution              Conv_186                 1 1 1116_splitncnn_1 1119 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_188                 1 1 1119 1122 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_190                 1 1 1122 1709 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_191                  2 1 1709 1116_splitncnn_0 1125\nReLU                     Relu_192                 1 1 1125 1126\nSplit                    splitncnn_26             1 2 1126 1126_splitncnn_0 1126_splitncnn_1\nConvolution              Conv_193                 1 1 1126_splitncnn_1 1129 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_195                 1 1 1129 1132 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_197                 1 1 1132 1718 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_198                  2 1 1718 1126_splitncnn_0 1135\nReLU                     Relu_199                 1 1 1135 1136\nSplit                    splitncnn_27             1 2 1136 1136_splitncnn_0 1136_splitncnn_1\nConvolution              Conv_200                 1 1 1136_splitncnn_1 1139 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_202                 1 1 1139 1142 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_204                 1 1 1142 1727 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_205                  2 1 1727 1136_splitncnn_0 1145\nReLU                     Relu_206                 1 1 1145 1146\nSplit                    splitncnn_28             1 2 1146 1146_splitncnn_0 1146_splitncnn_1\nConvolution              Conv_207                 1 1 1146_splitncnn_1 1149 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_209                 1 1 1149 1152 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_211                 1 1 1152 1736 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_212                  2 1 1736 1146_splitncnn_0 1155\nReLU                     Relu_213                 1 1 1155 1156\nSplit                    splitncnn_29             1 2 1156 1156_splitncnn_0 1156_splitncnn_1\nConvolution              Conv_214                 1 1 1156_splitncnn_1 1159 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_216                 1 1 1159 1162 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_218                 1 1 1162 1745 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_219                  2 1 1745 1156_splitncnn_0 1165\nReLU                     Relu_220                 1 1 1165 1166\nSplit                    splitncnn_30             1 2 1166 1166_splitncnn_0 1166_splitncnn_1\nConvolution              Conv_221                 1 1 1166_splitncnn_1 1169 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_223                 1 1 1169 1172 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_225                 1 1 1172 1754 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_226                  2 1 1754 1166_splitncnn_0 1175\nReLU                     Relu_227                 1 1 1175 1176\nSplit                    splitncnn_31             1 2 1176 1176_splitncnn_0 1176_splitncnn_1\nConvolution              Conv_228                 1 1 1176_splitncnn_1 1179 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_230                 1 1 1179 1182 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_232                 1 1 1182 1763 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_233                  2 1 1763 1176_splitncnn_0 1185\nReLU                     Relu_234                 1 1 1185 1186\nSplit                    splitncnn_32             1 2 1186 1186_splitncnn_0 1186_splitncnn_1\nConvolution              Conv_235                 1 1 1186_splitncnn_1 1189 0=56 1=1 5=1 6=12544 9=1\nConvolution              Conv_237                 1 1 1189 1192 0=56 1=3 4=1 5=1 6=28224 9=1\nConvolution              Conv_239                 1 1 1192 1772 0=224 1=1 5=1 6=12544\nBinaryOp                 Add_240                  2 1 1772 1186_splitncnn_0 1195\nReLU                     Relu_241                 1 1 1195 1196\nSplit                    splitncnn_33             1 3 1196 1196_splitncnn_0 1196_splitncnn_1 1196_splitncnn_2\nConvolution              Conv_242                 1 1 1196_splitncnn_2 1199 0=144 1=1 5=1 6=32256 9=1\nConvolution              Conv_244                 1 1 1199 1202 0=144 1=3 3=2 4=1 5=1 6=186624 9=1\nConvolution              Conv_246                 1 1 1202 1781 0=576 1=1 5=1 6=82944\nPooling                  AveragePool_247          1 1 1196_splitncnn_1 1205 0=1 1=2 2=2\nConvolution              Conv_248                 1 1 1205 1784 0=576 1=1 5=1 6=129024\nBinaryOp                 Add_249                  2 1 1781 1784 1208\nReLU                     Relu_250                 1 1 1208 1209\nSplit                    splitncnn_34             1 2 1209 1209_splitncnn_0 1209_splitncnn_1\nConvolution              Conv_251                 1 1 1209_splitncnn_1 1212 0=144 1=1 5=1 6=82944 9=1\nConvolution              Conv_253                 1 1 1212 1215 0=144 1=3 4=1 5=1 6=186624 9=1\nConvolution              Conv_255                 1 1 1215 1793 0=576 1=1 5=1 6=82944\nBinaryOp                 Add_256                  2 1 1793 1209_splitncnn_0 1218\nReLU                     Relu_257                 1 1 1218 1219\nSplit                    splitncnn_35             1 3 1219 1219_splitncnn_0 1219_splitncnn_1 1219_splitncnn_2\nConvolution              Conv_258                 1 1 1219_splitncnn_2 1222 0=184 1=1 5=1 6=105984 9=1\nConvolution              Conv_260                 1 1 1222 1225 0=184 1=3 3=2 4=1 5=1 6=304704 9=1\nConvolution              Conv_262                 1 1 1225 1802 0=736 1=1 5=1 6=135424\nPooling                  AveragePool_263          1 1 1219_splitncnn_1 1228 0=1 1=2 2=2\nConvolution              Conv_264                 1 1 1228 1805 0=736 1=1 5=1 6=423936\nBinaryOp                 Add_265                  2 1 1802 1805 1231\nReLU                     Relu_266                 1 1 1231 1232\nSplit                    splitncnn_36             1 2 1232 1232_splitncnn_0 1232_splitncnn_1\nConvolution              Conv_267                 1 1 1232_splitncnn_1 1235 0=184 1=1 5=1 6=135424 9=1\nConvolution              Conv_269                 1 1 1235 1238 0=184 1=3 4=1 5=1 6=304704 9=1\nConvolution              Conv_271                 1 1 1238 1814 0=736 1=1 5=1 6=135424\nBinaryOp                 Add_272                  2 1 1814 1232_splitncnn_0 1241\nReLU                     Relu_273                 1 1 1241 1242\nSplit                    splitncnn_37             1 2 1242 1242_splitncnn_0 1242_splitncnn_1\nConvolution              Conv_274                 1 1 1242_splitncnn_1 1245 0=184 1=1 5=1 6=135424 9=1\nConvolution              Conv_276                 1 1 1245 1248 0=184 1=3 4=1 5=1 6=304704 9=1\nConvolution              Conv_278                 1 1 1248 1823 0=736 1=1 5=1 6=135424\nBinaryOp                 Add_279                  2 1 1823 1242_splitncnn_0 1251\nReLU                     Relu_280                 1 1 1251 1252\nSplit                    splitncnn_38             1 2 1252 1252_splitncnn_0 1252_splitncnn_1\nConvolution              Conv_281                 1 1 1252_splitncnn_1 1255 0=184 1=1 5=1 6=135424 9=1\nConvolution              Conv_283                 1 1 1255 1258 0=184 1=3 4=1 5=1 6=304704 9=1\nConvolution              Conv_285                 1 1 1258 1832 0=736 1=1 5=1 6=135424\nBinaryOp                 Add_286                  2 1 1832 1252_splitncnn_0 1261\nReLU                     Relu_287                 1 1 1261 1262\nSplit                    splitncnn_39             1 2 1262 1262_splitncnn_0 1262_splitncnn_1\nConvolution              Conv_288                 1 1 1262_splitncnn_1 1265 0=184 1=1 5=1 6=135424 9=1\nConvolution              Conv_290                 1 1 1265 1268 0=184 1=3 4=1 5=1 6=304704 9=1\nConvolution              Conv_292                 1 1 1268 1841 0=736 1=1 5=1 6=135424\nBinaryOp                 Add_293                  2 1 1841 1262_splitncnn_0 1271\nReLU                     Relu_294                 1 1 1271 1272\nSplit                    splitncnn_40             1 2 1272 1272_splitncnn_0 1272_splitncnn_1\nConvolution              Conv_295                 1 1 1272_splitncnn_1 1275 0=184 1=1 5=1 6=135424 9=1\nConvolution              Conv_297                 1 1 1275 1278 0=184 1=3 4=1 5=1 6=304704 9=1\nConvolution              Conv_299                 1 1 1278 1850 0=736 1=1 5=1 6=135424\nBinaryOp                 Add_300                  2 1 1850 1272_splitncnn_0 1281\nReLU                     Relu_301                 1 1 1281 1282\nSplit                    splitncnn_41             1 2 1282 1282_splitncnn_0 1282_splitncnn_1\nConvolution              Conv_302                 1 1 1282_splitncnn_1 1285 0=184 1=1 5=1 6=135424 9=1\nConvolution              Conv_304                 1 1 1285 1288 0=184 1=3 4=1 5=1 6=304704 9=1\nConvolution              Conv_306                 1 1 1288 1859 0=736 1=1 5=1 6=135424\nBinaryOp                 Add_307                  2 1 1859 1282_splitncnn_0 1291\nReLU                     Relu_308                 1 1 1291 1292\nSplit                    splitncnn_42             1 2 1292 1292_splitncnn_0 1292_splitncnn_1\nConvolution              Conv_309                 1 1 1292_splitncnn_1 1295 0=184 1=1 5=1 6=135424 9=1\nConvolution              Conv_311                 1 1 1295 1298 0=184 1=3 4=1 5=1 6=304704 9=1\nConvolution              Conv_313                 1 1 1298 1868 0=736 1=1 5=1 6=135424\nBinaryOp                 Add_314                  2 1 1868 1292_splitncnn_0 1301\nReLU                     Relu_315                 1 1 1301 1302\nConvolution              Conv_316                 1 1 1196_splitncnn_0 1303 0=128 1=1 5=1 6=28672\nConvolution              Conv_317                 1 1 1219_splitncnn_0 1304 0=128 1=1 5=1 6=73728\nConvolution              Conv_318                 1 1 1302 1305 0=128 1=1 5=1 6=94208\nSplit                    splitncnn_43             1 2 1305 1305_splitncnn_0 1305_splitncnn_1\nInterp                   Resize_337               1 1 1305_splitncnn_1 1324 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_338                  2 1 1304 1324 1325\nSplit                    splitncnn_44             1 2 1325 1325_splitncnn_0 1325_splitncnn_1\nInterp                   Resize_357               1 1 1325_splitncnn_1 1344 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_358                  2 1 1303 1344 1345\nConvolution              Conv_359                 1 1 1345 1346 0=128 1=3 4=1 5=1 6=147456\nSplit                    splitncnn_45             1 2 1346 1346_splitncnn_0 1346_splitncnn_1\nConvolution              Conv_360                 1 1 1325_splitncnn_0 1347 0=128 1=3 4=1 5=1 6=147456\nConvolution              Conv_361                 1 1 1305_splitncnn_0 1348 0=128 1=3 4=1 5=1 6=147456\nConvolution              Conv_362                 1 1 1346_splitncnn_1 1349 0=128 1=3 3=2 4=1 5=1 6=147456\nBinaryOp                 Add_363                  2 1 1347 1349 1350\nSplit                    splitncnn_46             1 2 1350 1350_splitncnn_0 1350_splitncnn_1\nConvolution              Conv_364                 1 1 1350_splitncnn_1 1351 0=128 1=3 3=2 4=1 5=1 6=147456\nBinaryOp                 Add_365                  2 1 1348 1351 1352\nConvolution              Conv_366                 1 1 1350_splitncnn_0 1353 0=128 1=3 4=1 5=1 6=147456\nConvolution              Conv_367                 1 1 1352 1354 0=128 1=3 4=1 5=1 6=147456\nConvolution              Conv_368                 1 1 1346_splitncnn_0 1355 0=256 1=3 4=1 6=294912\nGroupNorm                Add_377                  1 1 1355 1366 0=32 1=256 2=1.000000e-05\nReLU                     Relu_378                 1 1 1366 1367\nConvolution              Conv_379                 1 1 1367 1368 0=256 1=3 4=1 6=589824\nGroupNorm                Add_388                  1 1 1368 1379 0=32 1=256 2=1.000000e-05\nReLU                     Relu_389                 1 1 1379 1380\nSplit                    splitncnn_47             1 2 1380 1380_splitncnn_0 1380_splitncnn_1\nConvolution              Conv_390                 1 1 1380_splitncnn_1 1386 0=2 1=3 4=1 5=1 6=4608\nConvolution              Conv_391                 1 1 1380_splitncnn_0 1382 0=8 1=3 4=1 5=1 6=18432\nBinaryOp                 Mul_392                  1 1 1382 bbox_8 0=2 1=1 2=9.446464e-01\nSigmoid                  Sigmoid_396              1 1 1386 score_8\nConvolution              Conv_400                 1 1 1353 1391 0=256 1=3 4=1 6=294912\nGroupNorm                Add_409                  1 1 1391 1402 0=32 1=256 2=1.000000e-05\nReLU                     Relu_410                 1 1 1402 1403\nConvolution              Conv_411                 1 1 1403 1404 0=256 1=3 4=1 6=589824\nGroupNorm                Add_420                  1 1 1404 1415 0=32 1=256 2=1.000000e-05\nReLU                     Relu_421                 1 1 1415 1416\nSplit                    splitncnn_48             1 2 1416 1416_splitncnn_0 1416_splitncnn_1\nConvolution              Conv_422                 1 1 1416_splitncnn_1 1422 0=2 1=3 4=1 5=1 6=4608\nConvolution              Conv_423                 1 1 1416_splitncnn_0 1418 0=8 1=3 4=1 5=1 6=18432\nBinaryOp                 Mul_424                  1 1 1418 bbox_16 0=2 1=1 2=1.461800e+00\nSigmoid                  Sigmoid_428              1 1 1422 score_16\nConvolution              Conv_432                 1 1 1354 1427 0=256 1=3 4=1 6=294912\nGroupNorm                Add_441                  1 1 1427 1438 0=32 1=256 2=1.000000e-05\nReLU                     Relu_442                 1 1 1438 1439\nConvolution              Conv_443                 1 1 1439 1440 0=256 1=3 4=1 6=589824\nGroupNorm                Add_452                  1 1 1440 1451 0=32 1=256 2=1.000000e-05\nReLU                     Relu_453                 1 1 1451 1452\nSplit                    splitncnn_49             1 2 1452 1452_splitncnn_0 1452_splitncnn_1\nConvolution              Conv_454                 1 1 1452_splitncnn_1 1458 0=2 1=3 4=1 5=1 6=4608\nConvolution              Conv_455                 1 1 1452_splitncnn_0 1454 0=8 1=3 4=1 5=1 6=18432\nBinaryOp                 Mul_456                  1 1 1454 bbox_32 0=2 1=1 2=1.589572e+00\nSigmoid                  Sigmoid_460              1 1 1458 score_32\n"
  },
  {
    "path": "app/src/main/assets/scrfd_500m-opt2.param",
    "content": "7767517\n103 112\nInput                    input.1                  0 1 input.1\nConvolution              Conv_0                   1 1 input.1 217 0=16 1=3 3=2 4=1 5=1 6=432 9=1\nConvolutionDepthWise     Conv_2                   1 1 217 220 0=16 1=3 4=1 5=1 6=144 7=16 9=1\nConvolution              Conv_4                   1 1 220 223 0=16 1=1 5=1 6=256 9=1\nConvolutionDepthWise     Conv_6                   1 1 223 226 0=16 1=3 3=2 4=1 5=1 6=144 7=16 9=1\nConvolution              Conv_8                   1 1 226 229 0=40 1=1 5=1 6=640 9=1\nConvolutionDepthWise     Conv_10                  1 1 229 232 0=40 1=3 4=1 5=1 6=360 7=40 9=1\nConvolution              Conv_12                  1 1 232 235 0=40 1=1 5=1 6=1600 9=1\nConvolutionDepthWise     Conv_14                  1 1 235 238 0=40 1=3 3=2 4=1 5=1 6=360 7=40 9=1\nConvolution              Conv_16                  1 1 238 241 0=72 1=1 5=1 6=2880 9=1\nConvolutionDepthWise     Conv_18                  1 1 241 244 0=72 1=3 4=1 5=1 6=648 7=72 9=1\nConvolution              Conv_20                  1 1 244 247 0=72 1=1 5=1 6=5184 9=1\nConvolutionDepthWise     Conv_22                  1 1 247 250 0=72 1=3 4=1 5=1 6=648 7=72 9=1\nConvolution              Conv_24                  1 1 250 253 0=72 1=1 5=1 6=5184 9=1\nSplit                    splitncnn_0              1 2 253 253_splitncnn_0 253_splitncnn_1\nConvolutionDepthWise     Conv_26                  1 1 253_splitncnn_1 256 0=72 1=3 3=2 4=1 5=1 6=648 7=72 9=1\nConvolution              Conv_28                  1 1 256 259 0=152 1=1 5=1 6=10944 9=1\nConvolutionDepthWise     Conv_30                  1 1 259 262 0=152 1=3 4=1 5=1 6=1368 7=152 9=1\nConvolution              Conv_32                  1 1 262 265 0=152 1=1 5=1 6=23104 9=1\nSplit                    splitncnn_1              1 2 265 265_splitncnn_0 265_splitncnn_1\nConvolutionDepthWise     Conv_34                  1 1 265_splitncnn_1 268 0=152 1=3 3=2 4=1 5=1 6=1368 7=152 9=1\nConvolution              Conv_36                  1 1 268 271 0=288 1=1 5=1 6=43776 9=1\nConvolutionDepthWise     Conv_38                  1 1 271 274 0=288 1=3 4=1 5=1 6=2592 7=288 9=1\nConvolution              Conv_40                  1 1 274 277 0=288 1=1 5=1 6=82944 9=1\nConvolutionDepthWise     Conv_42                  1 1 277 280 0=288 1=3 4=1 5=1 6=2592 7=288 9=1\nConvolution              Conv_44                  1 1 280 283 0=288 1=1 5=1 6=82944 9=1\nConvolutionDepthWise     Conv_46                  1 1 283 286 0=288 1=3 4=1 5=1 6=2592 7=288 9=1\nConvolution              Conv_48                  1 1 286 289 0=288 1=1 5=1 6=82944 9=1\nConvolutionDepthWise     Conv_50                  1 1 289 292 0=288 1=3 4=1 5=1 6=2592 7=288 9=1\nConvolution              Conv_52                  1 1 292 295 0=288 1=1 5=1 6=82944 9=1\nConvolutionDepthWise     Conv_54                  1 1 295 298 0=288 1=3 4=1 5=1 6=2592 7=288 9=1\nConvolution              Conv_56                  1 1 298 301 0=288 1=1 5=1 6=82944 9=1\nConvolution              Conv_58                  1 1 253_splitncnn_0 302 0=16 1=1 5=1 6=1152\nConvolution              Conv_59                  1 1 265_splitncnn_0 303 0=16 1=1 5=1 6=2432\nConvolution              Conv_60                  1 1 301 304 0=16 1=1 5=1 6=4608\nSplit                    splitncnn_2              1 2 304 304_splitncnn_0 304_splitncnn_1\nInterp                   Resize_79                1 1 304_splitncnn_1 323 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_80                   2 1 303 323 324\nSplit                    splitncnn_3              1 2 324 324_splitncnn_0 324_splitncnn_1\nInterp                   Resize_99                1 1 324_splitncnn_1 343 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_100                  2 1 302 343 344\nConvolution              Conv_101                 1 1 344 345 0=16 1=3 4=1 5=1 6=2304\nSplit                    splitncnn_4              1 2 345 345_splitncnn_0 345_splitncnn_1\nConvolution              Conv_102                 1 1 324_splitncnn_0 346 0=16 1=3 4=1 5=1 6=2304\nConvolution              Conv_103                 1 1 304_splitncnn_0 347 0=16 1=3 4=1 5=1 6=2304\nConvolution              Conv_104                 1 1 345_splitncnn_1 348 0=16 1=3 3=2 4=1 5=1 6=2304\nBinaryOp                 Add_105                  2 1 346 348 349\nSplit                    splitncnn_5              1 2 349 349_splitncnn_0 349_splitncnn_1\nConvolution              Conv_106                 1 1 349_splitncnn_1 350 0=16 1=3 3=2 4=1 5=1 6=2304\nBinaryOp                 Add_107                  2 1 347 350 351\nConvolution              Conv_108                 1 1 349_splitncnn_0 352 0=16 1=3 4=1 5=1 6=2304\nConvolution              Conv_109                 1 1 351 353 0=16 1=3 4=1 5=1 6=2304\nConvolutionDepthWise     Conv_110                 1 1 345_splitncnn_0 354 0=16 1=3 4=1 6=144 7=16\nGroupNorm                Add_119                  1 1 354 365 0=16 1=16 2=1.000000e-05\nReLU                     Relu_120                 1 1 365 366\nConvolution              Conv_121                 1 1 366 367 0=64 1=1 6=1024\nGroupNorm                Add_130                  1 1 367 378 0=16 1=64 2=1.000000e-05\nReLU                     Relu_131                 1 1 378 379\nConvolutionDepthWise     Conv_132                 1 1 379 380 0=64 1=3 4=1 6=576 7=64\nGroupNorm                Add_141                  1 1 380 391 0=16 1=64 2=1.000000e-05\nReLU                     Relu_142                 1 1 391 392\nConvolution              Conv_143                 1 1 392 393 0=64 1=1 6=4096\nGroupNorm                Add_152                  1 1 393 404 0=16 1=64 2=1.000000e-05\nReLU                     Relu_153                 1 1 404 405\nSplit                    splitncnn_6              1 2 405 405_splitncnn_0 405_splitncnn_1\nConvolution              Conv_154                 1 1 405_splitncnn_1 411 0=2 1=3 4=1 5=1 6=1152\nConvolution              Conv_155                 1 1 405_splitncnn_0 407 0=8 1=3 4=1 5=1 6=4608\nBinaryOp                 Mul_156                  1 1 407 bbox_8 0=2 1=1 2=7.957783e-01\nSigmoid                  Sigmoid_160              1 1 411 score_8\nConvolutionDepthWise     Conv_164                 1 1 352 416 0=16 1=3 4=1 6=144 7=16\nGroupNorm                Add_173                  1 1 416 427 0=16 1=16 2=1.000000e-05\nReLU                     Relu_174                 1 1 427 428\nConvolution              Conv_175                 1 1 428 429 0=64 1=1 6=1024\nGroupNorm                Add_184                  1 1 429 440 0=16 1=64 2=1.000000e-05\nReLU                     Relu_185                 1 1 440 441\nConvolutionDepthWise     Conv_186                 1 1 441 442 0=64 1=3 4=1 6=576 7=64\nGroupNorm                Add_195                  1 1 442 453 0=16 1=64 2=1.000000e-05\nReLU                     Relu_196                 1 1 453 454\nConvolution              Conv_197                 1 1 454 455 0=64 1=1 6=4096\nGroupNorm                Add_206                  1 1 455 466 0=16 1=64 2=1.000000e-05\nReLU                     Relu_207                 1 1 466 467\nSplit                    splitncnn_7              1 2 467 467_splitncnn_0 467_splitncnn_1\nConvolution              Conv_208                 1 1 467_splitncnn_1 473 0=2 1=3 4=1 5=1 6=1152\nConvolution              Conv_209                 1 1 467_splitncnn_0 469 0=8 1=3 4=1 5=1 6=4608\nBinaryOp                 Mul_210                  1 1 469 bbox_16 0=2 1=1 2=1.201926e+00\nSigmoid                  Sigmoid_214              1 1 473 score_16\nConvolutionDepthWise     Conv_218                 1 1 353 478 0=16 1=3 4=1 6=144 7=16\nGroupNorm                Add_227                  1 1 478 489 0=16 1=16 2=1.000000e-05\nReLU                     Relu_228                 1 1 489 490\nConvolution              Conv_229                 1 1 490 491 0=64 1=1 6=1024\nGroupNorm                Add_238                  1 1 491 502 0=16 1=64 2=1.000000e-05\nReLU                     Relu_239                 1 1 502 503\nConvolutionDepthWise     Conv_240                 1 1 503 504 0=64 1=3 4=1 6=576 7=64\nGroupNorm                Add_249                  1 1 504 515 0=16 1=64 2=1.000000e-05\nReLU                     Relu_250                 1 1 515 516\nConvolution              Conv_251                 1 1 516 517 0=64 1=1 6=4096\nGroupNorm                Add_260                  1 1 517 528 0=16 1=64 2=1.000000e-05\nReLU                     Relu_261                 1 1 528 529\nSplit                    splitncnn_8              1 2 529 529_splitncnn_0 529_splitncnn_1\nConvolution              Conv_262                 1 1 529_splitncnn_1 535 0=2 1=3 4=1 5=1 6=1152\nConvolution              Conv_263                 1 1 529_splitncnn_0 531 0=8 1=3 4=1 5=1 6=4608\nBinaryOp                 Mul_264                  1 1 531 bbox_32 0=2 1=1 2=1.992024e+00\nSigmoid                  Sigmoid_268              1 1 535 score_32\n"
  },
  {
    "path": "app/src/main/assets/scrfd_500m_kps-opt2.param",
    "content": "7767517\n79 91\nInput                    input.1                  0 1 input.1\nConvolution              Conv_0                   1 1 input.1 288 0=16 1=3 3=2 4=1 5=1 6=432 9=1\nConvolutionDepthWise     Conv_3                   1 1 288 291 0=16 1=3 4=1 5=1 6=144 7=16 9=1\nConvolution              Conv_6                   1 1 291 294 0=16 1=1 5=1 6=256 9=1\nConvolutionDepthWise     Conv_9                   1 1 294 297 0=16 1=3 3=2 4=1 5=1 6=144 7=16 9=1\nConvolution              Conv_12                  1 1 297 300 0=40 1=1 5=1 6=640 9=1\nConvolutionDepthWise     Conv_15                  1 1 300 303 0=40 1=3 4=1 5=1 6=360 7=40 9=1\nConvolution              Conv_18                  1 1 303 306 0=40 1=1 5=1 6=1600 9=1\nConvolutionDepthWise     Conv_21                  1 1 306 309 0=40 1=3 3=2 4=1 5=1 6=360 7=40 9=1\nConvolution              Conv_24                  1 1 309 312 0=72 1=1 5=1 6=2880 9=1\nConvolutionDepthWise     Conv_27                  1 1 312 315 0=72 1=3 4=1 5=1 6=648 7=72 9=1\nConvolution              Conv_30                  1 1 315 318 0=72 1=1 5=1 6=5184 9=1\nConvolutionDepthWise     Conv_33                  1 1 318 321 0=72 1=3 4=1 5=1 6=648 7=72 9=1\nConvolution              Conv_36                  1 1 321 324 0=72 1=1 5=1 6=5184 9=1\nSplit                    splitncnn_0              1 2 324 324_splitncnn_0 324_splitncnn_1\nConvolutionDepthWise     Conv_39                  1 1 324_splitncnn_1 327 0=72 1=3 3=2 4=1 5=1 6=648 7=72 9=1\nConvolution              Conv_42                  1 1 327 330 0=152 1=1 5=1 6=10944 9=1\nConvolutionDepthWise     Conv_45                  1 1 330 333 0=152 1=3 4=1 5=1 6=1368 7=152 9=1\nConvolution              Conv_48                  1 1 333 336 0=152 1=1 5=1 6=23104 9=1\nSplit                    splitncnn_1              1 2 336 336_splitncnn_0 336_splitncnn_1\nConvolutionDepthWise     Conv_51                  1 1 336_splitncnn_1 339 0=152 1=3 3=2 4=1 5=1 6=1368 7=152 9=1\nConvolution              Conv_54                  1 1 339 342 0=288 1=1 5=1 6=43776 9=1\nConvolutionDepthWise     Conv_57                  1 1 342 345 0=288 1=3 4=1 5=1 6=2592 7=288 9=1\nConvolution              Conv_60                  1 1 345 348 0=288 1=1 5=1 6=82944 9=1\nConvolutionDepthWise     Conv_63                  1 1 348 351 0=288 1=3 4=1 5=1 6=2592 7=288 9=1\nConvolution              Conv_66                  1 1 351 354 0=288 1=1 5=1 6=82944 9=1\nConvolutionDepthWise     Conv_69                  1 1 354 357 0=288 1=3 4=1 5=1 6=2592 7=288 9=1\nConvolution              Conv_72                  1 1 357 360 0=288 1=1 5=1 6=82944 9=1\nConvolutionDepthWise     Conv_75                  1 1 360 363 0=288 1=3 4=1 5=1 6=2592 7=288 9=1\nConvolution              Conv_78                  1 1 363 366 0=288 1=1 5=1 6=82944 9=1\nConvolutionDepthWise     Conv_81                  1 1 366 369 0=288 1=3 4=1 5=1 6=2592 7=288 9=1\nConvolution              Conv_84                  1 1 369 372 0=288 1=1 5=1 6=82944 9=1\nConvolution              Conv_87                  1 1 324_splitncnn_0 373 0=16 1=1 5=1 6=1152\nConvolution              Conv_88                  1 1 336_splitncnn_0 374 0=16 1=1 5=1 6=2432\nConvolution              Conv_89                  1 1 372 375 0=16 1=1 5=1 6=4608\nSplit                    splitncnn_2              1 2 375 375_splitncnn_0 375_splitncnn_1\nInterp                   Resize_108               1 1 375_splitncnn_1 394 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_109                  2 1 374 394 395\nSplit                    splitncnn_3              1 2 395 395_splitncnn_0 395_splitncnn_1\nInterp                   Resize_128               1 1 395_splitncnn_1 414 0=1 1=2.000000e+00 2=2.000000e+00\nBinaryOp                 Add_129                  2 1 373 414 415\nConvolution              Conv_130                 1 1 415 416 0=16 1=3 4=1 5=1 6=2304\nSplit                    splitncnn_4              1 2 416 416_splitncnn_0 416_splitncnn_1\nConvolution              Conv_131                 1 1 395_splitncnn_0 417 0=16 1=3 4=1 5=1 6=2304\nConvolution              Conv_132                 1 1 375_splitncnn_0 418 0=16 1=3 4=1 5=1 6=2304\nConvolution              Conv_133                 1 1 416_splitncnn_1 419 0=16 1=3 3=2 4=1 5=1 6=2304\nBinaryOp                 Add_134                  2 1 417 419 420\nSplit                    splitncnn_5              1 2 420 420_splitncnn_0 420_splitncnn_1\nConvolution              Conv_135                 1 1 420_splitncnn_1 421 0=16 1=3 3=2 4=1 5=1 6=2304\nBinaryOp                 Add_136                  2 1 418 421 422\nConvolution              Conv_137                 1 1 420_splitncnn_0 423 0=16 1=3 4=1 5=1 6=2304\nConvolution              Conv_138                 1 1 422 424 0=16 1=3 4=1 5=1 6=2304\nConvolutionDepthWise     Conv_139                 1 1 416_splitncnn_0 427 0=16 1=3 4=1 5=1 6=144 7=16 9=1\nConvolution              Conv_142                 1 1 427 430 0=64 1=1 5=1 6=1024 9=1\nConvolutionDepthWise     Conv_145                 1 1 430 433 0=64 1=3 4=1 5=1 6=576 7=64 9=1\nConvolution              Conv_148                 1 1 433 436 0=64 1=1 5=1 6=4096 9=1\nSplit                    splitncnn_6              1 3 436 436_splitncnn_0 436_splitncnn_1 436_splitncnn_2\nConvolution              Conv_151                 1 1 436_splitncnn_2 442 0=2 1=3 4=1 5=1 6=1152\nConvolution              Conv_152                 1 1 436_splitncnn_1 bbox_8 0=8 1=3 4=1 5=1 6=4608\nConvolution              Conv_153                 1 1 436_splitncnn_0 kps_8 0=20 1=3 4=1 5=1 6=11520\nSigmoid                  Sigmoid_157              1 1 442 score_8\nConvolutionDepthWise     Conv_164                 1 1 423 452 0=16 1=3 4=1 5=1 6=144 7=16 9=1\nConvolution              Conv_167                 1 1 452 455 0=64 1=1 5=1 6=1024 9=1\nConvolutionDepthWise     Conv_170                 1 1 455 458 0=64 1=3 4=1 5=1 6=576 7=64 9=1\nConvolution              Conv_173                 1 1 458 461 0=64 1=1 5=1 6=4096 9=1\nSplit                    splitncnn_7              1 3 461 461_splitncnn_0 461_splitncnn_1 461_splitncnn_2\nConvolution              Conv_176                 1 1 461_splitncnn_2 467 0=2 1=3 4=1 5=1 6=1152\nConvolution              Conv_177                 1 1 461_splitncnn_1 bbox_16 0=8 1=3 4=1 5=1 6=4608\nConvolution              Conv_178                 1 1 461_splitncnn_0 kps_16 0=20 1=3 4=1 5=1 6=11520\nSigmoid                  Sigmoid_182              1 1 467 score_16\nConvolutionDepthWise     Conv_189                 1 1 424 477 0=16 1=3 4=1 5=1 6=144 7=16 9=1\nConvolution              Conv_192                 1 1 477 480 0=64 1=1 5=1 6=1024 9=1\nConvolutionDepthWise     Conv_195                 1 1 480 483 0=64 1=3 4=1 5=1 6=576 7=64 9=1\nConvolution              Conv_198                 1 1 483 486 0=64 1=1 5=1 6=4096 9=1\nSplit                    splitncnn_8              1 3 486 486_splitncnn_0 486_splitncnn_1 486_splitncnn_2\nConvolution              Conv_201                 1 1 486_splitncnn_2 492 0=2 1=3 4=1 5=1 6=1152\nConvolution              Conv_202                 1 1 486_splitncnn_1 bbox_32 0=8 1=3 4=1 5=1 6=4608\nConvolution              Conv_203                 1 1 486_splitncnn_0 kps_32 0=20 1=3 4=1 5=1 6=11520\nSigmoid                  Sigmoid_207              1 1 492 score_32\n"
  },
  {
    "path": "app/src/main/java/com/tencent/scrfdncnn/MainActivity.java",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\npackage com.tencent.scrfdncnn;\n\nimport android.Manifest;\nimport android.app.Activity;\nimport android.content.pm.PackageManager;\nimport android.graphics.PixelFormat;\nimport android.os.Bundle;\nimport android.util.Log;\nimport android.view.Surface;\nimport android.view.SurfaceHolder;\nimport android.view.SurfaceView;\nimport android.view.View;\nimport android.view.WindowManager;\nimport android.widget.AdapterView;\nimport android.widget.Button;\nimport android.widget.Spinner;\n\nimport android.support.v4.app.ActivityCompat;\nimport android.support.v4.content.ContextCompat;\n\npublic class MainActivity extends Activity implements SurfaceHolder.Callback\n{\n    public static final int REQUEST_CAMERA = 100;\n\n    private SCRFDNcnn scrfdncnn = new SCRFDNcnn();\n    private int facing = 0;\n\n    private Spinner spinnerModel;\n    private Spinner spinnerCPUGPU;\n    private int current_model = 0;\n    private int current_cpugpu = 0;\n\n    private SurfaceView cameraView;\n\n    /** Called when the activity is first created. */\n    @Override\n    public void onCreate(Bundle savedInstanceState)\n    {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.main);\n\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        cameraView = (SurfaceView) findViewById(R.id.cameraview);\n\n        cameraView.getHolder().setFormat(PixelFormat.RGBA_8888);\n        cameraView.getHolder().addCallback(this);\n\n        Button buttonSwitchCamera = (Button) findViewById(R.id.buttonSwitchCamera);\n        buttonSwitchCamera.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View arg0) {\n\n                int new_facing = 1 - facing;\n\n                scrfdncnn.closeCamera();\n\n                scrfdncnn.openCamera(new_facing);\n\n                facing = new_facing;\n            }\n        });\n\n        spinnerModel = (Spinner) findViewById(R.id.spinnerModel);\n        spinnerModel.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {\n            @Override\n            public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id)\n            {\n                if (position != current_model)\n                {\n                    current_model = position;\n                    reload();\n                }\n            }\n\n            @Override\n            public void onNothingSelected(AdapterView<?> arg0)\n            {\n            }\n        });\n\n        spinnerCPUGPU = (Spinner) findViewById(R.id.spinnerCPUGPU);\n        spinnerCPUGPU.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {\n            @Override\n            public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id)\n            {\n                if (position != current_cpugpu)\n                {\n                    current_cpugpu = position;\n                    reload();\n                }\n            }\n\n            @Override\n            public void onNothingSelected(AdapterView<?> arg0)\n            {\n            }\n        });\n\n        reload();\n    }\n\n    private void reload()\n    {\n        boolean ret_init = scrfdncnn.loadModel(getAssets(), current_model, current_cpugpu);\n        if (!ret_init)\n        {\n            Log.e(\"MainActivity\", \"scrfdncnn loadModel failed\");\n        }\n    }\n\n    @Override\n    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)\n    {\n        scrfdncnn.setOutputWindow(holder.getSurface());\n    }\n\n    @Override\n    public void surfaceCreated(SurfaceHolder holder)\n    {\n    }\n\n    @Override\n    public void surfaceDestroyed(SurfaceHolder holder)\n    {\n    }\n\n    @Override\n    public void onResume()\n    {\n        super.onResume();\n\n        if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED)\n        {\n            ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA}, REQUEST_CAMERA);\n        }\n\n        scrfdncnn.openCamera(facing);\n    }\n\n    @Override\n    public void onPause()\n    {\n        super.onPause();\n\n        scrfdncnn.closeCamera();\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/tencent/scrfdncnn/SCRFDNcnn.java",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\npackage com.tencent.scrfdncnn;\n\nimport android.content.res.AssetManager;\nimport android.view.Surface;\n\npublic class SCRFDNcnn\n{\n    public native boolean loadModel(AssetManager mgr, int modelid, int cpugpu);\n    public native boolean openCamera(int facing);\n    public native boolean closeCamera();\n    public native boolean setOutputWindow(Surface surface);\n\n    static {\n        System.loadLibrary(\"scrfdncnn\");\n    }\n}\n"
  },
  {
    "path": "app/src/main/jni/CMakeLists.txt",
    "content": "project(scrfdncnn)\n\ncmake_minimum_required(VERSION 3.10)\n\nset(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv-mobile-4.13.0-android/sdk/native/jni)\nfind_package(OpenCV REQUIRED core imgproc)\n\nset(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn-20260113-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn)\nfind_package(ncnn REQUIRED)\n\nadd_library(scrfdncnn SHARED scrfdncnn.cpp scrfd.cpp ndkcamera.cpp)\n\ntarget_link_libraries(scrfdncnn ncnn ${OpenCV_LIBS} camera2ndk mediandk)\n"
  },
  {
    "path": "app/src/main/jni/ndkcamera.cpp",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#include \"ndkcamera.h\"\n\n#include <string>\n\n#include <android/log.h>\n\n#include <opencv2/core/core.hpp>\n\n#include \"mat.h\"\n\nstatic void onDisconnected(void* context, ACameraDevice* device)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onDisconnected %p\", device);\n}\n\nstatic void onError(void* context, ACameraDevice* device, int error)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onError %p %d\", device, error);\n}\n\nstatic void onImageAvailable(void* context, AImageReader* reader)\n{\n//     __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onImageAvailable %p\", reader);\n\n    AImage* image = 0;\n    media_status_t status = AImageReader_acquireLatestImage(reader, &image);\n\n    if (status != AMEDIA_OK)\n    {\n        // error\n        return;\n    }\n\n    int32_t format;\n    AImage_getFormat(image, &format);\n\n    // assert format == AIMAGE_FORMAT_YUV_420_888\n\n    int32_t width = 0;\n    int32_t height = 0;\n    AImage_getWidth(image, &width);\n    AImage_getHeight(image, &height);\n\n    int32_t y_pixelStride = 0;\n    int32_t u_pixelStride = 0;\n    int32_t v_pixelStride = 0;\n    AImage_getPlanePixelStride(image, 0, &y_pixelStride);\n    AImage_getPlanePixelStride(image, 1, &u_pixelStride);\n    AImage_getPlanePixelStride(image, 2, &v_pixelStride);\n\n    int32_t y_rowStride = 0;\n    int32_t u_rowStride = 0;\n    int32_t v_rowStride = 0;\n    AImage_getPlaneRowStride(image, 0, &y_rowStride);\n    AImage_getPlaneRowStride(image, 1, &u_rowStride);\n    AImage_getPlaneRowStride(image, 2, &v_rowStride);\n\n    uint8_t* y_data = 0;\n    uint8_t* u_data = 0;\n    uint8_t* v_data = 0;\n    int y_len = 0;\n    int u_len = 0;\n    int v_len = 0;\n    AImage_getPlaneData(image, 0, &y_data, &y_len);\n    AImage_getPlaneData(image, 1, &u_data, &u_len);\n    AImage_getPlaneData(image, 2, &v_data, &v_len);\n\n    if (u_data == v_data + 1 && v_data == y_data + width * height && y_pixelStride == 1 && u_pixelStride == 2 && v_pixelStride == 2 && y_rowStride == width && u_rowStride == width && v_rowStride == width)\n    {\n        // already nv21  :)\n        ((NdkCamera*)context)->on_image((unsigned char*)y_data, (int)width, (int)height);\n    }\n    else\n    {\n        // construct nv21\n        unsigned char* nv21 = new unsigned char[width * height + width * height / 2];\n        {\n            // Y\n            unsigned char* yptr = nv21;\n            for (int y=0; y<height; y++)\n            {\n                const unsigned char* y_data_ptr = y_data + y_rowStride * y;\n                for (int x=0; x<width; x++)\n                {\n                    yptr[0] = y_data_ptr[0];\n                    yptr++;\n                    y_data_ptr += y_pixelStride;\n                }\n            }\n\n            // UV\n            unsigned char* uvptr = nv21 + width * height;\n            for (int y=0; y<height/2; y++)\n            {\n                const unsigned char* v_data_ptr = v_data + v_rowStride * y;\n                const unsigned char* u_data_ptr = u_data + u_rowStride * y;\n                for (int x=0; x<width/2; x++)\n                {\n                    uvptr[0] = v_data_ptr[0];\n                    uvptr[1] = u_data_ptr[0];\n                    uvptr += 2;\n                    v_data_ptr += v_pixelStride;\n                    u_data_ptr += u_pixelStride;\n                }\n            }\n        }\n\n        ((NdkCamera*)context)->on_image((unsigned char*)nv21, (int)width, (int)height);\n\n        delete[] nv21;\n    }\n\n    AImage_delete(image);\n}\n\nstatic void onSessionActive(void* context, ACameraCaptureSession *session)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onSessionActive %p\", session);\n}\n\nstatic void onSessionReady(void* context, ACameraCaptureSession *session)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onSessionReady %p\", session);\n}\n\nstatic void onSessionClosed(void* context, ACameraCaptureSession *session)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onSessionClosed %p\", session);\n}\n\nvoid onCaptureFailed(void* context, ACameraCaptureSession* session, ACaptureRequest* request, ACameraCaptureFailure* failure)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureFailed %p %p %p\", session, request, failure);\n}\n\nvoid onCaptureSequenceCompleted(void* context, ACameraCaptureSession* session, int sequenceId, int64_t frameNumber)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureSequenceCompleted %p %d %ld\", session, sequenceId, frameNumber);\n}\n\nvoid onCaptureSequenceAborted(void* context, ACameraCaptureSession* session, int sequenceId)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureSequenceAborted %p %d\", session, sequenceId);\n}\n\nvoid onCaptureCompleted(void* context, ACameraCaptureSession* session, ACaptureRequest* request, const ACameraMetadata* result)\n{\n//     __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"onCaptureCompleted %p %p %p\", session, request, result);\n}\n\nNdkCamera::NdkCamera()\n{\n    camera_facing = 0;\n    camera_orientation = 0;\n\n    camera_manager = 0;\n    camera_device = 0;\n    image_reader = 0;\n    image_reader_surface = 0;\n    image_reader_target = 0;\n    capture_request = 0;\n    capture_session_output_container = 0;\n    capture_session_output = 0;\n    capture_session = 0;\n\n\n    // setup imagereader and its surface\n    {\n        AImageReader_new(640, 480, AIMAGE_FORMAT_YUV_420_888, /*maxImages*/2, &image_reader);\n\n        AImageReader_ImageListener listener;\n        listener.context = this;\n        listener.onImageAvailable = onImageAvailable;\n\n        AImageReader_setImageListener(image_reader, &listener);\n\n        AImageReader_getWindow(image_reader, &image_reader_surface);\n\n        ANativeWindow_acquire(image_reader_surface);\n    }\n}\n\nNdkCamera::~NdkCamera()\n{\n    close();\n\n    if (image_reader)\n    {\n        AImageReader_delete(image_reader);\n        image_reader = 0;\n    }\n\n    if (image_reader_surface)\n    {\n        ANativeWindow_release(image_reader_surface);\n        image_reader_surface = 0;\n    }\n}\n\nint NdkCamera::open(int _camera_facing)\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"open\");\n\n    camera_facing = _camera_facing;\n\n    camera_manager = ACameraManager_create();\n\n    // find front camera\n    std::string camera_id;\n    {\n        ACameraIdList* camera_id_list = 0;\n        ACameraManager_getCameraIdList(camera_manager, &camera_id_list);\n\n        for (int i = 0; i < camera_id_list->numCameras; ++i)\n        {\n            const char* id = camera_id_list->cameraIds[i];\n            ACameraMetadata* camera_metadata = 0;\n            ACameraManager_getCameraCharacteristics(camera_manager, id, &camera_metadata);\n\n            // query faceing\n            acamera_metadata_enum_android_lens_facing_t facing = ACAMERA_LENS_FACING_FRONT;\n            {\n                ACameraMetadata_const_entry e = { 0 };\n                ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_LENS_FACING, &e);\n                facing = (acamera_metadata_enum_android_lens_facing_t)e.data.u8[0];\n            }\n\n            if (camera_facing == 0 && facing != ACAMERA_LENS_FACING_FRONT)\n            {\n                ACameraMetadata_free(camera_metadata);\n                continue;\n            }\n\n            if (camera_facing == 1 && facing != ACAMERA_LENS_FACING_BACK)\n            {\n                ACameraMetadata_free(camera_metadata);\n                continue;\n            }\n\n            camera_id = id;\n\n            // query orientation\n            int orientation = 0;\n            {\n                ACameraMetadata_const_entry e = { 0 };\n                ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_SENSOR_ORIENTATION, &e);\n\n                orientation = (int)e.data.i32[0];\n            }\n\n            camera_orientation = orientation;\n\n            ACameraMetadata_free(camera_metadata);\n\n            break;\n        }\n\n        ACameraManager_deleteCameraIdList(camera_id_list);\n    }\n\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"open %s %d\", camera_id.c_str(), camera_orientation);\n\n    // open camera\n    {\n        ACameraDevice_StateCallbacks camera_device_state_callbacks;\n        camera_device_state_callbacks.context = this;\n        camera_device_state_callbacks.onDisconnected = onDisconnected;\n        camera_device_state_callbacks.onError = onError;\n\n        ACameraManager_openCamera(camera_manager, camera_id.c_str(), &camera_device_state_callbacks, &camera_device);\n    }\n\n    // capture request\n    {\n        ACameraDevice_createCaptureRequest(camera_device, TEMPLATE_PREVIEW, &capture_request);\n\n        ACameraOutputTarget_create(image_reader_surface, &image_reader_target);\n        ACaptureRequest_addTarget(capture_request, image_reader_target);\n    }\n\n    // capture session\n    {\n        ACameraCaptureSession_stateCallbacks camera_capture_session_state_callbacks;\n        camera_capture_session_state_callbacks.context = this;\n        camera_capture_session_state_callbacks.onActive = onSessionActive;\n        camera_capture_session_state_callbacks.onReady = onSessionReady;\n        camera_capture_session_state_callbacks.onClosed = onSessionClosed;\n\n        ACaptureSessionOutputContainer_create(&capture_session_output_container);\n\n        ACaptureSessionOutput_create(image_reader_surface, &capture_session_output);\n\n        ACaptureSessionOutputContainer_add(capture_session_output_container, capture_session_output);\n\n        ACameraDevice_createCaptureSession(camera_device, capture_session_output_container, &camera_capture_session_state_callbacks, &capture_session);\n\n        ACameraCaptureSession_captureCallbacks camera_capture_session_capture_callbacks;\n        camera_capture_session_capture_callbacks.context = this;\n        camera_capture_session_capture_callbacks.onCaptureStarted = 0;\n        camera_capture_session_capture_callbacks.onCaptureProgressed = 0;\n        camera_capture_session_capture_callbacks.onCaptureCompleted = onCaptureCompleted;\n        camera_capture_session_capture_callbacks.onCaptureFailed = onCaptureFailed;\n        camera_capture_session_capture_callbacks.onCaptureSequenceCompleted = onCaptureSequenceCompleted;\n        camera_capture_session_capture_callbacks.onCaptureSequenceAborted = onCaptureSequenceAborted;\n        camera_capture_session_capture_callbacks.onCaptureBufferLost = 0;\n\n        ACameraCaptureSession_setRepeatingRequest(capture_session, &camera_capture_session_capture_callbacks, 1, &capture_request, nullptr);\n    }\n\n    return 0;\n}\n\nvoid NdkCamera::close()\n{\n    __android_log_print(ANDROID_LOG_WARN, \"NdkCamera\", \"close\");\n\n    if (capture_session)\n    {\n        ACameraCaptureSession_stopRepeating(capture_session);\n        ACameraCaptureSession_close(capture_session);\n        capture_session = 0;\n    }\n\n    if (camera_device)\n    {\n        ACameraDevice_close(camera_device);\n        camera_device = 0;\n    }\n\n    if (capture_session_output_container)\n    {\n        ACaptureSessionOutputContainer_free(capture_session_output_container);\n        capture_session_output_container = 0;\n    }\n\n    if (capture_session_output)\n    {\n        ACaptureSessionOutput_free(capture_session_output);\n        capture_session_output = 0;\n    }\n\n    if (capture_request)\n    {\n        ACaptureRequest_free(capture_request);\n        capture_request = 0;\n    }\n\n    if (image_reader_target)\n    {\n        ACameraOutputTarget_free(image_reader_target);\n        image_reader_target = 0;\n    }\n\n    if (camera_manager)\n    {\n        ACameraManager_delete(camera_manager);\n        camera_manager = 0;\n    }\n}\n\nvoid NdkCamera::on_image(const cv::Mat& rgb) const\n{\n}\n\nvoid NdkCamera::on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const\n{\n    // rotate nv21\n    int w = 0;\n    int h = 0;\n    int rotate_type = 0;\n    {\n        if (camera_orientation == 0)\n        {\n            w = nv21_width;\n            h = nv21_height;\n            rotate_type = camera_facing == 0 ? 2 : 1;\n        }\n        if (camera_orientation == 90)\n        {\n            w = nv21_height;\n            h = nv21_width;\n            rotate_type = camera_facing == 0 ? 5 : 6;\n        }\n        if (camera_orientation == 180)\n        {\n            w = nv21_width;\n            h = nv21_height;\n            rotate_type = camera_facing == 0 ? 4 : 3;\n        }\n        if (camera_orientation == 270)\n        {\n            w = nv21_height;\n            h = nv21_width;\n            rotate_type = camera_facing == 0 ? 7 : 8;\n        }\n    }\n\n    cv::Mat nv21_rotated(h + h / 2, w, CV_8UC1);\n    ncnn::kanna_rotate_yuv420sp(nv21, nv21_width, nv21_height, nv21_rotated.data, w, h, rotate_type);\n\n    // nv21_rotated to rgb\n    cv::Mat rgb(h, w, CV_8UC3);\n    ncnn::yuv420sp2rgb(nv21_rotated.data, w, h, rgb.data);\n\n    on_image(rgb);\n}\n\nstatic const int NDKCAMERAWINDOW_ID = 233;\n\nNdkCameraWindow::NdkCameraWindow() : NdkCamera()\n{\n    sensor_manager = 0;\n    sensor_event_queue = 0;\n    accelerometer_sensor = 0;\n    win = 0;\n\n    accelerometer_orientation = 0;\n\n    // sensor\n    sensor_manager = ASensorManager_getInstance();\n\n    accelerometer_sensor = ASensorManager_getDefaultSensor(sensor_manager, ASENSOR_TYPE_ACCELEROMETER);\n}\n\nNdkCameraWindow::~NdkCameraWindow()\n{\n    if (accelerometer_sensor)\n    {\n        ASensorEventQueue_disableSensor(sensor_event_queue, accelerometer_sensor);\n        accelerometer_sensor = 0;\n    }\n\n    if (sensor_event_queue)\n    {\n        ASensorManager_destroyEventQueue(sensor_manager, sensor_event_queue);\n        sensor_event_queue = 0;\n    }\n\n    if (win)\n    {\n        ANativeWindow_release(win);\n    }\n}\n\nvoid NdkCameraWindow::set_window(ANativeWindow* _win)\n{\n    if (win)\n    {\n        ANativeWindow_release(win);\n    }\n\n    win = _win;\n    ANativeWindow_acquire(win);\n}\n\nvoid NdkCameraWindow::on_image_render(cv::Mat& rgb) const\n{\n}\n\nvoid NdkCameraWindow::on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const\n{\n    // resolve orientation from camera_orientation and accelerometer_sensor\n    {\n        if (!sensor_event_queue)\n        {\n            sensor_event_queue = ASensorManager_createEventQueue(sensor_manager, ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS), NDKCAMERAWINDOW_ID, 0, 0);\n\n            ASensorEventQueue_enableSensor(sensor_event_queue, accelerometer_sensor);\n        }\n\n        int id = ALooper_pollOnce(0, 0, 0, 0);\n        if (id == NDKCAMERAWINDOW_ID)\n        {\n            ASensorEvent e[8];\n            ssize_t num_event = 0;\n            while (ASensorEventQueue_hasEvents(sensor_event_queue) == 1)\n            {\n                num_event = ASensorEventQueue_getEvents(sensor_event_queue, e, 8);\n                if (num_event < 0)\n                    break;\n            }\n\n            if (num_event > 0)\n            {\n                float acceleration_x = e[num_event - 1].acceleration.x;\n                float acceleration_y = e[num_event - 1].acceleration.y;\n                float acceleration_z = e[num_event - 1].acceleration.z;\n//                 __android_log_print(ANDROID_LOG_WARN, \"NdkCameraWindow\", \"x = %f, y = %f, z = %f\", x, y, z);\n\n                if (acceleration_y > 7)\n                {\n                    accelerometer_orientation = 0;\n                }\n                if (acceleration_x < -7)\n                {\n                    accelerometer_orientation = 90;\n                }\n                if (acceleration_y < -7)\n                {\n                    accelerometer_orientation = 180;\n                }\n                if (acceleration_x > 7)\n                {\n                    accelerometer_orientation = 270;\n                }\n            }\n        }\n    }\n\n    // roi crop and rotate nv21\n    int nv21_roi_x = 0;\n    int nv21_roi_y = 0;\n    int nv21_roi_w = 0;\n    int nv21_roi_h = 0;\n    int roi_x = 0;\n    int roi_y = 0;\n    int roi_w = 0;\n    int roi_h = 0;\n    int rotate_type = 0;\n    int render_w = 0;\n    int render_h = 0;\n    int render_rotate_type = 0;\n    {\n        int win_w = ANativeWindow_getWidth(win);\n        int win_h = ANativeWindow_getHeight(win);\n\n        if (accelerometer_orientation == 90 || accelerometer_orientation == 270)\n        {\n            std::swap(win_w, win_h);\n        }\n\n        const int final_orientation = (camera_orientation + accelerometer_orientation) % 360;\n\n        if (final_orientation == 0 || final_orientation == 180)\n        {\n            if (win_w * nv21_height > win_h * nv21_width)\n            {\n                roi_w = nv21_width;\n                roi_h = (nv21_width * win_h / win_w) / 2 * 2;\n                roi_x = 0;\n                roi_y = ((nv21_height - roi_h) / 2) / 2 * 2;\n            }\n            else\n            {\n                roi_h = nv21_height;\n                roi_w = (nv21_height * win_w / win_h) / 2 * 2;\n                roi_x = ((nv21_width - roi_w) / 2) / 2 * 2;\n                roi_y = 0;\n            }\n\n            nv21_roi_x = roi_x;\n            nv21_roi_y = roi_y;\n            nv21_roi_w = roi_w;\n            nv21_roi_h = roi_h;\n        }\n        if (final_orientation == 90 || final_orientation == 270)\n        {\n            if (win_w * nv21_width > win_h * nv21_height)\n            {\n                roi_w = nv21_height;\n                roi_h = (nv21_height * win_h / win_w) / 2 * 2;\n                roi_x = 0;\n                roi_y = ((nv21_width - roi_h) / 2) / 2 * 2;\n            }\n            else\n            {\n                roi_h = nv21_width;\n                roi_w = (nv21_width * win_w / win_h) / 2 * 2;\n                roi_x = ((nv21_height - roi_w) / 2) / 2 * 2;\n                roi_y = 0;\n            }\n\n            nv21_roi_x = roi_y;\n            nv21_roi_y = roi_x;\n            nv21_roi_w = roi_h;\n            nv21_roi_h = roi_w;\n        }\n\n        if (camera_facing == 0)\n        {\n            if (camera_orientation == 0 && accelerometer_orientation == 0)\n            {\n                rotate_type = 2;\n            }\n            if (camera_orientation == 0 && accelerometer_orientation == 90)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 0 && accelerometer_orientation == 180)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 0 && accelerometer_orientation == 270)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 0)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 90)\n            {\n                rotate_type = 2;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 180)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 90 && accelerometer_orientation == 270)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 0)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 90)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 180)\n            {\n                rotate_type = 2;\n            }\n            if (camera_orientation == 180 && accelerometer_orientation == 270)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 0)\n            {\n                rotate_type = 7;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 90)\n            {\n                rotate_type = 4;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 180)\n            {\n                rotate_type = 5;\n            }\n            if (camera_orientation == 270 && accelerometer_orientation == 270)\n            {\n                rotate_type = 2;\n            }\n        }\n        else\n        {\n            if (final_orientation == 0)\n            {\n                rotate_type = 1;\n            }\n            if (final_orientation == 90)\n            {\n                rotate_type = 6;\n            }\n            if (final_orientation == 180)\n            {\n                rotate_type = 3;\n            }\n            if (final_orientation == 270)\n            {\n                rotate_type = 8;\n            }\n        }\n\n        if (accelerometer_orientation == 0)\n        {\n            render_w = roi_w;\n            render_h = roi_h;\n            render_rotate_type = 1;\n        }\n        if (accelerometer_orientation == 90)\n        {\n            render_w = roi_h;\n            render_h = roi_w;\n            render_rotate_type = 8;\n        }\n        if (accelerometer_orientation == 180)\n        {\n            render_w = roi_w;\n            render_h = roi_h;\n            render_rotate_type = 3;\n        }\n        if (accelerometer_orientation == 270)\n        {\n            render_w = roi_h;\n            render_h = roi_w;\n            render_rotate_type = 6;\n        }\n    }\n\n    // crop and rotate nv21\n    cv::Mat nv21_croprotated(roi_h + roi_h / 2, roi_w, CV_8UC1);\n    {\n        const unsigned char* srcY = nv21 + nv21_roi_y * nv21_width + nv21_roi_x;\n        unsigned char* dstY = nv21_croprotated.data;\n        ncnn::kanna_rotate_c1(srcY, nv21_roi_w, nv21_roi_h, nv21_width, dstY, roi_w, roi_h, roi_w, rotate_type);\n\n        const unsigned char* srcUV = nv21 + nv21_width * nv21_height + nv21_roi_y * nv21_width / 2 + nv21_roi_x;\n        unsigned char* dstUV = nv21_croprotated.data + roi_w * roi_h;\n        ncnn::kanna_rotate_c2(srcUV, nv21_roi_w / 2, nv21_roi_h / 2, nv21_width, dstUV, roi_w / 2, roi_h / 2, roi_w, rotate_type);\n    }\n\n    // nv21_croprotated to rgb\n    cv::Mat rgb(roi_h, roi_w, CV_8UC3);\n    ncnn::yuv420sp2rgb(nv21_croprotated.data, roi_w, roi_h, rgb.data);\n\n    on_image_render(rgb);\n\n    // rotate to native window orientation\n    cv::Mat rgb_render(render_h, render_w, CV_8UC3);\n    ncnn::kanna_rotate_c3(rgb.data, roi_w, roi_h, rgb_render.data, render_w, render_h, render_rotate_type);\n\n    ANativeWindow_setBuffersGeometry(win, render_w, render_h, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM);\n\n    ANativeWindow_Buffer buf;\n    ANativeWindow_lock(win, &buf, NULL);\n\n    // scale to target size\n    if (buf.format == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM || buf.format == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM)\n    {\n        for (int y = 0; y < render_h; y++)\n        {\n            const unsigned char* ptr = rgb_render.ptr<const unsigned char>(y);\n            unsigned char* outptr = (unsigned char*)buf.bits + buf.stride * 4 * y;\n\n            int x = 0;\n#if __ARM_NEON\n            for (; x + 7 < render_w; x += 8)\n            {\n                uint8x8x3_t _rgb = vld3_u8(ptr);\n                uint8x8x4_t _rgba;\n                _rgba.val[0] = _rgb.val[0];\n                _rgba.val[1] = _rgb.val[1];\n                _rgba.val[2] = _rgb.val[2];\n                _rgba.val[3] = vdup_n_u8(255);\n                vst4_u8(outptr, _rgba);\n\n                ptr += 24;\n                outptr += 32;\n            }\n#endif // __ARM_NEON\n            for (; x < render_w; x++)\n            {\n                outptr[0] = ptr[0];\n                outptr[1] = ptr[1];\n                outptr[2] = ptr[2];\n                outptr[3] = 255;\n\n                ptr += 3;\n                outptr += 4;\n            }\n        }\n    }\n\n    ANativeWindow_unlockAndPost(win);\n}\n"
  },
  {
    "path": "app/src/main/jni/ndkcamera.h",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#ifndef NDKCAMERA_H\n#define NDKCAMERA_H\n\n#include <android/looper.h>\n#include <android/native_window.h>\n#include <android/sensor.h>\n#include <camera/NdkCameraDevice.h>\n#include <camera/NdkCameraManager.h>\n#include <camera/NdkCameraMetadata.h>\n#include <media/NdkImageReader.h>\n\n#include <opencv2/core/core.hpp>\n\nclass NdkCamera\n{\npublic:\n    NdkCamera();\n    virtual ~NdkCamera();\n\n    // facing 0=front 1=back\n    int open(int camera_facing = 0);\n    void close();\n\n    virtual void on_image(const cv::Mat& rgb) const;\n\n    virtual void on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const;\n\npublic:\n    int camera_facing;\n    int camera_orientation;\n\nprivate:\n    ACameraManager* camera_manager;\n    ACameraDevice* camera_device;\n    AImageReader* image_reader;\n    ANativeWindow* image_reader_surface;\n    ACameraOutputTarget* image_reader_target;\n    ACaptureRequest* capture_request;\n    ACaptureSessionOutputContainer* capture_session_output_container;\n    ACaptureSessionOutput* capture_session_output;\n    ACameraCaptureSession* capture_session;\n};\n\nclass NdkCameraWindow : public NdkCamera\n{\npublic:\n    NdkCameraWindow();\n    virtual ~NdkCameraWindow();\n\n    void set_window(ANativeWindow* win);\n\n    virtual void on_image_render(cv::Mat& rgb) const;\n\n    virtual void on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const;\n\npublic:\n    mutable int accelerometer_orientation;\n\nprivate:\n    ASensorManager* sensor_manager;\n    mutable ASensorEventQueue* sensor_event_queue;\n    const ASensor* accelerometer_sensor;\n    ANativeWindow* win;\n};\n\n#endif // NDKCAMERA_H\n"
  },
  {
    "path": "app/src/main/jni/scrfd.cpp",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#include \"scrfd.h\"\n\n#include <string.h>\n#include <opencv2/core/core.hpp>\n#include <opencv2/imgproc/imgproc.hpp>\n\n#include \"cpu.h\"\n\nstatic inline float intersection_area(const FaceObject& a, const FaceObject& b)\n{\n    cv::Rect_<float> inter = a.rect & b.rect;\n    return inter.area();\n}\n\nstatic void qsort_descent_inplace(std::vector<FaceObject>& faceobjects, int left, int right)\n{\n    int i = left;\n    int j = right;\n    float p = faceobjects[(left + right) / 2].prob;\n\n    while (i <= j)\n    {\n        while (faceobjects[i].prob > p)\n            i++;\n\n        while (faceobjects[j].prob < p)\n            j--;\n\n        if (i <= j)\n        {\n            // swap\n            std::swap(faceobjects[i], faceobjects[j]);\n\n            i++;\n            j--;\n        }\n    }\n\n//     #pragma omp parallel sections\n    {\n//         #pragma omp section\n        {\n            if (left < j) qsort_descent_inplace(faceobjects, left, j);\n        }\n//         #pragma omp section\n        {\n            if (i < right) qsort_descent_inplace(faceobjects, i, right);\n        }\n    }\n}\n\nstatic void qsort_descent_inplace(std::vector<FaceObject>& faceobjects)\n{\n    if (faceobjects.empty())\n        return;\n\n    qsort_descent_inplace(faceobjects, 0, faceobjects.size() - 1);\n}\n\nstatic void nms_sorted_bboxes(const std::vector<FaceObject>& faceobjects, std::vector<int>& picked, float nms_threshold)\n{\n    picked.clear();\n\n    const int n = faceobjects.size();\n\n    std::vector<float> areas(n);\n    for (int i = 0; i < n; i++)\n    {\n        areas[i] = faceobjects[i].rect.area();\n    }\n\n    for (int i = 0; i < n; i++)\n    {\n        const FaceObject& a = faceobjects[i];\n\n        int keep = 1;\n        for (int j = 0; j < (int)picked.size(); j++)\n        {\n            const FaceObject& b = faceobjects[picked[j]];\n\n            // intersection over union\n            float inter_area = intersection_area(a, b);\n            float union_area = areas[i] + areas[picked[j]] - inter_area;\n            //             float IoU = inter_area / union_area\n            if (inter_area / union_area > nms_threshold)\n                keep = 0;\n        }\n\n        if (keep)\n            picked.push_back(i);\n    }\n}\n\n// insightface/detection/scrfd/mmdet/core/anchor/anchor_generator.py gen_single_level_base_anchors()\nstatic ncnn::Mat generate_anchors(int base_size, const ncnn::Mat& ratios, const ncnn::Mat& scales)\n{\n    int num_ratio = ratios.w;\n    int num_scale = scales.w;\n\n    ncnn::Mat anchors;\n    anchors.create(4, num_ratio * num_scale);\n\n    const float cx = 0;\n    const float cy = 0;\n\n    for (int i = 0; i < num_ratio; i++)\n    {\n        float ar = ratios[i];\n\n        int r_w = round(base_size / sqrt(ar));\n        int r_h = round(r_w * ar); //round(base_size * sqrt(ar));\n\n        for (int j = 0; j < num_scale; j++)\n        {\n            float scale = scales[j];\n\n            float rs_w = r_w * scale;\n            float rs_h = r_h * scale;\n\n            float* anchor = anchors.row(i * num_scale + j);\n\n            anchor[0] = cx - rs_w * 0.5f;\n            anchor[1] = cy - rs_h * 0.5f;\n            anchor[2] = cx + rs_w * 0.5f;\n            anchor[3] = cy + rs_h * 0.5f;\n        }\n    }\n\n    return anchors;\n}\n\nstatic void generate_proposals(const ncnn::Mat& anchors, int feat_stride, const ncnn::Mat& score_blob, const ncnn::Mat& bbox_blob, const ncnn::Mat& kps_blob, float prob_threshold, std::vector<FaceObject>& faceobjects)\n{\n    int w = score_blob.w;\n    int h = score_blob.h;\n\n    // generate face proposal from bbox deltas and shifted anchors\n    const int num_anchors = anchors.h;\n\n    for (int q = 0; q < num_anchors; q++)\n    {\n        const float* anchor = anchors.row(q);\n\n        const ncnn::Mat score = score_blob.channel(q);\n        const ncnn::Mat bbox = bbox_blob.channel_range(q * 4, 4);\n\n        // shifted anchor\n        float anchor_y = anchor[1];\n\n        float anchor_w = anchor[2] - anchor[0];\n        float anchor_h = anchor[3] - anchor[1];\n\n        for (int i = 0; i < h; i++)\n        {\n            float anchor_x = anchor[0];\n\n            for (int j = 0; j < w; j++)\n            {\n                int index = i * w + j;\n\n                float prob = score[index];\n\n                if (prob >= prob_threshold)\n                {\n                    // insightface/detection/scrfd/mmdet/models/dense_heads/scrfd_head.py _get_bboxes_single()\n                    float dx = bbox.channel(0)[index] * feat_stride;\n                    float dy = bbox.channel(1)[index] * feat_stride;\n                    float dw = bbox.channel(2)[index] * feat_stride;\n                    float dh = bbox.channel(3)[index] * feat_stride;\n\n                    // insightface/detection/scrfd/mmdet/core/bbox/transforms.py distance2bbox()\n                    float cx = anchor_x + anchor_w * 0.5f;\n                    float cy = anchor_y + anchor_h * 0.5f;\n\n                    float x0 = cx - dx;\n                    float y0 = cy - dy;\n                    float x1 = cx + dw;\n                    float y1 = cy + dh;\n\n                    FaceObject obj;\n                    obj.rect.x = x0;\n                    obj.rect.y = y0;\n                    obj.rect.width = x1 - x0 + 1;\n                    obj.rect.height = y1 - y0 + 1;\n                    obj.prob = prob;\n\n                    if (!kps_blob.empty())\n                    {\n                        const ncnn::Mat kps = kps_blob.channel_range(q * 10, 10);\n\n                        obj.landmark[0].x = cx + kps.channel(0)[index] * feat_stride;\n                        obj.landmark[0].y = cy + kps.channel(1)[index] * feat_stride;\n                        obj.landmark[1].x = cx + kps.channel(2)[index] * feat_stride;\n                        obj.landmark[1].y = cy + kps.channel(3)[index] * feat_stride;\n                        obj.landmark[2].x = cx + kps.channel(4)[index] * feat_stride;\n                        obj.landmark[2].y = cy + kps.channel(5)[index] * feat_stride;\n                        obj.landmark[3].x = cx + kps.channel(6)[index] * feat_stride;\n                        obj.landmark[3].y = cy + kps.channel(7)[index] * feat_stride;\n                        obj.landmark[4].x = cx + kps.channel(8)[index] * feat_stride;\n                        obj.landmark[4].y = cy + kps.channel(9)[index] * feat_stride;\n                    }\n\n                    faceobjects.push_back(obj);\n                }\n\n                anchor_x += feat_stride;\n            }\n\n            anchor_y += feat_stride;\n        }\n    }\n}\n\nint SCRFD::load(const char* modeltype, bool use_gpu)\n{\n    scrfd.clear();\n\n    ncnn::set_cpu_powersave(2);\n    ncnn::set_omp_num_threads(ncnn::get_big_cpu_count());\n\n    scrfd.opt = ncnn::Option();\n\n#if NCNN_VULKAN\n    scrfd.opt.use_vulkan_compute = use_gpu;\n#endif\n\n    scrfd.opt.num_threads = ncnn::get_big_cpu_count();\n\n    char parampath[256];\n    char modelpath[256];\n    sprintf(parampath, \"scrfd_%s-opt2.param\", modeltype);\n    sprintf(modelpath, \"scrfd_%s-opt2.bin\", modeltype);\n\n    scrfd.load_param(parampath);\n    scrfd.load_model(modelpath);\n\n    has_kps = strstr(modeltype, \"_kps\") != NULL;\n\n    return 0;\n}\n\nint SCRFD::load(AAssetManager* mgr, const char* modeltype, bool use_gpu)\n{\n    scrfd.clear();\n\n    ncnn::set_cpu_powersave(2);\n    ncnn::set_omp_num_threads(ncnn::get_big_cpu_count());\n\n    scrfd.opt = ncnn::Option();\n\n#if NCNN_VULKAN\n    scrfd.opt.use_vulkan_compute = use_gpu;\n#endif\n\n    scrfd.opt.num_threads = ncnn::get_big_cpu_count();\n\n    char parampath[256];\n    char modelpath[256];\n    sprintf(parampath, \"scrfd_%s-opt2.param\", modeltype);\n    sprintf(modelpath, \"scrfd_%s-opt2.bin\", modeltype);\n\n    scrfd.load_param(mgr, parampath);\n    scrfd.load_model(mgr, modelpath);\n\n    has_kps = strstr(modeltype, \"_kps\") != NULL;\n\n    return 0;\n}\n\nint SCRFD::detect(const cv::Mat& rgb, std::vector<FaceObject>& faceobjects, float prob_threshold, float nms_threshold)\n{\n    int width = rgb.cols;\n    int height = rgb.rows;\n\n    // insightface/detection/scrfd/configs/scrfd/scrfd_500m.py\n    const int target_size = 640;\n\n    // pad to multiple of 32\n    int w = width;\n    int h = height;\n    float scale = 1.f;\n    if (w > h)\n    {\n        scale = (float)target_size / w;\n        w = target_size;\n        h = h * scale;\n    }\n    else\n    {\n        scale = (float)target_size / h;\n        h = target_size;\n        w = w * scale;\n    }\n\n    ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB, width, height, w, h);\n\n    // pad to target_size rectangle\n    int wpad = (w + 31) / 32 * 32 - w;\n    int hpad = (h + 31) / 32 * 32 - h;\n    ncnn::Mat in_pad;\n    ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, ncnn::BORDER_CONSTANT, 0.f);\n\n    const float mean_vals[3] = {127.5f, 127.5f, 127.5f};\n    const float norm_vals[3] = {1/128.f, 1/128.f, 1/128.f};\n    in_pad.substract_mean_normalize(mean_vals, norm_vals);\n\n    ncnn::Extractor ex = scrfd.create_extractor();\n\n    ex.input(\"input.1\", in_pad);\n\n    std::vector<FaceObject> faceproposals;\n\n    // stride 8\n    {\n        ncnn::Mat score_blob, bbox_blob, kps_blob;\n        ex.extract(\"score_8\", score_blob);\n        ex.extract(\"bbox_8\", bbox_blob);\n        if (has_kps)\n            ex.extract(\"kps_8\", kps_blob);\n\n        const int base_size = 16;\n        const int feat_stride = 8;\n        ncnn::Mat ratios(1);\n        ratios[0] = 1.f;\n        ncnn::Mat scales(2);\n        scales[0] = 1.f;\n        scales[1] = 2.f;\n        ncnn::Mat anchors = generate_anchors(base_size, ratios, scales);\n\n        std::vector<FaceObject> faceobjects8;\n        generate_proposals(anchors, feat_stride, score_blob, bbox_blob, kps_blob, prob_threshold, faceobjects8);\n\n        faceproposals.insert(faceproposals.end(), faceobjects8.begin(), faceobjects8.end());\n    }\n\n    // stride 16\n    {\n        ncnn::Mat score_blob, bbox_blob, kps_blob;\n        ex.extract(\"score_16\", score_blob);\n        ex.extract(\"bbox_16\", bbox_blob);\n        if (has_kps)\n            ex.extract(\"kps_16\", kps_blob);\n\n        const int base_size = 64;\n        const int feat_stride = 16;\n        ncnn::Mat ratios(1);\n        ratios[0] = 1.f;\n        ncnn::Mat scales(2);\n        scales[0] = 1.f;\n        scales[1] = 2.f;\n        ncnn::Mat anchors = generate_anchors(base_size, ratios, scales);\n\n        std::vector<FaceObject> faceobjects16;\n        generate_proposals(anchors, feat_stride, score_blob, bbox_blob, kps_blob, prob_threshold, faceobjects16);\n\n        faceproposals.insert(faceproposals.end(), faceobjects16.begin(), faceobjects16.end());\n    }\n\n    // stride 32\n    {\n        ncnn::Mat score_blob, bbox_blob, kps_blob;\n        ex.extract(\"score_32\", score_blob);\n        ex.extract(\"bbox_32\", bbox_blob);\n        if (has_kps)\n            ex.extract(\"kps_32\", kps_blob);\n\n        const int base_size = 256;\n        const int feat_stride = 32;\n        ncnn::Mat ratios(1);\n        ratios[0] = 1.f;\n        ncnn::Mat scales(2);\n        scales[0] = 1.f;\n        scales[1] = 2.f;\n        ncnn::Mat anchors = generate_anchors(base_size, ratios, scales);\n\n        std::vector<FaceObject> faceobjects32;\n        generate_proposals(anchors, feat_stride, score_blob, bbox_blob, kps_blob, prob_threshold, faceobjects32);\n\n        faceproposals.insert(faceproposals.end(), faceobjects32.begin(), faceobjects32.end());\n    }\n\n    // sort all proposals by score from highest to lowest\n    qsort_descent_inplace(faceproposals);\n\n    // apply nms with nms_threshold\n    std::vector<int> picked;\n    nms_sorted_bboxes(faceproposals, picked, nms_threshold);\n\n    int face_count = picked.size();\n\n    faceobjects.resize(face_count);\n    for (int i = 0; i < face_count; i++)\n    {\n        faceobjects[i] = faceproposals[picked[i]];\n\n        // adjust offset to original unpadded\n        float x0 = (faceobjects[i].rect.x - (wpad / 2)) / scale;\n        float y0 = (faceobjects[i].rect.y - (hpad / 2)) / scale;\n        float x1 = (faceobjects[i].rect.x + faceobjects[i].rect.width - (wpad / 2)) / scale;\n        float y1 = (faceobjects[i].rect.y + faceobjects[i].rect.height - (hpad / 2)) / scale;\n\n        x0 = std::max(std::min(x0, (float)width - 1), 0.f);\n        y0 = std::max(std::min(y0, (float)height - 1), 0.f);\n        x1 = std::max(std::min(x1, (float)width - 1), 0.f);\n        y1 = std::max(std::min(y1, (float)height - 1), 0.f);\n\n        faceobjects[i].rect.x = x0;\n        faceobjects[i].rect.y = y0;\n        faceobjects[i].rect.width = x1 - x0;\n        faceobjects[i].rect.height = y1 - y0;\n\n        if (has_kps)\n        {\n            float x0 = (faceobjects[i].landmark[0].x - (wpad / 2)) / scale;\n            float y0 = (faceobjects[i].landmark[0].y - (hpad / 2)) / scale;\n            float x1 = (faceobjects[i].landmark[1].x - (wpad / 2)) / scale;\n            float y1 = (faceobjects[i].landmark[1].y - (hpad / 2)) / scale;\n            float x2 = (faceobjects[i].landmark[2].x - (wpad / 2)) / scale;\n            float y2 = (faceobjects[i].landmark[2].y - (hpad / 2)) / scale;\n            float x3 = (faceobjects[i].landmark[3].x - (wpad / 2)) / scale;\n            float y3 = (faceobjects[i].landmark[3].y - (hpad / 2)) / scale;\n            float x4 = (faceobjects[i].landmark[4].x - (wpad / 2)) / scale;\n            float y4 = (faceobjects[i].landmark[4].y - (hpad / 2)) / scale;\n\n            faceobjects[i].landmark[0].x = std::max(std::min(x0, (float)width - 1), 0.f);\n            faceobjects[i].landmark[0].y = std::max(std::min(y0, (float)height - 1), 0.f);\n            faceobjects[i].landmark[1].x = std::max(std::min(x1, (float)width - 1), 0.f);\n            faceobjects[i].landmark[1].y = std::max(std::min(y1, (float)height - 1), 0.f);\n            faceobjects[i].landmark[2].x = std::max(std::min(x2, (float)width - 1), 0.f);\n            faceobjects[i].landmark[2].y = std::max(std::min(y2, (float)height - 1), 0.f);\n            faceobjects[i].landmark[3].x = std::max(std::min(x3, (float)width - 1), 0.f);\n            faceobjects[i].landmark[3].y = std::max(std::min(y3, (float)height - 1), 0.f);\n            faceobjects[i].landmark[4].x = std::max(std::min(x4, (float)width - 1), 0.f);\n            faceobjects[i].landmark[4].y = std::max(std::min(y4, (float)height - 1), 0.f);\n        }\n    }\n\n    return 0;\n}\n\nint SCRFD::draw(cv::Mat& rgb, const std::vector<FaceObject>& faceobjects)\n{\n    for (size_t i = 0; i < faceobjects.size(); i++)\n    {\n        const FaceObject& obj = faceobjects[i];\n\n//         fprintf(stderr, \"%.5f at %.2f %.2f %.2f x %.2f\\n\", obj.prob,\n//                 obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height);\n\n        cv::rectangle(rgb, obj.rect, cv::Scalar(0, 255, 0));\n\n        if (has_kps)\n        {\n            cv::circle(rgb, obj.landmark[0], 2, cv::Scalar(255, 255, 0), -1);\n            cv::circle(rgb, obj.landmark[1], 2, cv::Scalar(255, 255, 0), -1);\n            cv::circle(rgb, obj.landmark[2], 2, cv::Scalar(255, 255, 0), -1);\n            cv::circle(rgb, obj.landmark[3], 2, cv::Scalar(255, 255, 0), -1);\n            cv::circle(rgb, obj.landmark[4], 2, cv::Scalar(255, 255, 0), -1);\n        }\n\n        char text[256];\n        sprintf(text, \"%.1f%%\", obj.prob * 100);\n\n        int baseLine = 0;\n        cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);\n\n        int x = obj.rect.x;\n        int y = obj.rect.y - label_size.height - baseLine;\n        if (y < 0)\n            y = 0;\n        if (x + label_size.width > rgb.cols)\n            x = rgb.cols - label_size.width;\n\n        cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)), cv::Scalar(255, 255, 255), -1);\n\n        cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0), 1);\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "app/src/main/jni/scrfd.h",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#ifndef SCRFD_H\n#define SCRFD_H\n\n#include <opencv2/core/core.hpp>\n\n#include <net.h>\n\nstruct FaceObject\n{\n    cv::Rect_<float> rect;\n    cv::Point2f landmark[5];\n    float prob;\n};\n\nclass SCRFD\n{\npublic:\n    int load(const char* modeltype, bool use_gpu = false);\n\n    int load(AAssetManager* mgr, const char* modeltype, bool use_gpu = false);\n\n    int detect(const cv::Mat& rgb, std::vector<FaceObject>& faceobjects, float prob_threshold = 0.5f, float nms_threshold = 0.45f);\n\n    int draw(cv::Mat& rgb, const std::vector<FaceObject>& faceobjects);\n\nprivate:\n    ncnn::Net scrfd;\n    bool has_kps;\n};\n\n#endif // SCRFD_H\n"
  },
  {
    "path": "app/src/main/jni/scrfdncnn.cpp",
    "content": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.\n//\n// Licensed under the BSD 3-Clause License (the \"License\"); you may not use this file except\n// in compliance with the License. You may obtain a copy of the License at\n//\n// https://opensource.org/licenses/BSD-3-Clause\n//\n// Unless required by applicable law or agreed to in writing, software distributed\n// under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n// CONDITIONS OF ANY KIND, either express or implied. See the License for the\n// specific language governing permissions and limitations under the License.\n\n#include <android/asset_manager_jni.h>\n#include <android/native_window_jni.h>\n#include <android/native_window.h>\n\n#include <android/log.h>\n\n#include <jni.h>\n\n#include <string>\n#include <vector>\n\n#include <platform.h>\n#include <benchmark.h>\n\n#include \"scrfd.h\"\n\n#include \"ndkcamera.h\"\n\n#include <opencv2/core/core.hpp>\n#include <opencv2/imgproc/imgproc.hpp>\n\n#if __ARM_NEON\n#include <arm_neon.h>\n#endif // __ARM_NEON\n\nstatic int draw_unsupported(cv::Mat& rgb)\n{\n    const char text[] = \"unsupported\";\n\n    int baseLine = 0;\n    cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 1.0, 1, &baseLine);\n\n    int y = (rgb.rows - label_size.height) / 2;\n    int x = (rgb.cols - label_size.width) / 2;\n\n    cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),\n                    cv::Scalar(255, 255, 255), -1);\n\n    cv::putText(rgb, text, cv::Point(x, y + label_size.height),\n                cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0, 0, 0));\n\n    return 0;\n}\n\nstatic int draw_fps(cv::Mat& rgb)\n{\n    // resolve moving average\n    float avg_fps = 0.f;\n    {\n        static double t0 = 0.f;\n        static float fps_history[10] = {0.f};\n\n        double t1 = ncnn::get_current_time();\n        if (t0 == 0.f)\n        {\n            t0 = t1;\n            return 0;\n        }\n\n        float fps = 1000.f / (t1 - t0);\n        t0 = t1;\n\n        for (int i = 9; i >= 1; i--)\n        {\n            fps_history[i] = fps_history[i - 1];\n        }\n        fps_history[0] = fps;\n\n        if (fps_history[9] == 0.f)\n        {\n            return 0;\n        }\n\n        for (int i = 0; i < 10; i++)\n        {\n            avg_fps += fps_history[i];\n        }\n        avg_fps /= 10.f;\n    }\n\n    char text[32];\n    sprintf(text, \"FPS=%.2f\", avg_fps);\n\n    int baseLine = 0;\n    cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);\n\n    int y = 0;\n    int x = rgb.cols - label_size.width;\n\n    cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),\n                    cv::Scalar(255, 255, 255), -1);\n\n    cv::putText(rgb, text, cv::Point(x, y + label_size.height),\n                cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));\n\n    return 0;\n}\n\nstatic SCRFD* g_scrfd = 0;\nstatic ncnn::Mutex lock;\n\nclass MyNdkCamera : public NdkCameraWindow\n{\npublic:\n    virtual void on_image_render(cv::Mat& rgb) const;\n};\n\nvoid MyNdkCamera::on_image_render(cv::Mat& rgb) const\n{\n    // scrfd\n    {\n        ncnn::MutexLockGuard g(lock);\n\n        if (g_scrfd)\n        {\n            std::vector<FaceObject> faceobjects;\n            g_scrfd->detect(rgb, faceobjects);\n\n            g_scrfd->draw(rgb, faceobjects);\n        }\n        else\n        {\n            draw_unsupported(rgb);\n        }\n    }\n\n    draw_fps(rgb);\n}\n\nstatic MyNdkCamera* g_camera = 0;\n\nextern \"C\" {\n\nJNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)\n{\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"JNI_OnLoad\");\n\n    g_camera = new MyNdkCamera;\n\n    return JNI_VERSION_1_4;\n}\n\nJNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved)\n{\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"JNI_OnUnload\");\n\n    {\n        ncnn::MutexLockGuard g(lock);\n\n        delete g_scrfd;\n        g_scrfd = 0;\n    }\n\n    delete g_camera;\n    g_camera = 0;\n}\n\n// public native boolean loadModel(AssetManager mgr, int modelid, int cpugpu);\nJNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_loadModel(JNIEnv* env, jobject thiz, jobject assetManager, jint modelid, jint cpugpu)\n{\n    if (modelid < 0 || modelid > 7 || cpugpu < 0 || cpugpu > 1)\n    {\n        return JNI_FALSE;\n    }\n\n    AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);\n\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"loadModel %p\", mgr);\n\n    const char* modeltypes[] =\n    {\n        \"500m\",\n        \"500m_kps\",\n        \"1g\",\n        \"2.5g\",\n        \"2.5g_kps\",\n        \"10g\",\n        \"10g_kps\",\n        \"34g\"\n    };\n\n    const char* modeltype = modeltypes[(int)modelid];\n    bool use_gpu = (int)cpugpu == 1;\n\n    // reload\n    {\n        ncnn::MutexLockGuard g(lock);\n\n        if (use_gpu && ncnn::get_gpu_count() == 0)\n        {\n            // no gpu\n            delete g_scrfd;\n            g_scrfd = 0;\n        }\n        else\n        {\n            if (!g_scrfd)\n                g_scrfd = new SCRFD;\n            g_scrfd->load(mgr, modeltype, use_gpu);\n        }\n    }\n\n    return JNI_TRUE;\n}\n\n// public native boolean openCamera(int facing);\nJNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_openCamera(JNIEnv* env, jobject thiz, jint facing)\n{\n    if (facing < 0 || facing > 1)\n        return JNI_FALSE;\n\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"openCamera %d\", facing);\n\n    g_camera->open((int)facing);\n\n    return JNI_TRUE;\n}\n\n// public native boolean closeCamera();\nJNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_closeCamera(JNIEnv* env, jobject thiz)\n{\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"closeCamera\");\n\n    g_camera->close();\n\n    return JNI_TRUE;\n}\n\n// public native boolean setOutputWindow(Surface surface);\nJNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_setOutputWindow(JNIEnv* env, jobject thiz, jobject surface)\n{\n    ANativeWindow* win = ANativeWindow_fromSurface(env, surface);\n\n    __android_log_print(ANDROID_LOG_DEBUG, \"ncnn\", \"setOutputWindow %p\", win);\n\n    g_camera->set_window(win);\n\n    return JNI_TRUE;\n}\n\n}\n"
  },
  {
    "path": "app/src/main/res/layout/main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n              android:orientation=\"vertical\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"fill_parent\"\n              android:fitsSystemWindows=\"true\">\n\n    <LinearLayout\n        android:orientation=\"horizontal\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\">\n\n    <Button\n        android:id=\"@+id/buttonSwitchCamera\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"切换摄像头\" />\n\n    </LinearLayout>\n\n    <LinearLayout\n        android:orientation=\"horizontal\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\">\n\n    <Spinner\n        android:id=\"@+id/spinnerModel\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:drawSelectorOnTop=\"true\"\n        android:entries=\"@array/model_array\" />\n\n    <Spinner\n        android:id=\"@+id/spinnerCPUGPU\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:drawSelectorOnTop=\"true\"\n        android:entries=\"@array/cpugpu_array\" />\n\n    </LinearLayout>\n\n    <SurfaceView\n        android:id=\"@+id/cameraview\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"fill_parent\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"app_name\">scrfdncnn</string>\n    <string-array name=\"model_array\">\n        <item>500m</item>\n        <item>500m_kps</item>\n        <item>1g</item>\n        <item>2.5g</item>\n        <item>2.5g_kps</item>\n        <item>10g</item>\n        <item>10g_kps</item>\n        <item>34g</item>\n    </string-array>\n    <string-array name=\"cpugpu_array\">\n        <item>CPU</item>\n        <item>GPU</item>\n    </string-array>\n</resources>\n"
  },
  {
    "path": "build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\nplugins {\nid 'com.android.application' version '8.7.3' apply false\n}\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Wed Dec 25 17:36:46 CST 2024\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.12-bin.zip\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif [ \"$cygwin\" = \"true\" -o \"$msys\" = \"true\" ] ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=`expr $i + 1`\n    done\n    case $i in\n        0) set -- ;;\n        1) set -- \"$args0\" ;;\n        2) set -- \"$args0\" \"$args1\" ;;\n        3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=`save \"$@\"`\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\r\n@rem you may not use this file except in compliance with the License.\r\n@rem You may obtain a copy of the License at\r\n@rem\r\n@rem      https://www.apache.org/licenses/LICENSE-2.0\r\n@rem\r\n@rem Unless required by applicable law or agreed to in writing, software\r\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\r\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n@rem See the License for the specific language governing permissions and\r\n@rem limitations under the License.\r\n@rem\r\n\r\n@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\r\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto execute\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto execute\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "settings.gradle",
    "content": "pluginManagement {\n    repositories {\n        google()\n        mavenCentral()\n        gradlePluginPortal()\n    }\n}\ndependencyResolutionManagement {\n    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)\n    repositories {\n        google()\n        mavenCentral()\n    }\n}\n\nrootProject.name = \"scrfdncnn\"\ninclude ':app'\n"
  }
]