Question of gstreamer pipeline on Nano

Hi, and sorry for being a noob!

I’d like to capture a raw video file using my Waveshare IMX219-160IR camera on a Jetson nano, and then experiment with various encodings of that file. I am able to succeeding in capturing video and storing it in a file using a line like this:

sudo gst-launch-1.0 nvarguscamerasrc ! ‘video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, st=1, wb=1, format=(string)NV12, framerate=(fraction)15/1’ ! nvvidconv flip-method=2 ! ‘video/x-raw, width=(int)1280, height=(int)720, format=(string)BGRx’ ! videoconvert ! filesink location=video.BGRx

Using ffmpeg I can read in this file and convert it to various other formats and view it using totem. But try as I might, I can’t seem to get any kind of gstreamer pipeline set up to further process the file video.BGRx. For example, if I try the following

gst-launch-1.0 filesrc location=video.BGRx ! ‘video/x-raw, width=(int)1280, height=(int)720, format=(string)BGR, framerate=(fraction)15/1’ ! videoconvert ! video/x-raw, format=GRAY8 ! nvvidconv ! omxh264enc ! h264parse ! qtmux ! filesink location=video.h265

I get an error message like this:

Pipeline is PREROLLING …
Framerate set to : 15 at NvxVideoEncoderSetParameterNvMMLiteOpen : Block : BlockType = 4
===== NVMEDIA: NVENC =====
NvMMLiteBlockCreate : Block : BlockType = 4
H264: Profile = 66, Level = 40
WARNING: from element /GstPipeline:pipeline0/GstVideoConvert:videoconvert0: Internal GStreamer error: code not implemented. Please file a bug at http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer.
Additional debug info:
gstvideofilter.c(293): gst_video_filter_transform (): /GstPipeline:pipeline0/GstVideoConvert:videoconvert0:
invalid video buffer received

I’ve tried many different variations on the second gst-launch-1.0 command, and just can’t convert the raw video to anything. Any suggestions?

Thanks!

Bruce

Moving into Jetson Nano forum.

Hi,
You don’t need to convert it to BGRx. You can send NV12 to encoder directly:

sudo gst-launch-1.0 nvarguscamerasrc ! ‘video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, st=1, wb=1, format=(string)NV12, framerate=(fraction)15/1’ ! nvvidconv flip-method=2 ! nvv4l2h265enc ! h265parse ! video/x-h265,stream-format=byte-stream ! filesink location=video.h265

Hi Dane,

Thanks so much for the tip. I’ll try skipping the conversion to BGRx and let you know what happens.

Bruce

Hi Dane,

The command line you suggested works for me. I’m able to use it to produce h.265 video in one shot.

But (I think) I’d like to do something a little different. I’d like to record a raw sample video, then experiment repeatedly with different encoding settings (e.g., bit-rate and grayscale) to find the lowest bit rate that still produces useful videos for my purposes.

My actual application is written in python. It’s code that I have inherited. In a frame-by-frame fashion, it grabs the video, adds some time stamps, and then writes out h.265. Currently the code converts the video to BGRx before storing frames. I can set the bit-rate, grayscale, etc., in the python code, but the results aren’t reproducible because the python code records a new video each time. So I want to first use gst-launch-1.0 to record a fixed raw video. Then I want to use gst-launch-1.0 to experiment repeatedly with different encoding settings. Once I’ve figured out the settings, I’ll port them back to the python implementation.

I was hoping that I could take your sample line and break it into two parts, something along these lines:

first grab the video

sudo gst-launch-1.0 nvarguscamerasrc ! ‘video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, st=1, wb=1, format=(string)NV12, framerate=(fraction)15/1, stream-format=byte-stream’ ! filesink location=video.nv12

then convert to h.265

gst-launch-1.0 filesrc location=video.nv12 ! ‘video/x-raw(memory:NVMM), width=(int)1280, height=(int)720, st=1, wb=1, format=(string)NV12, framerate=(fraction)15/1, stream-format=byte-stream’ ! nvvidconv flip-method=2 ! nvv4l2h265enc ! h265parse ! video/x-h265, stream-format=byte-stream’ ! filesink location=video.h265

The first line seems to record something, but the file size seems too small to really be correct. Then when I run the second line I get an error:

Pipeline is PREROLLING …
Redistribute latency…
NvMMLiteOpen : Block : BlockType = 8
===== NVMEDIA: NVENC =====
NvMMLiteBlockCreate : Block : BlockType = 8
NVMEDIA: H265 : Profile : 1
nvbuf_utils: nvbuffer Payload Type not supported
NvBufferGetParams failed for src_dmabuf_fd
nvbuffer_transform Failed
gst_nvvconv_transform: NvBufferTransform Failed
ERROR: from element /GstPipeline:pipeline0/GstFileSrc:filesrc0: Internal data stream error.
Additional debug info:
gstbasesrc.c(3055): gst_base_src_loop (): /GstPipeline:pipeline0/GstFileSrc:filesrc0:
streaming stopped, reason error (-5)
ERROR: pipeline doesn’t want to preroll.

Once again, thanks for your help. I realize that I’m probably making some sort of trivial mistakes in writing these lines, but it has been a struggle to get them exactly right.

Bruce

What you want to try is possible, but be aware that it may be dangerous because raw video can very quickly fill your filesystem. If stroring on rootfs and it gets full, your system may be very difficult to fix, so my example will just record 150 frames, so 10s @15fps.

Before trying it, check with:

df -H

that the filesystem you want to record to has at least 200MB available.

For recording 10s:

gst-launch-1.0 nvarguscamerasrc num-buffers=150 ! 'video/x-raw(memory:NVMM),width=1280,height=720,st=1,wb=1,format=NV12,framerate=15/1' ! nvvidconv ! video/x-raw ! filesink location=test_1280x720p15.NV12

You may play with:

gst-launch-1.0 filesrc location=test_1280x720p15.NV12 ! videoparse format=nv12 width=1280 height=720 framerate=15/1 ! videoconvert ! xvimagesink

Or encode into h265 and store into mkv container (so that you may play back with many players) with:

gst-launch-1.0 -e filesrc location=test_1280x720p15.NV12 ! videoparse format=nv12 width=1280 height=720 framerate=15/1 ! nvvidconv ! 'video/x-raw(memory:NVMM)' ! nvv4l2h265enc ! h265parse ! matroskamux ! filesink location=test_1280x720p15_h265.mkv

and try various encoding options.

Thanks very much, Honey! I’ll try your suggestion. And yes, I’ve got to watch my disk capacity carefully. For now I’m only going to record about ten seconds of video. Eventually I’m going to attach a large SSD so that (if I can get the bit rate low enough) I can store a fair amount of video.

Hi Honey. I tried your suggestion, and it worked very well! There was one typo: in your last command-line example, nnv4l2h265enc should be nvv4l2h265enc

Here’s an example of how I modified the last line to flip the video (my camera happens to be oriented upside-down), convert to gray scale, and limit the bit rate to 600,000 bits/second:

gst-launch-1.0 -e filesrc location=test_1280x720p15.NV12 ! videoparse format=nv12 width=1280 height=720 framerate=15/1 ! videoconvert ! ‘video/x-raw, format=GRAY8’ ! nvvidconv flip-method=2 ! ‘video/x-raw(memory:NVMM)’ ! nvv4l2h265enc bitrate=600000 ! h265parse ! matroskamux ! filesink location=test_1280x720p15_h265_gray_600.mkv

Thanks again, Bruce

Thanks for sharing. It is fixed now for next users.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.