No video at peer (persistent black)
Some black at the very start of a video stream is normal — the
codec is initialising, the first keyframe (IDR) hasn’t arrived yet,
and the renderer surface may not be wired up. The library
pre-fills the renderer’s frame buffer with black via
pjmedia_video_format_fill_black(), so the user does not
see uninitialised colours during this window. The cleanest way to
hide the startup window from the user is to leave the renderer
hidden until PJMEDIA_EVENT_FMT_CHANGED arrives — see
Video window UX.
If the remote side keeps showing black past that initial window, work through these in order:
Verify outgoing transmission is enabled. Outgoing video is not started by default. Either set
pjsua_acc_config::vid_out_auto_transmittoPJ_TRUEon the account, or start it explicitly per call withpjsua_call_set_vid_strm()andPJSUA_CALL_VID_STRM_START_TRANSMIT/PJSUA_CALL_VID_STRM_ADD. See Modifying video during a call in Working with video media.Verify the SDP carries video sendrecv. Inspect the
media[i].dirfield ofpjsua_call_infoand look for video markedsendonly/recvonly/inactive. If the call setting’spjsua_call_setting::media_dirwas used, it persists across re-INVITEs.Verify a video codec is actually negotiated by both ends. At least one video codec must be enabled in the build and supported by the peer. Use
pjsua_vid_enum_codecs()to see what we offer; check Video Components and Backends for which backends provide which codecs per platform.Confirm RTP packets are actually being received. See Check if RTP packets are received — the same diagnostic applies to video. If no RTP arrives, the problem is at the transport / NAT level, not the codec.
Force a keyframe if the peer is decoding but stuck without one (e.g. lost the original IDR): call
pjsua_call_set_vid_strm()withPJSUA_CALL_VID_STRM_SEND_KEYFRAME. Conversely, the peer requests a keyframe from us via SIP INFO or RTCP PLI; allowed transports are governed bypjsua_call_setting::req_keyframe_method. The default already enables both. See Video Keyframe Transmission.Hook the call media-state callback. Implement
pjsua_callback::on_call_media_stateand read the per-stream status frompjsua_call_infoto confirm the video stream actually transitioned to active.
Related: Green frames, Mobile: video stops after backgrounding, Network / IP change leaves video black.