struct video_data {
AVClass *class;
int fd;
- int frame_format; /* V4L2_PIX_FMT_* */
+ int pixelformat; /* V4L2_PIX_FMT_* */
int width, height;
int frame_size;
int interlaced;
struct video_data *s = ctx->priv_data;
struct v4l2_capability cap;
int fd;
- int ret;
+ int err;
int flags = O_RDWR;
#define SET_WRAPPERS(prefix) do { \
fd = v4l2_open(ctx->filename, flags, 0);
if (fd < 0) {
- ret = AVERROR(errno);
+ err = AVERROR(errno);
av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s: %s\n",
- ctx->filename, av_err2str(ret));
- return ret;
+ ctx->filename, av_err2str(err));
+ return err;
}
if (v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
- ret = AVERROR(errno);
+ err = AVERROR(errno);
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
- av_err2str(ret));
+ av_err2str(err));
goto fail;
}
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
av_log(ctx, AV_LOG_ERROR, "Not a video capture device.\n");
- ret = AVERROR(ENODEV);
+ err = AVERROR(ENODEV);
goto fail;
}
if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
av_log(ctx, AV_LOG_ERROR,
"The device does not support the streaming I/O method.\n");
- ret = AVERROR(ENOSYS);
+ err = AVERROR(ENOSYS);
goto fail;
}
fail:
v4l2_close(fd);
- return ret;
+ return err;
}
static int device_init(AVFormatContext *ctx, int *width, int *height,
- uint32_t pix_fmt)
+ uint32_t pixelformat)
{
struct video_data *s = ctx->priv_data;
struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
- struct v4l2_pix_format *pix = &fmt.fmt.pix;
int res = 0;
- pix->width = *width;
- pix->height = *height;
- pix->pixelformat = pix_fmt;
- pix->field = V4L2_FIELD_ANY;
+ fmt.fmt.pix.width = *width;
+ fmt.fmt.pix.height = *height;
+ fmt.fmt.pix.pixelformat = pixelformat;
+ fmt.fmt.pix.field = V4L2_FIELD_ANY;
+ /* Some drivers will fail and return EINVAL when the pixelformat
+ is not supported (even if type field is valid and supported) */
if (v4l2_ioctl(s->fd, VIDIOC_S_FMT, &fmt) < 0)
res = AVERROR(errno);
*height = fmt.fmt.pix.height;
}
- if (pix_fmt != fmt.fmt.pix.pixelformat) {
+ if (pixelformat != fmt.fmt.pix.pixelformat) {
av_log(ctx, AV_LOG_DEBUG,
"The V4L2 driver changed the pixel format "
"from 0x%08X to 0x%08X\n",
- pix_fmt, fmt.fmt.pix.pixelformat);
+ pixelformat, fmt.fmt.pix.pixelformat);
res = AVERROR(EINVAL);
}
struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
while(!v4l2_ioctl(s->fd, VIDIOC_ENUM_FMT, &vfd)) {
- enum AVCodecID codec_id = avpriv_fmt_v4l2codec(vfd.pixelformat);
- enum AVPixelFormat pix_fmt = avpriv_fmt_v4l2ff(vfd.pixelformat, codec_id);
+ enum AVCodecID codec_id = ff_fmt_v4l2codec(vfd.pixelformat);
+ enum AVPixelFormat pix_fmt = ff_fmt_v4l2ff(vfd.pixelformat, codec_id);
vfd.index++;
return AVERROR(EAGAIN);
}
res = AVERROR(errno);
- av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", av_err2str(res));
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n",
+ av_err2str(res));
return res;
}
if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) < 0) {
res = AVERROR(errno);
- av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", av_err2str(res));
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
+ av_err2str(res));
return res;
}
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type) < 0) {
res = AVERROR(errno);
- av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n", av_err2str(res));
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n",
+ av_err2str(res));
return res;
}
if (v4l2_ioctl(s->fd, VIDIOC_S_PARM, &streamparm) < 0) {
ret = AVERROR(errno);
- av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_S_PARM): %s\n", av_err2str(ret));
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_S_PARM): %s\n",
+ av_err2str(ret));
return ret;
}
{
int ret, i;
- *desired_format = avpriv_fmt_ff2v4l(pix_fmt, ctx->video_codec_id);
+ *desired_format = ff_fmt_ff2v4l(pix_fmt, ctx->video_codec_id);
if (*desired_format) {
ret = device_init(ctx, width, height, *desired_format);
}
if (!*desired_format) {
- for (i = 0; avpriv_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
+ for (i = 0; ff_fmt_conversion_table[i].codec_id != AV_CODEC_ID_NONE; i++) {
if (ctx->video_codec_id == AV_CODEC_ID_NONE ||
- avpriv_fmt_conversion_table[i].codec_id == ctx->video_codec_id) {
+ ff_fmt_conversion_table[i].codec_id == ctx->video_codec_id) {
av_log(ctx, AV_LOG_DEBUG, "Trying to set codec:%s pix_fmt:%s\n",
- avcodec_get_name(avpriv_fmt_conversion_table[i].codec_id),
- (char *)av_x_if_null(av_get_pix_fmt_name(avpriv_fmt_conversion_table[i].ff_fmt), "none"));
+ avcodec_get_name(ff_fmt_conversion_table[i].codec_id),
+ (char *)av_x_if_null(av_get_pix_fmt_name(ff_fmt_conversion_table[i].ff_fmt), "none"));
- *desired_format = avpriv_fmt_conversion_table[i].v4l2_fmt;
+ *desired_format = ff_fmt_conversion_table[i].v4l2_fmt;
ret = device_init(ctx, width, height, *desired_format);
if (ret >= 0)
break;
}
}
- *codec_id = avpriv_fmt_v4l2codec(*desired_format);
+ *codec_id = ff_fmt_v4l2codec(*desired_format);
av_assert0(*codec_id != AV_CODEC_ID_NONE);
return ret;
}
+static int v4l2_read_probe(AVProbeData *p)
+{
+ if (av_strstart(p->filename, "/dev/video", NULL))
+ return AVPROBE_SCORE_MAX - 1;
+ return 0;
+}
+
static int v4l2_read_header(AVFormatContext *ctx)
{
struct video_data *s = ctx->priv_data;
avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
- if ((res = v4l2_set_parameters(ctx)) < 0)
- goto fail;
-
if (s->pixel_format) {
AVCodec *codec = avcodec_find_decoder_by_name(s->pixel_format);
"Querying the device for the current frame size\n");
if (v4l2_ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
res = AVERROR(errno);
- av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n", av_err2str(res));
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",
+ av_err2str(res));
goto fail;
}
if ((res = av_image_check_size(s->width, s->height, 0, ctx)) < 0)
goto fail;
- s->frame_format = desired_format;
+ s->pixelformat = desired_format;
+
+ if ((res = v4l2_set_parameters(ctx)) < 0)
+ goto fail;
- st->codec->pix_fmt = avpriv_fmt_v4l2ff(desired_format, codec_id);
+ st->codec->pix_fmt = ff_fmt_v4l2ff(desired_format, codec_id);
s->frame_size =
avpicture_get_size(st->codec->pix_fmt, s->width, s->height);
.name = "video4linux2,v4l2",
.long_name = NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
.priv_data_size = sizeof(struct video_data),
+ .read_probe = v4l2_read_probe,
.read_header = v4l2_read_header,
.read_packet = v4l2_read_packet,
.read_close = v4l2_read_close,