Observe actual silent device intervals when adapting playback history

This commit is contained in:
evgeny committed 2026-10-13 23:26:55 +02:00
1 parent 5c75487446
commit e1abcb5d69
4 files changed
+20 -2

No files matched your search

@@ -10,6 +10,7 @@
#include "../../../lib/audio_compressor.h"
#include "../libutun_lite/stream_bridge.h"
#include "../../../src/stream/stream_media.h"
#include "../../../src/stream/stream_media_buffer.h"
#include "../../../src/stream/stream_playback_clock.h"
#include "../../../src/stream/stream_playback_audio.h"
@@ -88,6 +89,7 @@ struct android_stream_playback {
struct stream_playback_state state;
struct stream_playback_audio *audio;
int64_t position, time_us;
int finished;
};
JNIEXPORT jlong JNICALL Java_com_utun_chat_data_NativeLib_nativeStreamPlaybackCreate(
@@ -136,6 +138,7 @@ JNIEXPORT jlongArray JNICALL Java_com_utun_chat_data_NativeLib_nativeStreamPlayb
if (p->audio) {
p->position = stream_playback_audio_position(p->audio, (uint64_t)played);
pending = stream_playback_audio_pending_gain(p->audio, (uint64_t)played);
if (!p->finished && stream_playback_audio_starved(p->audio, (uint64_t)played)) starved = JNI_TRUE;
} else if (p->time_us >= 0 && !starved) {
int64_t elapsed = now - p->time_us;
if (elapsed < 0) { DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "JNI playback wall clock regressed"); return NULL; }
@@ -157,7 +160,7 @@ JNIEXPORT jlongArray JNICALL Java_com_utun_chat_data_NativeLib_nativeStreamPlayb
JNIEXPORT void JNICALL Java_com_utun_chat_data_NativeLib_nativeStreamPlaybackFinish(JNIEnv *env, jobject obj, jlong handle) {
(void)env; (void)obj; struct android_stream_playback *p = (struct android_stream_playback *)(intptr_t)handle;
if (p) stream_playback_audio_finish(p->audio);
if (p) { p->finished = 1; stream_playback_audio_finish(p->audio); }
}
JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeStreamPlaybackEmpty(JNIEnv *env, jobject obj, jlong handle) {
@@ -264,6 +264,9 @@ static void media_process(void *arg) {
if (packet.kind == STREAM_MEDIA_READ_END) media_close(&viewer, 5);
else media_frame(&viewer, &packet.format, packet.kind == STREAM_MEDIA_READ_VIDEO ? &packet.video : NULL,
packet.kind == STREAM_MEDIA_READ_AUDIO ? &packet.audio : NULL);
} else if (result == STREAM_MORE) {
viewer.want_read = 1;
if (media_schedule() < 0) DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "Android media assembly scheduling failed");
} else if (result == STREAM_WAIT) viewer.waiting = 1;
else if (result == STREAM_GAP || result == STREAM_EXPIRED) {
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "Android playback resync id=%llu result=%d", (unsigned long long)viewer.id, result);
@@ -296,7 +299,7 @@ static void media_process(void *arg) {
}
}
if (publisher.finished && now >= publisher.drain_until) media_close(&publisher, 5);
if (video_queue.head || audio_queue.head || publisher.finished) {
if (!media_post && (video_queue.head || audio_queue.head || publisher.finished)) {
media_timer = uasync_set_timeout(media_inst->ua, publisher.finished ? 200 : 50, NULL, media_process, "android_stream");
if (!media_timer) { DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "Android media timer allocation failed"); media_close(&publisher, 6); }
}