Skip to content

Commit 8073537

Browse files
committed
Setup Kotlin/Native
1 parent fcd2d0a commit 8073537

File tree

13 files changed

+128
-5
lines changed

13 files changed

+128
-5
lines changed

Diff for: .github/workflows/android.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ jobs:
1414
with:
1515
java-version: 1.8
1616
- name: Build with Gradle
17-
run: ./gradlew build
17+
run: |
18+
chmod +x build.sh
19+
./build.sh
1820
- name: Upload artifact
1921
uses: actions/upload-artifact@v1
2022
if: success()

Diff for: README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
### Binary Camera2 ![Android CI](https://github.com/demba003/BinaryCamera2/workflows/Android%20CI/badge.svg?branch=master)
22

33
App shows how to implement camera live stream processing using different techniques
4-
- Processing via Kotlin code
5-
- Processing via JNI
4+
- Processing via Kotlin/JVM
5+
- Processing via JNI (C++ and Kotlin/Native)
66
- Processing via RenderScript
77

88
App is making direct use of Camera2 API

Diff for: app/src/main/java/pl/pk/binarycamera2/BinaryCameraActivity.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class BinaryCameraActivity : AppCompatActivity() {
2020
private val buttons: List<Button> by lazy {
2121
listOf(
2222
originalPreviewButton,
23-
simpleKotlinButton, simpleCppButton, simpleRsButton,
23+
simpleKotlinButton, simpleKtNativeButton, simpleCppButton, simpleRsButton,
2424
bradleyKotlinButton, bradleyCppButton, bradleyRsButton,
2525
bradleyIntKotlinButton, bradleyIntCppButton
2626
)
@@ -51,6 +51,7 @@ class BinaryCameraActivity : AppCompatActivity() {
5151
benchmarkButton.setOnClickListener { viewModel.benchmark() }
5252

5353
simpleKotlinButton.setOnClickListener { viewModel.switchMode(ProcessingMode.SIMPLE_KT) }
54+
simpleKtNativeButton.setOnClickListener { viewModel.switchMode(ProcessingMode.SIMPLE_KT_NATIVE) }
5455
simpleCppButton.setOnClickListener { viewModel.switchMode(ProcessingMode.SIMPLE_CPP) }
5556
simpleRsButton.setOnClickListener { viewModel.switchMode(ProcessingMode.SIMPLE_RS) }
5657

@@ -86,6 +87,7 @@ class BinaryCameraActivity : AppCompatActivity() {
8687
ProcessingMode.BRADLEY_INT_CPP -> bradleyIntCppButton.disable()
8788
ProcessingMode.BRADLEY_RS -> bradleyRsButton.disable()
8889
ProcessingMode.SIMPLE_KT -> simpleKotlinButton.disable()
90+
ProcessingMode.SIMPLE_KT_NATIVE -> simpleKtNativeButton.disable()
8991
ProcessingMode.SIMPLE_CPP -> simpleCppButton.disable()
9092
ProcessingMode.SIMPLE_RS -> simpleRsButton.disable()
9193
else -> {

Diff for: app/src/main/java/pl/pk/binarycamera2/ProcessorProxy.kt

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class ProcessorProxy(rs: RenderScript) : Processor, Benchmarkable, KoinComponent
3232
ProcessingMode.ORIGINAL to YuvToMonochrome(rs),
3333

3434
ProcessingMode.SIMPLE_KT to pl.pk.binarizer.jvm.SimpleBinarization(rs),
35+
ProcessingMode.SIMPLE_KT_NATIVE to pl.pk.binarizer.ktnative.SimpleBinarization(rs),
3536
ProcessingMode.SIMPLE_CPP to pl.pk.binarizer.cpp.SimpleBinarization(rs),
3637
ProcessingMode.SIMPLE_RS to pl.pk.binarizer.rs.SimpleBinarization(rs),
3738

Diff for: app/src/main/res/layout/main.xml

+7
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@
7777
android:layout_weight="1"
7878
android:text="@string/simple_kotlin" />
7979

80+
<Button
81+
android:id="@+id/simpleKtNativeButton"
82+
android:layout_width="match_parent"
83+
android:layout_height="wrap_content"
84+
android:layout_weight="1"
85+
android:text="@string/simple_ktnative" />
86+
8087
<Button
8188
android:id="@+id/simpleCppButton"
8289
android:layout_width="match_parent"

Diff for: app/src/main/res/values/strings.xml

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<string name="start_benchmark">Start benchmark</string>
55
<string name="simple_kotlin">Simple Kotlin</string>
66
<string name="simple_cpp">Simple C++</string>
7+
<string name="simple_ktnative">Simple Kotlin/Native</string>
78
<string name="simple_rs">Simple RS</string>
89
<string name="bradley_kotlin">Bradley Kotlin</string>
910
<string name="bradley_int_kotlin">Bradley Int Kotlin</string>

Diff for: binarizer/src/main/java/pl/pk/binarizer/ProcessingMode.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package pl.pk.binarizer
22

33
enum class ProcessingMode {
44
ORIGINAL,
5-
SIMPLE_KT, SIMPLE_CPP, SIMPLE_RS,
5+
SIMPLE_KT, SIMPLE_KT_NATIVE, SIMPLE_CPP, SIMPLE_RS,
66
BRADLEY_KT, BRADLEY_CPP, BRADLEY_RS,
77
BRADLEY_INT_KT, BRADLEY_INT_CPP
88
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package pl.pk.binarizer.ktnative
2+
3+
import android.renderscript.Allocation
4+
import android.renderscript.RenderScript
5+
import pl.pk.binarizer.Processor
6+
import pl.pk.binarizer.rs.ScriptC_YuvToMonochrome
7+
8+
class SimpleBinarization(rs: RenderScript) : Processor {
9+
10+
private val kernel = ScriptC_YuvToMonochrome(rs)
11+
private external fun binarize(input: ByteArray, output: ByteArray, size: Int)
12+
13+
init {
14+
System.loadLibrary("ktnative")
15+
}
16+
17+
override fun process(input: Allocation, output: Allocation) {
18+
val monochromeBytesSize = (input.bytesSize / 1.5).toInt()
19+
val originalBytes = ByteArray(monochromeBytesSize)
20+
val processedBytes = ByteArray(monochromeBytesSize)
21+
22+
input.copy1DRangeTo(0, monochromeBytesSize, originalBytes)
23+
24+
binarize(originalBytes, processedBytes, monochromeBytesSize)
25+
26+
input.copy1DRangeFrom(0, monochromeBytesSize, processedBytes)
27+
28+
kernel._currentFrame = input
29+
kernel.forEach_process(output)
30+
}
31+
32+
}

Diff for: build.sh

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env bash
2+
./gradlew :ktnative:build
3+
./gradlew build

Diff for: ktnative/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

Diff for: ktnative/build.gradle.kts

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTargetPreset
2+
3+
plugins {
4+
kotlin("multiplatform")
5+
}
6+
7+
val androidPresets = mapOf(
8+
"arm32" to "androidNativeArm32",
9+
"arm64" to "androidNativeArm64",
10+
"x86" to "androidNativeX86",
11+
"x64" to "androidNativeX64"
12+
)
13+
14+
val directories = mapOf(
15+
"arm32" to "armeabi-v7a",
16+
"arm64" to "arm64-v8a",
17+
"x86" to "x86",
18+
"x64" to "x86_64"
19+
)
20+
21+
kotlin {
22+
androidPresets.forEach {
23+
val preset = kotlin.presets[it.value] as KotlinNativeTargetPreset
24+
targetFromPreset(preset, it.key) {
25+
binaries {
26+
sharedLib {
27+
// freeCompilerArgs += "-opt"
28+
outputDirectory = File("${project(":binarizer").projectDir}/src/main/jniLibs/${directories[it.key]}/")
29+
baseName = "ktnative"
30+
}
31+
}
32+
}
33+
}
34+
35+
sourceSets {
36+
val arm64Main by getting {}
37+
val arm32Main by getting {}
38+
val x64Main by getting {}
39+
val x86Main by getting {}
40+
arm32Main.dependsOn(arm64Main)
41+
x64Main.dependsOn(arm64Main)
42+
x86Main.dependsOn(arm64Main)
43+
}
44+
}

Diff for: ktnative/src/arm64Main/kotlin/ktnative.kt

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import kotlinx.cinterop.*
2+
import platform.android.JNIEnvVar
3+
import platform.android.jbyteArray
4+
import platform.android.jclass
5+
import platform.android.jint
6+
7+
8+
@CName("Java_pl_pk_binarizer_ktnative_SimpleBinarization_binarize")
9+
fun simpleBinarize(
10+
env: CPointer<JNIEnvVar>,
11+
thiz: jclass,
12+
input: jbyteArray,
13+
output: jbyteArray,
14+
size: jint
15+
) {
16+
val originalBytes = env.pointed.pointed!!.GetByteArrayElements!!.invoke(env, input, null)!!
17+
val processedBytes = env.pointed.pointed!!.GetByteArrayElements!!.invoke(env, output, null)!!
18+
19+
for (i in 0 until size) {
20+
if (originalBytes[i] < 0) {
21+
processedBytes[i] = -1
22+
} else {
23+
processedBytes[i] = 0
24+
}
25+
}
26+
27+
env.pointed.pointed!!.ReleaseByteArrayElements!!.invoke(env, input, originalBytes, 0)
28+
env.pointed.pointed!!.ReleaseByteArrayElements!!.invoke(env, output, processedBytes, 0)
29+
}

Diff for: settings.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
rootProject.name='BinaryCamera2'
22
include ':app'
33
include ':binarizer'
4+
include ':ktnative'

0 commit comments

Comments
 (0)