RTP decompression failure with repeated constant TS

Bug #1265304 reported by Gil Beniamini
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
rohc
Status tracked in Rohc-main
Rohc-1.5.x
Invalid
Undecided
Didier Barvaux
Rohc-1.6.x
Invalid
Undecided
Didier Barvaux
Rohc-main
Fix Released
High
Didier Barvaux

Bug Description

I have a VoIP stream with audio (either G729 or G711) + video in RTP PT=H264.
The H264 stream is compressed but most frames fail to decompress (give error-code -4 or -5).
I proved that the H265 causes rohc failures, by filtering out the video/H264 steam (it is udp-port 5006 which I can sent uncompressed) while I feeding the rohc_compress2 with the rest (i.e. the audio), which make the "call" successful.
I have tried to use it with & without ROHC_PROFILE_RTP, while only using ROHC_PROFILE_UDP, but the problem was there.
I am using ROHC v1.6.1 in x86 Ubuntu-10.4
Attached a pcap file, of the original stream (w/o rohc) stream.
Gil

Tags: library rtp
Revision history for this message
Gil Beniamini (gilb-z) wrote :
Revision history for this message
Didier Barvaux (didier-barvaux) wrote :

I reproduced the problem. It seems to be related to RTP TS that doesn't change for several packets. I continue the analysis.

tags: added: library rtp
Revision history for this message
Gil Beniamini (gilb-z) wrote :

Dear Didier,
(1) It is strange that a problem related to "RTP TS" while both the comp/decomp decide it is not "RTP" but rather "UDP" profile.
compress-part:
[rohc_comp.c:2706 c_get_profile_from_packet()] skip profile 'RTP / Compressor' (0x0001) because it does not match packet
[rohc_comp.c:648 rohc_compress2()] using profile 'UDP / Compressor' (0x0002)

decompress-part:
[d_generic.c:4011 d_generic_decode()] decode packet as 'UO-1 (non-RTP)'

(2) I noted that the packets which fail to "decompress" are NOT the "video"/"coded-slice" (which are the large packets), but rather the small packets (size<96bytes) like: "picture parameter set" & "sequence parameter set" which are generated in the given stream once every 3 second.
I hope this helps, Gil

Revision history for this message
Didier Barvaux (didier-barvaux) wrote :

With the non-regression tool from the dev branch (revision 984), I got no comp/decomp error with default settings. I then configured the ROHC compressor to assign UDP/5006 to the RTP protocol, and I got some decompression failures at packet #427. I'm coding a fix for that problem.

With the 1.6.x branch, I got no error as well with the default settings of the non-regression tool. I got no error when I added UDP/5006 to the RTP ports.

I performed the test with the following command from the compiled sources:
  $ ./test/non_regression/test_non_regression --verbose smallcid rtpAudioVideo.pcap

The difference may come from the compression parameters you used (CID type, W-LSB width...). Please give me more information.

summary: - ROHC 1.6.1 compress H264 but fail decompress
+ RTP decompression failure with repeated constant TS
Revision history for this message
Gil Beniamini (gilb-z) wrote :

Dear Didier,
Sorry the problem when using PROFILE_UDP was not related to ROHC but rather my setup.
I was doing RTP test relay without any tunnel, and was using "raw-socket" to TX/RX L2(14 bytes) + ROHC-layload, I assumed that if I send specific-length, the recv length will be the same specific-length. But what I found out is that I was wrong and if the TX Rohc-payload length was less than 46 (like the packets I was investigating on 2Jan14) the "recv()" alway return with payload-length of 46. It seems to be called "Allowed Packet Lengths: Ethernet packets with less than the minimum 64 bytes for an Ethernet packet (header + user data + FCS) are padded to 64 bytes, which means that if there's less than 64-(14+4) = 46 bytes of user data, extra padding data is added to the packet. " (ref: http://wiki.wireshark.org/Ethernet).
So that padding-bytes + extra/wrong-length caused the problems with PROFILE_UDP.
Temporarily I moved to use a tunnel, and my problem is resolved.
But over satellite each byte counts and tunnel should be avoided, I might filter-out sending compressed packet when the compressed output-length < 46, or I'll find how to avoid the above padding to 46!
Thanks for everything, Gil

Revision history for this message
Didier Barvaux (didier-barvaux) wrote :

Gil,

I was hit by this one some time ago ;-) I'm glad you found the root of the problem. You might use ROHC padding to handle such a case (it allows you to still use ROHC and avoid both tunnel and filtering). Or use another link layer than Ethernet if possible (the satellite link doesn't use Ethernet, maybe it uses Ethernet only between you and the satellite terminal).

About the bug discovered in the main dev branch, I fixed it in revision 987: If RTP TS is constant, it must be transmitted uncompressed. It is however sent encoded with W-LSB. So, given enough RTP packets with the same constant RTP TS value, 0 bit are needed by the decompressor to decode the value. As it is forbidden to not sent at least 1 bit of TS when it is constant, the compressor forces the transmission of 1 bit. In the meanwhile, the TS bits to send were reset, so the compressor sends bits(TS) = 0. That's wrong. The TS bit shall be extracted again from the uncompressed TS in such a case.

Didier

Revision history for this message
Gil Beniamini (gilb-z) wrote :

Didier,
I managed doing "padding" instead of "tunnel", and it works OK.
Thanks for your excellent support, Gil

Revision history for this message
Didier Barvaux (didier-barvaux) wrote :

Gil,

Did you perform padding as described in RFC 3095, §5.2, page 41 [1] ? It is not supported by the ROHC compressor yet (but could be prepended before the ROHC header easily after rohc_compress() ). The ROHC decompressor already handles padding bytes just fine. It could make your padding mechanism easier (no need to transmit the size of the padding for example).

Didier

[1] https://tools.ietf.org/html/rfc3095#page-41

Revision history for this message
Gil Beniamini (gilb-z) wrote :

Didier,
No, I was doing my own padding.

On the compressor side:
If compress2 was successful and L3-output-len < 46, knowing that 46 bytes are going to be TX in any case, I put at rohc_txbuf[45] = (char) L3-output-len, and this is what is TX as L3.

On the decompressor side:
If L3-len == 46, I obtain rohc_actual_len from rxL3_buf[45] and use it as rohs_decompress input-len if the value is < 46.

The above method is not full proof when compress2 l3-compress2-out-length is exactly 46 and the last output_byte is realy < 46.
As the compresss Packets are TX with L2 ETHERTYPE of 0x22f1, and I still hasitate if when the above padding (<46) is done to use a different ETHERTYPE?!
Gil

Revision history for this message
Gil Beniamini (gilb-z) wrote :

Didier,
Now I tried your suggestion of prepending of 46-compress2-out-len * 0xE0 before ROHC-header on the compress side (nothing on the decompress side), and it works OK!
Thanks again, Gil

Revision history for this message
Didier Barvaux (didier-barvaux) wrote :

Gil,

Cool, thx for the feedback!

If you have some free time, it would be great to add support for ROHC padding on compressor side in the library itself. See the blueprint https://blueprints.launchpad.net/rohc/+spec/padding for details.

Regards,
Didier

Revision history for this message
Gil Beniamini (gilb-z) wrote :

Didier,
(1) I looked at https://tools.ietf.org/html/rfc3095#section-6.3.1 and if I understand it correctly, in case of ETHERNET with ETHER_MIN_LEN=46, the PACKET_SIZES_ALLOWED list should be long starting with 46,47,48,49,...1500-14 where the upper limit is compress2' parameter5==rohc_packet_max_len ?! Am I correct? Can't the RFC be changed (i.e. min_len (best) or range)?
(2) In any case at this stage I want to proceed and create rtp_detector_cb() maybe with some deep packet inspection.
(3) So when I am done, I might re-consider if I can help in one of the above.
Best Regards, Gil

Revision history for this message
Didier Barvaux (didier-barvaux) wrote :

Gil,

(1) To my opinion, this part of the RFC are not strict requirements (MUST in RFC vocabulary), so we may adapt the interface to our needs. Your usage (>= min_value) is indeed difficult to define with a list of discreet values. Another usage I think of is ATM/AAL5 encapsulation: ROHC packets should be (48*N)-8 byte long. We shall find a way to make the API interface handle all those cases fine IMHO.

(2) See http://bazaar.launchpad.net/~didier-barvaux/rohc/main/view/head:/app/sniffer/sniffer.c#L952 + http://bazaar.launchpad.net/~didier-barvaux/rohc/main/view/head:/app/sniffer/sniffer.c#L960 + http://bazaar.launchpad.net/~didier-barvaux/rohc/main/view/head:/app/sniffer/sniffer.c#L1722 for an example of DPI used by the ROHC sniffer.

(3) That would be great ;-)

For next questions, please consider registering to the mailing list (https://launchpad.net/~rohc/+join) and send emails on it. This bugtracker entry is not really a forum ;-)

Didier

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.