mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 04:42:18 +02:00
Add planar YUV 4:4:4 format support
Adds the ability to natively output with planar YUV 4:4:4.
This commit is contained in:
parent
822d1ec3fc
commit
908a165d62
@ -83,6 +83,17 @@ void video_frame_init(struct video_frame *frame, enum video_format format,
|
||||
frame->data[0] = bmalloc(size);
|
||||
frame->linesize[0] = width*4;
|
||||
break;
|
||||
|
||||
case VIDEO_FORMAT_I444:
|
||||
size = width * height;
|
||||
ALIGN_SIZE(size, alignment);
|
||||
frame->data[0] = bmalloc(size * 3);
|
||||
frame->data[1] = (uint8_t*)frame->data[0] + size;
|
||||
frame->data[2] = (uint8_t*)frame->data[1] + size;
|
||||
frame->linesize[0] = width;
|
||||
frame->linesize[1] = width;
|
||||
frame->linesize[2] = width;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,5 +123,11 @@ void video_frame_copy(struct video_frame *dst, const struct video_frame *src,
|
||||
case VIDEO_FORMAT_BGRX:
|
||||
memcpy(dst->data[0], src->data[0], src->linesize[0] * cy);
|
||||
break;
|
||||
|
||||
case VIDEO_FORMAT_I444:
|
||||
memcpy(dst->data[0], src->data[0], src->linesize[0] * cy);
|
||||
memcpy(dst->data[1], src->data[1], src->linesize[1] * cy);
|
||||
memcpy(dst->data[2], src->data[2], src->linesize[2] * cy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,9 @@ enum video_format {
|
||||
VIDEO_FORMAT_RGBA,
|
||||
VIDEO_FORMAT_BGRA,
|
||||
VIDEO_FORMAT_BGRX,
|
||||
|
||||
/* planar 4:4:4 */
|
||||
VIDEO_FORMAT_I444,
|
||||
};
|
||||
|
||||
enum video_colorspace {
|
||||
@ -88,6 +91,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_I444:
|
||||
return true;
|
||||
case VIDEO_FORMAT_NONE:
|
||||
case VIDEO_FORMAT_RGBA:
|
||||
|
@ -38,6 +38,7 @@ static inline enum AVPixelFormat get_ffmpeg_video_format(
|
||||
case VIDEO_FORMAT_RGBA: return AV_PIX_FMT_RGBA;
|
||||
case VIDEO_FORMAT_BGRA: return AV_PIX_FMT_BGRA;
|
||||
case VIDEO_FORMAT_BGRX: return AV_PIX_FMT_BGRA;
|
||||
case VIDEO_FORMAT_I444: return AV_PIX_FMT_YUV444P;
|
||||
}
|
||||
|
||||
return AV_PIX_FMT_NONE;
|
||||
|
@ -791,6 +791,7 @@ static inline enum convert_type get_convert_type(enum video_format format)
|
||||
case VIDEO_FORMAT_UYVY:
|
||||
return CONVERT_422_U;
|
||||
|
||||
case VIDEO_FORMAT_I444:
|
||||
case VIDEO_FORMAT_NONE:
|
||||
case VIDEO_FORMAT_RGBA:
|
||||
case VIDEO_FORMAT_BGRA:
|
||||
@ -963,6 +964,7 @@ static const char *select_conversion_technique(enum video_format format)
|
||||
case VIDEO_FORMAT_BGRX:
|
||||
case VIDEO_FORMAT_RGBA:
|
||||
case VIDEO_FORMAT_NONE:
|
||||
case VIDEO_FORMAT_I444:
|
||||
assert(false && "No conversion requested");
|
||||
break;
|
||||
}
|
||||
@ -1598,6 +1600,12 @@ static void copy_frame_data(struct obs_source_frame *dst,
|
||||
copy_frame_data_plane(dst, src, 1, dst->height/2);
|
||||
break;
|
||||
|
||||
case VIDEO_FORMAT_I444:
|
||||
copy_frame_data_plane(dst, src, 0, dst->height);
|
||||
copy_frame_data_plane(dst, src, 1, dst->height);
|
||||
copy_frame_data_plane(dst, src, 2, dst->height);
|
||||
break;
|
||||
|
||||
case VIDEO_FORMAT_YVYU:
|
||||
case VIDEO_FORMAT_YUY2:
|
||||
case VIDEO_FORMAT_UYVY:
|
||||
|
@ -457,6 +457,12 @@ static void convert_frame(
|
||||
0, info->height,
|
||||
output->data, output->linesize);
|
||||
|
||||
} else if (info->format == VIDEO_FORMAT_I444) {
|
||||
convert_uyvx_to_i444(
|
||||
input->data[0], input->linesize[0],
|
||||
0, info->height,
|
||||
output->data, output->linesize);
|
||||
|
||||
} else {
|
||||
blog(LOG_ERROR, "convert_frame: unsupported texture format");
|
||||
}
|
||||
|
34
libobs/obs.c
34
libobs/obs.c
@ -118,6 +118,37 @@ static inline void set_nv12_sizes(const struct obs_video_info *ovi)
|
||||
video->conversion_tech = "NV12";
|
||||
}
|
||||
|
||||
static inline void set_444p_sizes(const struct obs_video_info *ovi)
|
||||
{
|
||||
struct obs_core_video *video = &obs->video;
|
||||
uint32_t chroma_pixels;
|
||||
uint32_t total_bytes;
|
||||
|
||||
chroma_pixels = (ovi->output_width * ovi->output_height);
|
||||
chroma_pixels = GET_ALIGN(chroma_pixels, PIXEL_SIZE);
|
||||
|
||||
video->plane_offsets[0] = 0;
|
||||
video->plane_offsets[1] = chroma_pixels;
|
||||
video->plane_offsets[2] = chroma_pixels + chroma_pixels;
|
||||
|
||||
video->plane_linewidth[0] = ovi->output_width;
|
||||
video->plane_linewidth[1] = ovi->output_width;
|
||||
video->plane_linewidth[2] = ovi->output_width;
|
||||
|
||||
video->plane_sizes[0] = chroma_pixels;
|
||||
video->plane_sizes[1] = chroma_pixels;
|
||||
video->plane_sizes[2] = chroma_pixels;
|
||||
|
||||
total_bytes = video->plane_offsets[2] + chroma_pixels;
|
||||
|
||||
video->conversion_height =
|
||||
(total_bytes/PIXEL_SIZE + ovi->output_width-1) /
|
||||
ovi->output_width;
|
||||
|
||||
video->conversion_height = GET_ALIGN(video->conversion_height, 2);
|
||||
video->conversion_tech = "Planar444";
|
||||
}
|
||||
|
||||
static inline void calc_gpu_conversion_sizes(const struct obs_video_info *ovi)
|
||||
{
|
||||
obs->video.conversion_height = 0;
|
||||
@ -133,6 +164,9 @@ static inline void calc_gpu_conversion_sizes(const struct obs_video_info *ovi)
|
||||
case VIDEO_FORMAT_NV12:
|
||||
set_nv12_sizes(ovi);
|
||||
break;
|
||||
case VIDEO_FORMAT_I444:
|
||||
set_444p_sizes(ovi);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ static inline enum AVPixelFormat obs_to_ffmpeg_video_format(
|
||||
{
|
||||
switch (format) {
|
||||
case VIDEO_FORMAT_NONE: return AV_PIX_FMT_NONE;
|
||||
case VIDEO_FORMAT_I444: return AV_PIX_FMT_YUV444P;
|
||||
case VIDEO_FORMAT_I420: return AV_PIX_FMT_YUV420P;
|
||||
case VIDEO_FORMAT_NV12: return AV_PIX_FMT_NV12;
|
||||
case VIDEO_FORMAT_YVYU: return AV_PIX_FMT_NONE;
|
||||
@ -29,6 +30,7 @@ static inline enum video_format ffmpeg_to_obs_video_format(
|
||||
enum AVPixelFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
case AV_PIX_FMT_YUV444P: return VIDEO_FORMAT_I444;
|
||||
case AV_PIX_FMT_YUV420P: return VIDEO_FORMAT_I420;
|
||||
case AV_PIX_FMT_NV12: return VIDEO_FORMAT_NV12;
|
||||
case AV_PIX_FMT_YUYV422: return VIDEO_FORMAT_YUY2;
|
||||
|
Loading…
Reference in New Issue
Block a user