Gstreamer omxh264enc issue with shmsink

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

Nvidia specific element docs here, including numerous gst-launch example pipelines: https://developer.download.nvidia.com/embedded/L4T/r32_Release_v1.0/Docs/Accelerated_GStreamer_User_Guide.pdf?wiCioNYLtTSbJhn2Bk7UCSg3PWXrj-WNnVxN-IYPXwXBr2pSORPYgNM-gxDzVqVuxxTRvAosDmp3zPgZKd-psiCbu53aITERLFSMORB-aHZwLjbrif3zigHsrrxo1sZtCrrHI7xdLmv8EXXTAkdsd6U8GWjlbD9w6kTWfbQXWVCbBCc5kP0

Not even the latest version, but most of what changes from version to version is backend things that we as users never see.

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.

Please check if increasing shm-size helps. Probably the default size of shared memory is too small.