From 7bb6898b16f3c5b1cd5c4c15ca96278df569ccd2 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Tue, 27 Aug 2019 17:21:36 -0700 Subject: [PATCH] avcodec/v4l2_m2m: fix av_pix_fmt changing when multiple /dev/video* devices are probed On the RPI, three different /dev/video devices exist (decoder, scaler, encoder). When probing the devices in order, the originally requested pix fmt would be mutated causing the wrong one to be chosen when a matching device was finally found. Signed-off-by: Aman Gupta --- libavcodec/v4l2_context.c | 4 ++-- libavcodec/v4l2_context.h | 3 ++- libavcodec/v4l2_m2m.c | 10 +++++----- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index 6924760840..3f8a510331 100644 --- a/libavcodec/v4l2_context.c +++ b/libavcodec/v4l2_context.c @@ -621,7 +621,7 @@ int ff_v4l2_context_dequeue_packet(V4L2Context* ctx, AVPacket* pkt) return ff_v4l2_buffer_buf_to_avpkt(pkt, avbuf); } -int ff_v4l2_context_get_format(V4L2Context* ctx) +int ff_v4l2_context_get_format(V4L2Context* ctx, int probe) { struct v4l2_format_update fmt = { 0 }; int ret; @@ -631,7 +631,7 @@ int ff_v4l2_context_get_format(V4L2Context* ctx) if (ret) return ret; - fmt.update_avfmt = 1; + fmt.update_avfmt = !probe; v4l2_save_to_context(ctx, &fmt); /* format has been tried already */ diff --git a/libavcodec/v4l2_context.h b/libavcodec/v4l2_context.h index 632f1d0aac..ee08f3de41 100644 --- a/libavcodec/v4l2_context.h +++ b/libavcodec/v4l2_context.h @@ -113,9 +113,10 @@ int ff_v4l2_context_set_format(V4L2Context* ctx); * Queries the driver for a valid v4l2 format and copies it to the context. * * @param[in] ctx A pointer to a V4L2Context. See V4L2Context description for required variables. + * @param[in] probe Probe only and ignore changes to the format. * @return 0 in case of success, a negative value representing the error otherwise. */ -int ff_v4l2_context_get_format(V4L2Context* ctx); +int ff_v4l2_context_get_format(V4L2Context* ctx, int probe); /** * Releases a V4L2Context. diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c index 0cf5db284a..827662b9a5 100644 --- a/libavcodec/v4l2_m2m.c +++ b/libavcodec/v4l2_m2m.c @@ -108,13 +108,13 @@ static int v4l2_probe_driver(V4L2m2mContext* s) if (ret < 0) goto done; - ret = ff_v4l2_context_get_format(&s->output); + ret = ff_v4l2_context_get_format(&s->output, 1); if (ret) { av_log(s->avctx, AV_LOG_DEBUG, "v4l2 output format not supported\n"); goto done; } - ret = ff_v4l2_context_get_format(&s->capture); + ret = ff_v4l2_context_get_format(&s->capture, 1); if (ret) { av_log(s->avctx, AV_LOG_DEBUG, "v4l2 capture format not supported\n"); goto done; @@ -222,7 +222,7 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mContext* s) ff_v4l2_context_release(&s->capture); /* 3. get the new capture format */ - ret = ff_v4l2_context_get_format(&s->capture); + ret = ff_v4l2_context_get_format(&s->capture, 0); if (ret) { av_log(s->avctx, AV_LOG_ERROR, "query the new capture format\n"); return ret; @@ -273,13 +273,13 @@ int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s) s->draining = 0; s->reinit = 0; - ret = ff_v4l2_context_get_format(&s->output); + ret = ff_v4l2_context_get_format(&s->output, 0); if (ret) { av_log(log_ctx, AV_LOG_DEBUG, "v4l2 output format not supported\n"); goto error; } - ret = ff_v4l2_context_get_format(&s->capture); + ret = ff_v4l2_context_get_format(&s->capture, 0); if (ret) { av_log(log_ctx, AV_LOG_DEBUG, "v4l2 capture format not supported\n"); goto error;