Skip to content

Commit 4fbbf8f

Browse files
committed
Make encoder and decoder thread-safe
1 parent 8f8cf58 commit 4fbbf8f

File tree

6 files changed

+97
-37
lines changed

6 files changed

+97
-37
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>de.maxhenkel.opus4j</groupId>
88
<artifactId>opus4j</artifactId>
9-
<version>2.0.1</version>
9+
<version>2.0.2</version>
1010

1111
<name>Opus Wrapper for Java</name>
1212
<url>https://maxhenkel.de</url>

readme.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ A Java wrapper for the [Opus Codec](https://opus-codec.org/) written in Rust usi
1010
<dependency>
1111
<groupId>de.maxhenkel.opus4j</groupId>
1212
<artifactId>opus4j</artifactId>
13-
<version>2.0.0</version>
13+
<version>2.0.2</version>
1414
</dependency>
1515

1616
<repositories>
@@ -25,7 +25,7 @@ A Java wrapper for the [Opus Codec](https://opus-codec.org/) written in Rust usi
2525

2626
``` groovy
2727
dependencies {
28-
implementation 'de.maxhenkel.opus4j:opus4j:2.0.0'
28+
implementation 'de.maxhenkel.opus4j:opus4j:2.0.2'
2929
}
3030
3131
repositories {

rust/src/opus/decoder.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ struct DecoderWrapper {
1313
}
1414

1515
#[no_mangle]
16-
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_createDecoder(mut env: JNIEnv, _class: JClass, sample_rate: jint, channels: jint) -> jlong {
16+
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_createDecoder0(mut env: JNIEnv, _class: JClass, sample_rate: jint, channels: jint) -> jlong {
1717
let channels = match channels {
1818
1 => Channels::Mono,
1919
2 => Channels::Stereo,
@@ -37,7 +37,7 @@ pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_createDecoder(mut env: JN
3737
}
3838

3939
#[no_mangle]
40-
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_setFrameSize(mut env: JNIEnv, obj: JObject, frame_size: jint) {
40+
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_setFrameSize0(mut env: JNIEnv, obj: JObject, frame_size: jint) {
4141
if frame_size <= 0 {
4242
throw_illegal_argument_exception(&mut env, format!("Invalid frame size: {}", frame_size));
4343
return;
@@ -54,7 +54,7 @@ pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_setFrameSize(mut env: JNI
5454
}
5555

5656
#[no_mangle]
57-
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_getFrameSize(mut env: JNIEnv, obj: JObject) -> jint {
57+
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_getFrameSize0(mut env: JNIEnv, obj: JObject) -> jint {
5858
let decoder = match get_decoder(&mut env, &obj) {
5959
Some(encoder) => encoder,
6060
None => {
@@ -67,7 +67,7 @@ pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_getFrameSize(mut env: JNI
6767
}
6868

6969
#[no_mangle]
70-
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_decode<'a>(mut env: JNIEnv<'a>, obj: JObject<'a>, input: JByteArray<'a>, fec: jboolean) -> JShortArray<'a> {
70+
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_decode0<'a>(mut env: JNIEnv<'a>, obj: JObject<'a>, input: JByteArray<'a>, fec: jboolean) -> JShortArray<'a> {
7171
let decoder = match get_decoder(&mut env, &obj) {
7272
Some(decoder) => decoder,
7373
None => {
@@ -129,7 +129,7 @@ pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_decode<'a>(mut env: JNIEn
129129
}
130130

131131
#[no_mangle]
132-
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_resetState(mut env: JNIEnv, obj: JObject) {
132+
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_resetState0(mut env: JNIEnv, obj: JObject) {
133133
let decoder = match get_decoder(&mut env, &obj) {
134134
Some(decoder) => decoder,
135135
None => {
@@ -145,7 +145,7 @@ pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_resetState(mut env: JNIEn
145145
}
146146

147147
#[no_mangle]
148-
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_destroyDecoder(mut env: JNIEnv, obj: JObject) {
148+
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusDecoder_destroyDecoder0(mut env: JNIEnv, obj: JObject) {
149149
let pointer = get_pointer(&mut env, &obj);
150150

151151
if pointer == 0 {

rust/src/opus/encoder.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ struct EncoderWrapper {
1212
}
1313

1414
#[no_mangle]
15-
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_createEncoder(mut env: JNIEnv, _class: JClass, sample_rate: jint, channels: jint, application: JObject) -> jlong {
15+
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_createEncoder0(mut env: JNIEnv, _class: JClass, sample_rate: jint, channels: jint, application: JObject) -> jlong {
1616
let channels = match channels {
1717
1 => Channels::Mono,
1818
2 => Channels::Stereo,
@@ -58,7 +58,7 @@ pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_createEncoder(mut env: JN
5858
}
5959

6060
#[no_mangle]
61-
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_setMaxPayloadSize(mut env: JNIEnv, obj: JObject, max_payload_size: jint) {
61+
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_setMaxPayloadSize0(mut env: JNIEnv, obj: JObject, max_payload_size: jint) {
6262
if max_payload_size <= 0 {
6363
throw_illegal_argument_exception(&mut env, format!("Invalid maximum payload size: {}", max_payload_size));
6464
return;
@@ -75,7 +75,7 @@ pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_setMaxPayloadSize(mut env
7575
}
7676

7777
#[no_mangle]
78-
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_getMaxPayloadSize(mut env: JNIEnv, obj: JObject) -> jint {
78+
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_getMaxPayloadSize0(mut env: JNIEnv, obj: JObject) -> jint {
7979
let encoder = match get_encoder(&mut env, &obj) {
8080
Some(encoder) => encoder,
8181
None => {
@@ -88,7 +88,7 @@ pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_getMaxPayloadSize(mut env
8888
}
8989

9090
#[no_mangle]
91-
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_encode<'a>(mut env: JNIEnv<'a>, obj: JObject<'a>, input: JShortArray<'a>) -> JByteArray<'a> {
91+
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_encode0<'a>(mut env: JNIEnv<'a>, obj: JObject<'a>, input: JShortArray<'a>) -> JByteArray<'a> {
9292
let encoder = match get_encoder(&mut env, &obj) {
9393
Some(encoder) => encoder,
9494
None => {
@@ -148,7 +148,7 @@ pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_encode<'a>(mut env: JNIEn
148148
}
149149

150150
#[no_mangle]
151-
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_resetState(mut env: JNIEnv, obj: JObject) {
151+
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_resetState0(mut env: JNIEnv, obj: JObject) {
152152
let encoder = match get_encoder(&mut env, &obj) {
153153
Some(decoder) => decoder,
154154
None => {
@@ -164,7 +164,7 @@ pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_resetState(mut env: JNIEn
164164
}
165165

166166
#[no_mangle]
167-
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_destroyEncoder(mut env: JNIEnv, obj: JObject) {
167+
pub extern "C" fn Java_de_maxhenkel_opus4j_OpusEncoder_destroyEncoder0(mut env: JNIEnv, obj: JObject) {
168168
let pointer = get_pointer(&mut env, &obj);
169169

170170
if pointer == 0 {

src/main/java/de/maxhenkel/opus4j/OpusDecoder.java

+41-11
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,34 @@ public class OpusDecoder implements AutoCloseable {
1717
*/
1818
public OpusDecoder(int sampleRate, int channels) throws IOException, UnknownPlatformException {
1919
Opus.load();
20-
decoder = createDecoder(sampleRate, channels);
20+
decoder = createDecoder0(sampleRate, channels);
2121
}
2222

23-
private static native long createDecoder(int sampleRate, int channels) throws IOException;
23+
private static native long createDecoder0(int sampleRate, int channels) throws IOException;
2424

25-
public native void setFrameSize(int frameSize);
25+
private native void setFrameSize0(int frameSize);
2626

27-
public native int getFrameSize();
27+
public void setFrameSize(int frameSize) {
28+
synchronized (this) {
29+
setFrameSize0(frameSize);
30+
}
31+
}
32+
33+
private native int getFrameSize0();
34+
35+
public int getFrameSize() {
36+
synchronized (this) {
37+
return getFrameSize0();
38+
}
39+
}
2840

29-
public native short[] decode(@Nullable byte[] input, boolean fec);
41+
private native short[] decode0(@Nullable byte[] input, boolean fec);
42+
43+
public short[] decode(@Nullable byte[] input, boolean fec) {
44+
synchronized (this) {
45+
return decode0(input, fec);
46+
}
47+
}
3048

3149
public short[] decode(@Nullable byte[] input) {
3250
return decode(input, false);
@@ -36,22 +54,34 @@ public short[] decodeFec() {
3654
return decode(null, true);
3755
}
3856

39-
public native void resetState();
57+
private native void resetState0();
58+
59+
public void resetState() {
60+
synchronized (this) {
61+
resetState0();
62+
}
63+
}
4064

41-
private native void destroyDecoder();
65+
private native void destroyDecoder0();
4266

4367
@Override
4468
public void close() {
45-
destroyDecoder();
46-
decoder = 0L;
69+
synchronized (this) {
70+
destroyDecoder0();
71+
decoder = 0L;
72+
}
4773
}
4874

4975
public boolean isClosed() {
50-
return decoder == 0L;
76+
synchronized (this) {
77+
return decoder == 0L;
78+
}
5179
}
5280

5381
@Override
5482
public String toString() {
55-
return String.format("OpusDecoder[%d]", decoder);
83+
synchronized (this) {
84+
return String.format("OpusDecoder[%d]", decoder);
85+
}
5686
}
5787
}

src/main/java/de/maxhenkel/opus4j/OpusEncoder.java

+41-11
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,64 @@ public class OpusEncoder implements AutoCloseable {
1717
*/
1818
public OpusEncoder(int sampleRate, int channels, Application application) throws IOException, UnknownPlatformException {
1919
Opus.load();
20-
encoder = createEncoder(sampleRate, channels, application);
20+
encoder = createEncoder0(sampleRate, channels, application);
2121
}
2222

23-
private static native long createEncoder(int sampleRate, int channels, Application application) throws IOException;
23+
private static native long createEncoder0(int sampleRate, int channels, Application application) throws IOException;
2424

25-
public native void setMaxPayloadSize(int maxPayloadSize);
25+
private native void setMaxPayloadSize0(int maxPayloadSize);
2626

27-
public native int getMaxPayloadSize();
27+
public void setMaxPayloadSize(int maxPayloadSize) {
28+
synchronized (this) {
29+
setMaxPayloadSize0(maxPayloadSize);
30+
}
31+
}
32+
33+
private native int getMaxPayloadSize0();
34+
35+
public int getMaxPayloadSize() {
36+
synchronized (this) {
37+
return getMaxPayloadSize0();
38+
}
39+
}
2840

29-
public native byte[] encode(short[] input);
41+
private native byte[] encode0(short[] input);
3042

31-
public native void resetState();
43+
public byte[] encode(short[] input) {
44+
synchronized (this) {
45+
return encode0(input);
46+
}
47+
}
3248

33-
private native void destroyEncoder();
49+
private native void resetState0();
50+
51+
public void resetState() {
52+
synchronized (this) {
53+
resetState0();
54+
}
55+
}
56+
57+
private native void destroyEncoder0();
3458

3559
@Override
3660
public void close() {
37-
destroyEncoder();
38-
encoder = 0L;
61+
synchronized (this) {
62+
destroyEncoder0();
63+
encoder = 0L;
64+
}
3965
}
4066

4167
public boolean isClosed() {
42-
return encoder == 0L;
68+
synchronized (this) {
69+
return encoder == 0L;
70+
}
4371
}
4472

4573
@Override
4674
public String toString() {
47-
return String.format("OpusEncoder[%d]", encoder);
75+
synchronized (this) {
76+
return String.format("OpusEncoder[%d]", encoder);
77+
}
4878
}
4979

5080
public static enum Application {

0 commit comments

Comments
 (0)