Skip to content

libobs: Add UYVA pixel format support #12125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/sphinx/reference-outputs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,7 @@ Functions used by outputs
VIDEO_FORMAT_YVYU,
VIDEO_FORMAT_YUY2, /* YUYV */
VIDEO_FORMAT_UYVY,
VIDEO_FORMAT_UYVA, /* two-plane, packed luma/chroma like UYVY and then alpha plane */

/* packed uncompressed formats */
VIDEO_FORMAT_RGBA,
Expand Down
1 change: 1 addition & 0 deletions docs/sphinx/reference-sources.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1560,6 +1560,7 @@ Functions used by sources
VIDEO_FORMAT_YVYU,
VIDEO_FORMAT_YUY2, /* YUYV */
VIDEO_FORMAT_UYVY,
VIDEO_FORMAT_UYVA, /* two-plane, packed luma/chroma like UYVY and then alpha plane */

/* packed uncompressed formats */
VIDEO_FORMAT_RGBA,
Expand Down
2 changes: 2 additions & 0 deletions frontend/widgets/OBSBasic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1458,6 +1458,8 @@ static inline enum video_format GetVideoFormatFromName(const char *name)
return VIDEO_FORMAT_YUY2;
else if (astrcmpi(name, "UYVY") == 0)
return VIDEO_FORMAT_UYVY;
else if (astrcmpi(name, "UYVA") == 0)
return VIDEO_FORMAT_UYVA;
#endif
else
return VIDEO_FORMAT_BGRA;
Expand Down
22 changes: 22 additions & 0 deletions libobs/data/format_conversion.effect
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,19 @@ float3 PSUYVY_Reverse(FragTexTex frag_in) : TARGET
return rgb;
}

float4 PSUYVA_Reverse(VertTexTexPos frag_in) : TARGET
{
float2 y01 = image.Load(int3(frag_in.uvuv.xy, 0)).yw;
float2 cbcr = image.Sample(def_sampler, frag_in.uvuv.zw, 0.0).zx;
float leftover = frac(frag_in.uvuv.x);
float y = (leftover < 0.5) ? y01.x : y01.y;
float3 yuv = float3(y, cbcr);
float3 rgb = YUV_to_RGB(yuv);

float alpha = image1.Load(int3(frag_in.uvuv.x * 2, frag_in.uvuv.y, 0)).x;
return float4(rgb, alpha);
}

float3 PSYUY2_Reverse(FragTexTex frag_in) : TARGET
{
float2 y01 = image.Load(int3(frag_in.uvuv.xy, 0)).zx;
Expand Down Expand Up @@ -1435,6 +1448,15 @@ technique UYVY_Reverse
}
}

technique UYVA_Reverse
{
pass
{
vertex_shader = VSPacked422Left_Reverse(id);
pixel_shader = PSUYVA_Reverse(frag_in);
}
}

technique YUY2_Reverse
{
pass
Expand Down
3 changes: 3 additions & 0 deletions libobs/media-io/video-fourcc.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ enum video_format video_format_from_fourcc(uint32_t fourcc)

case MAKE_FOURCC('Y', '8', '0', '0'):
return VIDEO_FORMAT_Y800;

case MAKE_FOURCC('U', 'Y', 'V', 'A'):
return VIDEO_FORMAT_UYVA;
}
return VIDEO_FORMAT_NONE;
}
5 changes: 5 additions & 0 deletions libobs/media-io/video-frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ void video_frame_get_linesizes(uint32_t linesize[MAX_AV_PLANES], enum video_form
case VIDEO_FORMAT_UYVY:
linesize[0] = width * 2;
break;
case VIDEO_FORMAT_UYVA: /* two planes: one double width, one single width */
linesize[0] = width * 2;
linesize[1] = width;
break;
case VIDEO_FORMAT_P010: /* two planes: all double width */
case VIDEO_FORMAT_P216:
linesize[0] = width * 2;
Expand Down Expand Up @@ -181,6 +185,7 @@ void video_frame_get_plane_heights(uint32_t heights[MAX_AV_PLANES], enum video_f

case VIDEO_FORMAT_P216: /* two planes: all full height */
case VIDEO_FORMAT_P416:
case VIDEO_FORMAT_UYVA:
heights[0] = height;
heights[1] = height;
break;
Expand Down
6 changes: 6 additions & 0 deletions libobs/media-io/video-io.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ enum video_format {

/* packed uncompressed 10-bit format */
VIDEO_FORMAT_R10L,

/* two-plane, packed luma/chroma like UYVY and then alpha plane */
VIDEO_FORMAT_UYVA,
};

enum video_trc {
Expand Down Expand Up @@ -148,6 +151,7 @@ static inline bool format_is_yuv(enum video_format format)
case VIDEO_FORMAT_YVYU:
case VIDEO_FORMAT_YUY2:
case VIDEO_FORMAT_UYVY:
case VIDEO_FORMAT_UYVA:
case VIDEO_FORMAT_I444:
case VIDEO_FORMAT_I412:
case VIDEO_FORMAT_I40A:
Expand Down Expand Up @@ -191,6 +195,8 @@ static inline const char *get_video_format_name(enum video_format format)
return "YUY2";
case VIDEO_FORMAT_UYVY:
return "UYVY";
case VIDEO_FORMAT_UYVA:
return "UYVA";
case VIDEO_FORMAT_RGBA:
return "RGBA";
case VIDEO_FORMAT_BGRA:
Expand Down
1 change: 1 addition & 0 deletions libobs/obs-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,7 @@ static inline enum gs_color_format convert_video_format(enum video_format format
case VIDEO_FORMAT_I42A:
case VIDEO_FORMAT_YUVA:
case VIDEO_FORMAT_AYUV:
case VIDEO_FORMAT_UYVA:
return GS_BGRA;
case VIDEO_FORMAT_I010:
case VIDEO_FORMAT_P010:
Expand Down
31 changes: 31 additions & 0 deletions libobs/obs-source.c
Original file line number Diff line number Diff line change
Expand Up @@ -1561,6 +1561,7 @@ enum convert_type {
CONVERT_422P10LE,
CONVERT_422_A,
CONVERT_422_PACK,
CONVERT_422_PACK_A,
CONVERT_444,
CONVERT_444P12LE,
CONVERT_444_A,
Expand Down Expand Up @@ -1596,6 +1597,9 @@ static inline enum convert_type get_convert_type(enum video_format format, bool
case VIDEO_FORMAT_UYVY:
return CONVERT_422_PACK;

case VIDEO_FORMAT_UYVA:
return CONVERT_422_PACK_A;

case VIDEO_FORMAT_Y800:
return CONVERT_800;

Expand Down Expand Up @@ -1656,6 +1660,21 @@ static inline bool set_packed422_sizes(struct obs_source *source, const struct o
return true;
}

static inline bool set_packed422_sep_alpha_sizes(struct obs_source *source, const struct obs_source_frame *frame)
{
const uint32_t width = frame->width;
const uint32_t height = frame->height;
const uint32_t half_width = (width + 1) / 2;
source->async_convert_width[0] = half_width;
source->async_convert_height[0] = height;
source->async_texture_formats[0] = GS_BGRA;
source->async_convert_width[1] = width;
source->async_convert_height[1] = height;
source->async_texture_formats[1] = GS_R8;
source->async_channel_count = 2;
return true;
}

static inline bool set_packed444_alpha_sizes(struct obs_source *source, const struct obs_source_frame *frame)
{
source->async_convert_width[0] = frame->width;
Expand Down Expand Up @@ -1933,6 +1952,9 @@ static inline bool init_gpu_conversion(struct obs_source *source, const struct o
case CONVERT_422_PACK:
return set_packed422_sizes(source, frame);

case CONVERT_422_PACK_A:
return set_packed422_sep_alpha_sizes(source, frame);

case CONVERT_420:
case CONVERT_420_PQ:
return set_planar420_sizes(source, frame);
Expand Down Expand Up @@ -2050,6 +2072,7 @@ static void upload_raw_frame(gs_texture_t *tex[MAX_AV_PLANES], const struct obs_
{
switch (get_convert_type(frame->format, frame->full_range, frame->trc)) {
case CONVERT_422_PACK:
case CONVERT_422_PACK_A:
case CONVERT_800:
case CONVERT_RGB_LIMITED:
case CONVERT_BGR3:
Expand Down Expand Up @@ -2087,6 +2110,9 @@ static const char *select_conversion_technique(enum video_format format, bool fu
case VIDEO_FORMAT_UYVY:
return "UYVY_Reverse";

case VIDEO_FORMAT_UYVA:
return "UYVA_Reverse";

case VIDEO_FORMAT_YUY2:
switch (trc) {
case VIDEO_TRC_PQ:
Expand Down Expand Up @@ -3324,6 +3350,11 @@ static void copy_frame_data(struct obs_source_frame *dst, const struct obs_sourc
copy_frame_data_plane(dst, src, 0, dst->height);
break;

case VIDEO_FORMAT_UYVA:
copy_frame_data_plane(dst, src, 0, dst->height);
copy_frame_data_plane(dst, src, 1, dst->height);
break;

case VIDEO_FORMAT_I40A: {
const uint32_t height = dst->height;
const uint32_t half_height = (height + 1) / 2;
Expand Down
1 change: 1 addition & 0 deletions libobs/obs-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,7 @@ static void set_gpu_converted_data(struct video_frame *output, const struct vide
case VIDEO_FORMAT_YVYU:
case VIDEO_FORMAT_YUY2:
case VIDEO_FORMAT_UYVY:
case VIDEO_FORMAT_UYVA:
case VIDEO_FORMAT_RGBA:
case VIDEO_FORMAT_BGRA:
case VIDEO_FORMAT_BGRX:
Expand Down
Loading