I split and convert the raw output file to pgm, which is the simplest image file format using the following script :
v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=RG12 --set-ctrl bypass_mode=0 --stream-mmap --stream-count=20 --stream-to=test.raw
for i in $(seq 10 19)
do
for m in 4095 32767 65535
do
(
echo P5
echo 1920 1080
echo $m
dd if=test.raw conv=swab bs=4147200 skip=$i count=1
) > frame-$i-swab-$m.pgm
(
echo P5
echo 1920 1080
echo $m
dd if=test.raw bs=4147200 skip=$i count=1
) > frame-$i-raw-$m.pgm
done
done
I skip the first 10 frames to give some time to the sensor to stabilize, and try every combination of big-endian or little-endian way of encoding 12 bits on 2 bytes and not rescaled (highest pixel value is 4095), rescaled to 15 bits (highest pixel value is 32767) or rescaled to 16 bits (highest pixel value is 65535), but no combination gives me a perfect raw monochrome image.
You can attach a file to a previous post.
Moving your mouse cursor in the upper right corner of a previous post (being logged in), you will see a paper clip icon for this purpose.
OK, file is attached to comment #16 (as .pgm.gz, because plain .pgm is refused)
It’s the best combination I’ve found of swab or notswab and maxpixel = 2^12-1, 2^15-1 or 2^16-1.
Surprisingly, 2^16-1 is the best maxval but that does not match documentation (2^15-1 or 2^12-1) as I read it
I seems to me that what I get with the command in comment #4 is not the raw output from the sensor, but what I get is the output from the sensor processed by some other step (probably the ISP). Is that true ?
the commands in comment #4 dump the raw files, which process by the V4L2 media framework.
please also refer to the [Camera Architecture Stack] from [L4T Documentation]-> [NVIDIA Tegra Linux Driver Package]-> [Release 28.2 Development Guide]-> [Camera Development] chapter-> [Camera Software Development Solution] session.
thanks
Sorry for some noise here : actually the connection to my monochrome sensor was faulty : some mipi lane was garbled. I now have another sensor that does not have that bug. Command in comment #4 (updated to my 12-bit sensor) actually gives a dump of the images sent by the sensor, with pixels stored as 16-bit big endian values : each 12-bit pixel is shifted by 4 positions to give a 16-bit value.
After adding the following entries to vi2_video_formats
and of course my driver telling that its mediabus_format is MEDIA_BUS_FMT_Y12_1X12, I now have the following list of formats :
nvidia@cam5-ubuntu:~$ v4l2-ctl --list-formats
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'Y16 -BE'
Name : 16-bit Greyscale BE
Index : 1
Type : Video Capture
Pixel Format: 'GREY'
Name : 8-bit Greyscale
nvidia@cam5-ubuntu:~$
Unfortunately, using it in a gstreamer pipeline ‘gst-launch-1.0 v4l2src …’ only gives me 2 fps.
If I let my driver pretend that its media_bus_format is MEDIA_BUS_FMT_SRGGB12_1X12, and use a gstreamer pipeline ‘gst-launch-1.0 nvcamerasrc …’ I get at least 20 fps. Why such a poor performance with v4l2src ?
I checked the above command on a freshly installed tx1 devkit with jetpack-3.2.1 (l4t 28.2) and equipped with a ov5693 sensor provided by nvidia. It confirms a bug in the handling of rawN sensors, with N > 8 : LSB bits are discarded !
Do I misunderstand ?
Does the CSI-VI pair truncate the incoming pixels to 8 bits while also replicating the most significant bits ?
Is the image stored in memory in big endian or little endian mode ?
Is the RAW10 value shifted into 16 bits to produce values between 0 and 0xffc0, or are the 10-bits not shifted at all and produce values between 0 and 3ff ? I have read chapters 29 and 32 of the TX1 TRM, but experimental results seem not to match documentation.
are actually stored in 16 bytes word, in little endian form, without any shift occuring, thus with values between 0 and 1023 (2^10-1).
This does not seem to match the TX1 TRM 31.3.2.3 “Raw Pixel Formatting to Memory”/“T_R16_I Formatting for RAW10, RAW12 and RAW14”, where RAW10 pixels are shown written in memory as
Sorry I cannot tell much more, but the 16 bits format may only be used by option stream-to which writes to disk.
v4l2-ctl would have read into memory in RG10 format as explained by TRM, and then made the 16 bits format for disk storage with stream-to. So the raw file may not be an exact image of the memory stream. It is much easier to read just 2 bytes and get ‘short’ values for further computing, than having to manage the shifts and mask.
I am currently trying to add grayscale format support to a Jetson Xavier with L4T 31.1 by following the steps described in the above comment for the sensor OV24A1B. I started from the driver for the sensor OV5693.
In ov5693.c, I modified the default data format to match the required format (Gray 10 bits)
I do not have a Xavier, only TX1 and TX2, and while the TX1 uses the vi2_formats.h file, TX2 uses vi4_formats.h. Additions for grayscale must go there also for Xavier, I surmise.
Also, the stack trace is not the most interesting part of the error message (except for the name of the function where it happens : ‘tegra_channel_fmts_bitmap_init’ here), but there is also a panic message (probably about a null pointer). ‘printk’ is your friend :)