I'm building an app that is capturing frames from any v4l2 supported webcam. I'm controlling the camera with v4l2 (golang package https://github.com/blackjack/webcam) and one of the things I need is pixel format. However, what I get is uint32
representing the format in v4l2.
I do the streaming by wrapping ffmpeg command and reading from its stdout
:
args := []string{
"-f", "v4l2",
"-c:v", "rawvideo",
"-pix_fmt", pixFmt,
"-s", size,
"-i", input,
"-f", "image2pipe",
"-c:v", "mjpeg",
"-qscale:v", "5",
"-", // pipes to stdout
}
cmd := exec.Command("ffmpeg", args...)
Now the problem is that -pix_fmt
option requires format name in string that is recognized by ffmpeg (for example 8-bit Bayer RGGB8 corresponds to bayer_rggb8
, while this format in v4l2 has code 1111967570
).
I found the mapping code for it in ffmpeg's libavdevice
: https://github.com/FFmpeg/FFmpeg/blob/master/libavdevice/v4l2-common.h includes the functions I need, but somehow I'm not able to include <libavdevice/v4l2-common.h>
in CGo (no problems with <libavdevice/avdevice.h>
):
package conv
/*
#cgo pkg-config: libavdevice
#include <libavdevice/avdevice.h>
#include <libavdevice/v4l2-common.h>
*/
import "C"
type (
)
// PixFmtToFF takes v4l2 pixel format code and converts it to a string
// recognized by ffmpeg command
// example: 1111967570 to "bayer_rggb8"
func PixFmtToFF(v4l2code uint32) (string, error) {
// should work something like this, couldn't test
codecID := C.ff_fmt_v4l2codec(v4l2code)
pixFmt := C.ff_fmt_v4l2ff(vfd.pixelformat, codec_id)
return C.av_get_pix_fmt_name(pixFmt)
}
Build output returns:
go build \
-mod=vendor \
-o ./bin/camera-api \
./cmd/camera-api
# kca/internal/camera/conv
internal/camera/conv/convert.go:6:11: fatal error: libavdevice/v4l2-common.h: No such file or directory
#include <libavdevice/v4l2-common.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make: *** [Makefile:13: build/camera-api] Error 2
make: *** [builder/camera-api] Error 2
Output of pkg-config --libs libavdevice
is -L/usr/local/lib -lavdevice
.
So, I have two questions:
1) How could I include v4l2-common.h
so I can use the mapping functions?
2) Is there a better way? I need ffmpeg wrapping so we can support wide range of formats for captured frames.