Code change:
LGTM
I have a doubt about why an SRC for the CTR is needed at all and if a global counter for all streams would be equally secure in terms forming the IV or was due to implementation details to be able to have different context for each streams?
Because the key is used to encrypt all outgoing stream, we need a global counter for the IV to avoid counter reuse. If we use the frame counter only, then each stream will have their own counter and IV will collide
If the frame counter is global for the participant instead that per stream, i.e. increased whenever a new frame is encoded regarding the media stream, there would be no IV collision.
Correct. But I imagine this will be more complex to implement, having a single global counter across all media sources including audio and video
Prepared a PR to change it to a global counter, however I want to make sure I understand how the counter is maintained globally, If the frame N is encrypted in 3 different layers, they will have different counter values right? One potential benefit of having a global counter it will free up some bits in the header which we can use as a keyId (up to 16 keys) which is nice
Yes, each call to the frame encryptor which would require to atomically increment the counter. In the case of the simulcast, the same input image will produce N different encoded frames which would have their unique counter. Regarding the free bits, I was thinking in something like this: If x=0 then K is the key id ( 0-7) if x=1 then K is the length of the key that is inserted before the This would allow to avoid the extra byte for conferences with less than 9 participants. Another option would be to always use the KLEN/KEYID and reserve that bit for extensions in the future.
I like it :-)

Related discussion:
text: encryption IV.  The frame counter must be unique and monodically increasing to avoid IV reuse. <del> The frame counter itself can be encoded in a variable length format to decrease the overhead, the following encoding schema is used The first byte in the header is fixed and contains the header metadata S 1 bit Signature flag, indicates the payload contains a signature of set. Reserved (4 bits) Reserved bits LEN (3 bits) The length of the CTR fields in bytes. CTR (Variable length) Frame counter up to 8 bytes long </del> <ins> As each sender will use their own key for encryption, so the SFrame header will include the key id to allow the receiver to identify the key that needs to be used for decrypting. Both the frame counter and the key id are encoded in a variable length format to decrease the overhead, so the first byte in the Sframe header is fixed and contains the header metadata with the following format: Signature flag (S): 1 bit This field indicates the payload contains a signature of set.  Counter Length (LEN): 3 bits This field indicates the length of the CTR fields in bytes.  Extended Key Id Flag (X): 1 bit Indicates if the key field contains the key id or the key length. Key or Key Length: 3 bits This field containts the key id (KID) if the X flag is set to 0, or the key length (KLEN) if set to 1. If X flag is 0 then the KID is in the range of 0-7 and the frame counter (CTR) is found in the next LEN bytes: Key id (KID): 3 bits The key id (0-7).  Frame counter (CTR): (Variable length) Frame counter value up to 8 bytes long. if X flag is 1 then KLEN is the length of the key (KID), that is found after the SFrame header metadata byte.  After the key id (KID), the frame counter (CTR) will be found in the next LEN bytes: 0 1 2 3 4 5 6 7 +-+-+-+-+-+-+-+-+----------------------+------------- ---------+ |S|LEN |1|KLEN | KID... (length=KLEN) | CTR... (length=LEN) | +-+-+-+-+-+-+-+-+----------------------+----------------------+ Key length (KLEN): 3 bits The key length in bytes.  Key id (KID): (Variable length) The key id value up to 8 bytes long.  Frame counter (CTR): (Variable length) Frame counter value up to 8 bytes long. </ins> 3.2.