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 796525 - v4l2h264enc: when gst-rtsp-server is used in conjunction with v4l2h264enc on an imx6, nobody allocates downstream buffers
v4l2h264enc: when gst-rtsp-server is used in conjunction with v4l2h264enc on...
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
1.14.1
Other Linux
: Normal normal
: 1.14.2
Assigned To: GStreamer Maintainers
GStreamer Maintainers
: 794400 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2018-06-07 09:41 UTC by Keith Thornton
Modified: 2018-07-03 10:00 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
0001-v4l2videoenc-Hack-reconfiguration-while-encoder-is-s.patch (1.97 KB, patch)
2018-06-25 12:58 UTC, Michael Tretter
rejected Details | Review
v4l2videoenc: Only renegotiate with upstream (1.10 KB, patch)
2018-06-28 23:12 UTC, Nicolas Dufresne (ndufresne)
committed Details | Review

Description Keith Thornton 2018-06-07 09:41:09 UTC
using gst-rtsp-server with v4l2h264enc, the allocation query finds no element with a decide_allocation function so no downstream buffers are allocated.
example 
./test-launch "( v4l2src min-buffers=10 device=/dev/v4l/by-path/platform-captu
re-subsystem-video-index4 video/x-raw,format=NV12,width=1920,height=1080,framera
te=60000/1001 ! v4l2h264enc ! video/x-h264,profile=baseline ! rtph264pay name=pay0 pt=96 )"
Comment 1 Tim-Philipp Müller 2018-06-07 09:53:43 UTC
Are you saying this only happens within gst-rtsp-server but not in a plain gst-launch command line or why are you reporting it against gst-rtsp-server?
Comment 2 Keith Thornton 2018-06-07 10:59:52 UTC
Similar pipelines with v4lsink or filesink work. I assume they provide the downstream buffer pool. I have only seen the problem up until now when using gst-rtsp-server. If I replace the v4l2h264enc by openh264enc without using dma buffers upstream I can stream, all be it with a lot of dropped frams. In this case I assume (but haven't checked) that openh264enc implements the decide_allocation and instantiates its own buffer pool.
Comment 3 Nicolas Dufresne (ndufresne) 2018-06-07 14:23:03 UTC
(In reply to Keith Thornton from comment #0)
> using gst-rtsp-server with v4l2h264enc, the allocation query finds no
> element with a decide_allocation function so no downstream buffers are
> allocated.

The encoder does not run an allocation query. Encoded data is always pushed using the v4l2 driver allocated buffers, dmabuf by default. Why does it matter ? Do you actually have an error or something or is this just conceptually not what you expected ?

> example 
> ./test-launch "( v4l2src min-buffers=10

There is no min-buffers property in upstream v4l2src code. Can you explain which modifications you are running with ?

> device=/dev/v4l/by-path/platform-captu
> re-subsystem-video-index4
> video/x-raw,format=NV12,width=1920,height=1080,framera

This pipeline is unlinked, you need a ! between v4l2src and the caps filter.

> te=60000/1001 ! v4l2h264enc ! video/x-h264,profile=baseline ! rtph264pay
> name=pay0 pt=96 )"

(In reply to Keith Thornton from comment #2)
> Similar pipelines with v4lsink or filesink work. I assume they provide the
> downstream buffer pool. I have only seen the problem up until now when using
> gst-rtsp-server. If I replace the v4l2h264enc by openh264enc without using
> dma buffers upstream I can stream, all be it with a lot of dropped frams. In
> this case I assume (but haven't checked) that openh264enc implements the
> decide_allocation and instantiates its own buffer pool.
Comment 4 Keith Thornton 2018-06-07 14:34:20 UTC
yes, im am experiencing an error, see below
the missing ! was a paste error
./test-launch "( v4l2src min-buffers=10 device=/dev/v4l/by-path/platform-captu
re-subsystem-video-index4 io-mode=4 ! video/x-raw,format=NV12,width=1920,height=
1080,framerate=60000/1001 ! v4l2h264enc output-io-mode=5 output-min-buffers=6 ca
pture-min-buffers=12 ! video/x-h264,profile=baseline ! queue max-size-buffers=3,
leaky=1 ! rtph264pay name=pay0 pt=96 )"

0:00:07.640716668   654 0x74f10320 DEBUG           videoencoder gstvideoencoder.c:1763:gst_video_encoder_negotiate_default:<v4l2h264enc0> didn't get downstream ALLOCATION hints
0:00:07.642418668   654 0x74f10320 DEBUG           videoencoder gstvideoencoder.c:1770:gst_video_encoder_negotiate_default:<v4l2h264enc0> ALLOCATION (1) params: allocation query: 0x73b03580, GstQueryAllocation, caps=(GstCaps)"video/x-h264\,\ stream-format\=\(string\)byte-stream\,\ alignment\=\(string\)au\,\ profile\=\(string\)baseline\,\ level\=\(string\)4\,\ width\=\(int\)1920\,\ height\=\(int\)1080\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ framerate\=\(fraction\)60000/1001\,\ interlace-mode\=\(string\)progressive\,\ colorimetry\=\(string\)bt709", need-pool=(boolean)true, allocator=(GArray)NULL, pool=(GArray)NULL, meta=(GArray)NULL;
0:00:07.839548335   654 0x74f10320 DEBUG           v4l2videoenc gstv4l2videoenc.c:352:gst_v4l2_video_enc_set_format:<v4l2h264enc0> output caps: video/x-raw, format=(string)NV12, width=(int)1920, height=(int)1080, framerate=(fraction)60000/1001, interlace-mode=(string)progressive, colorimetry=(string)bt709
0:00:07.840003001   654 0x74f10320 DEBUG           videoencoder gstvideoencoder.c:894:gst_video_encoder_sink_query:<v4l2h264enc0> received query 35846, allocation
0:00:07.840139335   654 0x74f10320 DEBUG           v4l2videoenc gstv4l2videoenc.c:859:gst_v4l2_video_enc_propose_allocation:<v4l2h264enc0> called
0:00:08.064016335   654 0x74f10320 DEBUG           videoencoder gstvideoencoder.c:1206:gst_video_encoder_sink_event:<v4l2h264enc0> received event 17934, segment
0:00:08.064191668   654 0x74f10320 DEBUG           videoencoder gstvideoencoder.c:1063:gst_video_encoder_sink_event_default:<v4l2h264enc0> segment time segment start=0:00:00.000000000, offset=0:00:00.000000000, stop=99:99:99.999999999, rate=1.000000, applied_rate=1.000000, flags=0x00, time=0:00:00.000000000, base=0:00:00.000000000, position 0:00:00.000000000, duration 99:99:99.999999999
0:00:08.064498001   654 0x74f10320 LOG             videoencoder gstvideoencoder.c:1455:gst_video_encoder_chain:<v4l2h264enc0> received buffer of size 3110400 with PTS 0:00:01.099792114, DTS 99:99:99.999999999, duration 0:00:00.016683333
0:00:08.064711001   654 0x74f10320 LOG             videoencoder gstvideoencoder.c:1542:gst_video_encoder_chain:<v4l2h264enc0> passing frame pfn 0 to subclass
0:00:08.064829335   654 0x74f10320 DEBUG           v4l2videoenc gstv4l2videoenc.c:714:gst_v4l2_video_enc_handle_frame:<v4l2h264enc0> Handling frame 0
0:00:08.065129001   654 0x74f10320 WARN            v4l2videoenc gstv4l2videoenc.c:782:gst_v4l2_video_enc_handle_frame:<v4l2h264enc0> error: Failed to allocate required memory.
0:00:08.065250001   654 0x74f10320 WARN            v4l2videoenc gstv4l2videoenc.c:782:gst_v4l2_video_enc_handle_frame:<v4l2h264enc0> error: Buffer pool activation failed
0:00:08.066023001   654 0x74f10320 DEBUG           videoencoder gstvideoencoder.c:1206:gst_video_encoder_sink_event:<v4l2h264enc0> received event 28174, eos
0:00:08.071124335   654  0x1f46290 DEBUG           v4l2videoenc gstv4l2videoenc.c:200:gst_v4l2_video_enc_stop:<v4l2h264enc0> Stopping
0:00:08.083856001   654  0x1f46290 DEBUG           v4l2videoenc gstv4l2videoenc.c:224:gst_v4l2_video_enc_stop:<v4l2h264enc0> Stopped
0:00:08.085544335   654  0x1f46290 DEBUG           v4l2videoenc gstv4l2videoenc.c:171:gst_v4l2_video_enc_close:<v4l2h264enc0> Closing
Comment 5 Nicolas Dufresne (ndufresne) 2018-06-07 14:50:50 UTC
I'm not aware of these patches adding properties like "output-min-buffers" and "capture-min-buffers". Please document the changes you apply to GStreamer, otherwise it's really hard to help.

In this context, you should also provide a trace with "GST_DEBUG="v4l2*:7" so we wee what is happening on V4L2 side. So far we only see that the decoder refused to start, apparently due to allocation failure, but there was a error message fix recently for this specific error, so I don't know if this is exact or not.

About traces, please, attach them instead of pasting them, they are pretty hard to read due to the reflow.
Comment 6 Keith Thornton 2018-06-12 06:53:42 UTC
you are correct, we have some not mainlined test-patches either from my company or from a supporting company. I will try to get hold of these patches or run the same test with an unpached version. The same problems occur without using these additional parameters. A v4l2*:7 listing makes the server so slow that the client dismantles the connection due to a timeout :-(
Comment 7 Keith Thornton 2018-06-20 13:24:22 UTC
Michael Tretter traced this problem and has determined the following
gst-rtsp-server links the RtpBin after the pipeline has been set to running. This leads to a reconfigure event being sent to the v4l2videoenc. The element tries a re-format but this is refused because the element (the driver) is in streaming mode. In our case, the caps are identical to the previously negotiated caps so it could continue without re-configuration. If a reconfiguration were necessary, the encoder would need to be stopped and then re-started.
Comment 8 Nicolas Dufresne (ndufresne) 2018-06-20 15:00:53 UTC
Which version of GStreamer is this ? The reconfiguration code has been added in 1.14, prior to that it would have failed. Also, are you going to provide a patch that detect that caps haven't changed and thus reallocation is not needed ?
Comment 9 Keith Thornton 2018-06-21 06:47:01 UTC
we are running 1.14.0
We are working on a patch but it is not yet correct.
Comment 10 Michael Tretter 2018-06-25 12:58:28 UTC
Created attachment 372813 [details] [review]
0001-v4l2videoenc-Hack-reconfiguration-while-encoder-is-s.patch
Comment 11 Nicolas Dufresne (ndufresne) 2018-06-25 22:03:38 UTC
Review of attachment 372813 [details] [review]:

Renegotiation should work, it's just a bug. All bits are in place, no need for hacks.
Comment 12 Keith Thornton 2018-06-26 06:11:32 UTC
I quite agrree, it should work but with test-launch it didn't :-(
Comment 13 Michael Tretter 2018-06-26 07:30:19 UTC
(In reply to Nicolas Dufresne (ndufresne) from comment #11)
> Review of attachment 372813 [details] [review] [review]:
> 
> Renegotiation should work, it's just a bug. All bits are in place, no need
> for hacks.

Yes, there shouldn't be the need for the hack and it wasn't meant for inclusion into master. The patch only helps to track down the actual bug.

During renegotiation the encoder element calls set_format for capture. Since v4l2 is currently in streaming mode, set_format fails to change the format and the entire renegotiation fails.

I think during renegotiation we should (1) stop streaming, (2) set the format and (3) start streaming with the new format. This is currently not implemented, but this should fix renegotiation for the common case.

The patch that I submitted assumes that the caps are the same as prior to the renegotiation event (there is no check if this is actually true). If we detect this condition, we can skip the set_format and just continue the renegotiation. However, I wasn't able to detect this case in v4l2videoenc, and I don't know if this should be handled in the videoencoder.
Comment 14 Nicolas Dufresne (ndufresne) 2018-06-27 02:57:30 UTC
Ok, there is two form of renegotiation, firs one, there is new caps on the sink pad, that's the one covered. You'll see the two calls to v4l2_object_stop() in there, which do STREAMOFF.

The second one is the renegotiation event on the srcpad (caused by linking downstream). I think this one is not currently covered and am guessing that this is what happens. There is no obligation to change the caps though on this one, the renegotiation event is a suggestion. Worst, changing the caps would flush the encoder, hence produce a new IDR for nearly no reason.

Can anyone tell me what other encoders do ?
Comment 15 Nicolas Dufresne (ndufresne) 2018-06-28 21:02:27 UTC
*** Bug 794400 has been marked as a duplicate of this bug. ***
Comment 16 Nicolas Dufresne (ndufresne) 2018-06-28 21:45:49 UTC
Review of attachment 372813 [details] [review]:

::: sys/v4l2/gstv4l2videoenc.c
@@ +824,3 @@
+   * the caps, because the videoencoder just set encoder->srcpad caps to
+   * state->caps. */
+  if (GST_V4L2_IS_ACTIVE (self->v4l2capture)) {

It's a bit late, we have already done bunch of illegal calls in _negotiate(). decide_allocation is called by the base class implementation of negotiate(). If negotiate() is called with an self->input_state set, it means we are not being called from _set_format(). I'm surprise running decide_allocation worked, what I would do is simply return TRUE in negotiate() if the reason we negotiate is not a new input format. Replying to reconfigure event is optional anyway. I'll test this tomorrow and report.
Comment 17 Nicolas Dufresne (ndufresne) 2018-06-28 23:12:52 UTC
Created attachment 372873 [details] [review]
v4l2videoenc: Only renegotiate with upstream

When the decoder get linked further, it will receive a renegotiation
event from downstream. This case is not supported and should be ignored.

This fixes issues when this encoder is used inside an GstRtspServer
pipeline.
Comment 18 Nicolas Dufresne (ndufresne) 2018-06-28 23:14:19 UTC
This fixes the issue for me, let me know how it goes for you.
Comment 19 Nicolas Dufresne (ndufresne) 2018-06-29 14:39:49 UTC
Attachment 372873 [details] pushed as 047dc61 - v4l2videoenc: Only renegotiate with upstream
Comment 20 Keith Thornton 2018-07-03 09:11:42 UTC
The patch works for me. We (you or me?) can close the bug.
Thank you.
Comment 21 Nicolas Dufresne (ndufresne) 2018-07-03 10:00:20 UTC
It's already marked resolved fixed, I've backported to 1.14 branch, so rtsp server on imx6 should work in 1.14.2.