Greetings!
I’m trying to play video stream from “custom” usb-camera on Jetson Nano (32.3.X and 32.4.2 images) via GStreamer. And run into some weird behaviour of nvv4l2decoder.
Camera is some kind of “black-box” for me. Only know, it produces h.264 encoded video(656x496@60), packed into mpeg-ts protocol.
According to “Accelerated GStreamer user guide”, my pipeline should looks like:
appsrc ! tsdemux ! h264parse ! nvv4l2decoder ! nvdrmvideosink
And it’s only black screen, with no error (or even warnings on codec site) messages. (or transparent window with X and nd3dsink)
There is no proper driver for this camera, so i have to grab stream via libusb api to push it to pipline.
I dumped some stream data to file, for debug purposes, so pipeline is:
gst-launch-1.0 -v filesrc location=out.mp4 ! tsdemux ! h264parse ! nvv4l2decoder ! nvdrmvideosink
The output is:
nvbuf_utils: Could not get EGL display connection
Setting pipeline to PAUSED ...
Opening in BLOCKING MODE
Pipeline is PREROLLING ...
/GstPipeline:pipeline0/GstH264Parse:h264parse0.GstPad:sink: caps = video/x-h264, stream-format=(string)byte-stream, alignment=(string)nal
/GstPipeline:pipeline0/GstH264Parse:h264parse0.GstPad:src: caps = video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, pixel-aspect-ratio=(fraction)124/123, width=(int)656, height=(int)496, framerate=(fraction)30/1, interlace-mode=(string)progressive, chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, parsed=(boolean)true, profile=(string)high, level=(string)4
NvMMLiteOpen : Block : BlockType = 261
NVMEDIA: Reading vendor.tegra.display-size : status: 6
NvMMLiteBlockCreate : Block : BlockType = 261
/GstPipeline:pipeline0/nvv4l2decoder:nvv4l2decoder0.GstPad:sink: caps = video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, pixel-aspect-ratio=(fraction)124/123, width=(int)656, height=(int)496, framerate=(fraction)30/1, interlace-mode=(string)progressive, chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, parsed=(boolean)true, profile=(string)high, level=(string)4
/GstPipeline:pipeline0/nvv4l2decoder:nvv4l2decoder0.GstPad:src: caps = video/x-raw(memory:NVMM), format=(string)NV12, width=(int)656, height=(int)496, interlace-mode=(string)progressive, multiview-mode=(string)mono, multiview-flags=(GstVideoMultiviewFlagsSet)0:ffffffff:/right-view-first/left-flipped/left-flopped/right-flipped/right-flopped/half-aspect/mixed-mono, pixel-aspect-ratio=(fraction)124/123, chroma-site=(string)jpeg, colorimetry=(string)bt601, framerate=(fraction)30/1
/GstPipeline:pipeline0/GstNvDrmVideoSink:nvdrmvideosink0.GstPad:sink: caps = video/x-raw(memory:NVMM), format=(string)NV12, width=(int)656, height=(int)496, interlace-mode=(string)progressive, multiview-mode=(string)mono, multiview-flags=(GstVideoMultiviewFlagsSet)0:ffffffff:/right-view-first/left-flipped/left-flopped/right-flipped/right-flopped/half-aspect/mixed-mono, pixel-aspect-ratio=(fraction)124/123, chroma-site=(string)jpeg, colorimetry=(string)bt601, framerate=(fraction)30/1
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
Got EOS from element "pipeline0".
Execution ended after 0:00:00.000432402
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...
And no video, ofc.
After some experiments i tried to enable enable-frame-type-reporting
, and it works! I saw the video.
$ gst-launch-1.0 -v filesrc location=out.mp4 ! tsdemux ! h264parse ! nvv4l2decoder enable-frame-type-reporting=true ! nvdrmvideosink
nvbuf_utils: Could not get EGL display connection
Setting pipeline to PAUSED ...
Opening in BLOCKING MODE
Pipeline is PREROLLING ...
/GstPipeline:pipeline0/GstH264Parse:h264parse0.GstPad:sink: caps = video/x-h264, stream-format=(string)byte-stream, alignment=(string)nal
/GstPipeline:pipeline0/GstH264Parse:h264parse0.GstPad:src: caps = video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, pixel-aspect-ratio=(fraction)124/123, width=(int)656, height=(int)496, framerate=(fraction)30/1, interlace-mode=(string)progressive, chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, parsed=(boolean)true, profile=(string)high, level=(string)4
NvMMLiteOpen : Block : BlockType = 261
NVMEDIA: Reading vendor.tegra.display-size : status: 6
NvMMLiteBlockCreate : Block : BlockType = 261
NvMMLiteNVMEDIADecSetAttribute:: Error status reporting set to 1
/GstPipeline:pipeline0/nvv4l2decoder:nvv4l2decoder0.GstPad:sink: caps = video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, pixel-aspect-ratio=(fraction)124/123, width=(int)656, height=(int)496, framerate=(fraction)30/1, interlace-mode=(string)progressive, chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, parsed=(boolean)true, profile=(string)high, level=(string)4
/GstPipeline:pipeline0/nvv4l2decoder:nvv4l2decoder0.GstPad:src: caps = video/x-raw(memory:NVMM), format=(string)NV12, width=(int)656, height=(int)496, interlace-mode=(string)progressive, multiview-mode=(string)mono, multiview-flags=(GstVideoMultiviewFlagsSet)0:ffffffff:/right-view-first/left-flipped/left-flopped/right-flipped/right-flopped/half-aspect/mixed-mono, pixel-aspect-ratio=(fraction)124/123, chroma-site=(string)jpeg, colorimetry=(string)bt601, framerate=(fraction)30/1
/GstPipeline:pipeline0/GstNvDrmVideoSink:nvdrmvideosink0.GstPad:sink: caps = video/x-raw(memory:NVMM), format=(string)NV12, width=(int)656, height=(int)496, interlace-mode=(string)progressive, multiview-mode=(string)mono, multiview-flags=(GstVideoMultiviewFlagsSet)0:ffffffff:/right-view-first/left-flipped/left-flopped/right-flipped/right-flopped/half-aspect/mixed-mono, pixel-aspect-ratio=(fraction)124/123, chroma-site=(string)jpeg, colorimetry=(string)bt601, framerate=(fraction)30/1
FrameType = P
nActiveRefFrames = 2
Frame 0
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
FrameType = P
nActiveRefFrames = 2
Frame 1
FrameType = P
nActiveRefFrames = 2
Frame 2
FrameType = P
nActiveRefFrames = 2
Frame 3
FrameType = P
nActiveRefFrames = 2
Frame 4
FrameType = P
nActiveRefFrames = 2
Frame 5
FrameType = P
nActiveRefFrames = 2
...
The same result was with enable-error-check=true
parameter.
...
New clock: GstSystemClock
ErrorType= 0 Decoded MBs= 1271 Concealed MBs= 0 FrameDecodeTime 572
ErrorType= 0 Decoded MBs= 1271 Concealed MBs= 0 FrameDecodeTime 577
ErrorType= 0 Decoded MBs= 1271 Concealed MBs= 0 FrameDecodeTime 574
...
I saw, there is no I-frames/slices in my stream, so some first frames are “broken”, but it’s fine for me.
The same behaviour was with deprecated omxh264dec. No video with error/frame-type checks set to false and all works fine if any is true.
So, technically, stream is fine and VPU can handle it.
Also, all works fine with software decoding with avdec_h264 (libav). But it uses “avc” stream-format cap, nor byte-stream:
$ gst-launch-1.0 -v filesrc location=out.mp4 ! tsdemux ! h264parse ! avdec_h264 ! nvdrmvideosink
nvbuf_utils: Could not get EGL display connection
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
/GstPipeline:pipeline0/GstH264Parse:h264parse0.GstPad:sink: caps = video/x-h264, stream-format=(string)byte-stream, alignment=(string)nal
/GstPipeline:pipeline0/GstH264Parse:h264parse0.GstPad:src: caps = video/x-h264, stream-format=(string)avc, alignment=(string)au, pixel-aspect-ratio=(fraction)124/123, width=(int)656, height=(int)496, framerate=(fraction)30/1, interlace-mode=(string)progressive, chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, parsed=(boolean)true, profile=(string)high, level=(string)4, codec_data=(buffer)01640028ffe1002627640028ad0056c0a43fbff007c007b68800000303200000bb87100002d9f800331931e4014001000528de029cb0
Redistribute latency...
/GstPipeline:pipeline0/avdec_h264:avdec_h264-0.GstPad:sink: caps = video/x-h264, stream-format=(string)avc, alignment=(string)au, pixel-aspect-ratio=(fraction)124/123, width=(int)656, height=(int)496, framerate=(fraction)30/1, interlace-mode=(string)progressive, chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, parsed=(boolean)true, profile=(string)high, level=(string)4, codec_data=(buffer)01640028ffe1002627640028ad0056c0a43fbff007c007b68800000303200000bb87100002d9f800331931e4014001000528de029cb0
/GstPipeline:pipeline0/avdec_h264:avdec_h264-0.GstPad:src: caps = video/x-raw, format=(string)I420, width=(int)656, height=(int)496, interlace-mode=(string)progressive, multiview-mode=(string)mono, multiview-flags=(GstVideoMultiviewFlagsSet)0:ffffffff:/right-view-first/left-flipped/left-flopped/right-flipped/right-flopped/half-aspect/mixed-mono, pixel-aspect-ratio=(fraction)124/123, chroma-site=(string)mpeg2, colorimetry=(string)bt601, framerate=(fraction)30/1
/GstPipeline:pipeline0/GstNvDrmVideoSink:nvdrmvideosink0.GstPad:sink: caps = video/x-raw, format=(string)I420, width=(int)656, height=(int)496, interlace-mode=(string)progressive, multiview-mode=(string)mono, multiview-flags=(GstVideoMultiviewFlagsSet)0:ffffffff:/right-view-first/left-flipped/left-flopped/right-flipped/right-flopped/half-aspect/mixed-mono, pixel-aspect-ratio=(fraction)124/123, chroma-site=(string)mpeg2, colorimetry=(string)bt601, framerate=(fraction)30/1
Redistribute latency...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
...
I try to enable this parameters in code, playback works, but latency was about ~600ms vs ~100ms using software avdec_264, at the same conditions. “sync” parameter of nvdrmvideosink was disabled in both cases.
Also, i try to disable frame type check “on hot”. Stream still playing, debug info output was stopped, but latency was still about ~400-600ms.
So… My questions: Is there any suggestions of codec behaviour? Why it works only with “debug” output parameters? Is there way to decrease latency on hw-decode? (disable-dpb only increase it.) Is there any additional capabilities for decoder tuning?
Thanks in advance for your help.