@@ -7,10 +7,19 @@ defmodule ExWebRTC.RTP.H264 do
77
88 # Copied nearly 1-to-1 from https://github.com/membraneframework/membrane_rtp_h264_plugin/blob/master/lib/rtp_h264/utils.ex
99 # originally based on galene's implementation https://github.com/jech/galene/blob/6fbdf0eab2c9640e673d9f9ec0331da24cbf2c4c/codecs/codecs.go#L119
10- # but only looks for SPS
11- # it is also unclear why we sometimes check against nalu type == 7
12- # and sometimes against nalu type == 5 but galene does it this way
13- # and it works
10+ # but only looks for SPS, in packetization_mode=0 as well as packetization_mode=1.
11+ #
12+ # It's been empirically tested with simulated packet loss that for packetization_mode=0 (`nalu_type in 1..23` clause):
13+ # * if we're checking against `nalu_type == 5`, the stream breaks regularly when switching layers,
14+ # * if we're checking against `nalu_type == 5 or nalu_type == 7`, the stream breaks occasionally when switching layers,
15+ # this happens when we've lost the packet containing SPS, but received the following one containing the keyframe,
16+ # * if we're checking against `nalu_type == 7`, no issues were encountered.
17+ #
18+ # Janus also does it this way.
19+ # https://github.com/meetecho/janus-gateway/blob/3367f41de9225daed812ca0991c259f1458fe49f/src/utils.h#L352
20+ #
21+ # For more info, refer to the H264 spec and RFC 6184, sections 5.4 and 6
22+ # https://datatracker.ietf.org/doc/html/rfc6184#section-5.4
1423
1524 @ doc """
1625 Returns a boolean telling if the packets contains a beginning of a H264 intra-frame.
@@ -21,14 +30,21 @@ defmodule ExWebRTC.RTP.H264 do
2130
2231 def keyframe? ( % Packet { } ) , do: false
2332
33+ # Reserved
2434 defp do_keyframe? ( 0 , _ ) , do: false
25- defp do_keyframe? ( nalu_type , _ ) when nalu_type in 1 .. 23 , do: nalu_type == 5
35+
36+ # Single NAL Unit packets: check if NALU contains SPS (type 7)
37+ defp do_keyframe? ( nalu_type , _ ) when nalu_type in 1 .. 23 , do: nalu_type == 7
38+
39+ # STAP-A
2640 defp do_keyframe? ( 24 , aus ) , do: check_aggr_units ( 24 , aus )
2741
42+ # STAP-B, MTAP16, MTAP24
2843 defp do_keyframe? ( nalu_type , << _don :: 16 , aus :: binary >> )
2944 when nalu_type in 25 .. 27 ,
3045 do: check_aggr_units ( nalu_type , aus )
3146
47+ # FU-A, FU-B
3248 defp do_keyframe? ( nalu_type , << s :: 1 , _e :: 1 , _r :: 1 , type :: 5 , _fu_payload :: binary >> )
3349 when nalu_type in 28 .. 29 ,
3450 do: s == 1 and type == 7
0 commit comments