WebRTC remote video freeze after few seconds

3.5k Views Asked by At

I have an issue when using SurfaceViewRenderer to display remote video track when calling between android and iOs (android <-> android and ios<->ios work as well)

The remote video view on Android going to freeze after a few seconds, but the audio still works, (iOS is okay).

Maybe the problem caused by H264 codecs of iOS, but I follow the latest code to decode and encode PeerConnection, so I still stuck here.

Below is my code:

Create PeerConnectionFactory:

 PeerConnectionFactory.initialize(
                PeerConnectionFactory.InitializationOptions.builder(activity.getApplicationContext())
                        .setEnableInternalTracer(true)
                        .setEnableVideoHwAcceleration(true, true)
                        .createInitializationOptions());

decode and encode

 private void tryingToCreatePeerConnectionFactory(EglBase eglBase) {
        final PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
        final DefaultVideoEncoderFactory encoderFactory = new DefaultVideoEncoderFactory(eglBase.getEglBaseContext(), true, true);
        final DefaultVideoDecoderFactory decoderFactory = new DefaultVideoDecoderFactory(eglBase.getEglBaseContext());
        peerConnectionFactory = PeerConnectionFactory.builder().setOptions(options).
                setVideoDecoderFactory(decoderFactory).
                setVideoEncoderFactory(encoderFactory).
                createPeerConnectionFactory();
    }

SDP content

v=0
o=- 3807425029370800822 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS ARDAMS
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 9 102 0 8 105 13 110 113 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:pTq5
a=ice-pwd:EVfiXQOe4/G/01ezOXYv1fzB
a=ice-options:trickle renomination
a=fingerprint:sha-256 A3:D1:0B:D4:9F:A9:ED:C5:D2:94:04:F3:91:07:6F:FD:68:71:4C:7B:CA:87:3F:AB:34:B5:F3:7E:82:0B:42:77
a=setup:active
a=mid:audio
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=sendrecv
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:103 ISAC/16000
a=rtpmap:9 G722/8000
a=rtpmap:102 ILBC/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:105 CN/16000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:113 telephone-event/16000
a=rtpmap:126 telephone-event/8000
a=ssrc:3210082304 cname:PPyVOHEaYgrfSyKM
a=ssrc:3210082304 msid:ARDAMS ARDAMSa0
a=ssrc:3210082304 mslabel:ARDAMS
a=ssrc:3210082304 label:ARDAMSa0
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 127
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:pTq5
a=ice-pwd:EVfiXQOe4/G/01ezOXYv1fzB
a=ice-options:trickle renomination
a=fingerprint:sha-256 A3:D1:0B:D4:9F:A9:ED:C5:D2:94:04:F3:91:07:6F:FD:68:71:4C:7B:CA:87:3F:AB:34:B5:F3:7E:82:0B:42:77
a=setup:active
a=mid:video
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:4 urn:3gpp:video-orientation
a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=sendrecv
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:96 H264/90000
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=fmtp:96 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640c1f
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96
a=rtpmap:98 H264/90000
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=fmtp:98 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:100 red/90000
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:127 ulpfec/90000
a=ssrc-group:FID 2423939598 98025098
a=ssrc:2423939598 cname:PPyVOHEaYgrfSyKM
a=ssrc:2423939598 msid:ARDAMS ARDAMSv0
a=ssrc:2423939598 mslabel:ARDAMS
a=ssrc:2423939598 label:ARDAMSv0
a=ssrc:98025098 cname:PPyVOHEaYgrfSyKM
a=ssrc:98025098 msid:ARDAMS ARDAMSv0
a=ssrc:98025098 mslabel:ARDAMS
a=ssrc:98025098 label:ARDAMSv0

UPDATE We find out a cause of this issue, for an unknown reason, data received in the Android side go low and never up again, that why video be freeze

Below is a value of date received while video be freeze

getBytesInInterval= 6091

But I don't know why it happens

Does anyone have a suggestion for my issue? Any response would be appreciated.

3

There are 3 best solutions below

0
Nguyễn Đức Vũ On BEST ANSWER

UPDATE

I already found the solutions for this issue, man. Root cause come from the iOS size, the resolution for each Video Codecs (Decode/Encode) should be scale down and Freeze frame situation will gone.

Please Update this code for iOS Side

static let videoResolutionsStaticValues = [ "640x480", "960x540", "1280x720" ]
static let videoCodecsStaticValues = [ "H264", "VP8", "VP9" ]
1
Nguyễn Đức Vũ On

I already follow this link, I think it's maybe helpful, man.

  if (options != null) {
  Log.d(TAG, "Factory networkIgnoreMask option: " + options.networkIgnoreMask);
}
final boolean enableH264HighProfile =
    VIDEO_CODEC_H264_HIGH.equals(peerConnectionParameters.videoCodec);
final VideoEncoderFactory encoderFactory;
final VideoDecoderFactory decoderFactory;

if (peerConnectionParameters.videoCodecHwAcceleration) {
  encoderFactory = new DefaultVideoEncoderFactory(
      rootEglBase.getEglBaseContext(), true /* enableIntelVp8Encoder */, enableH264HighProfile);
  decoderFactory = new DefaultVideoDecoderFactory(rootEglBase.getEglBaseContext());
} else {
  encoderFactory = new SoftwareVideoEncoderFactory();
  decoderFactory = new SoftwareVideoDecoderFactory();
}

factory = PeerConnectionFactory.builder()
              .setOptions(options)
              .setAudioDeviceModule(adm)
              .setVideoEncoderFactory(encoderFactory)
              .setVideoDecoderFactory(decoderFactory)
              .createPeerConnectionFactory();

It's official document/code from WebRTC for android.

0
Ariadna Ll. On

The resolution sent from the iOS is what it was causing the issue in my case. To apply the solution you will need to set them as media constraints:

let constraints = [
    "minWidth": Self.videoResolutionsStaticValues[0],
    "maxWidth": Self.videoResolutionsStaticValues[2],
    "minHeight": "480",
    "maxHeight": "720"
]
RTCMediaConstraints(mandatoryConstraints: constraints, optionalConstraints: nil)

But most importantly, you should configure the video capture session's resolution directly using AVCaptureSession and AVCaptureDevice

// Set the desired video resolution
let targetResolution = CGSize(width: 640, height: 480)

if let format = videoDevice!.formats.first(where: { format -> Bool in
    let dimensions = CMVideoFormatDescriptionGetDimensions(format.formatDescription)
    return dimensions.width == Int32(targetResolution.width) && dimensions.height == Int32(targetResolution.height)
}) {
    do {
        try videoDevice!.lockForConfiguration()
        videoDevice!.activeFormat = format
        videoDevice!.unlockForConfiguration()
    } catch {
        print("Error setting the video device active format")
    }
}

captureSession.sessionPreset = .hd1280x720

With these changes, the video should not freeze anymore