Hi,
I’m trying to send H.264 encoded data from one Gstreamer pipeline to another using shmsink element.
When I encode using gstreamer x264enc encoder, both pipelines (sender and receiver) work as expected. But with omxh264 encoder, the receiver is unable to receive any frames through corresponding shmsrc
Sender pipeline with x264enc
gst-launch-1.0 videotestsrc ! videoconvert ! x264enc pass=qual quantizer=20 tune=zerolatency ! shmsink socket-path=check
Sender pipeline with omxh264enc
gst-launch-1.0 videotestsrc ! videoconvert ! omxh264enc ! shmsink socket-path=check
Receiver pipeline
gst-launch-1.0 shmsrc socket-path=check ! h264parse ! avdec_h264 ! videoconvert ! xvimagesink
Am I missing something in the pipeline with omxh264enc ?
Regards,
Rhythm
You likely need to place the nvvidconv element before and after the encoder as you likely have a caps negotiation issue. The nvvidconv element uses the GPU so it will be much more performant, and you can also pretty much use it in place of any videoconvert elements you are using.
gst-launch-1.0 videotestsrc ! nvvidconv ! omxh264enc ! nvvidconv ! shmsink socket-path=check
The above pipeline doesn’t allow nvvidconv after omxh264enc .
WARNING: erroneous pipeline: could not link omxh264enc-omxh264enc0 to nvvconv1
If I remove nvvidconv , after omxh264enc , I get the same results as before.
Regards,
Rhythm
On setting debug level 5 on receiver pipeline, I get following logs
0:00:05.791749837 9548 0x557ea14940 DEBUG basesrc gstbasesrc.c:2399:gst_base_src_update_length:<shmsrc0> reading offset 7724099, length 4096, size -1, segment.stop -1, maxsize -1
0:00:05.791767789 9548 0x557ea14940 DEBUG basesrc gstbasesrc.c:2506:gst_base_src_get_range:<shmsrc0> calling create offset 7724099 length 4096, time 0
0:00:05.791782125 9548 0x557ea14940 DEBUG shmsrc gstshmsrc.c:332:gst_shm_src_create:<shmsrc0> Stopping 0x557e9661c0
0:00:05.791799341 9548 0x557ea14940 DEBUG GST_POLL gstpoll.c:1317:gst_poll_wait: 0x557e81e590: timeout :99:99:99.999999999
0:00:05.824729205 9548 0x557ea14940 DEBUG GST_POLL gstpoll.c:1142:gst_poll_fd_has_closed: 0x557e81e590: fd (fd:12, idx:1) 0
0:00:05.824786772 9548 0x557ea14940 DEBUG GST_POLL gstpoll.c:1188:gst_poll_fd_has_error: 0x557e81e590: fd (fd:12, idx:1) 0
0:00:05.824805844 9548 0x557ea14940 DEBUG GST_POLL gstpoll.c:1213:gst_poll_fd_can_read_unlocked: 0x557e81e590: fd (fd:12, idx:1) 1
0:00:05.824832980 9548 0x557ea14940 DEBUG GST_MEMORY gstmemory.c:139:gst_memory_init: new memory 0x7f8c00c290, maxsize:5041 offset:0 size:5041
0:00:05.824856372 9548 0x557ea14940 DEBUG basesrc gstbasesrc.c:2360:gst_base_src_do_sync:<shmsrc0> no sync needed
0:00:05.824873620 9548 0x557ea14940 DEBUG basesrc gstbasesrc.c:2597:gst_base_src_get_range:<shmsrc0> buffer ok
0:00:05.824907316 9548 0x557ea14940 DEBUG GST_SCHEDULING gstpad.c:4320:gst_pad_chain_data_unchecked:<h264parse0:sink> calling chainfunction &gst_base_parse_chain with buffer buffer: 0x557ea349d0, pts 99:99:99.999999999, dts 99:99:99.999999999, dur 99:99:99.999999999, size 5041, offset none, offset_end none, flags 0x0
0:00:05.824925716 9548 0x557ea14940 DEBUG baseparse gstbaseparse.c:3029:gst_base_parse_chain:<h264parse0> chain
0:00:05.824950579 9548 0x557ea14940 DEBUG adapter gstadapter.c:344:copy_into_unchecked: bsize 5169, skip 5166, csize 3
0:00:05.824973427 9548 0x557ea14940 DEBUG GST_MEMORY gstmemory.c:139:gst_memory_init: new memory 0x7f8c00c0e0, maxsize:5044 offset:0 size:5044
0:00:05.824994195 9548 0x557ea14940 DEBUG baseparse gstbaseparse.c:758:gst_base_parse_update_frame:<h264parse0> marking DISCONT
0:00:05.825007731 9548 0x557ea14940 DEBUG h264parse gsth264parse.c:186:gst_h264_parse_reset_frame:<h264parse0> reset frame
0:00:05.825027955 9548 0x557ea14940 DEBUG h264parse gsth264parse.c:1113:gst_h264_parse_handle_frame:<h264parse0> last parse position 0
0:00:05.825046803 9548 0x557ea14940 DEBUG codecparsers_h264 gsth264parser.c:1281:gst_h264_parser_identify_nalu_unchecked: No start code prefix in this buffer
0:00:05.825076371 9548 0x557ea14940 DEBUG h264parse gsth264parse.c:1295:gst_h264_parse_handle_frame:<h264parse0> skipping 5041
0:00:05.825101683 9548 0x557ea14940 DEBUG h264parse gsth264parse.c:186:gst_h264_parse_reset_frame:<h264parse0> reset frame
0:00:05.825122194 9548 0x557ea14940 DEBUG baseparse gstbaseparse.c:2193:gst_base_parse_handle_buffer: Asked to skip 5041 (5044 available)
0:00:05.825137522 9548 0x557ea14940 DEBUG GST_MEMORY gstmemory.c:88:_gst_memory_free: free memory 0x7f8c00c3b0
0:00:05.825178130 9548 0x557ea14940 DEBUG GST_MEMORY gstmemory.c:88:_gst_memory_free: free memory 0x7f8c00c0e0
0:00:05.825198418 9548 0x557ea14940 DEBUG baseparse gstbaseparse.c:3198:gst_base_parse_chain:<h264parse0> not enough data available (only 3 bytes)
0:00:05.825217074 9548 0x557ea14940 DEBUG GST_SCHEDULING gstpad.c:4326:gst_pad_chain_data_unchecked:<h264parse0:sink> called chainfunction &gst_base_parse_chain with buffer 0x557ea349d0, returned ok
The weird log I see is,
gstbaseparse.c:3198:gst_base_parse_chain:<h264parse0> not enough data available (only 3 bytes)
I apologize, I forgot nvvidconv is only for x-raw video.
Does the same issue happen with nvv4l2h264enc ? Nvidia is deprecating the omx elements.
Try placing h264parse after the encoder.
gst-launch-1.0 videotestsrc ! nvvidconv ! nvv4l2h264enc ! h264parse config-interval=1 ! shmsink socket-path=check
gst-launch-1.0 shmsrc socket-path=check ! h264parse ! nvv4l2decoder ! nvvidconv ! xvimagesink
You might also need to look at h264parse config-interval. I feel like I had a similar error at some point and ended up setting the config-interval=1 and setting the encoder property: insert-sps-pps=True.
Element Properties:
config-interval : Send SPS and PPS Insertion Interval in seconds (sprop parameter sets will be multiplexed in the data stream when detected.) (0 = disabled, -1 = send with every IDR frame)
flags: readable, writable
Integer. Range: -1 - 3600 Default: 0
Hi,
The above pipelines seems to work. Although with nvv4l2decoder I’m getting a stuttering video at regular intervals.
Although, if I change decoder to avdev_h264 , it works smoothly.
So, final pipelines that work for me are,
gst-launch-1.0 videotestsrc ! nvvidconv ! nvv4l2h264enc ! h264parse config-interval=1 ! shmsink socket-path=check
gst-launch-1.0 shmsrc socket-path=check ! h264parse ! avdec_h264 ! xvimagesink
Thanks.
To handle the stuttering in the decoder, I suggest setting the enable-max-performance property to True. The encoder also has a maxperf-enable property that can be set to True as well. (Don’t ask me why nvidia named the properties differently…) I’m surprised avdec_ is smoother because it uses the CPU.
You could try placing queue2 elements after the encoder and before and after the decoder elements.
https://gstreamer.freedesktop.org/documentation/coreelements/queue2.html?gi-language=c
gst-launch-1.0 videotestsrc ! nvvidconv ! nvv4l2h264enc maxperf-enable=1 ! queue2 ! h264parse config-interval=1 ! shmsink socket-path=check
gst-launch-1.0 shmsrc socket-path=check ! queue2 ! h264parse ! nvv4l2decoder enable-max-performance=1 ! queue2 ! xvimagesink
You could also try placing the videorate element after the decoder. It is an element that produces a perfect stream by dropping or adding buffers.
https://gstreamer.freedesktop.org/documentation/videorate/index.html?gi-language=c
The above pipelines, even with max-performance enabled on either sides still doesn’t solve the stuttering issue.
Moreover, after putting videorate in between, only one frame is received on the receiver and pipeline.
Not sure what I’m missing here.
Are the pipelines working fine on your end?
I haven’t tested them, I don’t typically use shmsink/src. The issues probably have something to do with how those elements talk to one another. This forum post seems to be related: http://gstreamer-devel.966125.n4.nabble.com/Problem-with-using-shmsink-shmsrc-td4659936.html
Hi,
Also with nvv4l2h264enc , I keep getting following logs at encoder init.
GStreamer-CRITICAL **:gst_debug_log_valist: assertion 'category != NULL' failed
Any idea, how can I prevent this log.
Thanks.
DaneLLL
February 6, 2020, 10:45am
12
Please check if increasing shm-size helps. Probably the default size of shared memory is too small.