提交 908a165d 编写于 作者: J jp9000

Add planar YUV 4:4:4 format support

Adds the ability to natively output with planar YUV 4:4:4.
上级 822d1ec3
......@@ -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");
}
......
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册