go4vl: Cannot retrieve pixel format info from device [Error While Encoding v4l2 command via ioctl]
Error
device.GetPixFormat()
always fails with error device: pix format failed: unsupported error
if we do a system call trace i get following
ioctl(3, _IOC(_IOC_READ|_IOC_WRITE, 0x56, 0x4, 0xcc), 0xc000076ca8) = -1 ENOTTY (Inappropriate ioctl for device)
write(1, "failed to get pix format\n", 25failed to get pix format
It looks like encoded command is not VIDIOC_G_FMT
and is not recognized by kernel.
package main
import (
"fmt"
"github.com/vladimirvivien/go4vl/v4l2"
)
func main() {
device, err := v4l2.Open("/dev/video0")
if err != nil {
panic(err)
}
_, err = device.GetPixFormat()
if err != nil {
fmt.Println("failed to get pix format")
panic(err)
}
}
My kernel is
Linux endless 5.14.14-arch1-1 #1 SMP PREEMPT Wed, 20 Oct 2021 21:35:18 +0000 x86_64 GNU/Linux
Cause
I don’t think this problem is caused by kernel. I can use <linux/videodev2.h> and it does not cause this error
With the C API I get
ioctl(3, VIDIOC_G_FMT, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, fmt.pix={width=1280, height=720, pixelformat=v4l2_fourcc('M', 'J', 'P', 'G') /* V4L2_PIX_FMT_MJPEG */, field=V4L2_FIELD_NONE, bytesperline=0, sizeimage=1843200, colorspace=V4L2_COLORSPACE_SRGB}}) = 0
It looks like the problem is caused in ioctl encoding functions. I rechecked the ioct.go but could not find the problem
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 1
- Comments: 22 (8 by maintainers)
I think it would be great if we can add some unit testing to important parts of project like (ioctl commands , structs etc) , this would help the project to avoid future errors and keep up the standards with v4l2 api. Also the unit testing should use cgo , something similar to above program . I intend to use this project for my upcoming projects , let me know if I can help speed up the process
@EtienneBruines @vladimirvivien Of all implementations of V4l2, this is my favorite. It is more simple, readable, and has more functions implemented. It would be great if we can overcome this issue
@EtienneBruines that is great!!! This confirms that cgo works (better than crafting Go types manually for C counter parts). So this means I will do a refactor of current code to integrate cgo-generated types.
Again, thank you considering using this code.
@vladimirvivien I played around with it a little bit, and it seems to have done wonders!
I was able to
setFormat
and then verify the settings usinggetFormat
reliably now. 🎉@tarunKoyalwar that snippet is really helpful! (Especially with debugging)
From the looks of it (earlier on), those 4 bytes seem to be in between the
StreamType
and thefmt [200]byte
- possibly to help define which of theunion
types it is.@vladimirvivien @EtienneBruines I believe following data would help.
This program returns
It looks like the v4l2format defined here(https://github.com/vladimirvivien/go4vl/blob/aab6d9c4a2496f2e9bc90c2763e94eba389bde9d/v4l2/format.go#L289)
is short of 4 bytes . It looks like this missing 4 bytes are causing above discussed errors. It looks like a field (possibly __u32 which is of size 4 bytes) is missing in golang implementation of v4l2_format
@EtienneBruines @tarunKoyalwar Apologies for late reply, I have been on vacation and got busy at work.
This is an awesome thread and appreciate all the great information/comments you both have provided. But, I must start my reply with the following disclaimers:
So as you can see this is pretty early stuff. Having said all of that, I welcome your great feedback and will be investigating this issue this week. My lofty aspiration for this project is to provide a great idiomatic Go experience using the API without cgo. However, I havent used it in enough cases to know if that’s a possibility.
I will spend time on this issue to see if it’s something that can be quickly resolved or need to completely change direction of the project (using cgo).
Thanks.
@vladimirvivien any comment about this issue would be great !
I am actually working on a generalized pam module with face auth . I intended to use this package for webcam . But it doesnot seem stable right now.
It looks like only stable way to get all features of webcam in linux is to use cgo
The only idea I think now is implement all logic in c and just get buffers using cgo