Commit b3da2692 authored by Anton Khirnov's avatar Anton Khirnov

v4l2: add a private option for video standard.

parent a861ffef
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
#include <time.h> #include <time.h>
#include <strings.h> #include <strings.h>
#include "libavutil/imgutils.h" #include "libavutil/imgutils.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"
static const int desired_video_buffers = 256; static const int desired_video_buffers = 256;
...@@ -54,6 +56,7 @@ enum io_method { ...@@ -54,6 +56,7 @@ enum io_method {
}; };
struct video_data { struct video_data {
AVClass *class;
int fd; int fd;
int frame_format; /* V4L2_PIX_FMT_* */ int frame_format; /* V4L2_PIX_FMT_* */
enum io_method io_method; enum io_method io_method;
...@@ -64,6 +67,7 @@ struct video_data { ...@@ -64,6 +67,7 @@ struct video_data {
int buffers; int buffers;
void **buf_start; void **buf_start;
unsigned int *buf_len; unsigned int *buf_len;
char *standard;
}; };
struct buff_data { struct buff_data {
...@@ -467,31 +471,37 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap) ...@@ -467,31 +471,37 @@ static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
} }
if (ap->standard) { if (ap->standard) {
av_freep(&s->standard);
s->standard = av_strdup(ap->standard);
}
if (s->standard) {
av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n", av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n",
ap->standard); s->standard);
/* set tv standard */ /* set tv standard */
memset (&standard, 0, sizeof (standard)); memset (&standard, 0, sizeof (standard));
for(i=0;;i++) { for(i=0;;i++) {
standard.index = i; standard.index = i;
if (ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) { if (ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set standard(%s) failed\n", av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set standard(%s) failed\n",
ap->standard); s->standard);
return AVERROR(EIO); return AVERROR(EIO);
} }
if (!strcasecmp(standard.name, ap->standard)) { if (!strcasecmp(standard.name, s->standard)) {
break; break;
} }
} }
av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s, id: %"PRIu64"\n", av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s, id: %"PRIu64"\n",
ap->standard, (uint64_t)standard.id); s->standard, (uint64_t)standard.id);
if (ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) { if (ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set standard(%s) failed\n", av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set standard(%s) failed\n",
ap->standard); s->standard);
return AVERROR(EIO); return AVERROR(EIO);
} }
} }
av_freep(&s->standard);
if (ap->time_base.num && ap->time_base.den) { if (ap->time_base.num && ap->time_base.den) {
av_log(s1, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n", av_log(s1, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n",
...@@ -680,6 +690,18 @@ static int v4l2_read_close(AVFormatContext *s1) ...@@ -680,6 +690,18 @@ static int v4l2_read_close(AVFormatContext *s1)
return 0; return 0;
} }
static const AVOption options[] = {
{ "standard", "", offsetof(struct video_data, standard), FF_OPT_TYPE_STRING, {.str = "NTSC" }, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
{ NULL },
};
static const AVClass v4l2_class = {
.class_name = "V4L2 indev",
.item_name = av_default_item_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
};
AVInputFormat ff_v4l2_demuxer = { AVInputFormat ff_v4l2_demuxer = {
"video4linux2", "video4linux2",
NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"), NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
...@@ -689,4 +711,5 @@ AVInputFormat ff_v4l2_demuxer = { ...@@ -689,4 +711,5 @@ AVInputFormat ff_v4l2_demuxer = {
v4l2_read_packet, v4l2_read_packet,
v4l2_read_close, v4l2_read_close,
.flags = AVFMT_NOFILE, .flags = AVFMT_NOFILE,
.priv_class = &v4l2_class,
}; };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment