Nvidia JetsonでMIPI-4Kカメラを使う

少し前にこれを買って、遊んでみた記録。

 

www.switch-science.com

 

 

4Kで記録する方法

これ、純粋な4K解像度(3840x2160)ではない(4032x3040)ので、4Kで動かすにはcropが必要でした。

 

GST_ARGUS: 4032 x 3040 FR = 29.999999 fps Duration = 33333334 ; Analog Gain range min 1.000000, max 22.250000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 1920 x 1080 FR = 59.999999 fps Duration = 16666667 ; Analog Gain range min 1.000000, max 22.250000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 2592 x 1944 FR = 29.999999 fps Duration = 33333334 ; Analog Gain range min 1.000000, max 22.250000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 2560 x 1440 FR = 40.000000 fps Duration = 25000000 ; Analog Gain range min 1.000000, max 22.250000; Exposure Range min 13000, max 683709000;

 

cropするには、nvvidconvを使います。

 

gst-launch-1.0 -e nvarguscamerasrc timeout=20 ! 'video/x-raw(memory:NVMM), width=4032, height=3040, format=(string)NV12, framerate=(fraction)30/1' ! nvvidconv top=440 bottom=2600 left=96 right=3936 ! 'video/x-raw(memory:NVMM), width=3840, height=2160, pixel-aspect-ratio=1/1, format=(string)NV12, framerate=(fraction)30/1' ! ...

 

top/bottom/left/rightは絶対座標みたいです。

pixel-aspect-ratio=1/1を使わないと、元の縦横比のままになるので、16:9になりませんでした。

 

静止画を明るくとる方法

 

静止画を撮ると、露出時間が足りないのか暗くしか取れなかったので、露出時間を無理やり伸ばしました。あと、avenc_bmpがNV12を受け付けないので、BGRAにコンバート。

 

露出時間を延ばすには、nvarguscamerasrcのオプションにexposuretimerangeを指定します。(露出時間は適当です。。。)

 

gst-launch-1.0 -e nvarguscamerasrc exposuretimerange="358733000 358733000" num-buffers=1 ! 'video/x-raw(memory:NVMM), width=1920, height=1080, format=(string)NV12, framerate=(fraction)1/1' ! nvvidconv ! video/x-raw ! videoconvert ! 'video/x-raw, format=(string)BGRA' ! avenc_bmp ! filesink location=filename

 

カメラの撮影時間を指定する方法

20秒録画したいと思ったのですが、Ctrl-Cだとさすがにイケてないので、自動で終わる方法にしました。

nvarguscamerasrcにtimeoutオプションをつけることで可能です。(EOSを送信する[-e]オプションをgst-launchにつけることを忘れずに。)

 

gst-launch-1.0 -e nvarguscamerasrc timeout=20 ! ...

 

Web上ではtimeoutコマンドを使ってる例(timeout 20 gst-launch-1.0 ...)がありましたが、gstreamer自体の起動に時間がかかるのでnvarguscamerasrcのオプションのほうが正確に20秒取れました。

 

ロスレスで動画を撮る方法

 

非圧縮で動画を撮るのを調べていたのので、I420非圧縮と、H264/H265の可逆圧縮をやってみました。

 

H264/H265はエンコーダに以下のオプションをつけることがポイントのようです。

control-rate=0 qp-range=0,1:0,1:0,1 quant-i-frames=0 quant-p-frames=0

 

gst-launch-1.0 -e nvarguscamerasrc timeout=20 ! 'video/x-raw(memory:NVMM), width=1920, height=1080, format=(string)NV12, framerate=(fraction)30/1' ! omxh264enc control-rate=0 qp-range=0,1:0,1:0,1 quant-i-frames=0 quant-p-frames=0 ! queue ! h264parse ! mp4mux ! filesink location=filename

 

gst-launch-1.0 -e nvarguscamerasrc timeout=20 ! 'video/x-raw(memory:NVMM), width=1920, height=1080, format=(string)NV12, framerate=(fraction)30/1' ! omxh265enc control-rate=0 qp-range=0,1:0,1:0,1 quant-i-frames=0 quant-p-frames=0 ! queue ! h265parse ! mp4mux ! filesink location=filename

 

I420はそのまま保存すればいいんですね。

 

gst-launch-1.0 -e nvarguscamerasrc timeout=20 ! 'video/x-raw(memory:NVMM), width=1920, height=1080, format=NV12, framerate=30/1' ! nvvidconv ! 'video/x-raw, width=1920, height=1080, format=I420, framerate=30/1' ! filesink location=filename

 

I420をgstreamerで再生する方法です。

 

gst-launch-1.0 filesrc location=filename ! videoparse width=1920 height=1080 framerate=30/1 ! xvimagesink

 

I420をWindowsVLCで再生する方法です。

 

"\Program Files\VideoLAN\VLC\vlc.exe" --demux rawvideo --rawvid-width 1920 --rawvid-height 1080 --rawvid-fps 30 --rawvid-chroma I420 filename

 

砂嵐パターンを録画する方法

 

結局カメラの映像だと動きが少なくて可逆/非可逆圧縮の差が分かりにくかったので、砂嵐パターンを録画しました。

 

videotestsrc pattern=snowで可能です。時間指定はできないので、30fps*20sで600枚分のバッファを指定しています。

 

gst-launch-1.0 -e videotestsrc pattern=snow num-buffers=600 ! 'video/x-raw, width=1920, height=1080, format=(string)NV12, framerate=(fraction)30/1' ! omxh264enc bitrate=10000000 ! queue ! h264parse ! mp4mux ! filesink location=filename

 

動画をBMPに展開する方法

下記はH265の例ですが、デコード後にBGRAに変換してavenc_bmpBMP化した後、multifilesinkでファイルに保存するのがポイントです。ファイル名に[%d]をつけると連番になります。

 

gst-launch-1.0 filesrc location=filename ! qtdemux ! h265parse ! omxh265dec ! nvvidconv ! video/x-raw ! videoconvert ! 'video/x-raw, format=(string)BGRA' ! avenc_bmp ! multifilesink location="filename%d.bmp"