video(4) changes to support analog tv capture devices:
- support interlacing with VIDIOC_G_FMT - set V4L2_CAP_TUNER if driver implements the set_tuner/get_tuner callbacks - set V4L2_CAP_AUDIO if driver implements the set_audio/get_audio/enum_audio callbacks - add support for the following ioctls: VIDIOC_ENUMSTD, VIDIOC_G_STD, VIDIOC_S_STD, VIDIOC_ENUMINPUT, VIDIOC_G_INPUT, VIDIOC_S_INPUT, VIDIOC_ENUMAUDIO, VIDIOC_G_AUDIO, VIDIOC_S_AUDIO, VIDIOC_G_TUNER, VIDIOC_S_TUNER, VIDIOC_G_FREQUENCY, VIDIOC_S_FREQUENCY - in video_submit_payload(), fix support for signaling sample complete using frame numbers - new optional callbacks for drivers: enum_standard, get_standard, set_standard, enum_input, get_input, set_input, enum_audio, get_audio, set_audio, get_tuner, set_tuner, get_frequency, set_frequency for drivers that don't provide enum_standard, get_standard, set_standard, enum_input, get_input and set_input, the original stub implementations are provided
This commit is contained in:
parent
89d498aa24
commit
c618ceecc4
625
sys/dev/video.c
625
sys/dev/video.c
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: video.c,v 1.23 2009/12/06 22:42:48 dyoung Exp $ */
|
/* $NetBSD: video.c,v 1.24 2010/12/14 03:25:16 jmcneill Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008 Patrick Mahoney <pat@polycrystal.org>
|
* Copyright (c) 2008 Patrick Mahoney <pat@polycrystal.org>
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: video.c,v 1.23 2009/12/06 22:42:48 dyoung Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: video.c,v 1.24 2010/12/14 03:25:16 jmcneill Exp $");
|
||||||
|
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#if NVIDEO > 0
|
#if NVIDEO > 0
|
||||||
|
@ -224,8 +224,24 @@ static void v4l2_format_to_video_format(const struct v4l2_format *,
|
||||||
struct video_format *);
|
struct video_format *);
|
||||||
static void video_format_to_v4l2_format(const struct video_format *,
|
static void video_format_to_v4l2_format(const struct video_format *,
|
||||||
struct v4l2_format *);
|
struct v4l2_format *);
|
||||||
|
static void v4l2_standard_to_video_standard(v4l2_std_id,
|
||||||
|
enum video_standard *);
|
||||||
|
static void video_standard_to_v4l2_standard(enum video_standard,
|
||||||
|
struct v4l2_standard *);
|
||||||
|
static void v4l2_input_to_video_input(const struct v4l2_input *,
|
||||||
|
struct video_input *);
|
||||||
|
static void video_input_to_v4l2_input(const struct video_input *,
|
||||||
|
struct v4l2_input *);
|
||||||
|
static void v4l2_audio_to_video_audio(const struct v4l2_audio *,
|
||||||
|
struct video_audio *);
|
||||||
|
static void video_audio_to_v4l2_audio(const struct video_audio *,
|
||||||
|
struct v4l2_audio *);
|
||||||
|
static void v4l2_tuner_to_video_tuner(const struct v4l2_tuner *,
|
||||||
|
struct video_tuner *);
|
||||||
|
static void video_tuner_to_v4l2_tuner(const struct video_tuner *,
|
||||||
|
struct v4l2_tuner *);
|
||||||
|
|
||||||
/* V4L2 api functions, typically called from videoioclt() */
|
/* V4L2 api functions, typically called from videoioctl() */
|
||||||
static int video_enum_format(struct video_softc *, struct v4l2_fmtdesc *);
|
static int video_enum_format(struct video_softc *, struct v4l2_fmtdesc *);
|
||||||
static int video_get_format(struct video_softc *,
|
static int video_get_format(struct video_softc *,
|
||||||
struct v4l2_format *);
|
struct v4l2_format *);
|
||||||
|
@ -233,6 +249,22 @@ static int video_set_format(struct video_softc *,
|
||||||
struct v4l2_format *);
|
struct v4l2_format *);
|
||||||
static int video_try_format(struct video_softc *,
|
static int video_try_format(struct video_softc *,
|
||||||
struct v4l2_format *);
|
struct v4l2_format *);
|
||||||
|
static int video_enum_standard(struct video_softc *,
|
||||||
|
struct v4l2_standard *);
|
||||||
|
static int video_get_standard(struct video_softc *, v4l2_std_id *);
|
||||||
|
static int video_set_standard(struct video_softc *, v4l2_std_id);
|
||||||
|
static int video_enum_input(struct video_softc *, struct v4l2_input *);
|
||||||
|
static int video_get_input(struct video_softc *, int *);
|
||||||
|
static int video_set_input(struct video_softc *, int);
|
||||||
|
static int video_enum_audio(struct video_softc *, struct v4l2_audio *);
|
||||||
|
static int video_get_audio(struct video_softc *, struct v4l2_audio *);
|
||||||
|
static int video_set_audio(struct video_softc *, struct v4l2_audio *);
|
||||||
|
static int video_get_tuner(struct video_softc *, struct v4l2_tuner *);
|
||||||
|
static int video_set_tuner(struct video_softc *, struct v4l2_tuner *);
|
||||||
|
static int video_get_frequency(struct video_softc *,
|
||||||
|
struct v4l2_frequency *);
|
||||||
|
static int video_set_frequency(struct video_softc *,
|
||||||
|
struct v4l2_frequency *);
|
||||||
static int video_query_control(struct video_softc *,
|
static int video_query_control(struct video_softc *,
|
||||||
struct v4l2_queryctrl *);
|
struct v4l2_queryctrl *);
|
||||||
static int video_get_control(struct video_softc *,
|
static int video_get_control(struct video_softc *,
|
||||||
|
@ -586,14 +618,25 @@ video_format_to_v4l2_format(const struct video_format *src,
|
||||||
dest->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
dest->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
dest->fmt.pix.width = src->width;
|
dest->fmt.pix.width = src->width;
|
||||||
dest->fmt.pix.height = src->height;
|
dest->fmt.pix.height = src->height;
|
||||||
dest->fmt.pix.field = V4L2_FIELD_NONE; /* TODO: for now,
|
if (VIDEO_INTERLACED(src->interlace_flags))
|
||||||
* just set to
|
dest->fmt.pix.field = V4L2_FIELD_INTERLACED;
|
||||||
* progressive */
|
else
|
||||||
|
dest->fmt.pix.field = V4L2_FIELD_NONE;
|
||||||
dest->fmt.pix.bytesperline = src->stride;
|
dest->fmt.pix.bytesperline = src->stride;
|
||||||
dest->fmt.pix.sizeimage = src->sample_size;
|
dest->fmt.pix.sizeimage = src->sample_size;
|
||||||
dest->fmt.pix.colorspace = 0; /* XXX */
|
|
||||||
dest->fmt.pix.priv = src->priv;
|
dest->fmt.pix.priv = src->priv;
|
||||||
|
|
||||||
|
switch (src->color.primaries) {
|
||||||
|
case VIDEO_COLOR_PRIMARIES_SMPTE_170M:
|
||||||
|
dest->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
|
||||||
|
break;
|
||||||
|
/* XXX */
|
||||||
|
case VIDEO_COLOR_PRIMARIES_UNSPECIFIED:
|
||||||
|
default:
|
||||||
|
dest->fmt.pix.colorspace = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
switch (src->pixel_format) {
|
switch (src->pixel_format) {
|
||||||
case VIDEO_FORMAT_UYVY:
|
case VIDEO_FORMAT_UYVY:
|
||||||
dest->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
|
dest->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
|
||||||
|
@ -652,6 +695,23 @@ v4l2_format_to_video_format(const struct v4l2_format *src,
|
||||||
dest->stride = src->fmt.pix.bytesperline;
|
dest->stride = src->fmt.pix.bytesperline;
|
||||||
dest->sample_size = src->fmt.pix.sizeimage;
|
dest->sample_size = src->fmt.pix.sizeimage;
|
||||||
|
|
||||||
|
if (src->fmt.pix.field == V4L2_FIELD_INTERLACED)
|
||||||
|
dest->interlace_flags = VIDEO_INTERLACE_ON;
|
||||||
|
else
|
||||||
|
dest->interlace_flags = VIDEO_INTERLACE_OFF;
|
||||||
|
|
||||||
|
switch (src->fmt.pix.colorspace) {
|
||||||
|
case V4L2_COLORSPACE_SMPTE170M:
|
||||||
|
dest->color.primaries =
|
||||||
|
VIDEO_COLOR_PRIMARIES_SMPTE_170M;
|
||||||
|
break;
|
||||||
|
/* XXX */
|
||||||
|
default:
|
||||||
|
dest->color.primaries =
|
||||||
|
VIDEO_COLOR_PRIMARIES_UNSPECIFIED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
switch (src->fmt.pix.pixelformat) {
|
switch (src->fmt.pix.pixelformat) {
|
||||||
case V4L2_PIX_FMT_UYVY:
|
case V4L2_PIX_FMT_UYVY:
|
||||||
dest->pixel_format = VIDEO_FORMAT_UYVY;
|
dest->pixel_format = VIDEO_FORMAT_UYVY;
|
||||||
|
@ -720,6 +780,7 @@ video_enum_format(struct video_softc *sc, struct v4l2_fmtdesc *fmtdesc)
|
||||||
video_format_to_v4l2_format(&vfmt, &fmt);
|
video_format_to_v4l2_format(&vfmt, &fmt);
|
||||||
|
|
||||||
fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* TODO: only one type for now */
|
fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* TODO: only one type for now */
|
||||||
|
fmtdesc->flags = 0;
|
||||||
if (vfmt.pixel_format >= VIDEO_FORMAT_MJPEG)
|
if (vfmt.pixel_format >= VIDEO_FORMAT_MJPEG)
|
||||||
fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;
|
fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;
|
||||||
strlcpy(fmtdesc->description,
|
strlcpy(fmtdesc->description,
|
||||||
|
@ -798,6 +859,475 @@ video_try_format(struct video_softc *sc,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
v4l2_standard_to_video_standard(v4l2_std_id stdid,
|
||||||
|
enum video_standard *vstd)
|
||||||
|
{
|
||||||
|
#define VSTD(id, vid) case (id): *vstd = (vid); break;
|
||||||
|
switch (stdid) {
|
||||||
|
VSTD(V4L2_STD_NTSC_M, VIDEO_STANDARD_NTSC_M)
|
||||||
|
default:
|
||||||
|
*vstd = VIDEO_STANDARD_UNKNOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#undef VSTD
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
video_standard_to_v4l2_standard(enum video_standard vstd,
|
||||||
|
struct v4l2_standard *std)
|
||||||
|
{
|
||||||
|
switch (vstd) {
|
||||||
|
case VIDEO_STANDARD_NTSC_M:
|
||||||
|
std->id = V4L2_STD_NTSC_M;
|
||||||
|
strlcpy(std->name, "NTSC-M", sizeof(std->name));
|
||||||
|
std->frameperiod.numerator = 1001;
|
||||||
|
std->frameperiod.denominator = 30000;
|
||||||
|
std->framelines = 525;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
std->id = V4L2_STD_UNKNOWN;
|
||||||
|
strlcpy(std->name, "Unknown", sizeof(std->name));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
video_enum_standard(struct video_softc *sc, struct v4l2_standard *std)
|
||||||
|
{
|
||||||
|
const struct video_hw_if *hw = sc->hw_if;
|
||||||
|
enum video_standard vstd;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* simple webcam drivers don't need to implement this callback */
|
||||||
|
if (hw->enum_standard == NULL) {
|
||||||
|
if (std->index != 0)
|
||||||
|
return EINVAL;
|
||||||
|
std->id = V4L2_STD_UNKNOWN;
|
||||||
|
strlcpy(std->name, "webcam", sizeof(std->name));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v4l2_standard_to_video_standard(std->id, &vstd);
|
||||||
|
|
||||||
|
err = hw->enum_standard(sc->hw_softc, std->index, &vstd);
|
||||||
|
if (err != 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
video_standard_to_v4l2_standard(vstd, std);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
video_get_standard(struct video_softc *sc, v4l2_std_id *stdid)
|
||||||
|
{
|
||||||
|
const struct video_hw_if *hw = sc->hw_if;
|
||||||
|
struct v4l2_standard std;
|
||||||
|
enum video_standard vstd;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* simple webcam drivers don't need to implement this callback */
|
||||||
|
if (hw->get_standard == NULL) {
|
||||||
|
*stdid = V4L2_STD_UNKNOWN;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = hw->get_standard(sc->hw_softc, &vstd);
|
||||||
|
if (err != 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
video_standard_to_v4l2_standard(vstd, &std);
|
||||||
|
*stdid = std.id;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
video_set_standard(struct video_softc *sc, v4l2_std_id stdid)
|
||||||
|
{
|
||||||
|
const struct video_hw_if *hw = sc->hw_if;
|
||||||
|
enum video_standard vstd;
|
||||||
|
|
||||||
|
/* simple webcam drivers don't need to implement this callback */
|
||||||
|
if (hw->set_standard == NULL) {
|
||||||
|
if (stdid != V4L2_STD_UNKNOWN)
|
||||||
|
return EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v4l2_standard_to_video_standard(stdid, &vstd);
|
||||||
|
|
||||||
|
return hw->set_standard(sc->hw_softc, vstd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
v4l2_input_to_video_input(const struct v4l2_input *input,
|
||||||
|
struct video_input *vi)
|
||||||
|
{
|
||||||
|
vi->index = input->index;
|
||||||
|
strlcpy(vi->name, input->name, sizeof(vi->name));
|
||||||
|
switch (input->type) {
|
||||||
|
case V4L2_INPUT_TYPE_TUNER:
|
||||||
|
vi->type = VIDEO_INPUT_TYPE_TUNER;
|
||||||
|
break;
|
||||||
|
case V4L2_INPUT_TYPE_CAMERA:
|
||||||
|
vi->type = VIDEO_INPUT_TYPE_CAMERA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
vi->audiomask = input->audioset;
|
||||||
|
vi->tuner_index = input->tuner;
|
||||||
|
vi->standards = input->std; /* ... values are the same */
|
||||||
|
vi->status = 0;
|
||||||
|
if (input->status & V4L2_IN_ST_NO_POWER)
|
||||||
|
vi->status |= VIDEO_STATUS_NO_POWER;
|
||||||
|
if (input->status & V4L2_IN_ST_NO_SIGNAL)
|
||||||
|
vi->status |= VIDEO_STATUS_NO_SIGNAL;
|
||||||
|
if (input->status & V4L2_IN_ST_NO_COLOR)
|
||||||
|
vi->status |= VIDEO_STATUS_NO_COLOR;
|
||||||
|
if (input->status & V4L2_IN_ST_NO_H_LOCK)
|
||||||
|
vi->status |= VIDEO_STATUS_NO_HLOCK;
|
||||||
|
if (input->status & V4L2_IN_ST_MACROVISION)
|
||||||
|
vi->status |= VIDEO_STATUS_MACROVISION;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
video_input_to_v4l2_input(const struct video_input *vi,
|
||||||
|
struct v4l2_input *input)
|
||||||
|
{
|
||||||
|
input->index = vi->index;
|
||||||
|
strlcpy(input->name, vi->name, sizeof(input->name));
|
||||||
|
switch (vi->type) {
|
||||||
|
case VIDEO_INPUT_TYPE_TUNER:
|
||||||
|
input->type = V4L2_INPUT_TYPE_TUNER;
|
||||||
|
break;
|
||||||
|
case VIDEO_INPUT_TYPE_CAMERA:
|
||||||
|
input->type = V4L2_INPUT_TYPE_CAMERA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
input->audioset = vi->audiomask;
|
||||||
|
input->tuner = vi->tuner_index;
|
||||||
|
input->std = vi->standards; /* ... values are the same */
|
||||||
|
input->status = 0;
|
||||||
|
if (vi->status & VIDEO_STATUS_NO_POWER)
|
||||||
|
input->status |= V4L2_IN_ST_NO_POWER;
|
||||||
|
if (vi->status & VIDEO_STATUS_NO_SIGNAL)
|
||||||
|
input->status |= V4L2_IN_ST_NO_SIGNAL;
|
||||||
|
if (vi->status & VIDEO_STATUS_NO_COLOR)
|
||||||
|
input->status |= V4L2_IN_ST_NO_COLOR;
|
||||||
|
if (vi->status & VIDEO_STATUS_NO_HLOCK)
|
||||||
|
input->status |= V4L2_IN_ST_NO_H_LOCK;
|
||||||
|
if (vi->status & VIDEO_STATUS_MACROVISION)
|
||||||
|
input->status |= V4L2_IN_ST_MACROVISION;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
video_enum_input(struct video_softc *sc, struct v4l2_input *input)
|
||||||
|
{
|
||||||
|
const struct video_hw_if *hw = sc->hw_if;
|
||||||
|
struct video_input vi;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* simple webcam drivers don't need to implement this callback */
|
||||||
|
if (hw->enum_input == NULL) {
|
||||||
|
if (input->index != 0)
|
||||||
|
return EINVAL;
|
||||||
|
memset(input, 0, sizeof(*input));
|
||||||
|
input->index = 0;
|
||||||
|
strlcpy(input->name, "Camera", sizeof(input->name));
|
||||||
|
input->type = V4L2_INPUT_TYPE_CAMERA;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v4l2_input_to_video_input(input, &vi);
|
||||||
|
|
||||||
|
err = hw->enum_input(sc->hw_softc, input->index, &vi);
|
||||||
|
if (err != 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
video_input_to_v4l2_input(&vi, input);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
video_get_input(struct video_softc *sc, int *index)
|
||||||
|
{
|
||||||
|
const struct video_hw_if *hw = sc->hw_if;
|
||||||
|
struct video_input vi;
|
||||||
|
struct v4l2_input input;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* simple webcam drivers don't need to implement this callback */
|
||||||
|
if (hw->get_input == NULL) {
|
||||||
|
*index = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.index = *index;
|
||||||
|
v4l2_input_to_video_input(&input, &vi);
|
||||||
|
|
||||||
|
err = hw->get_input(sc->hw_softc, &vi);
|
||||||
|
if (err != 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
video_input_to_v4l2_input(&vi, &input);
|
||||||
|
*index = input.index;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
video_set_input(struct video_softc *sc, int index)
|
||||||
|
{
|
||||||
|
const struct video_hw_if *hw = sc->hw_if;
|
||||||
|
struct video_input vi;
|
||||||
|
struct v4l2_input input;
|
||||||
|
|
||||||
|
/* simple webcam drivers don't need to implement this callback */
|
||||||
|
if (hw->set_input == NULL) {
|
||||||
|
if (index != 0)
|
||||||
|
return EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.index = index;
|
||||||
|
v4l2_input_to_video_input(&input, &vi);
|
||||||
|
|
||||||
|
return hw->set_input(sc->hw_softc, &vi);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
v4l2_audio_to_video_audio(const struct v4l2_audio *audio,
|
||||||
|
struct video_audio *va)
|
||||||
|
{
|
||||||
|
va->index = audio->index;
|
||||||
|
strlcpy(va->name, audio->name, sizeof(va->name));
|
||||||
|
va->caps = va->mode = 0;
|
||||||
|
if (audio->capability & V4L2_AUDCAP_STEREO)
|
||||||
|
va->caps |= VIDEO_AUDIO_F_STEREO;
|
||||||
|
if (audio->capability & V4L2_AUDCAP_AVL)
|
||||||
|
va->caps |= VIDEO_AUDIO_F_AVL;
|
||||||
|
if (audio->mode & V4L2_AUDMODE_AVL)
|
||||||
|
va->mode |= VIDEO_AUDIO_F_AVL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
video_audio_to_v4l2_audio(const struct video_audio *va,
|
||||||
|
struct v4l2_audio *audio)
|
||||||
|
{
|
||||||
|
audio->index = va->index;
|
||||||
|
strlcpy(audio->name, va->name, sizeof(audio->name));
|
||||||
|
audio->capability = audio->mode = 0;
|
||||||
|
if (va->caps & VIDEO_AUDIO_F_STEREO)
|
||||||
|
audio->capability |= V4L2_AUDCAP_STEREO;
|
||||||
|
if (va->caps & VIDEO_AUDIO_F_AVL)
|
||||||
|
audio->capability |= V4L2_AUDCAP_AVL;
|
||||||
|
if (va->mode & VIDEO_AUDIO_F_AVL)
|
||||||
|
audio->mode |= V4L2_AUDMODE_AVL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
video_enum_audio(struct video_softc *sc, struct v4l2_audio *audio)
|
||||||
|
{
|
||||||
|
const struct video_hw_if *hw = sc->hw_if;
|
||||||
|
struct video_audio va;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (hw->enum_audio == NULL)
|
||||||
|
return ENOTTY;
|
||||||
|
|
||||||
|
v4l2_audio_to_video_audio(audio, &va);
|
||||||
|
|
||||||
|
err = hw->enum_audio(sc->hw_softc, audio->index, &va);
|
||||||
|
if (err != 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
video_audio_to_v4l2_audio(&va, audio);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
video_get_audio(struct video_softc *sc, struct v4l2_audio *audio)
|
||||||
|
{
|
||||||
|
const struct video_hw_if *hw = sc->hw_if;
|
||||||
|
struct video_audio va;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (hw->get_audio == NULL)
|
||||||
|
return ENOTTY;
|
||||||
|
|
||||||
|
v4l2_audio_to_video_audio(audio, &va);
|
||||||
|
|
||||||
|
err = hw->get_audio(sc->hw_softc, &va);
|
||||||
|
if (err != 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
video_audio_to_v4l2_audio(&va, audio);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
video_set_audio(struct video_softc *sc, struct v4l2_audio *audio)
|
||||||
|
{
|
||||||
|
const struct video_hw_if *hw = sc->hw_if;
|
||||||
|
struct video_audio va;
|
||||||
|
|
||||||
|
if (hw->set_audio == NULL)
|
||||||
|
return ENOTTY;
|
||||||
|
|
||||||
|
v4l2_audio_to_video_audio(audio, &va);
|
||||||
|
|
||||||
|
return hw->set_audio(sc->hw_softc, &va);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
v4l2_tuner_to_video_tuner(const struct v4l2_tuner *tuner,
|
||||||
|
struct video_tuner *vt)
|
||||||
|
{
|
||||||
|
vt->index = tuner->index;
|
||||||
|
strlcpy(vt->name, tuner->name, sizeof(vt->name));
|
||||||
|
vt->freq_lo = tuner->rangelow;
|
||||||
|
vt->freq_hi = tuner->rangehigh;
|
||||||
|
vt->signal = tuner->signal;
|
||||||
|
vt->afc = tuner->afc;
|
||||||
|
vt->caps = 0;
|
||||||
|
if (tuner->capability & V4L2_TUNER_CAP_STEREO)
|
||||||
|
vt->caps |= VIDEO_TUNER_F_STEREO;
|
||||||
|
if (tuner->capability & V4L2_TUNER_CAP_LANG1)
|
||||||
|
vt->caps |= VIDEO_TUNER_F_LANG1;
|
||||||
|
if (tuner->capability & V4L2_TUNER_CAP_LANG2)
|
||||||
|
vt->caps |= VIDEO_TUNER_F_LANG2;
|
||||||
|
switch (tuner->audmode) {
|
||||||
|
case V4L2_TUNER_MODE_MONO:
|
||||||
|
vt->mode = VIDEO_TUNER_F_MONO;
|
||||||
|
break;
|
||||||
|
case V4L2_TUNER_MODE_STEREO:
|
||||||
|
vt->mode = VIDEO_TUNER_F_STEREO;
|
||||||
|
break;
|
||||||
|
case V4L2_TUNER_MODE_LANG1:
|
||||||
|
vt->mode = VIDEO_TUNER_F_LANG1;
|
||||||
|
break;
|
||||||
|
case V4L2_TUNER_MODE_LANG2:
|
||||||
|
vt->mode = VIDEO_TUNER_F_LANG2;
|
||||||
|
break;
|
||||||
|
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||||
|
vt->mode = VIDEO_TUNER_F_LANG1 | VIDEO_TUNER_F_LANG2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
video_tuner_to_v4l2_tuner(const struct video_tuner *vt,
|
||||||
|
struct v4l2_tuner *tuner)
|
||||||
|
{
|
||||||
|
tuner->index = vt->index;
|
||||||
|
strlcpy(tuner->name, vt->name, sizeof(tuner->name));
|
||||||
|
tuner->rangelow = vt->freq_lo;
|
||||||
|
tuner->rangehigh = vt->freq_hi;
|
||||||
|
tuner->signal = vt->signal;
|
||||||
|
tuner->afc = vt->afc;
|
||||||
|
tuner->capability = 0;
|
||||||
|
if (vt->caps & VIDEO_TUNER_F_STEREO)
|
||||||
|
tuner->capability |= V4L2_TUNER_CAP_STEREO;
|
||||||
|
if (vt->caps & VIDEO_TUNER_F_LANG1)
|
||||||
|
tuner->capability |= V4L2_TUNER_CAP_LANG1;
|
||||||
|
if (vt->caps & VIDEO_TUNER_F_LANG2)
|
||||||
|
tuner->capability |= V4L2_TUNER_CAP_LANG2;
|
||||||
|
switch (vt->mode) {
|
||||||
|
case VIDEO_TUNER_F_MONO:
|
||||||
|
tuner->audmode = V4L2_TUNER_MODE_MONO;
|
||||||
|
break;
|
||||||
|
case VIDEO_TUNER_F_STEREO:
|
||||||
|
tuner->audmode = V4L2_TUNER_MODE_STEREO;
|
||||||
|
break;
|
||||||
|
case VIDEO_TUNER_F_LANG1:
|
||||||
|
tuner->audmode = V4L2_TUNER_MODE_LANG1;
|
||||||
|
break;
|
||||||
|
case VIDEO_TUNER_F_LANG2:
|
||||||
|
tuner->audmode = V4L2_TUNER_MODE_LANG2;
|
||||||
|
break;
|
||||||
|
case VIDEO_TUNER_F_LANG1|VIDEO_TUNER_F_LANG2:
|
||||||
|
tuner->audmode = V4L2_TUNER_MODE_LANG1_LANG2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
video_get_tuner(struct video_softc *sc, struct v4l2_tuner *tuner)
|
||||||
|
{
|
||||||
|
const struct video_hw_if *hw = sc->hw_if;
|
||||||
|
struct video_tuner vt;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (hw->get_tuner == NULL)
|
||||||
|
return ENOTTY;
|
||||||
|
|
||||||
|
v4l2_tuner_to_video_tuner(tuner, &vt);
|
||||||
|
|
||||||
|
err = hw->get_tuner(sc->hw_softc, &vt);
|
||||||
|
if (err != 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
video_tuner_to_v4l2_tuner(&vt, tuner);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
video_set_tuner(struct video_softc *sc, struct v4l2_tuner *tuner)
|
||||||
|
{
|
||||||
|
const struct video_hw_if *hw = sc->hw_if;
|
||||||
|
struct video_tuner vt;
|
||||||
|
|
||||||
|
if (hw->set_tuner == NULL)
|
||||||
|
return ENOTTY;
|
||||||
|
|
||||||
|
v4l2_tuner_to_video_tuner(tuner, &vt);
|
||||||
|
|
||||||
|
return hw->set_tuner(sc->hw_softc, &vt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
video_get_frequency(struct video_softc *sc, struct v4l2_frequency *freq)
|
||||||
|
{
|
||||||
|
const struct video_hw_if *hw = sc->hw_if;
|
||||||
|
struct video_frequency vfreq;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (hw->get_frequency == NULL)
|
||||||
|
return ENOTTY;
|
||||||
|
|
||||||
|
err = hw->get_frequency(sc->hw_softc, &vfreq);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
freq->tuner = vfreq.tuner_index;
|
||||||
|
freq->type = V4L2_TUNER_ANALOG_TV;
|
||||||
|
freq->frequency = vfreq.frequency;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
video_set_frequency(struct video_softc *sc, struct v4l2_frequency *freq)
|
||||||
|
{
|
||||||
|
const struct video_hw_if *hw = sc->hw_if;
|
||||||
|
struct video_frequency vfreq;
|
||||||
|
|
||||||
|
if (hw->set_frequency == NULL)
|
||||||
|
return ENOTTY;
|
||||||
|
if (freq->type != V4L2_TUNER_ANALOG_TV)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
vfreq.tuner_index = freq->tuner;
|
||||||
|
vfreq.frequency = freq->frequency;
|
||||||
|
|
||||||
|
return hw->set_frequency(sc->hw_softc, &vfreq);
|
||||||
|
}
|
||||||
|
|
||||||
/* Takes a single Video4Linux2 control, converts it to a struct
|
/* Takes a single Video4Linux2 control, converts it to a struct
|
||||||
* video_control, and calls the hardware driver. */
|
* video_control, and calls the hardware driver. */
|
||||||
static int
|
static int
|
||||||
|
@ -1290,6 +1820,9 @@ videoioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
|
||||||
struct v4l2_format *fmt;
|
struct v4l2_format *fmt;
|
||||||
struct v4l2_standard *std;
|
struct v4l2_standard *std;
|
||||||
struct v4l2_input *input;
|
struct v4l2_input *input;
|
||||||
|
struct v4l2_audio *audio;
|
||||||
|
struct v4l2_tuner *tuner;
|
||||||
|
struct v4l2_frequency *freq;
|
||||||
struct v4l2_control *control;
|
struct v4l2_control *control;
|
||||||
struct v4l2_queryctrl *query;
|
struct v4l2_queryctrl *query;
|
||||||
struct v4l2_requestbuffers *reqbufs;
|
struct v4l2_requestbuffers *reqbufs;
|
||||||
|
@ -1322,6 +1855,11 @@ videoioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
|
||||||
if (hw->start_transfer != NULL && hw->stop_transfer != NULL)
|
if (hw->start_transfer != NULL && hw->stop_transfer != NULL)
|
||||||
cap->capabilities |= V4L2_CAP_VIDEO_CAPTURE |
|
cap->capabilities |= V4L2_CAP_VIDEO_CAPTURE |
|
||||||
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
|
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
|
||||||
|
if (hw->set_tuner != NULL && hw->get_tuner != NULL)
|
||||||
|
cap->capabilities |= V4L2_CAP_TUNER;
|
||||||
|
if (hw->set_audio != NULL && hw->get_audio != NULL &&
|
||||||
|
hw->enum_audio != NULL)
|
||||||
|
cap->capabilities |= V4L2_CAP_AUDIO;
|
||||||
return 0;
|
return 0;
|
||||||
case VIDIOC_ENUM_FMT:
|
case VIDIOC_ENUM_FMT:
|
||||||
/* TODO: for now, just enumerate one default format */
|
/* TODO: for now, just enumerate one default format */
|
||||||
|
@ -1331,7 +1869,7 @@ videoioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
|
||||||
return video_enum_format(sc, fmtdesc);
|
return video_enum_format(sc, fmtdesc);
|
||||||
case VIDIOC_G_FMT:
|
case VIDIOC_G_FMT:
|
||||||
fmt = data;
|
fmt = data;
|
||||||
return (video_get_format(sc, fmt));
|
return video_get_format(sc, fmt);
|
||||||
case VIDIOC_S_FMT:
|
case VIDIOC_S_FMT:
|
||||||
fmt = data;
|
fmt = data;
|
||||||
if ((flag & FWRITE) == 0)
|
if ((flag & FWRITE) == 0)
|
||||||
|
@ -1339,47 +1877,56 @@ videoioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
|
||||||
return video_set_format(sc, fmt);
|
return video_set_format(sc, fmt);
|
||||||
case VIDIOC_TRY_FMT:
|
case VIDIOC_TRY_FMT:
|
||||||
fmt = data;
|
fmt = data;
|
||||||
return (video_try_format(sc, fmt));
|
return video_try_format(sc, fmt);
|
||||||
case VIDIOC_ENUMSTD:
|
case VIDIOC_ENUMSTD:
|
||||||
/* TODO: implement properly */
|
|
||||||
std = data;
|
std = data;
|
||||||
if (std->index != 0)
|
return video_enum_standard(sc, std);
|
||||||
return EINVAL;
|
|
||||||
std->id = V4L2_STD_UNKNOWN;
|
|
||||||
strlcpy(std->name, "webcam", sizeof(std->name));
|
|
||||||
return 0;
|
|
||||||
case VIDIOC_G_STD:
|
case VIDIOC_G_STD:
|
||||||
/* TODO: implement properly */
|
|
||||||
stdid = data;
|
stdid = data;
|
||||||
*stdid = V4L2_STD_UNKNOWN;
|
return video_get_standard(sc, stdid);
|
||||||
return 0;
|
|
||||||
case VIDIOC_S_STD:
|
case VIDIOC_S_STD:
|
||||||
/* TODO: implement properly */
|
|
||||||
stdid = data;
|
stdid = data;
|
||||||
if (*stdid != V4L2_STD_UNKNOWN)
|
if ((flag & FWRITE) == 0)
|
||||||
return EINVAL;
|
return EPERM;
|
||||||
return 0;
|
return video_set_standard(sc, *stdid);
|
||||||
case VIDIOC_ENUMINPUT:
|
case VIDIOC_ENUMINPUT:
|
||||||
/* TODO: implement properly */
|
|
||||||
input = data;
|
input = data;
|
||||||
if (input->index != 0)
|
return video_enum_input(sc, input);
|
||||||
return EINVAL;
|
|
||||||
memset(input, 0, sizeof(*input));
|
|
||||||
input->index = 0;
|
|
||||||
strlcpy(input->name, "Camera", sizeof(input->name));
|
|
||||||
input->type = V4L2_INPUT_TYPE_CAMERA;
|
|
||||||
return 0;
|
|
||||||
case VIDIOC_G_INPUT:
|
case VIDIOC_G_INPUT:
|
||||||
/* TODO: implement properly */
|
|
||||||
ip = data;
|
ip = data;
|
||||||
*ip = 0;
|
return video_get_input(sc, ip);
|
||||||
return 0;
|
|
||||||
case VIDIOC_S_INPUT:
|
case VIDIOC_S_INPUT:
|
||||||
/* TODO: implement properly */
|
|
||||||
ip = data;
|
ip = data;
|
||||||
if (*ip != 0)
|
if ((flag & FWRITE) == 0)
|
||||||
return EINVAL;
|
return EPERM;
|
||||||
return 0;
|
return video_set_input(sc, *ip);
|
||||||
|
case VIDIOC_ENUMAUDIO:
|
||||||
|
audio = data;
|
||||||
|
return video_enum_audio(sc, audio);
|
||||||
|
case VIDIOC_G_AUDIO:
|
||||||
|
audio = data;
|
||||||
|
return video_get_audio(sc, audio);
|
||||||
|
case VIDIOC_S_AUDIO:
|
||||||
|
audio = data;
|
||||||
|
if ((flag & FWRITE) == 0)
|
||||||
|
return EPERM;
|
||||||
|
return video_set_audio(sc, audio);
|
||||||
|
case VIDIOC_G_TUNER:
|
||||||
|
tuner = data;
|
||||||
|
return video_get_tuner(sc, tuner);
|
||||||
|
case VIDIOC_S_TUNER:
|
||||||
|
tuner = data;
|
||||||
|
if ((flag & FWRITE) == 0)
|
||||||
|
return EPERM;
|
||||||
|
return video_set_tuner(sc, tuner);
|
||||||
|
case VIDIOC_G_FREQUENCY:
|
||||||
|
freq = data;
|
||||||
|
return video_get_frequency(sc, freq);
|
||||||
|
case VIDIOC_S_FREQUENCY:
|
||||||
|
freq = data;
|
||||||
|
if ((flag & FWRITE) == 0)
|
||||||
|
return EPERM;
|
||||||
|
return video_set_frequency(sc, freq);
|
||||||
case VIDIOC_QUERYCTRL:
|
case VIDIOC_QUERYCTRL:
|
||||||
query = data;
|
query = data;
|
||||||
return (video_query_control(sc, query));
|
return (video_query_control(sc, query));
|
||||||
|
@ -1937,8 +2484,10 @@ video_stream_write(struct video_stream *vs,
|
||||||
mutex_enter(&vs->vs_lock);
|
mutex_enter(&vs->vs_lock);
|
||||||
|
|
||||||
/* change of frameno implies end of current frame */
|
/* change of frameno implies end of current frame */
|
||||||
if (vs->vs_frameno > 0 && vs->vs_frameno != payload->frameno)
|
if (vs->vs_frameno >= 0 && vs->vs_frameno != payload->frameno)
|
||||||
video_stream_sample_done(vs);
|
video_stream_sample_done(vs);
|
||||||
|
|
||||||
|
vs->vs_frameno = payload->frameno;
|
||||||
|
|
||||||
if (vs->vs_drop || SIMPLEQ_EMPTY(&vs->vs_ingress)) {
|
if (vs->vs_drop || SIMPLEQ_EMPTY(&vs->vs_ingress)) {
|
||||||
/* DPRINTF(("video_stream_write: dropping sample %d\n",
|
/* DPRINTF(("video_stream_write: dropping sample %d\n",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: video_if.h,v 1.5 2008/09/20 18:13:40 jmcneill Exp $ */
|
/* $NetBSD: video_if.h,v 1.6 2010/12/14 03:25:16 jmcneill Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008 Patrick Mahoney <pat@polycrystal.org>
|
* Copyright (c) 2008 Patrick Mahoney <pat@polycrystal.org>
|
||||||
|
@ -199,6 +199,35 @@ enum video_pixel_format {
|
||||||
VIDEO_FORMAT_MPEG
|
VIDEO_FORMAT_MPEG
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* video standards */
|
||||||
|
enum video_standard {
|
||||||
|
VIDEO_STANDARD_PAL_B = 0x00000001,
|
||||||
|
VIDEO_STANDARD_PAL_B1 = 0x00000002,
|
||||||
|
VIDEO_STANDARD_PAL_G = 0x00000004,
|
||||||
|
VIDEO_STANDARD_PAL_H = 0x00000008,
|
||||||
|
VIDEO_STANDARD_PAL_I = 0x00000010,
|
||||||
|
VIDEO_STANDARD_PAL_D = 0x00000020,
|
||||||
|
VIDEO_STANDARD_PAL_D1 = 0x00000040,
|
||||||
|
VIDEO_STANDARD_PAL_K = 0x00000080,
|
||||||
|
VIDEO_STANDARD_PAL_M = 0x00000100,
|
||||||
|
VIDEO_STANDARD_PAL_N = 0x00000200,
|
||||||
|
VIDEO_STANDARD_PAL_Nc = 0x00000400,
|
||||||
|
VIDEO_STANDARD_PAL_60 = 0x00000800,
|
||||||
|
VIDEO_STANDARD_NTSC_M = 0x00001000,
|
||||||
|
VIDEO_STANDARD_NTSC_M_JP = 0x00002000,
|
||||||
|
VIDEO_STANDARD_NTSC_443 = 0x00004000,
|
||||||
|
VIDEO_STANDARD_NTSC_M_KR = 0x00008000,
|
||||||
|
VIDEO_STANDARD_SECAM_B = 0x00010000,
|
||||||
|
VIDEO_STANDARD_SECAM_D = 0x00020000,
|
||||||
|
VIDEO_STANDARD_SECAM_G = 0x00040000,
|
||||||
|
VIDEO_STANDARD_SECAM_H = 0x00080000,
|
||||||
|
VIDEO_STANDARD_SECAM_K = 0x00100000,
|
||||||
|
VIDEO_STANDARD_SECAM_K1 = 0x00200000,
|
||||||
|
VIDEO_STANDARD_SECAM_L = 0x00400000,
|
||||||
|
|
||||||
|
VIDEO_STANDARD_UNKNOWN = 0x00000000
|
||||||
|
};
|
||||||
|
|
||||||
/* interlace_flags bits are allocated like this:
|
/* interlace_flags bits are allocated like this:
|
||||||
7 6 5 4 3 2 1 0
|
7 6 5 4 3 2 1 0
|
||||||
\_/ | | |interlaced or progressive
|
\_/ | | |interlaced or progressive
|
||||||
|
@ -360,6 +389,66 @@ struct video_payload {
|
||||||
* payload in the frame. */
|
* payload in the frame. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* tuner frequency, frequencies are in units of 62.5 kHz */
|
||||||
|
struct video_frequency {
|
||||||
|
uint32_t tuner_index;
|
||||||
|
uint32_t frequency;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* video tuner capability flags */
|
||||||
|
#define VIDEO_TUNER_F_MONO (1 << 0)
|
||||||
|
#define VIDEO_TUNER_F_STEREO (1 << 1)
|
||||||
|
#define VIDEO_TUNER_F_LANG1 (1 << 2)
|
||||||
|
#define VIDEO_TUNER_F_LANG2 (1 << 3)
|
||||||
|
|
||||||
|
/* Video tuner definition */
|
||||||
|
struct video_tuner {
|
||||||
|
uint32_t index;
|
||||||
|
char name[32]; /* tuner name */
|
||||||
|
uint32_t freq_lo; /* lowest tunable frequency */
|
||||||
|
uint32_t freq_hi; /* highest tunable frequency */
|
||||||
|
uint32_t caps; /* capability flags */
|
||||||
|
uint32_t mode; /* audio mode flags */
|
||||||
|
uint32_t signal; /* signal strength */
|
||||||
|
int32_t afc; /* automatic frequency control */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Video input capability flags */
|
||||||
|
enum video_input_type {
|
||||||
|
VIDEO_INPUT_TYPE_TUNER, /* RF demodulator */
|
||||||
|
VIDEO_INPUT_TYPE_BASEBAND, /* analog baseband */
|
||||||
|
VIDEO_INPUT_TYPE_CAMERA = VIDEO_INPUT_TYPE_BASEBAND,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define VIDEO_STATUS_NO_POWER (1 << 0)
|
||||||
|
#define VIDEO_STATUS_NO_SIGNAL (1 << 1)
|
||||||
|
#define VIDEO_STATUS_NO_COLOR (1 << 2)
|
||||||
|
#define VIDEO_STATUS_NO_HLOCK (1 << 3)
|
||||||
|
#define VIDEO_STATUS_MACROVISION (1 << 4)
|
||||||
|
|
||||||
|
/* Video input definition */
|
||||||
|
struct video_input {
|
||||||
|
uint32_t index;
|
||||||
|
char name[32]; /* video input name */
|
||||||
|
enum video_input_type type; /* input type */
|
||||||
|
uint32_t audiomask; /* bitmask of assoc. audio inputs */
|
||||||
|
uint32_t tuner_index; /* tuner index if applicable */
|
||||||
|
uint64_t standards; /* all supported standards */
|
||||||
|
uint32_t status; /* input status */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Audio input capability flags */
|
||||||
|
#define VIDEO_AUDIO_F_STEREO (1 << 0)
|
||||||
|
#define VIDEO_AUDIO_F_AVL (1 << 1)
|
||||||
|
|
||||||
|
/* Audio input definition */
|
||||||
|
struct video_audio {
|
||||||
|
uint32_t index;
|
||||||
|
char name[32]; /* audio input name */
|
||||||
|
uint32_t caps; /* capabilities flags */
|
||||||
|
uint32_t mode; /* audio mode flags */
|
||||||
|
};
|
||||||
|
|
||||||
struct video_hw_if {
|
struct video_hw_if {
|
||||||
int (*open)(void *, int); /* open hardware */
|
int (*open)(void *, int); /* open hardware */
|
||||||
void (*close)(void *); /* close hardware */
|
void (*close)(void *); /* close hardware */
|
||||||
|
@ -371,6 +460,10 @@ struct video_hw_if {
|
||||||
int (*set_format)(void *, struct video_format *);
|
int (*set_format)(void *, struct video_format *);
|
||||||
int (*try_format)(void *, struct video_format *);
|
int (*try_format)(void *, struct video_format *);
|
||||||
|
|
||||||
|
int (*enum_standard)(void *, uint32_t, enum video_standard *);
|
||||||
|
int (*get_standard)(void *, enum video_standard *);
|
||||||
|
int (*set_standard)(void *, enum video_standard);
|
||||||
|
|
||||||
int (*start_transfer)(void *);
|
int (*start_transfer)(void *);
|
||||||
int (*stop_transfer)(void *);
|
int (*stop_transfer)(void *);
|
||||||
|
|
||||||
|
@ -380,6 +473,20 @@ struct video_hw_if {
|
||||||
struct video_control_desc_group *);
|
struct video_control_desc_group *);
|
||||||
int (*get_control_group)(void *, struct video_control_group *);
|
int (*get_control_group)(void *, struct video_control_group *);
|
||||||
int (*set_control_group)(void *, const struct video_control_group *);
|
int (*set_control_group)(void *, const struct video_control_group *);
|
||||||
|
|
||||||
|
int (*enum_input)(void *, uint32_t, struct video_input *);
|
||||||
|
int (*get_input)(void *, struct video_input *);
|
||||||
|
int (*set_input)(void *, struct video_input *);
|
||||||
|
|
||||||
|
int (*enum_audio)(void *, uint32_t, struct video_audio *);
|
||||||
|
int (*get_audio)(void *, struct video_audio *);
|
||||||
|
int (*set_audio)(void *, struct video_audio *);
|
||||||
|
|
||||||
|
int (*get_tuner)(void *, struct video_tuner *);
|
||||||
|
int (*set_tuner)(void *, struct video_tuner *);
|
||||||
|
|
||||||
|
int (*get_frequency)(void *, struct video_frequency *);
|
||||||
|
int (*set_frequency)(void *, struct video_frequency *);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct video_attach_args {
|
struct video_attach_args {
|
||||||
|
|
Loading…
Reference in New Issue