linux-v4l2: Use decoded MJPEG pixel format

Previously we assumed mjpeg was always decoded to 422 but it seems some
cameras provide frames that decode to different pixel formats such as
420.

This change delays setting the obs frame pixel format until after we
have decoded the v4l2 frame.

fixes #5821
This commit is contained in:
Kurt Kartaltepe 2022-02-14 17:14:02 -08:00 committed by Georges Basile Stavracas Neto
parent 2ded0f7050
commit 23feac1323
3 changed files with 19 additions and 12 deletions

View File

@ -79,8 +79,6 @@ static inline enum video_format v4l2_to_obs_video_format(uint_fast32_t format)
#endif
case V4L2_PIX_FMT_BGR24:
return VIDEO_FORMAT_BGR3;
case V4L2_PIX_FMT_MJPEG:
return VIDEO_FORMAT_I422;
default:
return VIDEO_FORMAT_NONE;
}

View File

@ -148,13 +148,6 @@ static void v4l2_prep_obs_frame(struct v4l2_data *data,
plane_offsets[1] = data->linesize * data->height;
plane_offsets[2] = data->linesize * data->height * 5 / 4;
break;
case V4L2_PIX_FMT_MJPEG:
frame->linesize[0] = 0;
frame->linesize[1] = 0;
frame->linesize[2] = 0;
plane_offsets[1] = 0;
plane_offsets[2] = 0;
break;
default:
frame->linesize[0] = data->linesize;
break;
@ -479,7 +472,8 @@ static void v4l2_format_list(int dev, obs_property_t *prop)
dstr_cat(&buffer, " (Emulated)");
if (v4l2_to_obs_video_format(fmt.pixelformat) !=
VIDEO_FORMAT_NONE) {
VIDEO_FORMAT_NONE ||
fmt.pixelformat == V4L2_PIX_FMT_MJPEG) {
obs_property_list_add_int(prop, buffer.array,
fmt.pixelformat);
blog(LOG_INFO, "Pixelformat: %s (available)",
@ -1003,7 +997,8 @@ static void v4l2_init(struct v4l2_data *data)
blog(LOG_ERROR, "Unable to set format");
goto fail;
}
if (v4l2_to_obs_video_format(data->pixfmt) == VIDEO_FORMAT_NONE) {
if (v4l2_to_obs_video_format(data->pixfmt) == VIDEO_FORMAT_NONE &&
data->pixfmt != V4L2_PIX_FMT_MJPEG) {
blog(LOG_ERROR, "Selected video format not supported");
goto fail;
}

View File

@ -45,7 +45,6 @@ int v4l2_init_mjpeg(struct v4l2_mjpeg_decoder *decoder)
}
decoder->context->flags2 |= AV_CODEC_FLAG2_FAST;
decoder->context->pix_fmt = AV_PIX_FMT_YUVJ422P;
if (avcodec_open2(decoder->context, decoder->codec, NULL) < 0) {
blog(LOG_ERROR, "failed to open codec");
@ -94,5 +93,20 @@ int v4l2_decode_mjpeg(struct obs_source_frame *out, uint8_t *data,
out->linesize[i] = decoder->frame->linesize[i];
}
switch (decoder->context->pix_fmt) {
case AV_PIX_FMT_YUVJ422P:
case AV_PIX_FMT_YUV422P:
out->format = VIDEO_FORMAT_I422;
break;
case AV_PIX_FMT_YUVJ420P:
case AV_PIX_FMT_YUV420P:
out->format = VIDEO_FORMAT_I420;
break;
case AV_PIX_FMT_YUVJ444P:
case AV_PIX_FMT_YUV444P:
out->format = VIDEO_FORMAT_I444;
break;
}
return 0;
}