SDK Version
Amazon IVS Broadcast Android SDK 1.44.0
Environment
- Android device: physical device, GPU "Adreno (TM) 610" (Qualcomm SoC), OMX.qcom.video.decoder.avc used for H264 decode
- App is a React Native app using the New Architecture (Fabric) with a custom native
FrameLayout-based ViewManager wrapping the Stages subscriber APIs
- Use case: subscribe-only (no publish), single remote participant, AUDIO_VIDEO subscribe type
Summary
When subscribing to a remote participant's stage, audio plays back correctly, but the video preview view remains completely black. This happens consistently across many repeated join/leave cycles and multiple approaches to preview attachment.
What we've confirmed is working
- WebRTC/ICE negotiation completes successfully (
ice connection state: connected / completed)
onStreamsAdded fires with both AudioStageStream and ImageStageStream
IVSVideoDecoder is created for H264 (OMX.qcom.video.decoder.avc)
SurfaceTextureHelper sets its listener
- Shader compilation succeeds, program link succeeds
- Audio plays correctly (
AAudio play stream, RTCAndroidAudioDevice::StartPlayout)
- The native view is correctly attached to the window before the preview is requested (confirmed via
isAttachedToWindow and layout logs)
ImageStageStream.device is a valid ImageDevice, and the preview object returned is com.amazonaws.ivs.broadcast.ImagePreviewView (confirmed via preview.javaClass.name)
attachPreview() executes with no exceptions; the ImagePreviewView is added to the view hierarchy with MATCH_PARENT layout params
What we've tried, in order
ImageDevice.getPreviewView(aspectMode) — attaches an ImagePreviewView (TextureView subclass) to our custom FrameLayout. Video area stays black.
- Deferring attachment until the view is confirmed attached to the window (
isAttachedToWindow, then later ViewTreeObserver.OnGlobalLayoutListener as a more robust check) — ruled out an attach-timing race, but video still doesn't render once attachment is confirmed.
ImageStageStream.getPreview() (per the "Display and Remove Participants" section of the developer guide) instead of ImageDevice.getPreviewView() — same result.
- Removed all caching/reuse of previously-detached preview views (aware of the documented known issue that a detached
ImagePreviewView cannot be reused) — always request a fresh preview on every onStreamsAdded. No change.
- Attempted to attach a
TextureView.SurfaceTextureListener to the returned ImagePreviewView for diagnostic purposes — this may have actively interfered with the SDK's own internal listener on the same TextureView, so we removed this and left the view untouched (just addView()), matching the developer guide's sample code exactly. Still black.
- Confirmed via repeated logcat captures that the
Surface=... EGLSurface=0x0 log line appears on every run regardless of whether our preview attachment code runs at all (including sessions where we deliberately deferred/skipped attaching the preview entirely) — this line appears to originate from the decoder/internal rendering pipeline and does not seem to correlate with whether our app-level attachPreview() succeeds.
- Ruled out layout/clipping issues on the RN side (removed
overflow: hidden and borderRadius from the parent view hierarchy) — no change.
Representative logcat excerpt (single join, our preview attach succeeding)
Stage: onStreamsAdded OlcpCm90xjuV
TYPE = com.amazonaws.ivs.broadcast.AudioStageStream
Audio stream received
TYPE = com.amazonaws.ivs.broadcast.ImageStageStream
Image stream received
attachImageStream() entered
Creating PictureSample 720.000000x1569.000000 for
Surface=0x7606 SurfaceTexture=0x75e6 EGLSurface=0xb400007826320200
preview=com.amazonaws.ivs.broadcast.ImagePreviewView
ENTER attachPreview, class=com.amazonaws.ivs.broadcast.ImagePreviewView
IVSVideoDecoder: Created decoder: OMX.qcom.video.decoder.avc for codec: H264
SurfaceTextureHelper: Setting listener to com.amazonaws.ivs.webrtc.IVSVideoDecoder@e12877
StageSource Event for participant: OlcpCm90xjuV, Type: 5, Error: 0
Surface=0x7986 SurfaceTexture=0x7966 EGLSurface=0x0
StageSource Event for participant: OlcpCm90xjuV, Type: 5, Error: 0
Shader compilation succeeded.
Shader compilation succeeded.
Program link success
Signalling Event for participant: OlcpCm90xjuV, Type: SelectLayer, Error: 0
Note the two separate Surface=... log lines with different EGLSurface values — the first (0xb40000...) appears valid, the second (0x0) appears immediately after the decoder is created and consistently shows EGLSurface=0x0. We were unable to determine from the SDK's public API/docs which of these corresponds to our attached preview view versus an internal decoder target, and whether EGLSurface=0x0 here is expected/benign or indicative of a real failure.
Minimal reproduction (native, no RN) — NOT YET DONE
We have not yet isolated this down to a plain Android sample app outside of React Native/Fabric. We plan to test whether stream.getPreview() + previewHolder.addView(preview) in a bare Activity (following the developer guide's sample exactly) renders correctly. We are opening this issue partly to ask: given the log signature above (successful decoder creation, successful shader/program linking, but persistent EGLSurface=0x0 on the second surface, and no visible frames), is this a recognized pattern, and does it point to a specific known cause?
Questions for the SDK team
- Is the
Surface=... EGLSurface=0x0 log line expected/benign in some cases, or does it always indicate a real rendering failure?
- Are there additional requirements for attaching
ImagePreviewView / ImagePreviewSurfaceView inside a custom Android ViewGroup (as opposed to directly in an Activity's layout) that aren't covered in the developer guide — e.g. regarding hardware layer type, view hierarchy depth, or GL context sharing?
- Is it safe to assign a custom
TextureView.SurfaceTextureListener to an ImagePreviewView for diagnostic purposes, or does the SDK rely on being the sole listener?
- Are there known issues with
ImagePreviewView/ImagePreviewSurfaceView rendering under React Native's Fabric renderer (custom FrameLayout-based Fabric components), given that Fabric can mount/measure/layout native views somewhat independently from the standard Android view attach lifecycle?
Relevant code (custom Fabric ViewManager + View)
Available on request — happy to share the full ReactIVSBroadcastView.kt / ReactIVSBroadcastManager.kt / LivestreamPlayer.tsx if useful for reproducing.
SDK Version
Amazon IVS Broadcast Android SDK 1.44.0
Environment
FrameLayout-based ViewManager wrapping the Stages subscriber APIsSummary
When subscribing to a remote participant's stage, audio plays back correctly, but the video preview view remains completely black. This happens consistently across many repeated join/leave cycles and multiple approaches to preview attachment.
What we've confirmed is working
ice connection state: connected/completed)onStreamsAddedfires with bothAudioStageStreamandImageStageStreamIVSVideoDecoderis created for H264 (OMX.qcom.video.decoder.avc)SurfaceTextureHelpersets its listenerAAudio play stream,RTCAndroidAudioDevice::StartPlayout)isAttachedToWindowand layout logs)ImageStageStream.deviceis a validImageDevice, and the preview object returned iscom.amazonaws.ivs.broadcast.ImagePreviewView(confirmed viapreview.javaClass.name)attachPreview()executes with no exceptions; theImagePreviewViewis added to the view hierarchy withMATCH_PARENTlayout paramsWhat we've tried, in order
ImageDevice.getPreviewView(aspectMode)— attaches anImagePreviewView(TextureViewsubclass) to our customFrameLayout. Video area stays black.isAttachedToWindow, then laterViewTreeObserver.OnGlobalLayoutListeneras a more robust check) — ruled out an attach-timing race, but video still doesn't render once attachment is confirmed.ImageStageStream.getPreview()(per the "Display and Remove Participants" section of the developer guide) instead ofImageDevice.getPreviewView()— same result.ImagePreviewViewcannot be reused) — always request a fresh preview on everyonStreamsAdded. No change.TextureView.SurfaceTextureListenerto the returnedImagePreviewViewfor diagnostic purposes — this may have actively interfered with the SDK's own internal listener on the sameTextureView, so we removed this and left the view untouched (justaddView()), matching the developer guide's sample code exactly. Still black.Surface=... EGLSurface=0x0log line appears on every run regardless of whether our preview attachment code runs at all (including sessions where we deliberately deferred/skipped attaching the preview entirely) — this line appears to originate from the decoder/internal rendering pipeline and does not seem to correlate with whether our app-levelattachPreview()succeeds.overflow: hiddenandborderRadiusfrom the parent view hierarchy) — no change.Representative logcat excerpt (single join, our preview attach succeeding)
Note the two separate
Surface=...log lines with different EGLSurface values — the first (0xb40000...) appears valid, the second (0x0) appears immediately after the decoder is created and consistently showsEGLSurface=0x0. We were unable to determine from the SDK's public API/docs which of these corresponds to our attached preview view versus an internal decoder target, and whetherEGLSurface=0x0here is expected/benign or indicative of a real failure.Minimal reproduction (native, no RN) — NOT YET DONE
We have not yet isolated this down to a plain Android sample app outside of React Native/Fabric. We plan to test whether
stream.getPreview()+previewHolder.addView(preview)in a bare Activity (following the developer guide's sample exactly) renders correctly. We are opening this issue partly to ask: given the log signature above (successful decoder creation, successful shader/program linking, but persistentEGLSurface=0x0on the second surface, and no visible frames), is this a recognized pattern, and does it point to a specific known cause?Questions for the SDK team
Surface=... EGLSurface=0x0log line expected/benign in some cases, or does it always indicate a real rendering failure?ImagePreviewView/ImagePreviewSurfaceViewinside a custom AndroidViewGroup(as opposed to directly in an Activity's layout) that aren't covered in the developer guide — e.g. regarding hardware layer type, view hierarchy depth, or GL context sharing?TextureView.SurfaceTextureListenerto anImagePreviewViewfor diagnostic purposes, or does the SDK rely on being the sole listener?ImagePreviewView/ImagePreviewSurfaceViewrendering under React Native's Fabric renderer (customFrameLayout-based Fabric components), given that Fabric can mount/measure/layout native views somewhat independently from the standard Android view attach lifecycle?Relevant code (custom Fabric ViewManager + View)
Available on request — happy to share the full
ReactIVSBroadcastView.kt/ReactIVSBroadcastManager.kt/LivestreamPlayer.tsxif useful for reproducing.