Skip to content

Commit

Permalink
Use java.time.Duration in configs
Browse files Browse the repository at this point in the history
  • Loading branch information
gavv committed Oct 16, 2024
1 parent 0bce11c commit f6a0adc
Show file tree
Hide file tree
Showing 11 changed files with 70 additions and 28 deletions.
25 changes: 25 additions & 0 deletions roc_jni/src/main/impl/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,31 @@ unsigned long long get_ullong_field_value(
return (unsigned long long) ret;
}

long long get_duration_field_value(
JNIEnv* env, jclass clazz, jobject obj, const char* attr_name, int* error) {
assert(env != NULL);
assert(clazz != NULL);
assert(attr_name != NULL);
assert(error != NULL);

jfieldID attrId = (*env)->GetFieldID(env, clazz, attr_name, "Ljava/time/Duration;");
assert(attrId != NULL);

jobject durationObj = (*env)->GetObjectField(env, obj, attrId);
if (durationObj == NULL) {
return 0;
}

jclass durationClass = (*env)->FindClass(env, "java/time/Duration");
assert(durationClass != NULL);

jmethodID toNanosMethodId = (*env)->GetMethodID(env, durationClass, "toNanos", "()J");
assert(toNanosMethodId != NULL);

jlong ret = (*env)->CallLongMethod(env, durationObj, toNanosMethodId);
return (long long) ret;
}

int get_enum_value(JNIEnv* env, jclass clazz, jobject enumObj) {
assert(env != NULL);
assert(clazz != NULL);
Expand Down
3 changes: 2 additions & 1 deletion roc_jni/src/main/impl/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ long long get_llong_field_value(
unsigned long long get_ullong_field_value(
JNIEnv* env, jclass clazz, jobject obj, const char* attr_name, int* error);

void set_int_field_value(JNIEnv* env, jclass clazz, jobject obj, const char* attr_name, int value);
long long get_duration_field_value(
JNIEnv* env, jclass clazz, jobject obj, const char* attr_name, int* error);

int get_enum_value(JNIEnv* env, jclass clazz, jobject enumObj);
jobject get_object_field(
Expand Down
14 changes: 7 additions & 7 deletions roc_jni/src/main/impl/receiver.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,31 +56,31 @@ static int receiver_config_unmarshal(JNIEnv* env, roc_receiver_config* config, j

// target_latency
config->target_latency
= get_ullong_field_value(env, receiverConfigClass, jconfig, "targetLatency", &err);
= get_duration_field_value(env, receiverConfigClass, jconfig, "targetLatency", &err);
if (err) return err;

// max_latency_overrun
config->max_latency_overrun
= get_ullong_field_value(env, receiverConfigClass, jconfig, "maxLatencyOverrun", &err);
= get_duration_field_value(env, receiverConfigClass, jconfig, "maxLatencyOverrun", &err);
if (err) return err;

// max_latency_underrun
config->max_latency_underrun
= get_ullong_field_value(env, receiverConfigClass, jconfig, "maxLatencyUnderrun", &err);
= get_duration_field_value(env, receiverConfigClass, jconfig, "maxLatencyUnderrun", &err);
if (err) return err;

// no_playback_timeout
config->no_playback_timeout
= get_llong_field_value(env, receiverConfigClass, jconfig, "noPlaybackTimeout", &err);
= get_duration_field_value(env, receiverConfigClass, jconfig, "noPlaybackTimeout", &err);
if (err) return err;

// broken_playback_timeout
config->broken_playback_timeout
= get_llong_field_value(env, receiverConfigClass, jconfig, "brokenPlaybackTimeout", &err);
config->broken_playback_timeout = get_duration_field_value(
env, receiverConfigClass, jconfig, "brokenPlaybackTimeout", &err);
if (err) return err;

// breakage_detection_window
config->breakage_detection_window = get_ullong_field_value(
config->breakage_detection_window = get_duration_field_value(
env, receiverConfigClass, jconfig, "breakageDetectionWindow", &err);
if (err) return err;

Expand Down
2 changes: 1 addition & 1 deletion roc_jni/src/main/impl/sender.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ static int sender_config_unmarshal(JNIEnv* env, roc_sender_config* config, jobje

// packet_length
config->packet_length
= get_ullong_field_value(env, senderConfigClass, jconfig, "packetLength", &err);
= get_duration_field_value(env, senderConfigClass, jconfig, "packetLength", &err);
if (err) return err;

// packet_interleaving
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/org/rocstreaming/roctoolkit/Check.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.rocstreaming.roctoolkit;

import java.time.Duration;

class Check {
private Check() {
}
Expand All @@ -18,6 +20,14 @@ static String notEmpty(String value, String name) {
return value;
}

static Duration notNegative(Duration value, String name) {
// Null ("unset") duration is fine, it's treated as zero on JNI side.
if (value != null && value.isNegative()) {
throw new IllegalArgumentException(name + " must not be negative");
}
return value;
}

static int notNegative(int value, String name) {
if (value < 0) {
throw new IllegalArgumentException(name + " must not be negative");
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/org/rocstreaming/roctoolkit/RocReceiverConfig.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.rocstreaming.roctoolkit;

import java.time.Duration;
import lombok.*;

/**
Expand Down Expand Up @@ -73,7 +74,7 @@ public class RocReceiverConfig {
* If zero or unset, default value is used.
* Should not be negative.
*/
private long targetLatency;
private Duration targetLatency;

/**
* Maximum delta between current and target latency, in nanoseconds.
Expand All @@ -82,7 +83,7 @@ public class RocReceiverConfig {
* If zero or unset, default value is used.
* Should not be negative.
*/
private long maxLatencyOverrun;
private Duration maxLatencyOverrun;

/**
* Maximum delta between target and current latency, in nanoseconds.
Expand All @@ -94,7 +95,7 @@ public class RocReceiverConfig {
* If zero or unset, default value is used.
* Should not be negative.
*/
private long maxLatencyUnderrun;
private Duration maxLatencyUnderrun;

/**
* Timeout for the lack of playback, in nanoseconds.
Expand All @@ -104,7 +105,7 @@ public class RocReceiverConfig {
* If zero or unset, default value is used.
* If negative, the timeout is disabled.
*/
private long noPlaybackTimeout;
private Duration noPlaybackTimeout;

/**
* Timeout for broken playback, in nanoseconds.
Expand All @@ -118,14 +119,14 @@ public class RocReceiverConfig {
* If zero or unset, default value is used.
* If negative, the timeout is disabled.
*/
private long brokenPlaybackTimeout;
private Duration brokenPlaybackTimeout;

/**
* Breakage detection window, in nanoseconds.
* If zero or unset, default value is used.
* Should not be negative.
*/
private long breakageDetectionWindow;
private Duration breakageDetectionWindow;

public static RocReceiverConfig.Builder builder() {
return new RocReceiverConfigValidator();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.rocstreaming.roctoolkit;

import java.time.Duration;
import lombok.*;

/**
Expand Down Expand Up @@ -63,7 +64,7 @@ public class RocSenderConfig {
* If zero or unset, default value is used.
* Should not be negative.
*/
private long packetLength;
private Duration packetLength;

/**
* Enable packet interleaving.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.time.Duration;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.*;
Expand All @@ -22,10 +23,10 @@ private static Stream<Arguments> testInvalidConfigArguments() {
Arguments.of("frameSampleRate must not be negative", validBuilder().frameSampleRate(-1)),
Arguments.of("frameChannels must not be null", validBuilder().frameChannels(null)),
Arguments.of("frameEncoding must not be null", validBuilder().frameEncoding(null)),
Arguments.of("targetLatency must not be negative", validBuilder().targetLatency(-1)),
Arguments.of("maxLatencyOverrun must not be negative", validBuilder().maxLatencyOverrun(-1)),
Arguments.of("maxLatencyUnderrun must not be negative", validBuilder().maxLatencyUnderrun(-1)),
Arguments.of("breakageDetectionWindow must not be negative", validBuilder().breakageDetectionWindow(-1))
Arguments.of("targetLatency must not be negative", validBuilder().targetLatency(Duration.ofNanos(-1))),
Arguments.of("maxLatencyOverrun must not be negative", validBuilder().maxLatencyOverrun(Duration.ofNanos(-1))),
Arguments.of("maxLatencyUnderrun must not be negative", validBuilder().maxLatencyUnderrun(Duration.ofNanos(-1))),
Arguments.of("breakageDetectionWindow must not be negative", validBuilder().breakageDetectionWindow(Duration.ofNanos(-1)))
);
}

Expand Down
13 changes: 7 additions & 6 deletions src/test/java/org/rocstreaming/roctoolkit/RocReceiverTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.time.Duration;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.*;
Expand Down Expand Up @@ -49,12 +50,12 @@ public void testCreationAndDeinitializationWithFullConfig() {
.clockSource(ClockSource.INTERNAL)
.resamplerBackend(ResamplerBackend.BUILTIN)
.resamplerProfile(ResamplerProfile.HIGH)
.targetLatency(1000)
.maxLatencyOverrun(500)
.maxLatencyUnderrun(500)
.noPlaybackTimeout(2000)
.brokenPlaybackTimeout(2000)
.breakageDetectionWindow(2000)
.targetLatency(Duration.ofNanos(1000))
.maxLatencyOverrun(Duration.ofNanos(500))
.maxLatencyUnderrun(Duration.ofNanos(500))
.noPlaybackTimeout(Duration.ofNanos(2000))
.brokenPlaybackTimeout(Duration.ofNanos(2000))
.breakageDetectionWindow(Duration.ofNanos(2000))
.build();
assertDoesNotThrow(() -> {
//noinspection EmptyTryBlock
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.time.Duration;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertEquals;
Expand All @@ -25,7 +26,7 @@ private static Stream<Arguments> testInvalidConfigArguments() {
Arguments.of("frameChannels must not be null", validBuilder().frameChannels(null)),
Arguments.of("frameEncoding must not be null", validBuilder().frameEncoding(null)),
Arguments.of("packetSampleRate must not be negative", validBuilder().packetSampleRate(-1)),
Arguments.of("packetLength must not be negative", validBuilder().packetLength(-1)),
Arguments.of("packetLength must not be negative", validBuilder().packetLength(Duration.ofNanos(-1))),
Arguments.of("fecBlockSourcePackets must not be negative", validBuilder().fecBlockSourcePackets(-1)),
Arguments.of("fecBlockRepairPackets must not be negative", validBuilder().fecBlockRepairPackets(-1))
);
Expand Down
3 changes: 2 additions & 1 deletion src/test/java/org/rocstreaming/roctoolkit/RocSenderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.junit.jupiter.params.provider.MethodSource;

import java.io.IOException;
import java.time.Duration;
import java.util.stream.Stream;

import static java.lang.Math.sin;
Expand Down Expand Up @@ -71,7 +72,7 @@ public void testCreationAndDeinitializationWithFullConfig() {
.packetSampleRate(44100)
.packetChannels(ChannelSet.STEREO)
.packetEncoding(PacketEncoding.AVP_L16)
.packetLength(2000)
.packetLength(Duration.ofNanos(2000))
.packetInterleaving(1)
.clockSource(ClockSource.INTERNAL)
.resamplerBackend(ResamplerBackend.BUILTIN)
Expand Down

0 comments on commit f6a0adc

Please sign in to comment.