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); return reinterpret_cast<WeakReferenceCounter*>(obj);
} }
constexpr int referredOffset = 0;
constexpr int lockOffset = sizeof(void*);
#if !KONAN_NO_THREADS #if !KONAN_NO_THREADS
inline void lock(int32_t* address) { inline void lock(int32_t* address) {
RuntimeAssert(*address == 0 || *address == 1, "Incorrect lock state");
while (__sync_val_compare_and_swap(address, 0, 1) == 1); 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() val id = currentInternal()
return if (id != 0) Worker(id) else null 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") throw RuntimeException("Shall not be called directly")
override public fun toString(): String = "worker $id" 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() { class SDLAudio(val player: VideoPlayer) : DisposableContainer() {
private val workerStable = StableRef.create(player.worker)
private var state = State.STOPPED private var state = State.STOPPED
fun start(audio: AudioOutput) { fun start(audio: AudioOutput) {
@@ -40,7 +39,7 @@ class SDLAudio(val player: VideoPlayer) : DisposableContainer() {
channels = audio.channels.convert() channels = audio.channels.convert()
silence = 0u silence = 0u
samples = 4096u samples = 4096u
userdata = workerStable.asCPointer() userdata = player.worker.asCPointer()
callback = staticCFunction(::audioCallback) callback = staticCFunction(::audioCallback)
} }
val realSpec = alloc<SDL_AudioSpec>() val realSpec = alloc<SDL_AudioSpec>()
@@ -63,7 +62,6 @@ class SDLAudio(val player: VideoPlayer) : DisposableContainer() {
fun stop() { fun stop() {
pause() pause()
state = state.transition(State.PAUSED, State.STOPPED) { SDL_CloseAudio() } 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. // This handler will be invoked in the audio thread, so reinit runtime.
kotlin.native.initRuntimeIfNeeded() kotlin.native.initRuntimeIfNeeded()
val decoder = decoder ?: val decoder = decoder ?:
DecoderWorker(userdata!!.asStableRef<Worker>().get()).also { decoder = it } DecoderWorker(Worker.fromCPointer(userdata)).also { decoder = it }
var outPosition = 0 var outPosition = 0
while (outPosition < length) { while (outPosition < length) {
val frame = decoder.nextAudioFrame(length - outPosition) val frame = decoder.nextAudioFrame(length - outPosition)