Fix incorrect Worker passing mechanisms in VideoPlayer sample. (#2688)

This commit is contained in:
Nikolay Igotti
2019-02-20 11:57:22 +03:00
committed by GitHub
parent 75805b3528
commit bdea1bd1d3
3 changed files with 17 additions and 7 deletions
+1 -3
View File
@@ -29,12 +29,10 @@ inline WeakReferenceCounter* asWeakReferenceCounter(ObjHeader* obj) {
return reinterpret_cast<WeakReferenceCounter*>(obj);
}
constexpr int referredOffset = 0;
constexpr int lockOffset = sizeof(void*);
#if !KONAN_NO_THREADS
inline void lock(int32_t* address) {
RuntimeAssert(*address == 0 || *address == 1, "Incorrect lock state");
while (__sync_val_compare_and_swap(address, 0, 1) == 1);
}
@@ -47,6 +47,14 @@ public inline class Worker @PublishedApi internal constructor(val id: Int) {
val id = currentInternal()
return if (id != 0) Worker(id) else null
}
/**
* Create worker object from a C pointer.
*
* @param pointer value returned earlier by [Worker.asCPointer]
*/
public fun fromCPointer(pointer: COpaquePointer?) =
if (pointer != null) Worker(pointer.toLong().toInt()) else throw IllegalArgumentException()
}
/**
@@ -81,4 +89,10 @@ public inline class Worker @PublishedApi internal constructor(val id: Int) {
throw RuntimeException("Shall not be called directly")
override public fun toString(): String = "worker $id"
/**
* Convert worker to a COpaquePointer value that could be passed via native void* pointer.
* Can be used as an argument of [Worker.fromCPointer].
*/
public fun asCPointer() : COpaquePointer? = id.toLong().toCPointer()
}
@@ -24,7 +24,6 @@ private fun SampleFormat.toSDLFormat(): SDL_AudioFormat? = when (this) {
}
class SDLAudio(val player: VideoPlayer) : DisposableContainer() {
private val workerStable = StableRef.create(player.worker)
private var state = State.STOPPED
fun start(audio: AudioOutput) {
@@ -40,7 +39,7 @@ class SDLAudio(val player: VideoPlayer) : DisposableContainer() {
channels = audio.channels.convert()
silence = 0u
samples = 4096u
userdata = workerStable.asCPointer()
userdata = player.worker.asCPointer()
callback = staticCFunction(::audioCallback)
}
val realSpec = alloc<SDL_AudioSpec>()
@@ -63,7 +62,6 @@ class SDLAudio(val player: VideoPlayer) : DisposableContainer() {
fun stop() {
pause()
state = state.transition(State.PAUSED, State.STOPPED) { SDL_CloseAudio() }
workerStable.dispose()
}
}
@@ -75,7 +73,7 @@ private fun audioCallback(userdata: COpaquePointer?, buffer: CPointer<Uint8Var>?
// This handler will be invoked in the audio thread, so reinit runtime.
kotlin.native.initRuntimeIfNeeded()
val decoder = decoder ?:
DecoderWorker(userdata!!.asStableRef<Worker>().get()).also { decoder = it }
DecoderWorker(Worker.fromCPointer(userdata)).also { decoder = it }
var outPosition = 0
while (outPosition < length) {
val frame = decoder.nextAudioFrame(length - outPosition)