Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib_ass_kt/src/main/cpp/AssKt.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,12 @@ jlong nativeAssTrackInit(JNIEnv* env, jclass clazz, jlong ass) {
}

jint nativeAssTrackGetWidth(JNIEnv* env, jclass clazz, jlong track) {
if (!track) return 0;
return ((ASS_Track *) track)->PlayResX;
}

jobjectArray nativeAssTrackGetEvents(JNIEnv* env, jclass clazz, jlong track) {
if (!track) return NULL;
jclass eventClass = (*env)->FindClass(env, "io/github/peerless2012/ass/AssEvent");
if (eventClass == NULL) {
return NULL;
Expand Down Expand Up @@ -121,6 +123,7 @@ jobjectArray nativeAssTrackGetEvents(JNIEnv* env, jclass clazz, jlong track) {
}

void nativeAssTrackClearEvents(JNIEnv* env, jclass clazz, jlong track) {
if (!track) return;
ASS_Track* tr = (ASS_Track *) track;
for (int i = 0; i < tr->n_events; i++) {
ass_free_event(tr, i);
Expand All @@ -129,10 +132,12 @@ void nativeAssTrackClearEvents(JNIEnv* env, jclass clazz, jlong track) {
}

jint nativeAssTrackGetHeight(JNIEnv* env, jclass clazz, jlong track) {
if (!track) return 0;
return ((ASS_Track *) track)->PlayResY;
}

void nativeAssTrackReadBuffer(JNIEnv* env, jclass clazz, jlong track, jbyteArray buffer, jint offset, jint length) {
if (!track) return;
jboolean isCopy;
jbyte* elements = (*env)->GetByteArrayElements(env, buffer, &isCopy);
if (elements == NULL) {
Expand All @@ -143,6 +148,7 @@ void nativeAssTrackReadBuffer(JNIEnv* env, jclass clazz, jlong track, jbyteArray
}

void nativeAssTrackReadChunk(JNIEnv* env, jclass clazz, jlong track, jlong start, jlong duration, jbyteArray buffer, jint offset, jint length) {
if (!track) return;
jboolean isCopy;
jbyte* elements = (*env)->GetByteArrayElements(env, buffer, &isCopy);
if (elements == NULL) {
Expand All @@ -153,6 +159,7 @@ void nativeAssTrackReadChunk(JNIEnv* env, jclass clazz, jlong track, jlong start
}

void nativeAssTrackDeinit(JNIEnv* env, jclass clazz, jlong track) {
if (!track) return;
ass_free_track((ASS_Track *) track);
}

Expand All @@ -175,18 +182,22 @@ jlong nativeAssRenderInit(JNIEnv* env, jclass clazz, jlong ass) {
}

void nativeAssRenderSetFontScale(JNIEnv* env, jclass clazz, jlong render, jfloat scale) {
if (!render) return;
ass_set_font_scale((ASS_Renderer *) render, scale);
}

void nativeAssRenderSetCacheLimit(JNIEnv* env, jclass clazz, jlong render, jint glyphMax, jint bitmapMaxSize) {
if (!render) return;
ass_set_cache_limits((ASS_Renderer *) render, glyphMax, bitmapMaxSize);
}

void nativeAssRenderSetFrameSize(JNIEnv* env, jclass clazz, jlong render, jint width, jint height) {
if (!render) return;
ass_set_frame_size((ASS_Renderer *) render, width, height);
}

void nativeAssRenderSetStorageSize(JNIEnv* env, jclass clazz, jlong render, jint width, jint height) {
if (!render) return;
ass_set_storage_size((ASS_Renderer *) render, width, height);
}

Expand Down Expand Up @@ -294,6 +305,7 @@ static int count_ass_images(ASS_Image *images) {
}

jobject nativeAssRenderFrame(JNIEnv* env, jclass clazz, jlong render, jlong track, jlong time, jint type) {
if (!render || !track) return NULL;
int changed;
ASS_Image *image = ass_render_frame((ASS_Renderer *) render, (ASS_Track *) track, time, &changed);
if (image == NULL) {
Expand Down
47 changes: 40 additions & 7 deletions lib_ass_kt/src/main/java/io/github/peerless2012/ass/Ass.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package io.github.peerless2012.ass

import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock

/**
* @Author peerless2012
* @Email peerless2012@126.com
Expand Down Expand Up @@ -29,26 +32,56 @@ class Ass {

}

private val nativeAss: Long = nativeAssInit()
/** Single lock for all libass calls on this library instance. */
val lock = ReentrantLock()

private var nativeAss: Long = nativeAssInit()

@Volatile
var released = false
private set

public fun createTrack(): AssTrack {
return AssTrack(nativeAss)
return lock.withLock {
if (released || nativeAss == 0L) throw IllegalStateException("Ass already released")
AssTrack(nativeAss, lock)
}
}

public fun createRender(): AssRender {
return AssRender(nativeAss)
return lock.withLock {
if (released || nativeAss == 0L) throw IllegalStateException("Ass already released")
AssRender(nativeAss, lock)
}
}

public fun addFont(name: String, buffer: ByteArray) {
nativeAssAddFont(nativeAss, name, buffer)
lock.withLock {
if (released || nativeAss == 0L) return
nativeAssAddFont(nativeAss, name, buffer)
}
}

public fun clearFont() {
nativeAssClearFont(nativeAss)
lock.withLock {
if (released || nativeAss == 0L) return
nativeAssClearFont(nativeAss)
}
}

fun release() {
lock.withLock {
if (released) return
released = true
if (nativeAss != 0L) {
nativeAssDeinit(nativeAss)
nativeAss = 0
}
}
}

protected fun finalize() {
nativeAssDeinit(nativeAss)
release()
}

}
}
58 changes: 48 additions & 10 deletions lib_ass_kt/src/main/java/io/github/peerless2012/ass/AssRender.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package io.github.peerless2012.ass

import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock

/**
* @Author peerless2012
* @Email peerless2012@126.com
* @DateTime 2025/Jan/05 14:18
* @Version V1.0
* @Description
*/
class AssRender(nativeAss: Long) {
class AssRender(nativeAss: Long, private val lock: ReentrantLock) {

companion object {

Expand All @@ -33,36 +36,71 @@ class AssRender(nativeAss: Long) {
external fun nativeAssRenderDeinit(render: Long)
}

private val nativeRender: Long = nativeAssRenderInit(nativeAss)
private var nativeRender: Long = nativeAssRenderInit(nativeAss)

@Volatile
var released = false
private set

private var track: AssTrack? = null

public fun setTrack(track: AssTrack?) {
this.track = track
lock.withLock {
this.track = track
}
}

public fun setFontScale(scale: Float) {
nativeAssRenderSetFontScale(nativeRender, scale)
lock.withLock {
if (released || nativeRender == 0L) return
nativeAssRenderSetFontScale(nativeRender, scale)
}
}

public fun setCacheLimit(glyphMax: Int, bitmapMaxSize: Int) {
nativeAssRenderSetCacheLimit(nativeRender, glyphMax, bitmapMaxSize)
lock.withLock {
if (released || nativeRender == 0L) return
nativeAssRenderSetCacheLimit(nativeRender, glyphMax, bitmapMaxSize)
}
}

public fun setStorageSize(width: Int, height: Int) {
nativeAssRenderSetStorageSize(nativeRender, width, height)
lock.withLock {
if (released || nativeRender == 0L) return
nativeAssRenderSetStorageSize(nativeRender, width, height)
}
}

public fun setFrameSize(width: Int, height: Int) {
nativeAssRenderSetFrameSize(nativeRender, width, height)
lock.withLock {
if (released || nativeRender == 0L) return
nativeAssRenderSetFrameSize(nativeRender, width, height)
}
}

public fun renderFrame(time: Long, type: AssTexType): AssFrame? {
return track?.let { nativeAssRenderFrame(nativeRender, it.nativeAssTrack, time, type.ordinal) }
lock.withLock {
if (released || nativeRender == 0L) return null
val t = track ?: return null
if (t.released || t.nativeAssTrack == 0L) return null
return nativeAssRenderFrame(nativeRender, t.nativeAssTrack, time, type.ordinal)
}
}

fun release() {
lock.withLock {
if (released) return
released = true
track = null
if (nativeRender != 0L) {
nativeAssRenderDeinit(nativeRender)
nativeRender = 0
}
}
}

protected fun finalize() {
nativeAssRenderDeinit(nativeRender)
release()
}

}
}
57 changes: 47 additions & 10 deletions lib_ass_kt/src/main/java/io/github/peerless2012/ass/AssTrack.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package io.github.peerless2012.ass

import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock

/**
* @Author peerless2012
* @Email peerless2012@126.com
* @DateTime 2025/Jan/05 14:18
* @Version V1.0
* @Description
*/
class AssTrack(private val ass: Long) {
class AssTrack(private val ass: Long, private val lock: ReentrantLock) {

companion object {

Expand Down Expand Up @@ -36,34 +39,68 @@ class AssTrack(private val ass: Long) {
external fun nativeAssTrackDeinit(track: Long)
}

public val nativeAssTrack = nativeAssTrackInit(ass)
var nativeAssTrack = nativeAssTrackInit(ass)
private set

@Volatile
var released = false
private set

public fun getWidth(): Int {
return nativeAssTrackGetWidth(nativeAssTrack)
lock.withLock {
if (released || nativeAssTrack == 0L) return 0
return nativeAssTrackGetWidth(nativeAssTrack)
}
}

public fun getHeight(): Int {
return nativeAssTrackGetHeight(nativeAssTrack)
lock.withLock {
if (released || nativeAssTrack == 0L) return 0
return nativeAssTrackGetHeight(nativeAssTrack)
}
}

public fun getEvents(): Array<AssEvent>? {
return nativeAssTrackGetEvents(nativeAssTrack)
lock.withLock {
if (released || nativeAssTrack == 0L) return null
return nativeAssTrackGetEvents(nativeAssTrack)
}
}

public fun clearEvent() {
nativeAssTrackClearEvents(nativeAssTrack)
lock.withLock {
if (released || nativeAssTrack == 0L) return
nativeAssTrackClearEvents(nativeAssTrack)
}
}

public fun readBuffer(array: ByteArray, offset: Int = 0, length : Int = array.size) {
nativeAssTrackReadBuffer(nativeAssTrack, array, offset, length)
lock.withLock {
if (released || nativeAssTrack == 0L) return
nativeAssTrackReadBuffer(nativeAssTrack, array, offset, length)
}
}

public fun readChunk(start: Long, duration: Long, array: ByteArray, offset: Int = 0, length: Int = array.size) {
nativeAssTrackReadChunk(nativeAssTrack, start, duration, array, offset, length)
lock.withLock {
if (released || nativeAssTrack == 0L) return
nativeAssTrackReadChunk(nativeAssTrack, start, duration, array, offset, length)
}
}

fun release() {
lock.withLock {
if (released) return
released = true
if (nativeAssTrack != 0L) {
nativeAssTrackDeinit(nativeAssTrack)
nativeAssTrack = 0
}
}
}

protected fun finalize() {
nativeAssTrackDeinit(nativeAssTrack)
release()
}

}
}
Loading