diff --git a/asan_run.sh b/asan_run.sh index 555cd772..ad9b1d97 100755 --- a/asan_run.sh +++ b/asan_run.sh @@ -8,7 +8,7 @@ if [ "$1""x" == "buildx" ]; then fi LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.6.0.0 \ -/usr/lib/jvm/java-19-openjdk-amd64/bin/java -Dapple.awt.application.name=TRIfA \ +/usr/lib/jvm/java-17-openjdk-amd64/bin/java -Dapple.awt.application.name=TRIfA \ -Dcom.apple.mrj.application.apple.menu.about.name=TRIfA -Dcompose.application.configure.swing.globals=true -Dcompose.application.resources.dir="$p"/build/compose/tmp/prepareAppResources -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant \ -cp "$p"/build/libs/trifa_material-1.0.8.jar:\ "$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.desktop/desktop-jvm/1.6.0-dev1347/f640e39ac0a51a00f788a0cc8ac1107fdc9a528f/desktop-jvm-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.material/material-desktop/1.6.0-dev1347/37f5fbfd7f792902ed6b5bf7f8ad0679b7770bba/material-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.components/components-resources-desktop/1.6.0-dev1347/bc53fa14f4ece5f8be90a899ef59152df7601ca/library-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.material3/material3-desktop/1.6.0-dev1347/c4f78e20d9bea223397212b80145934dc9507f76/material3-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.material/material-ripple-desktop/1.6.0-dev1347/73de6da196c34db3e71935baf37d6b6734eea6f6/material-ripple-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.foundation/foundation-desktop/1.6.0-dev1347/f4098f54feb3fe99e67eab4d48cbd43241644152/foundation-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.material/material-icons-extended-desktop/1.6.0-dev1347/20da10db08144f8020231ba2e48b4e1c34f913cd/material-icons-extended-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/io.github.alexzhirkevich/qrose-desktop/1.0.0-beta3/68deae874be302338efbf8c0cd4d1b2b97c495f/qrose-desktop-1.0.0-beta3.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.animation/animation-desktop/1.6.0-dev1347/da5a9e417f2cc10cc9840e4b66fb3fa1f09daca2/animation-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.foundation/foundation-layout-desktop/1.6.0-dev1347/312976986a73c70255570e5bfbc51847c0059baa/foundation-layout-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.animation/animation-core-desktop/1.6.0-dev1347/19c476a09cc66652fe69b9064f3a77c894e188c3/animation-core-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.material/material-icons-core-desktop/1.6.0-dev1347/30a5b7bdb98c19105b3bffb44f9d7591159e546c/material-icons-core-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.ui/ui-desktop/1.6.0-dev1347/2a9039f474df3ee61cfbe4c25afb22b86f481fb1/ui-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.ui/ui-tooling-preview-desktop/1.6.0-dev1347/62232c44c61692b56d3071c29b0f9c8481b20574/ui-tooling-preview-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.ui/ui-text-desktop/1.6.0-dev1347/d4334c70a8f05790c0e04069522ef4ac5b5847dc/ui-text-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.runtime/runtime-saveable-desktop/1.6.0-dev1347/88cee67f1f9b135321745f0f470e0c3f2c456cbc/runtime-saveable-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.ui/ui-graphics-desktop/1.6.0-dev1347/a775f10d95051b85eb468a5240495cfdaf483a67/ui-graphics-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.ui/ui-unit-desktop/1.6.0-dev1347/73a81fa29b6859c388996d3a2865206756aedc1a/ui-unit-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.ui/ui-geometry-desktop/1.6.0-dev1347/67678193a2f7e0cb1f8a899ae5de229bee3a30dc/ui-geometry-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.runtime/runtime-desktop/1.6.0-dev1347/14406b2d2a9e7a32b8f0b733d0d0eb6674f36896/runtime-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.skiko/skiko-awt-runtime-linux-x64/0.7.90/61a017dce555364c5dfeb7dde616bbe4414d6005/skiko-awt-runtime-linux-x64-0.7.90.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.skiko/skiko-awt/0.7.90/99e533b9554bdb885846c28a4d805325d711e32f/skiko-awt-0.7.90.jar:"$h"/.gradle/caches/modules-2/files-2.1/ca.gosyer/kotlin-multiplatform-appdirs-jvm/1.1.1/a8b92433066050fc0c0840185fde18c741aab4ce/Kotlin-Multiplatform-AppDirs-jvm-1.1.0.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.ui/ui-util-desktop/1.6.0-dev1347/82fadb7456a2328ac783c2a3b93641fbfe416dde/ui-util-desktop-1.6.0-dev1347.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/atomicfu-jvm/0.23.1/a4601dc42dceb031a586058e8356ff778a57dea0/atomicfu-jvm-0.23.1.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.9.21/290a25c998941b1c904d2cef480fd56be7ae9d7/kotlin-stdlib-jdk8-1.9.21.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core-jvm/1.8.0-RC/66f50b3d0f13b1fba29e99a06111626a962061fa/kotlinx-coroutines-core-jvm-1.8.0-RC.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.9.21/2d2c2b1d441e48ed37383e42f133339691436425/kotlin-stdlib-jdk7-1.9.21.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-datetime-jvm/0.5.0/8882b30187d18d2dcb5e22587447485e6f42dfb3/kotlinx-datetime-jvm-0.5.0.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.9.21/17ee3e873d439566c7d8354403b5f3d9744c4c9c/kotlin-stdlib-1.9.21.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.xerial/sqlite-jdbc/3.44.1.0/12e6182deef32d366ade664aa33bec9f4dd3ffe/sqlite-jdbc-3.44.1.0.jar:"$h"/.gradle/caches/modules-2/files-2.1/com.sksamuel.scrimage/scrimage-webp/4.1.1/9452b5920cb0536b5dfc9adddf4ed0af1ce25c31/scrimage-webp-4.1.1.jar:"$h"/.gradle/caches/modules-2/files-2.1/com.sksamuel.scrimage/scrimage-core/4.1.1/33b6fa2cc5d6d872f8de4d93528d978aeb3416d7/scrimage-core-4.1.1.jar:"$h"/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.10.1/b3add478d4382b78ea20b1671390a858002feb6c/gson-2.10.1.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/23.0.0/8cc20c07506ec18e0834947b84a864bfc094484e/annotations-23.0.0.jar:"$h"/.gradle/caches/modules-2/files-2.1/com.github.zh79325/open-gif/1.0.4/a52a4183dae721cb69dd1fcd4ef34b0bb72d7698/open-gif-1.0.4.jar:"$h"/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-classic/1.1.2/b316e9737eea25e9ddd6d88eaeee76878045c6b2/logback-classic-1.1.2.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-api/2.0.6/88c40d8b4f33326f19a7d3c0aaf2c7e8721d4953/slf4j-api-2.0.6.jar:"$h"/.gradle/caches/modules-2/files-2.1/com.twelvemonkeys.imageio/imageio-jpeg/3.9.4/af05e039169ab2d42efde9070f55565a169f795d/imageio-jpeg-3.9.4.jar:"$h"/.gradle/caches/modules-2/files-2.1/com.twelvemonkeys.imageio/imageio-metadata/3.9.4/423ab3a09a87ab0b1e6831269db74832ee4184ac/imageio-metadata-3.9.4.jar:"$h"/.gradle/caches/modules-2/files-2.1/com.twelvemonkeys.imageio/imageio-core/3.9.4/e33aabf2d21a2f66817a258abfcd9f5b1e898117/imageio-core-3.9.4.jar:"$h"/.gradle/caches/modules-2/files-2.1/com.drewnoakes/metadata-extractor/2.18.0/fa9fd43a28b10333108c603819810d5176d2b092/metadata-extractor-2.18.0.jar:"$h"/.gradle/caches/modules-2/files-2.1/commons-io/commons-io/2.11.0/a2503f302b11ebde7ebc3df41daebe0e4eea3689/commons-io-2.11.0.jar:"$h"/.gradle/caches/modules-2/files-2.1/ar.com.hjg/pngj/2.1.0/b9a0d5cca5108431c4068976e795d4d2766dab5b/pngj-2.1.0.jar:"$h"/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-lang3/3.12.0/c6842c86792ff03b9f1d1fe2aab8dc23aa6c6f0e/commons-lang3-3.12.0.jar:"$h"/.gradle/caches/modules-2/files-2.1/net.java.dev.jna/jna-platform/5.12.1/97406a297c852f4a41e688a176ec675f72e8329/jna-platform-5.12.1.jar:"$h"/.gradle/caches/modules-2/files-2.1/com.twelvemonkeys.common/common-image/3.9.4/8fc121f4f652cb8ef626ad4dade85b64948df36c/common-image-3.9.4.jar:"$h"/.gradle/caches/modules-2/files-2.1/com.twelvemonkeys.common/common-io/3.9.4/5a0bbb2f431196990780a4912f0ac46009c82f0e/common-io-3.9.4.jar:"$h"/.gradle/caches/modules-2/files-2.1/com.twelvemonkeys.common/common-lang/3.9.4/c68d7dd18962dda58615d3b5d929a68c8f8a1092/common-lang-3.9.4.jar:"$h"/.gradle/caches/modules-2/files-2.1/com.adobe.xmp/xmpcore/6.1.11/852f14101381e527e6d43339d7db1698c970436c/xmpcore-6.1.11.jar:"$h"/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-core/1.1.2/2d23694879c2c12f125dac5076bdfd5d771cc4cb/logback-core-1.1.2.jar:"$h"/.gradle/caches/modules-2/files-2.1/net.java.dev.jna/jna/5.12.1/b1e93a735caea94f503e95e6fe79bf9cdc1e985d/jna-5.12.1.jar MainKt diff --git a/resources/common/jni-c-toxcore.dll b/resources/common/jni-c-toxcore.dll index cd75db9f..19119ef9 100755 Binary files a/resources/common/jni-c-toxcore.dll and b/resources/common/jni-c-toxcore.dll differ diff --git a/resources/common/jni-c-toxcore_noise.dll b/resources/common/jni-c-toxcore_noise.dll index 5523ae32..306d7ecb 100755 Binary files a/resources/common/jni-c-toxcore_noise.dll and b/resources/common/jni-c-toxcore_noise.dll differ diff --git a/resources/common/libjni-c-toxcore.jnilib b/resources/common/libjni-c-toxcore.jnilib index 7edff30e..32fefda4 100644 Binary files a/resources/common/libjni-c-toxcore.jnilib and b/resources/common/libjni-c-toxcore.jnilib differ diff --git a/resources/common/libjni-c-toxcore.so b/resources/common/libjni-c-toxcore.so index 5eb301b7..2a68244e 100755 Binary files a/resources/common/libjni-c-toxcore.so and b/resources/common/libjni-c-toxcore.so differ diff --git a/resources/common/libjni-c-toxcore_noise.jnilib b/resources/common/libjni-c-toxcore_noise.jnilib index cdd082e7..27847da1 100644 Binary files a/resources/common/libjni-c-toxcore_noise.jnilib and b/resources/common/libjni-c-toxcore_noise.jnilib differ diff --git a/resources/common/libjni-c-toxcore_noise.so b/resources/common/libjni-c-toxcore_noise.so index a527176e..1c47c51b 100755 Binary files a/resources/common/libjni-c-toxcore_noise.so and b/resources/common/libjni-c-toxcore_noise.so differ diff --git a/src/main/java/com/zoffcc/applications/trifa/AudioSelectOutBox.java b/src/main/java/com/zoffcc/applications/trifa/AudioSelectOutBox.java index 3a25b733..7f440283 100644 --- a/src/main/java/com/zoffcc/applications/trifa/AudioSelectOutBox.java +++ b/src/main/java/com/zoffcc/applications/trifa/AudioSelectOutBox.java @@ -43,7 +43,7 @@ public class AudioSelectOutBox final static CustomSemaphore semaphore_audio_out_convert = new CustomSemaphore(1); static int semaphore_audio_out_convert_active_threads = 0; - static int semaphore_audio_out_convert_max_active_threads = 1; + static int semaphore_audio_out_convert_max_active_threads = 2; final static CustomSemaphore semaphore_audio_device_changes = new CustomSemaphore(1); final static int SAMPLE_RATE_DEFAULT = 48000; diff --git a/src/main/java/com/zoffcc/applications/trifa/HelperFriend.java b/src/main/java/com/zoffcc/applications/trifa/HelperFriend.java index 7e1874e6..d52370b5 100644 --- a/src/main/java/com/zoffcc/applications/trifa/HelperFriend.java +++ b/src/main/java/com/zoffcc/applications/trifa/HelperFriend.java @@ -2,9 +2,7 @@ import com.zoffcc.applications.sorm.FriendList; import com.zoffcc.applications.sorm.TRIFADatabaseGlobalsNew; -import org.sqlite.SQLiteException; -import javax.swing.*; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; @@ -471,4 +469,28 @@ static void update_friend_in_db_msgv3_capability(FriendList f) msgv3_capability(f.msgv3_capability). execute(); } + + static void add_pushurl_for_friend(final String friend_push_url, final String friend_pubkey) + { + try + { + TrifaToxService.Companion.getOrma().updateFriendList().tox_public_key_stringEq(friend_pubkey).push_url(friend_push_url).execute(); + } + catch (Exception e) + { + Log.i(TAG, "add_pushurl_for_friend:EE:" + e.getMessage()); + } + } + + static void remove_pushurl_for_friend(final String friend_pubkey) + { + try + { + TrifaToxService.Companion.getOrma().updateFriendList().tox_public_key_stringEq(friend_pubkey).push_url(null).execute(); + } + catch (Exception e) + { + Log.i(TAG, "remove_pushurl_for_friend:EE:" + e.getMessage()); + } + } } diff --git a/src/main/java/com/zoffcc/applications/trifa/HelperGroup.java b/src/main/java/com/zoffcc/applications/trifa/HelperGroup.java index 6268000d..8f4f68c9 100644 --- a/src/main/java/com/zoffcc/applications/trifa/HelperGroup.java +++ b/src/main/java/com/zoffcc/applications/trifa/HelperGroup.java @@ -1408,4 +1408,70 @@ static void group_message_add_from_sync(final String group_identifier, final Str Companion.incoming_synced_group_text_msg(m); } + + public static byte[] YUV420rotate90(byte[] data, byte[] output, int imageWidth, int imageHeight) + { + // Rotate the Y luma + int i = 0; + for (int x = 0; x < imageWidth; x++) + { + for (int y = imageHeight - 1; y >= 0; y--) + { + output[i++] = data[y * imageWidth + x]; + } + } + + // Rotate the U and V color components + int size = imageWidth * imageHeight; + i = size; + int j = size; + int uv = size / 4; + for (int x = 0; x < (imageWidth / 2); x++) + { + for (int y = (imageHeight / 2) - 1; y >= 0; y--) + { + try + { + output[i] = data[j + (y * (imageWidth / 2) + x)]; + output[i + uv] = data[j + uv + (y * (imageWidth / 2) + x)]; + } + catch (Exception e) + { + } + i++; + } + } + return output; + } + + public static byte[] YUV420rotateMinus90(byte[] data, byte[] output, int imageWidth, int imageHeight) + { + return rotateYUV420Degree180(YUV420rotate90(data, output, imageWidth, imageHeight), imageWidth, imageHeight); + } + + private static byte[] rotateYUV420Degree180(byte[] data, int imageWidth, int imageHeight) + { + byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2]; + int i = 0; + int count = 0; + // y + for (i = imageWidth * imageHeight - 1; i >= 0; i--) { + yuv[count] = data[i]; + count++; + } + // + final int y_size = imageWidth * imageHeight; + final int u_size = (imageWidth * imageHeight) / 4; + // u + for (i = u_size - 1; i >= 0; i--) { + yuv[count] = data[y_size + i]; + count++; + } + // v + for (i = u_size - 1; i >= 0; i--) { + yuv[count] = data[y_size + u_size + i]; + count++; + } + return yuv; + } } diff --git a/src/main/kotlin/Main.kt b/src/main/kotlin/Main.kt index fb05085b..ad1ffe57 100644 --- a/src/main/kotlin/Main.kt +++ b/src/main/kotlin/Main.kt @@ -88,6 +88,7 @@ import androidx.compose.ui.graphics.PathEffect import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.vector.VectorPainter diff --git a/src/main/kotlin/com/zoffcc/applications/trifa/HelperGeneric.kt b/src/main/kotlin/com/zoffcc/applications/trifa/HelperGeneric.kt index 3278c38f..4e0b709b 100644 --- a/src/main/kotlin/com/zoffcc/applications/trifa/HelperGeneric.kt +++ b/src/main/kotlin/com/zoffcc/applications/trifa/HelperGeneric.kt @@ -31,6 +31,7 @@ import com.zoffcc.applications.trifa.HelperFiletransfer.set_filetransfer_state_f import com.zoffcc.applications.trifa.HelperFriend.delete_friend import com.zoffcc.applications.trifa.HelperFriend.delete_friend_all_filetransfers import com.zoffcc.applications.trifa.HelperFriend.delete_friend_all_messages +import com.zoffcc.applications.trifa.HelperGroup.YUV420rotateMinus90 import com.zoffcc.applications.trifa.HelperGroup.delete_group import com.zoffcc.applications.trifa.HelperGroup.delete_group_all_messages import com.zoffcc.applications.trifa.HelperGroup.tox_group_by_groupid__wrapper @@ -39,8 +40,11 @@ import com.zoffcc.applications.trifa.HelperMessage.set_message_state_from_id import com.zoffcc.applications.trifa.HelperMessage.tox_friend_send_message_wrapper import com.zoffcc.applications.trifa.HelperMessage.update_message_in_db_messageid import com.zoffcc.applications.trifa.HelperMessage.update_message_in_db_resend_count +import com.zoffcc.applications.trifa.MainActivity.Companion.ROTATE_INCOMING_NGC_VIDEO +import com.zoffcc.applications.trifa.MainActivity.Companion.audio_queue_full_trigger import com.zoffcc.applications.trifa.MainActivity.Companion.modify_message_with_ft import com.zoffcc.applications.trifa.MainActivity.Companion.ngc_audio_in_queue +import com.zoffcc.applications.trifa.MainActivity.Companion.ngc_audio_in_queue_max_capacity import com.zoffcc.applications.trifa.MainActivity.Companion.tox_file_control import com.zoffcc.applications.trifa.MainActivity.Companion.tox_friend_by_public_key import com.zoffcc.applications.trifa.MainActivity.Companion.tox_friend_delete @@ -678,12 +682,37 @@ object HelperGeneric { //Log.i(TAG, "play_ngc_incoming_audio_frame:toxav_ngc_audio_decode:decoded_samples=" // + decoded_samples) // put pcm data into a FIFO - System.arraycopy(pcm_decoded_buf, 0, pcm_decoded_buf_delta_1, 0, bytes_in_40ms * 2) - ngc_audio_in_queue.offer(pcm_decoded_buf_delta_1) - System.arraycopy(pcm_decoded_buf, bytes_in_40ms * 2, pcm_decoded_buf_delta_2, 0, bytes_in_40ms * 2) - ngc_audio_in_queue.offer(pcm_decoded_buf_delta_2) - System.arraycopy(pcm_decoded_buf, bytes_in_40ms * 2 * 2, pcm_decoded_buf_delta_3, 0, bytes_in_40ms * 2) - ngc_audio_in_queue.offer(pcm_decoded_buf_delta_3) + if ((ngc_audio_in_queue.remainingCapacity() < 2) && (!audio_queue_full_trigger)) + { + Log.i(TAG, "play_ngc_incoming_audio_frame:trigger:" + ngc_audio_in_queue.size) + audio_queue_full_trigger = true + } + else + { + if (audio_queue_full_trigger) + { + if (ngc_audio_in_queue.remainingCapacity() >= ngc_audio_in_queue_max_capacity - 2) + { + audio_queue_full_trigger = false + Log.i(TAG, "play_ngc_incoming_audio_frame:release:") + } + else + { + //Log.i(TAG, "play_ngc_incoming_audio_frame:-----------:" + + // audio_queue_full_trigger) + } + } + else + { + // Log.i(TAG, "play_ngc_incoming_audio_frame:push:" + ngc_audio_in_queue.size + " " + ngc_audio_in_queue.remainingCapacity()) + System.arraycopy(pcm_decoded_buf, 0, pcm_decoded_buf_delta_1, 0, bytes_in_40ms * 2) + ngc_audio_in_queue.offer(pcm_decoded_buf_delta_1) + System.arraycopy(pcm_decoded_buf, bytes_in_40ms * 2, pcm_decoded_buf_delta_2, 0, bytes_in_40ms * 2) + ngc_audio_in_queue.offer(pcm_decoded_buf_delta_2) + System.arraycopy(pcm_decoded_buf, bytes_in_40ms * 2 * 2, pcm_decoded_buf_delta_3, 0, bytes_in_40ms * 2) + ngc_audio_in_queue.offer(pcm_decoded_buf_delta_3) + } + } ngc_video_frame_last_incoming_ts = System.currentTimeMillis() } catch (e: java.lang.Exception) { @@ -775,21 +804,50 @@ object HelperGeneric { } else { - val w2_decoder = ystride_ // encoder stride + var w2_decoder = ystride_ // encoder stride val w2_decoder_uv = ystride_ / 2 // encoder stride - val h2_decoder = 640 // 320; + var h2_decoder = 640 // 320; val h2_decoder_uv = h2_decoder / 2 val y_bytes2_decoder = h2_decoder * w2_decoder val u_bytes2_decoder = (h2_decoder_uv * w2_decoder_uv) val v_bytes2_decoder = (h2_decoder_uv * w2_decoder_uv) - val yuv_frame_data_buf = ByteBuffer.allocateDirect( - y_bytes2_decoder + u_bytes2_decoder + v_bytes2_decoder) - yuv_frame_data_buf.rewind() - // - yuv_frame_data_buf.put(y_buf2, 0, y_bytes2_decoder) - yuv_frame_data_buf.put(u_buf2, 0, u_bytes2_decoder) - yuv_frame_data_buf.put(v_buf2, 0, v_bytes2_decoder) - // + val yuv_frame_data_buf: ByteBuffer? + + if (ROTATE_INCOMING_NGC_VIDEO) + { + // - rotate yuv (not optimized!!) - + // - rotate yuv (not optimized!!) - + val tmp_yuv = ByteArray(y_bytes2_decoder + u_bytes2_decoder + v_bytes2_decoder) + var tmp_yuv_rotated = ByteArray(y_bytes2_decoder + u_bytes2_decoder + v_bytes2_decoder) + System.arraycopy(y_buf2, 0, tmp_yuv, 0, y_bytes2_decoder) + System.arraycopy(u_buf2, 0, tmp_yuv, y_bytes2_decoder, u_bytes2_decoder) + System.arraycopy(v_buf2, 0, tmp_yuv, y_bytes2_decoder + u_bytes2_decoder, v_bytes2_decoder) + tmp_yuv_rotated = YUV420rotateMinus90(tmp_yuv, tmp_yuv_rotated, w2_decoder, h2_decoder) + val tmp = w2_decoder + w2_decoder = h2_decoder + h2_decoder = tmp + // + yuv_frame_data_buf = ByteBuffer.allocateDirect( + y_bytes2_decoder + u_bytes2_decoder + v_bytes2_decoder) + yuv_frame_data_buf.rewind() + // + yuv_frame_data_buf.put(tmp_yuv_rotated, 0, y_bytes2_decoder) + yuv_frame_data_buf.put(tmp_yuv_rotated, y_bytes2_decoder, u_bytes2_decoder) + yuv_frame_data_buf.put(tmp_yuv_rotated, y_bytes2_decoder + u_bytes2_decoder, v_bytes2_decoder) + // - rotate yuv (not optimized!!) - + // - rotate yuv (not optimized!!) - + } + else + { + yuv_frame_data_buf = ByteBuffer.allocateDirect( + y_bytes2_decoder + u_bytes2_decoder + v_bytes2_decoder) + yuv_frame_data_buf.rewind() + // + yuv_frame_data_buf.put(y_buf2, 0, y_bytes2_decoder) + yuv_frame_data_buf.put(u_buf2, 0, u_bytes2_decoder) + yuv_frame_data_buf.put(v_buf2, 0, v_bytes2_decoder) + // + } yuv_frame_data_buf.rewind() if ((VideoInFrame.width != w2_decoder || VideoInFrame.height != h2_decoder) || (VideoInFrame.imageInByte == null)) { diff --git a/src/main/kotlin/com/zoffcc/applications/trifa/MainActivity.kt b/src/main/kotlin/com/zoffcc/applications/trifa/MainActivity.kt index 9ceae25e..07ceb8c3 100644 --- a/src/main/kotlin/com/zoffcc/applications/trifa/MainActivity.kt +++ b/src/main/kotlin/com/zoffcc/applications/trifa/MainActivity.kt @@ -29,7 +29,9 @@ import com.zoffcc.applications.trifa.HelperFiletransfer.insert_into_filetransfer import com.zoffcc.applications.trifa.HelperFiletransfer.move_tmp_file_to_real_file import com.zoffcc.applications.trifa.HelperFiletransfer.set_message_accepted_from_id import com.zoffcc.applications.trifa.HelperFiletransfer.update_filetransfer_db_full +import com.zoffcc.applications.trifa.HelperFriend.add_pushurl_for_friend import com.zoffcc.applications.trifa.HelperFriend.main_get_friend +import com.zoffcc.applications.trifa.HelperFriend.remove_pushurl_for_friend import com.zoffcc.applications.trifa.HelperFriend.send_friend_msg_receipt_v2_wrapper import com.zoffcc.applications.trifa.HelperFriend.update_friend_in_db_capabilities import com.zoffcc.applications.trifa.HelperFriend.update_friend_in_db_msgv3_capability @@ -45,6 +47,7 @@ import com.zoffcc.applications.trifa.HelperGeneric.show_ngc_incoming_video_frame import com.zoffcc.applications.trifa.HelperGeneric.shrink_image_file import com.zoffcc.applications.trifa.HelperGeneric.update_savedata_file_wrapper import com.zoffcc.applications.trifa.HelperGroup.bytebuffer_to_hexstring +import com.zoffcc.applications.trifa.HelperGroup.bytes_to_hex import com.zoffcc.applications.trifa.HelperGroup.fourbytes_of_long_to_hex import com.zoffcc.applications.trifa.HelperGroup.handle_incoming_group_file import com.zoffcc.applications.trifa.HelperGroup.handle_incoming_sync_group_file @@ -81,6 +84,7 @@ import com.zoffcc.applications.trifa.ToxVars.TOX_FILE_ID_LENGTH import com.zoffcc.applications.trifa.ToxVars.TOX_HASH_LENGTH import com.zoffcc.applications.trifa.ToxVars.TOX_MAX_NGC_FILESIZE import com.zoffcc.applications.trifa.ToxVars.TOX_MAX_NGC_FILE_AND_HEADER_SIZE +import com.zoffcc.applications.trifa.ToxVars.TOX_PUBLIC_KEY_SIZE import com.zoffcc.applications.trifa.TrifaToxService.Companion.orma import com.zoffcc.applications.trifa.TrifaToxService.Companion.resend_old_messages import com.zoffcc.applications.trifa.TrifaToxService.Companion.resend_v3_messages @@ -110,6 +114,7 @@ import java.io.File import java.io.PrintWriter import java.io.RandomAccessFile import java.nio.ByteBuffer +import java.nio.charset.StandardCharsets import java.util.* import java.util.concurrent.BlockingQueue import java.util.concurrent.LinkedBlockingQueue @@ -155,7 +160,10 @@ class MainActivity @JvmStatic var video_play_last_timestamp: Long = 0 var video_play_fps_value: Int = 0 @JvmStatic val video_play_measure_after_frame = 5; - var ngc_audio_in_queue: BlockingQueue = LinkedBlockingQueue(3 * 5) + const val ngc_audio_in_queue_max_capacity = 10 + var audio_queue_full_trigger = false + var audio_queue_play_trigger = true + var ngc_audio_in_queue: BlockingQueue = LinkedBlockingQueue(ngc_audio_in_queue_max_capacity) // var PREF__ngc_video_bitrate: Int = LOWER_NGC_VIDEO_BITRATE // ~600 kbits/s -> ~60 kbytes/s @@ -168,6 +176,7 @@ class MainActivity @JvmField var PREF__auto_accept_video = true @JvmField var PREF__auto_accept_all_upto = true const val AUDIO_VU_MIN_VALUE = -20f + var ROTATE_INCOMING_NGC_VIDEO = true // var video_buffer_1: ByteBuffer? = null var buffer_size_in_bytes = 0 @@ -1457,6 +1466,44 @@ class MainActivity @JvmStatic fun android_tox_callback_friend_lossless_packet_cb_method(friend_number: Long, data: ByteArray?, length: Long) { + if (length > 0) + { + val fpubkey = tox_friend_get_public_key(friend_number) + if (fpubkey == null) + { + return + } + + if (data!![0].toUByte().toInt() == TRIFAGlobals.CONTROL_PROXY_MESSAGE_TYPE.CONTROL_PROXY_MESSAGE_TYPE_PROXY_PUBKEY_FOR_FRIEND.value) + { + if (length == (TOX_PUBLIC_KEY_SIZE + 1).toLong()) + { + Log.i(TAG, "friend_lossless_packet_cb:recevied CONTROL_PROXY_MESSAGE_TYPE_PROXY_PUBKEY_FOR_FRIEND") + val relay_pubkey: String = bytes_to_hex(data).substring(2) + Log.i(TAG, "friend_lossless_packet_cb:recevied pubkey:" + relay_pubkey.uppercase()) + // TODO: add relays // HelperFriend.add_friend_to_system(relay_pubkey.uppercase(), true, fpubkey) + } + } else if (data[0].toUByte().toInt() == TRIFAGlobals.CONTROL_PROXY_MESSAGE_TYPE.CONTROL_PROXY_MESSAGE_TYPE_PUSH_URL_FOR_FRIEND.value) + { + Log.i(TAG, + "android_tox_callback_friend_lossless_packet_cb_method:CONTROL_PROXY_MESSAGE_TYPE_PUSH_URL_FOR_FRIEND:len=" + + length); + if (length > "https://".length + 1) + { + val pushurl = String(Arrays.copyOfRange(data, 1, data.size), StandardCharsets.UTF_8) + Log.i(TAG, + "android_tox_callback_friend_lossless_packet_cb_method:CONTROL_PROXY_MESSAGE_TYPE_PUSH_URL_FOR_FRIEND:pushurl=" + + pushurl) + add_pushurl_for_friend(pushurl, fpubkey) + } else + { + if (length == 0L) + { + remove_pushurl_for_friend(fpubkey) + } + } + } + } } @JvmStatic diff --git a/src/main/kotlin/com/zoffcc/applications/trifa/TrifaToxService.kt b/src/main/kotlin/com/zoffcc/applications/trifa/TrifaToxService.kt index 88ebca97..1dfbb8f3 100644 --- a/src/main/kotlin/com/zoffcc/applications/trifa/TrifaToxService.kt +++ b/src/main/kotlin/com/zoffcc/applications/trifa/TrifaToxService.kt @@ -22,6 +22,7 @@ import com.zoffcc.applications.trifa.HelperMessage.update_message_in_db_no_read_ import com.zoffcc.applications.trifa.HelperMessage.update_message_in_db_resend_count import com.zoffcc.applications.trifa.MainActivity.Companion.PREF__udp_enabled import com.zoffcc.applications.trifa.MainActivity.Companion.add_tcp_relay_single_wrapper +import com.zoffcc.applications.trifa.MainActivity.Companion.audio_queue_play_trigger import com.zoffcc.applications.trifa.MainActivity.Companion.bootstrap_single_wrapper import com.zoffcc.applications.trifa.MainActivity.Companion.init_tox_callbacks import com.zoffcc.applications.trifa.MainActivity.Companion.ngc_audio_in_queue @@ -316,7 +317,7 @@ class TrifaToxService fun ngc_audio_play_thread_start() { - Log.i(TAG, "ngc_audio_play_thread_start:starting Thread") + Log.i(TAG, "()PLAY_ngc_audio_frame:starting Thread") ngc_audio_play_thread = object : Thread() { override fun run() @@ -330,130 +331,142 @@ class TrifaToxService val channels = 1 val bytes_in_40ms = 1920 // val sample_count = bytes_in_40ms / 2 + audio_queue_play_trigger = true while (ngc_audio_play_thread_running) { - d1 = System.currentTimeMillis() // -- play incoming bytes -- // -- play incoming bytes -- try { - val buf: ByteArray = ngc_audio_in_queue.poll() - if (buf != null) + if ((ngc_audio_in_queue.size < 3) && (!audio_queue_play_trigger)) { - if ((sampling_rate != AudioSelectOutBox.SAMPLE_RATE) || - (channels != AudioSelectOutBox.CHANNELS) || - (AudioSelectOutBox.sourceDataLine == null)) - { - Log.i(TAG, "ngc_audio_play_thread_start:11:1"); - AudioSelectOutBox.init() - AudioSelectOutBox.change_audio_format(sampling_rate, channels) - Log.i(TAG, "ngc_audio_play_thread_start:11:2"); - } - if (sampling_rate != AudioSelectOutBox.SAMPLE_RATE || - channels != AudioSelectOutBox.CHANNELS) - { - Log.i(TAG, "ngc_audio_play_thread_start:22:1:$sampling_rate" + " " - + AudioSelectOutBox.SAMPLE_RATE) - AudioSelectOutBox.change_audio_format(sampling_rate, channels) - Log.i(TAG, "ngc_audio_play_thread_start:22:2") - } - - try + audio_queue_play_trigger = true + // Log.i(TAG, "()PLAY_ngc_audio_frame:trigger:" + ngc_audio_in_queue.size) + } + else + { + if (audio_queue_play_trigger) { - val want_bytes = buf.size - val sample_count = want_bytes / 2 - try + if (ngc_audio_in_queue.size >= 6) { - AudioSelectOutBox.semaphore_audio_out_convert.acquire_passthru() - if (AudioSelectOutBox.semaphore_audio_out_convert_active_threads >= AudioSelectOutBox.semaphore_audio_out_convert_max_active_threads) - { - Log.i(TAG, "ngc_audio_play_thread_start:too many threads running") - AudioSelectOutBox.semaphore_audio_out_convert.release_passthru() - return - } - AudioSelectOutBox.semaphore_audio_out_convert.release_passthru() - } catch (e: java.lang.Exception) + audio_queue_play_trigger = false + // Log.i(TAG, "()PLAY_ngc_audio_frame:release:") + } + else { - AudioSelectOutBox.semaphore_audio_out_convert.release_passthru() + //Log.i(TAG, "()PLAY_ngc_audio_frame:+++++++++:" + audio_queue_play_trigger + " " + //+ ngc_audio_in_queue.size + " " + ngc_audio_in_queue.remainingCapacity()) + sleep(20) } - - val t_audio_pcm_play = Thread{ - try - { - AudioSelectOutBox.semaphore_audio_out_convert.acquire_passthru() - AudioSelectOutBox.semaphore_audio_out_convert_active_threads++ - AudioSelectOutBox.semaphore_audio_out_convert.release_passthru() - } catch (e: java.lang.Exception) + } else + { + val buf: ByteArray = ngc_audio_in_queue.poll() + if (buf != null) + { + if ((sampling_rate != AudioSelectOutBox.SAMPLE_RATE) || + (channels != AudioSelectOutBox.CHANNELS) || + (AudioSelectOutBox.sourceDataLine == null)) { - AudioSelectOutBox.semaphore_audio_out_convert.release_passthru() + Log.i(TAG, "()PLAY_ngc_audio_frame:11:1"); + AudioSelectOutBox.init() + AudioSelectOutBox.change_audio_format(sampling_rate, channels) + Log.i(TAG, "()PLAY_ngc_audio_frame:11:2"); } - // HINT: this acutally plays incoming Audio - // HINT: this may block!! - try + if (sampling_rate != AudioSelectOutBox.SAMPLE_RATE || + channels != AudioSelectOutBox.CHANNELS) { - val bytes_actually_written = AudioSelectOutBox.sourceDataLine.write(buf, 0, want_bytes) - if (bytes_actually_written != want_bytes) - { - Log.i(TAG, "ngc_audio_play_thread_start:bytes_actually_written=" + bytes_actually_written + " want_bytes=" + want_bytes) - } - } catch (e: java.lang.Exception) - { - Log.i(TAG, "ngc_audio_play_thread_start:sourceDataLine.write:EE:" + e.message) // e.printStackTrace(); + Log.i(TAG, "()PLAY_ngc_audio_frame:22:1:$sampling_rate" + " " + + AudioSelectOutBox.SAMPLE_RATE) + AudioSelectOutBox.change_audio_format(sampling_rate, channels) + Log.i(TAG, "()PLAY_ngc_audio_frame:22:2") } try { - AudioSelectOutBox.semaphore_audio_out_convert.acquire_passthru() - AudioSelectOutBox.semaphore_audio_out_convert_active_threads-- - AudioSelectOutBox.semaphore_audio_out_convert.release_passthru() - } catch (e: java.lang.Exception) - { - AudioSelectOutBox.semaphore_audio_out_convert.release_passthru() - } - var global_audio_out_vu: Float = MainActivity.AUDIO_VU_MIN_VALUE - if (sample_count > 0) - { - val vu_value = AudioBar.audio_vu(buf, sample_count) - global_audio_out_vu = if (vu_value > MainActivity.AUDIO_VU_MIN_VALUE) + val want_bytes = buf.size + val sample_count = want_bytes / 2 + try { - vu_value - } else + AudioSelectOutBox.semaphore_audio_out_convert.acquire_passthru() + if (AudioSelectOutBox.semaphore_audio_out_convert_active_threads >= AudioSelectOutBox.semaphore_audio_out_convert_max_active_threads) + { + Log.i(TAG, "()PLAY_ngc_audio_frame:too many threads running: " + AudioSelectOutBox.semaphore_audio_out_convert_active_threads) + AudioSelectOutBox.semaphore_audio_out_convert.release_passthru() + continue + } + AudioSelectOutBox.semaphore_audio_out_convert.release_passthru() + } catch (e: java.lang.Exception) { - 0f + AudioSelectOutBox.semaphore_audio_out_convert.release_passthru() + } + + val t_audio_pcm_play = Thread{ + try + { + AudioSelectOutBox.semaphore_audio_out_convert.acquire_passthru() + AudioSelectOutBox.semaphore_audio_out_convert_active_threads++ + AudioSelectOutBox.semaphore_audio_out_convert.release_passthru() + } catch (e: java.lang.Exception) + { + AudioSelectOutBox.semaphore_audio_out_convert.release_passthru() + } + // HINT: this acutally plays incoming Audio + // HINT: this may block!! + try + { + val bytes_actually_written = AudioSelectOutBox.sourceDataLine.write(buf, 0, want_bytes) + if (bytes_actually_written != want_bytes) + { + Log.i(TAG, "()PLAY_ngc_audio_frame:bytes_actually_written=" + bytes_actually_written + " want_bytes=" + want_bytes) + } + } catch (e: java.lang.Exception) + { + Log.i(TAG, "()PLAY_ngc_audio_frame:sourceDataLine.write:EE:" + e.message) // e.printStackTrace(); + } + try + { + AudioSelectOutBox.semaphore_audio_out_convert.acquire_passthru() + AudioSelectOutBox.semaphore_audio_out_convert_active_threads-- + AudioSelectOutBox.semaphore_audio_out_convert.release_passthru() + } catch (e: java.lang.Exception) + { + Log.i(TAG, "()PLAY_ngc_audio_frame:--:EEEEEE") + AudioSelectOutBox.semaphore_audio_out_convert.release_passthru() + } + var global_audio_out_vu: Float = MainActivity.AUDIO_VU_MIN_VALUE + if (sample_count > 0) + { + val vu_value = AudioBar.audio_vu(buf, sample_count) + global_audio_out_vu = if (vu_value > MainActivity.AUDIO_VU_MIN_VALUE) + { + vu_value + } else + { + 0f + } + } + val global_audio_out_vu_ = global_audio_out_vu + AudioBar.set_cur_value(global_audio_out_vu_.toInt(), AudioBar.audio_out_bar) } + t_audio_pcm_play.start() + } + catch(e: Exception) + { + e.printStackTrace() } - val global_audio_out_vu_ = global_audio_out_vu - AudioBar.set_cur_value(global_audio_out_vu_.toInt(), AudioBar.audio_out_bar) } - t_audio_pcm_play.start() - } - catch(_: Exception) - { } - } } catch (e: java.lang.Exception) { } // -- play incoming bytes -- // -- play incoming bytes -- - val delta = (System.currentTimeMillis() - d1) - - sleep_millis_current = sleep_millis - delta - if (sleep_millis_current < 1) - { - sleep_millis_current = 1 - } else if (sleep_millis_current > sleep_millis + 5) - { - sleep_millis_current = sleep_millis + 5 - } - - sleep(sleep_millis_current - 1L, 1000000 - 5000) // sleep - // Log.i(TAG, "ngc_audio_play_thread_start: running ...") + sleep(20) } } catch (_: Exception) { } - Log.i(TAG, "ngc_audio_play_thread_start: Thread ending") + Log.i(TAG, "()PLAY_ngc_audio_frame: Thread ending") } } (ngc_audio_play_thread as Thread).start() @@ -909,8 +922,8 @@ class TrifaToxService val m_resend_v2 = ii.next() m_counter++ - Log.i(TAG, "resend_v2_messages: " + m_counter + ": " - + get_friend_name_from_pubkey(m_resend_v2.tox_friendpubkey) + " " + m_resend_v2.text) + Log.i(TAG, "resend_v2_messages: " + m_counter + ": friend=" + + get_friend_name_from_pubkey(m_resend_v2.tox_friendpubkey) + " text=" + m_resend_v2.text) } ii = m_v1.iterator() while (ii.hasNext())