Skip to content

Commit 9ee09e7

Browse files
author
Aaron Alaniz
committed
Add workaround to get access to OpenGL context thread
1 parent 55f4eba commit 9ee09e7

2 files changed

Lines changed: 50 additions & 22 deletions

File tree

exampleMultipartyVideo/src/main/java/com/twilio/examplemultipartyvideo/MultiPartyActivity.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ private void createAudioAndVideoTracks() {
356356

357357
// Share your camera
358358
cameraCapturerCompat = new CameraCapturer(this, getAvailableCameraSource());
359-
snapshotVideoRenderer = new SnapshotVideoRenderer(this, snapshotImageView, 25);
359+
snapshotVideoRenderer = new SnapshotVideoRenderer(this, snapshotImageView, 25, localVideoTextureView);
360360

361361
localVideoTrack = LocalVideoTrack.create(this,
362362
true,
@@ -539,7 +539,8 @@ private void addRemoteParticipantVideo(RemoteParticipant remoteParticipant, Vide
539539
videoTextureView.setVisibility(VISIBLE);
540540
videoTrack.addRenderer(videoTextureView);
541541

542-
remoteSnapshotVideoRenderer = new SnapshotVideoRenderer(getApplicationContext(), snapshotImageView, 25);
542+
remoteSnapshotVideoRenderer = new SnapshotVideoRenderer(getApplicationContext(), snapshotImageView, 25, videoTextureView);
543+
localVideoTrack.removeRenderer(snapshotVideoRenderer);
543544
videoTrack.addRenderer(remoteSnapshotVideoRenderer);
544545
updateRemoteBlurFrame();
545546

exampleMultipartyVideo/src/main/java/com/twilio/examplemultipartyvideo/SnapshotVideoRenderer.java

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@
1212

1313
import com.twilio.video.I420Frame;
1414
import com.twilio.video.VideoRenderer;
15-
import com.twilio.video.VideoView;
15+
import com.twilio.video.VideoTextureView;
1616

1717
import java.io.ByteArrayOutputStream;
18+
import java.lang.reflect.Field;
1819
import java.nio.ByteBuffer;
1920
import java.util.concurrent.atomic.AtomicBoolean;
2021

2122
import io.alterac.blurkit.BlurKit;
23+
import tvi.webrtc.EglRenderer;
2224
import tvi.webrtc.RendererCommon;
2325
import tvi.webrtc.YuvConverter;
2426

@@ -29,45 +31,70 @@
2931
* last frame rendered and will update the provided image view any time {@link #takeSnapshot()} is
3032
* invoked.
3133
*/
32-
public class SnapshotVideoRenderer extends VideoView {
34+
public class SnapshotVideoRenderer extends VideoTextureView {
3335
private final ImageView imageView;
3436
private int blurValue;
3537
private final AtomicBoolean snapshotRequsted = new AtomicBoolean(false);
3638
private final Handler handler = new Handler(Looper.getMainLooper());
39+
private Handler eglRendererHandler = null;
40+
private final VideoTextureView videoTextureView;
3741

38-
public SnapshotVideoRenderer(Context context, ImageView imageView, int blurValue) {
42+
public SnapshotVideoRenderer(Context context, ImageView imageView, int blurValue, VideoTextureView videoTextureView) {
3943
super(context);
4044
this.imageView = imageView;
4145
this.blurValue = blurValue;
46+
this.videoTextureView = videoTextureView;
4247
}
4348

4449
@Override
4550
public void renderFrame(final I420Frame i420Frame) {
4651

4752
// Capture bitmap and post to main thread
4853
if (snapshotRequsted.compareAndSet(true, false)) {
49-
/*
50-
* I420Frame can be represented as texture or an in-memory buffer. yuvPlanes is not
51-
* null and textureId is zero when frame is represented in memory and yuvPlanes is
52-
* null textureId is a non zero value when the frame is represented as a texture.
53-
*/
54-
final Bitmap bitmap = i420Frame.yuvPlanes == null ?
55-
captureBitmapFromTexture(i420Frame) :
56-
captureBitmapFromYuvFrame(i420Frame);
57-
handler.post(() -> {
58-
59-
// Update the bitmap of image view
60-
BlurKit.getInstance().blur(bitmap, blurValue);
61-
imageView.setImageBitmap(bitmap);
62-
63-
// Frames must be released after rendering to free the native memory
64-
i420Frame.release();
65-
});
54+
if (eglRendererHandler == null) {
55+
eglRendererHandler = getEglHandler();
56+
}
57+
if (eglRendererHandler != null) {
58+
eglRendererHandler.post(() -> {
59+
final Bitmap bitmap = i420Frame.yuvPlanes == null ?
60+
captureBitmapFromTexture(i420Frame) :
61+
captureBitmapFromYuvFrame(i420Frame);
62+
63+
// Update the bitmap of image view
64+
BlurKit.getInstance().blur(bitmap, blurValue);
65+
66+
handler.post(() -> {
67+
imageView.setImageBitmap(bitmap);
68+
69+
// Frames must be released after rendering to free the native memory
70+
i420Frame.release();
71+
});
72+
});
73+
}
6674
} else {
6775
i420Frame.release();
6876
}
6977
}
7078

79+
private Handler getEglHandler() {
80+
try {
81+
Field eglRendererField = videoTextureView.getClass().getDeclaredField("eglRenderer");
82+
eglRendererField.setAccessible(true);
83+
EglRenderer eglRenderer = (EglRenderer) eglRendererField.get(videoTextureView);
84+
Field renderThreadHandlerField = eglRenderer.getClass().getDeclaredField("renderThreadHandler");
85+
renderThreadHandlerField.setAccessible(true);
86+
Handler eglHandler = (Handler) renderThreadHandlerField.get(eglRenderer);
87+
88+
return eglHandler;
89+
} catch (NoSuchFieldException e) {
90+
e.printStackTrace();
91+
} catch (IllegalAccessException e) {
92+
e.printStackTrace();
93+
}
94+
95+
return null;
96+
}
97+
7198
/**
7299
* Request a snapshot on the rendering thread.
73100
*/

0 commit comments

Comments
 (0)