Skip to content

Commit

Permalink
Merge pull request #1462 from pedroSG94/fix/runtime-gl-crash
Browse files Browse the repository at this point in the history
try to fix error on stopSources
  • Loading branch information
pedroSG94 committed Apr 23, 2024
2 parents 9793c83 + f90ea1b commit d427750
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 30 deletions.
Expand Up @@ -30,6 +30,8 @@

import com.pedro.encoder.utils.gl.GlUtil;

import java.util.concurrent.atomic.AtomicBoolean;

/**
* Created by pedro on 9/09/17.
*/
Expand All @@ -44,10 +46,10 @@ public class SurfaceManager {
private EGLContext eglContext = EGL14.EGL_NO_CONTEXT;
private EGLSurface eglSurface = EGL14.EGL_NO_SURFACE;
private EGLDisplay eglDisplay = EGL14.EGL_NO_DISPLAY;
private volatile boolean isReady = false;
private final AtomicBoolean isReady = new AtomicBoolean(false);

public boolean isReady() {
return isReady;
return isReady.get();
}

public void makeCurrent() {
Expand All @@ -74,7 +76,7 @@ public void setPresentationTime(long nsecs) {
* Prepares EGL. We want a GLES 2.0 context and a surface that supports recording.
*/
public void eglSetup(int width, int height, Surface surface, EGLContext eglSharedContext) {
if (isReady) {
if (isReady()) {
Log.e(TAG, "already ready, ignored");
return;
}
Expand Down Expand Up @@ -155,7 +157,7 @@ public void eglSetup(int width, int height, Surface surface, EGLContext eglShare
eglSurface = EGL14.eglCreateWindowSurface(eglDisplay, configs[0], surface, surfaceAttribs, 0);
}
GlUtil.checkEglError("eglCreateWindowSurface");
isReady = true;
isReady.set(true);
Log.i(TAG, "GL initialized");
}

Expand Down Expand Up @@ -194,10 +196,10 @@ public void release() {
eglDisplay = EGL14.EGL_NO_DISPLAY;
eglContext = EGL14.EGL_NO_CONTEXT;
eglSurface = EGL14.EGL_NO_SURFACE;
isReady = false;
} else {
Log.e(TAG, "GL already released");
}
isReady.set(false);
}

public EGLContext getEglContext() {
Expand Down
Expand Up @@ -24,6 +24,7 @@ import androidx.annotation.RequiresApi
import com.pedro.encoder.input.gl.FilterAction
import com.pedro.encoder.input.gl.render.filters.BaseFilterRender
import com.pedro.encoder.utils.gl.AspectRatioMode
import java.util.concurrent.atomic.AtomicBoolean

/**
* Created by pedro on 20/3/22.
Expand All @@ -38,8 +39,7 @@ class MainRender {
private var previewHeight = 0
private var context: Context? = null
private var filterRenders: MutableList<BaseFilterRender> = ArrayList()
@Volatile
var isReady = false
private val running = AtomicBoolean(false)

fun initGl(context: Context, encoderWidth: Int, encoderHeight: Int, previewWidth: Int, previewHeight: Int) {
this.context = context
Expand All @@ -51,9 +51,11 @@ class MainRender {
screenRender.setStreamSize(encoderWidth, encoderHeight)
screenRender.setTexId(cameraRender.texId)
screenRender.initGl(context)
isReady = true
running.set(true)
}

fun isReady(): Boolean = running.get()

fun drawOffScreen() {
cameraRender.draw()
for (baseFilterRender in filterRenders) baseFilterRender.draw()
Expand All @@ -77,7 +79,7 @@ class MainRender {
}

fun release() {
isReady = false
running.set(false)
cameraRender.release()
for (baseFilterRender in filterRenders) baseFilterRender.release()
filterRenders.clear()
Expand Down
8 changes: 4 additions & 4 deletions library/src/main/java/com/pedro/library/base/StreamBase.kt
Expand Up @@ -266,7 +266,7 @@ abstract class StreamBase(
if (!surface.isValid) throw IllegalArgumentException("Make sure the Surface is valid")
if (isOnPreview) throw IllegalStateException("Preview already started, stopPreview before startPreview again")
isOnPreview = true
if (!glInterface.running) glInterface.start()
if (!glInterface.isRunning) glInterface.start()
if (!videoSource.isRunning()) {
videoSource.start(glInterface.surfaceTexture)
}
Expand Down Expand Up @@ -371,7 +371,7 @@ abstract class StreamBase(
protected fun getVideoFps() = videoEncoder.fps

private fun startSources() {
if (!glInterface.running) glInterface.start()
if (!glInterface.isRunning) glInterface.start()
if (!videoSource.isRunning()) {
videoSource.start(glInterface.surfaceTexture)
}
Expand All @@ -384,10 +384,10 @@ abstract class StreamBase(
private fun stopSources() {
if (!isOnPreview) videoSource.stop()
audioSource.stop()
videoEncoder.stop()
audioEncoder.stop()
glInterface.removeMediaCodecSurface()
if (!isOnPreview) glInterface.stop()
videoEncoder.stop()
audioEncoder.stop()
if (!isRecording) recordController.resetFormats()
}

Expand Down
24 changes: 12 additions & 12 deletions library/src/main/java/com/pedro/library/view/GlStreamInterface.kt
Expand Up @@ -38,6 +38,7 @@ import java.util.concurrent.BlockingQueue
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.atomic.AtomicBoolean


/**
Expand All @@ -47,9 +48,7 @@ import java.util.concurrent.LinkedBlockingQueue
class GlStreamInterface(private val context: Context): OnFrameAvailableListener, GlInterface {

private var takePhotoCallback: TakePhotoCallback? = null
@Volatile
var running = false
private set
private val running = AtomicBoolean(false)
private val surfaceManager = SurfaceManager()
private val surfaceManagerEncoder = SurfaceManager()
private val surfaceManagerPhoto = SurfaceManager()
Expand Down Expand Up @@ -108,7 +107,7 @@ class GlStreamInterface(private val context: Context): OnFrameAvailableListener,
setForceRender(enabled, 5)
}

override fun isRunning(): Boolean = running
override fun isRunning(): Boolean = running.get()

override fun getSurfaceTexture(): SurfaceTexture {
return mainRender.getSurfaceTexture()
Expand Down Expand Up @@ -146,15 +145,15 @@ class GlStreamInterface(private val context: Context): OnFrameAvailableListener,
mainRender.initGl(context, encoderWidth, encoderHeight, encoderWidth, encoderHeight)
surfaceManagerPhoto.release()
surfaceManagerPhoto.eglSetup(encoderWidth, encoderHeight, surfaceManager)
running = true
running.set(true)
mainRender.getSurfaceTexture().setOnFrameAvailableListener(this)
forceRender.start { executor?.execute { draw(true) } }
if (autoHandleOrientation) sensorRotationManager.start()
}
}

override fun stop() {
running = false
running.set(false)
executor?.secureSubmit {
forceRender.stop()
sensorRotationManager.stop()
Expand All @@ -168,17 +167,17 @@ class GlStreamInterface(private val context: Context): OnFrameAvailableListener,
}

private fun draw(forced: Boolean) {
if (!running || fpsLimiter.limitFPS()) return
if (!isRunning || fpsLimiter.limitFPS()) return
if (!forced) forceRender.frameAvailable()

if (surfaceManager.isReady && mainRender.isReady) {
if (surfaceManager.isReady && mainRender.isReady()) {
surfaceManager.makeCurrent()
mainRender.updateFrame()
mainRender.drawOffScreen()
surfaceManager.swapBuffer()
}

if (!filterQueue.isEmpty() && mainRender.isReady) {
if (!filterQueue.isEmpty() && mainRender.isReady()) {
try {
val filter = filterQueue.take()
mainRender.setFilterAction(filter.filterAction, filter.position, filter.baseFilterRender)
Expand All @@ -194,7 +193,7 @@ class GlStreamInterface(private val context: Context): OnFrameAvailableListener,
OrientationForced.NONE -> isPortrait
}
// render VideoEncoder (stream and record)
if (surfaceManagerEncoder.isReady && mainRender.isReady) {
if (surfaceManagerEncoder.isReady && mainRender.isReady()) {
val w = if (muteVideo) 0 else encoderWidth
val h = if (muteVideo) 0 else encoderHeight
surfaceManagerEncoder.makeCurrent()
Expand All @@ -203,7 +202,7 @@ class GlStreamInterface(private val context: Context): OnFrameAvailableListener,
surfaceManagerEncoder.swapBuffer()
}
//render surface photo if request photo
if (takePhotoCallback != null && surfaceManagerPhoto.isReady && mainRender.isReady) {
if (takePhotoCallback != null && surfaceManagerPhoto.isReady && mainRender.isReady()) {
surfaceManagerPhoto.makeCurrent()
mainRender.drawScreen(encoderWidth, encoderHeight, AspectRatioMode.NONE,
streamOrientation, isStreamVerticalFlip, isStreamHorizontalFlip)
Expand All @@ -212,7 +211,7 @@ class GlStreamInterface(private val context: Context): OnFrameAvailableListener,
surfaceManagerPhoto.swapBuffer()
}
// render preview
if (surfaceManagerPreview.isReady && mainRender.isReady) {
if (surfaceManagerPreview.isReady && mainRender.isReady()) {
val w = if (previewWidth == 0) encoderWidth else previewWidth
val h = if (previewHeight == 0) encoderHeight else previewHeight
surfaceManagerPreview.makeCurrent()
Expand All @@ -223,6 +222,7 @@ class GlStreamInterface(private val context: Context): OnFrameAvailableListener,
}

override fun onFrameAvailable(surfaceTexture: SurfaceTexture?) {
if (!isRunning) return
executor?.execute { draw(false) }
}

Expand Down
12 changes: 7 additions & 5 deletions library/src/main/java/com/pedro/library/view/OpenGlView.java
Expand Up @@ -45,6 +45,7 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;

/**
* Created by pedro on 10/03/18.
Expand All @@ -54,7 +55,7 @@
public class OpenGlView extends SurfaceView
implements GlInterface, SurfaceTexture.OnFrameAvailableListener, SurfaceHolder.Callback {

private volatile boolean running = false;
private AtomicBoolean running = new AtomicBoolean(false);
private final MainRender mainRender = new MainRender();
private final SurfaceManager surfaceManagerPhoto = new SurfaceManager();
private final SurfaceManager surfaceManager = new SurfaceManager();
Expand Down Expand Up @@ -213,7 +214,7 @@ public void setForceRender(boolean enabled) {

@Override
public boolean isRunning() {
return running;
return running.get();
}

@Override
Expand All @@ -233,7 +234,7 @@ public void takePhoto(TakePhotoCallback takePhotoCallback) {
}

private void draw(boolean forced) {
if (!running || fpsLimiter.limitFPS()) return;
if (!isRunning() || fpsLimiter.limitFPS()) return;
if (!forced) forceRenderer.frameAvailable();

if (surfaceManager.isReady() && mainRender.isReady()) {
Expand Down Expand Up @@ -311,7 +312,7 @@ public void start() {
mainRender.initGl(getContext(), encoderWidth, encoderHeight, encoderWidth, encoderHeight);
surfaceManagerPhoto.release();
surfaceManagerPhoto.eglSetup(encoderWidth, encoderHeight, surfaceManager);
running = true;
running.set(true);
mainRender.getSurfaceTexture().setOnFrameAvailableListener(this);
forceRenderer.start(() -> {
ExecutorService ex = this.executor;
Expand All @@ -325,7 +326,7 @@ public void start() {

@Override
public void stop() {
running = false;
running.set(false);
ExecutorService executor = this.executor;
if (executor == null) return;
ExtensionsKt.secureSubmit(executor, () -> {
Expand All @@ -342,6 +343,7 @@ public void stop() {

@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
if (!isRunning()) return;
ExecutorService ex = this.executor;
if (ex == null) return;
ex.execute(() -> draw(false));
Expand Down

0 comments on commit d427750

Please sign in to comment.