After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 604913 - rtph264pay/NALU/rtph264depay
rtph264pay/NALU/rtph264depay
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
0.10.17
Other All
: Normal major
: 0.10.18
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2009-12-18 14:37 UTC by Marc Leeman
Modified: 2009-12-22 09:22 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
patch rtph264pay to send sps/pps in data stream (6.05 KB, patch)
2009-12-21 13:36 UTC, Marc Leeman
none Details | Review
param tweak spspps_send (6.09 KB, patch)
2009-12-21 15:26 UTC, Marc Leeman
none Details | Review

Description Marc Leeman 2009-12-18 14:37:04 UTC
I am trying to convert an RTSP source H264 to RTP H264 with re-payloading.

The NALU are received in the rtsp headers and are passed to rtph264pay

gst-launch -v rtspsrc location=rtsp://10.3.0.159/axis-media/media.amp?videocodec=h264 debug=True ! rtph264depay ! queue ! rtph264pay sprop-parameter-sets="Z0IAKeKQFoe2BqwYBBuHiRFQ,aM48gA==" scan-mode=2 ! udpsink host=226.226.226.100 port=2222

The sprop-parameter-sets are obtained on a previous run.

starting the decoding is done with:
gst-launch -v udpsrc uri=udp://226.226.226.100:2222 caps="application/x-rtp, clock-rate=(int)90000" ! rtph264depay ! queue2  ! decodebin ! ffmpegcolorspace name=lcolour ! xvimagesink force-aspect-ratio=True sync=True

When the decoder is started before the repackaging; the decoder can pick in on the stream and decodes correctly.

However, when the decoder is started on an existing stream; it is never able to decode the stream.

The original hardware encoder is an AXIS Q7401 Video Encoder and since the NALU is passed in RTSP and not in the video stream; we assumed this was the cause.

Initially I thought that the NALU was only passed once; but by running with GST_DEBUG=*rtph264pay*:5; these seem to be passed regularly:

0:00:08.441315436 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:480:gst_rtp_h264_pay_decode_nal: NAL: 0 2 1 Len = 953
0:00:08.441325583 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:574:gst_rtp_h264_pay_payload_nal:<rtph264pay0> Processing Buffer with NAL TYPE=1
0:00:08.441335195 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:580:gst_rtp_h264_pay_payload_nal:<rtph264pay0> NAL Unit fit in one packet datasize=953 mtu=1400
0:00:08.478817110 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:456:gst_rtp_h264_pay_decode_nal: NAL payload len=1016
0:00:08.478825387 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:480:gst_rtp_h264_pay_decode_nal: NAL: 0 2 1 Len = 1016
0:00:08.478834491 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:574:gst_rtp_h264_pay_payload_nal:<rtph264pay0> Processing Buffer with NAL TYPE=1
0:00:08.478844317 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:580:gst_rtp_h264_pay_payload_nal:<rtph264pay0> NAL Unit fit in one packet datasize=1016 mtu=1400
0:00:08.509316843 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:456:gst_rtp_h264_pay_decode_nal: NAL payload len=1021
0:00:08.509325078 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:480:gst_rtp_h264_pay_decode_nal: NAL: 0 2 1 Len = 1021
0:00:08.509334329 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:574:gst_rtp_h264_pay_payload_nal:<rtph264pay0> Processing Buffer with NAL TYPE=1
0:00:08.509344233 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:580:gst_rtp_h264_pay_payload_nal:<rtph264pay0> NAL Unit fit in one packet datasize=1021 mtu=1400
0:00:08.541318572 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:456:gst_rtp_h264_pay_decode_nal: NAL payload len=18017
0:00:08.541326813 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:480:gst_rtp_h264_pay_decode_nal: NAL: 0 3 5 Len = 18017
0:00:08.541335917 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:574:gst_rtp_h264_pay_payload_nal:<rtph264pay0> Processing Buffer with NAL TYPE=5
0:00:08.541361968 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:635:gst_rtp_h264_pay_payload_nal:<rtph264pay0> NAL Unit DOES NOT fit in one packet datasize=18017 mtu=1400
0:00:08.578306974 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:456:gst_rtp_h264_pay_decode_nal: NAL payload len=1354
0:00:08.578315458 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:480:gst_rtp_h264_pay_decode_nal: NAL: 0 2 1 Len = 1354
0:00:08.578324391 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:574:gst_rtp_h264_pay_payload_nal:<rtph264pay0> Processing Buffer with NAL TYPE=1
0:00:08.578334219 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:580:gst_rtp_h264_pay_payload_nal:<rtph264pay0> NAL Unit fit in one packet datasize=1354 mtu=1400
0:00:08.609319216 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:456:gst_rtp_h264_pay_decode_nal: NAL payload len=1064
0:00:08.609329153 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:480:gst_rtp_h264_pay_decode_nal: NAL: 0 2 1 Len = 1064
0:00:08.609338137 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:574:gst_rtp_h264_pay_payload_nal:<rtph264pay0> Processing Buffer with NAL TYPE=1
0:00:08.609347710 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:580:gst_rtp_h264_pay_payload_nal:<rtph264pay0> NAL Unit fit in one packet datasize=1064 mtu=1400
0:00:08.641333959 19067      0x11407c0 DEBUG             rtph264pay gstrtph264pay.c:456:gst_rtp_h264_pay_decode_nal: NAL payload len=1050
Comment 1 Marc Leeman 2009-12-18 14:39:28 UTC
Don't know if this should be tagged 'maj'. It does not work in this particular case; it might be isolated to this setup.
Comment 2 Wim Taymans 2009-12-18 14:49:31 UTC
You don't have the sprop-parameter-sets on the receiver udpsrc so it does not know about SPS and PPS needed to decode h264. Why exactly do you think this should work?
Comment 3 Marc Leeman 2009-12-18 15:15:40 UTC
I might be missing something, but 

it does work if the decoder is started before the sender is started; so the data seems to be sent at that point.

Only the receiver/decoder is not able to pick in on the stream once the sender is started.

so:

1. start receiver then sender: OK
2. start sender then receiver: NOK

I'm trying to understand what is the difference between the two cases. The payloader only sends this packet once (gets it only once too):

0:00:00.584424652 27649      0x106d240 DEBUG             rtph264pay gstrtph264pay.c:748:gst_rtp_h264_pay_handle_buffer:<rtph264pay0> got 30 bytes
0:00:00.584436546 27649      0x106d240 DEBUG             rtph264pay gstrtph264pay.c:806:gst_rtp_h264_pay_handle_buffer:<rtph264pay0> found first start at 0, bytes left 30
0:00:00.584446946 27649      0x106d240 DEBUG             rtph264pay gstrtph264pay.c:833:gst_rtp_h264_pay_handle_buffer:<rtph264pay0> found next start at 18 of size 18
0:00:00.584456513 27649      0x106d240 DEBUG             rtph264pay gstrtph264pay.c:456:gst_rtp_h264_pay_decode_nal: NAL payload len=18
0:00:00.584465079 27649      0x106d240 DEBUG             rtph264pay gstrtph264pay.c:467:gst_rtp_h264_pay_decode_nal: Found SPS 0 3 7 Len=18
0:00:00.584473810 27649      0x106d240 DEBUG             rtph264pay gstrtph264pay.c:493:gst_rtp_h264_pay_decode_nal: Profile level IDC = 420029

at startup; type 7 is never encountered again. This seems to match the depayloader:

0:00:01.439597751 27702      0x153d400 DEBUG           rtph264depay gstrtph264depay.c:255:gst_rtp_h264_depay_setcaps:<rtph264depay0> decoding param 0 (Z0IAKeKQFoe2BqwYBBuHiRFQ)
0:00:01.439625204 27702      0x153d400 DEBUG           rtph264depay gstrtph264depay.c:261:gst_rtp_h264_depay_setcaps:<rtph264depay0> decoded 18 bytes
0:00:01.439655622 27702      0x153d400 DEBUG           rtph264depay gstrtph264depay.c:255:gst_rtp_h264_depay_setcaps:<rtph264depay0> decoding param 1 (aM48gA==)
0:00:01.439666585 27702      0x153d400 DEBUG           rtph264depay gstrtph264depay.c:261:gst_rtp_h264_depay_setcaps:<rtph264depay0> decoded 4 bytes


So probably this packet is inserted in the steam at startup of the depayloader; but is never repeated. If it would be repeated; I guess the decoder could pick in on the sender.
Comment 4 Wim Taymans 2009-12-18 15:23:54 UTC
Yes, the PPS and SPS are probably inserted at the start of the stream (although that is purely coincidental). There is currently no code to parse and insert the config params at regular intervals into the stream.

A patch to the payloader that inserts the config params into the payloaded packets (with a configurable delay) would be accepted.
Comment 5 Marc Leeman 2009-12-21 13:36:31 UTC
Created attachment 150167 [details] [review]
patch rtph264pay to send sps/pps in data stream

Waits delay seconds to re-insert SPS/PPS into the stream right in front of an IDR frame to avoid decoding errors.
Comment 6 Marc Leeman 2009-12-21 13:49:50 UTC
The patch resets the counter once it finds a Type 7/8 packet in the stream. So if the stream sends 7/8 type packets in a regular fashion, this option will not have any effect. It will only affect streams that do not send out SPS/PPS params regularly.

This option could probably be enabled by default to e.g. 3 or 5 seconds.

It is currently set to 0 (disabled) to keep the same default data stream behaviour as previously.
Comment 7 Olivier Crête 2009-12-21 14:33:35 UTC
Ideally, it would also re-send the sps/pps on a downstream GstForceKeyUnit event (which should come just before a new forced keyframe).
Comment 8 Marc Leeman 2009-12-21 15:26:02 UTC
Created attachment 150173 [details] [review]
param tweak spspps_send

Changed the parameter to an int instead of uint.

Setting it to 0 will send the sps/pps parameters in front of every IDR frame instead of waiting for a timeout; should minimise the time for the decoder to pick in on the stream in network applications.

default (disabled) is -1.
Comment 9 Wim Taymans 2009-12-21 16:22:32 UTC
 /* resend SPS */
 sps = gst_buffer_new_and_alloc (rtph264pay->sps_len);
 gst_buffer_set_data (sps, rtph264pay->sps, rtph264pay->sps_len);

This leaks the allocated data and frees the sps multiple times. Maybe you meant to memcpy into the allocated buffer data.

Also your code does nothing for the packetized case. I'm rewriting it a bit now to reset the counters in the _decode_nal() function and to prepend the SPS in the _payload_nal() function (when needed).
Comment 10 Wim Taymans 2009-12-21 20:06:57 UTC
Rewrote most of the patch, please test this. It should also work with AVC streams.

commit 46871993488a30c0544f5c07c2b4a580ece59cc1
Author: Wim Taymans <wim.taymans@collabora.co.uk>
Date:   Mon Dec 21 20:39:53 2009 +0100

    rtph264pay: add option to insert PPS/SPS in streams
    
    Add a new spspps-interval property to instruct the payloader to insert
    SPS and PPS at periodic intervals in the stream.
    Rework the SPS/PPS handling so that bytestream and AVC sample code both use the
    same code paths to handle sprop-parameter-sets. This also allows to have the AVC
    code to insert SPS/PPS like the bytestream code.
    
    Fixes #604913
Comment 11 Marc Leeman 2009-12-22 09:22:56 UTC
Tested the rebuilt code with the test setup as described; and the decoder is able to pick in as expected.