mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-02 03:06:28 +02:00
lavd/v4l2: select input immediately after opening the device
After opening the device, the first thing we should do is selecting the input. This is because the image formats (VIDIOC_ENUM_FMT ioctl) and the standards (VIDIOC_ENUMSTD ioctl) supported may depend on the selected input ([1] and [2]). [1] http://linuxtv.org/downloads/v4l-dvb-apis/vidioc-enum-fmt.html [2] http://linuxtv.org/downloads/v4l-dvb-apis/vidioc-enumstd.html Signed-off-by: Stefano Sabatini <stefasab@gmail.com>
This commit is contained in:
parent
5306976be8
commit
93d319a582
@ -112,6 +112,7 @@ struct video_data {
|
|||||||
void **buf_start;
|
void **buf_start;
|
||||||
unsigned int *buf_len;
|
unsigned int *buf_len;
|
||||||
char *standard;
|
char *standard;
|
||||||
|
v4l2_std_id std_id;
|
||||||
int channel;
|
int channel;
|
||||||
char *pixel_format; /**< Set by a private option. */
|
char *pixel_format; /**< Set by a private option. */
|
||||||
int list_format; /**< Set by a private option. */
|
int list_format; /**< Set by a private option. */
|
||||||
@ -655,7 +656,6 @@ static void mmap_close(struct video_data *s)
|
|||||||
static int v4l2_set_parameters(AVFormatContext *s1)
|
static int v4l2_set_parameters(AVFormatContext *s1)
|
||||||
{
|
{
|
||||||
struct video_data *s = s1->priv_data;
|
struct video_data *s = s1->priv_data;
|
||||||
struct v4l2_input input = { 0 };
|
|
||||||
struct v4l2_standard standard = { 0 };
|
struct v4l2_standard standard = { 0 };
|
||||||
struct v4l2_streamparm streamparm = { 0 };
|
struct v4l2_streamparm streamparm = { 0 };
|
||||||
struct v4l2_fract *tpf = &streamparm.parm.capture.timeperframe;
|
struct v4l2_fract *tpf = &streamparm.parm.capture.timeperframe;
|
||||||
@ -671,22 +671,6 @@ static int v4l2_set_parameters(AVFormatContext *s1)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set tv video input */
|
|
||||||
input.index = s->channel;
|
|
||||||
if (v4l2_ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
|
|
||||||
av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl enum input failed:\n");
|
|
||||||
return AVERROR(EIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n",
|
|
||||||
s->channel, input.name);
|
|
||||||
if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &input.index) < 0) {
|
|
||||||
av_log(s1, AV_LOG_ERROR,
|
|
||||||
"The V4L2 driver ioctl set input(%d) failed\n",
|
|
||||||
s->channel);
|
|
||||||
return AVERROR(EIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->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",
|
||||||
s->standard);
|
s->standard);
|
||||||
@ -807,6 +791,7 @@ static int v4l2_read_header(AVFormatContext *s1)
|
|||||||
uint32_t desired_format;
|
uint32_t desired_format;
|
||||||
enum AVCodecID codec_id = AV_CODEC_ID_NONE;
|
enum AVCodecID codec_id = AV_CODEC_ID_NONE;
|
||||||
enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
|
enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
|
||||||
|
struct v4l2_input input = { 0 };
|
||||||
|
|
||||||
st = avformat_new_stream(s1, NULL);
|
st = avformat_new_stream(s1, NULL);
|
||||||
if (!st)
|
if (!st)
|
||||||
@ -816,6 +801,24 @@ static int v4l2_read_header(AVFormatContext *s1)
|
|||||||
if (s->fd < 0)
|
if (s->fd < 0)
|
||||||
return s->fd;
|
return s->fd;
|
||||||
|
|
||||||
|
/* set tv video input */
|
||||||
|
av_log(s1, AV_LOG_DEBUG, "Selecting input_channel: %d\n", s->channel);
|
||||||
|
if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &s->channel) < 0) {
|
||||||
|
res = errno;
|
||||||
|
av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_S_INPUT): %s\n", strerror(errno));
|
||||||
|
return AVERROR(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
input.index = s->channel;
|
||||||
|
if (v4l2_ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
|
||||||
|
res = errno;
|
||||||
|
av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_ENUMINPUT): %s\n", strerror(errno));
|
||||||
|
return AVERROR(res);
|
||||||
|
}
|
||||||
|
s->std_id = input.std;
|
||||||
|
av_log(s1, AV_LOG_DEBUG, "input_channel: %d, input_name: %s\n",
|
||||||
|
s->channel, input.name);
|
||||||
|
|
||||||
if (s->list_format) {
|
if (s->list_format) {
|
||||||
list_formats(s1, s->fd, s->list_format);
|
list_formats(s1, s->fd, s->list_format);
|
||||||
return AVERROR_EXIT;
|
return AVERROR_EXIT;
|
||||||
|
Loading…
Reference in New Issue
Block a user