From bdf389099c4e5894c010c331d18663ab8b741e6c Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Tue, 10 Jan 2023 15:54:42 +0100 Subject: [PATCH] vc_deinterlace_ex: basic check if pixfmt is supported + use&check it in GL/SDL/deinterlace pp/double_framerate pp --- src/video_codec.c | 9 ++++++++- src/video_codec.h | 2 +- src/video_display/gl.cpp | 15 +++++++++------ src/video_display/sdl2.cpp | 5 ++++- src/vo_postprocess/deinterlace.c | 2 +- src/vo_postprocess/double-framerate.cpp | 8 +++++++- 6 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/video_codec.c b/src/video_codec.c index 1c2d27628..9026d14b9 100644 --- a/src/video_codec.c +++ b/src/video_codec.c @@ -689,9 +689,15 @@ static void vc_deinterlace_unaligned(unsigned char *src, long src_linesize, int /** * Extended version of vc_deinterlace(). The former version was in-place only. * This allows to output to different buffer. + * + * @returns false on unsupported codecs */ -void vc_deinterlace_ex(unsigned char *src, size_t src_linesize, unsigned char *dst, size_t dst_pitch, size_t lines) +bool vc_deinterlace_ex(codec_t codec, unsigned char *src, size_t src_linesize, unsigned char *dst, size_t dst_pitch, size_t lines) { + (void) codec; + if (codec != RGB && codec != RGBA && codec != UYVY) { + return false; + } for (size_t y = 0; y < lines; y += 2) { for (size_t x = 0; x < src_linesize; ++x) { int val = (*src + src[src_linesize] + 1) >> 1; @@ -702,6 +708,7 @@ void vc_deinterlace_ex(unsigned char *src, size_t src_linesize, unsigned char *d src += src_linesize; dst += dst_pitch; } + return true; } /** diff --git a/src/video_codec.h b/src/video_codec.h index 58cd0dab7..1b257b237 100644 --- a/src/video_codec.h +++ b/src/video_codec.h @@ -122,7 +122,7 @@ bool codec_is_hw_accelerated(codec_t codec) ATTRIBUTE(const); bool codec_is_planar(codec_t codec) ATTRIBUTE(const); void vc_deinterlace(unsigned char *src, long src_linesize, int lines); -void vc_deinterlace_ex(unsigned char *src, size_t src_linesize, unsigned char *dst, size_t dst_pitch, size_t lines); +bool vc_deinterlace_ex(codec_t codec, unsigned char *src, size_t src_linesize, unsigned char *dst, size_t dst_pitch, size_t lines); decoder_func_t vc_copylineRGBA; decoder_func_t vc_copylineToRGBA_inplace; diff --git a/src/video_display/gl.cpp b/src/video_display/gl.cpp index 1ab9987fd..3fcdf9bca 100644 --- a/src/video_display/gl.cpp +++ b/src/video_display/gl.cpp @@ -88,6 +88,7 @@ #define MAGIC_GL 0x1331018e #define MOD_NAME "[GL] " #define DEFAULT_WIN_NAME "Ultragrid - OpenGL Display" +#define GL_DEINTERLACE_IMPOSSIBLE_MSG_ID 0x38e52705 #define GL_DISABLE_10B_OPT_PARAM_NAME "gl-disable-10b" #define GL_WINDOW_HINT_OPT_PARAM_NAME "glfw-window-hint" #define MAX_BUFFER_SIZE 1 @@ -952,12 +953,14 @@ static void gl_reconfigure_screen(struct state_gl *s, struct video_desc desc) static void gl_render(struct state_gl *s, char *data) { - /* for DXT, deinterlacing doesn't make sense since it is - * always deinterlaced before comrpression */ - if(s->deinterlace && (s->current_display_desc.color_spec == RGBA || s->current_display_desc.color_spec == UYVY)) - vc_deinterlace((unsigned char *) data, - vc_get_linesize(s->current_display_desc.width, s->current_display_desc.color_spec), - s->current_display_desc.height); + if (s->deinterlace) { + if (!vc_deinterlace_ex(s->current_display_desc.color_spec, + (unsigned char *) data, vc_get_linesize(s->current_display_desc.width, s->current_display_desc.color_spec), + (unsigned char *) data, vc_get_linesize(s->current_display_desc.width, s->current_display_desc.color_spec), + s->current_display_desc.height)) { + log_msg_once(LOG_LEVEL_ERROR, GL_DEINTERLACE_IMPOSSIBLE_MSG_ID, MOD_NAME "Cannot deinterlace, unsupported pixel format!\n"); + } + } gl_check_error(); diff --git a/src/video_display/sdl2.cpp b/src/video_display/sdl2.cpp index 4b77e813d..be13def77 100644 --- a/src/video_display/sdl2.cpp +++ b/src/video_display/sdl2.cpp @@ -87,6 +87,7 @@ #include #include // pair +#define SDL2_DEINTERLACE_IMPOSSIBLE_MSG_ID 0x327058e5 #define MAGIC_SDL2 0x3cc234a1 #define MAX_BUFFER_SIZE 1 #define MOD_NAME "[SDL] " @@ -180,7 +181,9 @@ static void display_frame(struct state_sdl2 *s, struct video_frame *frame) unsigned char *pixels; int pitch; SDL_LockTexture(s->texture, NULL, (void **) &pixels, &pitch); - vc_deinterlace_ex((unsigned char *) frame->tiles[0].data, vc_get_linesize(frame->tiles[0].width, frame->color_spec), pixels, pitch, frame->tiles[0].height); + if (!vc_deinterlace_ex(frame->color_spec, (unsigned char *) frame->tiles[0].data, vc_get_linesize(frame->tiles[0].width, frame->color_spec), pixels, pitch, frame->tiles[0].height)) { + log_msg_once(LOG_LEVEL_ERROR, SDL2_DEINTERLACE_IMPOSSIBLE_MSG_ID, MOD_NAME "Cannot deinterlace, unsupported pixel format!\n"); + } SDL_UnlockTexture(s->texture); } diff --git a/src/vo_postprocess/deinterlace.c b/src/vo_postprocess/deinterlace.c index ca349ab98..f43eb2173 100644 --- a/src/vo_postprocess/deinterlace.c +++ b/src/vo_postprocess/deinterlace.c @@ -120,7 +120,7 @@ static bool deinterlace_postprocess(void *state, struct video_frame *in, struct assert (in->tiles[0].data_len <= vc_get_linesize(in->tiles[0].width, in->color_spec) * in->tiles[0].height); assert (out->tiles[0].data_len <= vc_get_linesize(in->tiles[0].width, in->color_spec) * in->tiles[0].height); - vc_deinterlace_ex((unsigned char *) in->tiles[0].data, vc_get_linesize(in->tiles[0].width, in->color_spec), + vc_deinterlace_ex(in->color_spec, (unsigned char *) in->tiles[0].data, vc_get_linesize(in->tiles[0].width, in->color_spec), (unsigned char *) out->tiles[0].data, vc_get_linesize(out->tiles[0].width, in->color_spec), in->tiles[0].height); memcpy(out->tiles[0].data, in->tiles[0].data, in->tiles[0].data_len); diff --git a/src/vo_postprocess/double-framerate.cpp b/src/vo_postprocess/double-framerate.cpp index b44992bf8..65a17e0e8 100644 --- a/src/vo_postprocess/double-framerate.cpp +++ b/src/vo_postprocess/double-framerate.cpp @@ -52,6 +52,7 @@ #define MOD_NAME "[double_framerate] " #define TIMEOUT "20ms" +#define DFR_DEINTERLACE_IMPOSSIBLE_MSG_ID 0x27ff0a78 struct state_df { struct video_frame *in; @@ -184,7 +185,12 @@ static bool df_postprocess(void *state, struct video_frame *in, struct video_fra } if (s->deinterlace) { - vc_deinterlace((unsigned char *) out->tiles[0].data, vc_get_linesize(out->tiles[0].width, out->color_spec), out->tiles[0].height); + if (!vc_deinterlace_ex(in->color_spec, + (unsigned char *) out->tiles[0].data, vc_get_linesize(out->tiles[0].width, out->color_spec), + (unsigned char *) out->tiles[0].data, vc_get_linesize(out->tiles[0].width, out->color_spec), + out->tiles[0].height)) { + log_msg_once(LOG_LEVEL_ERROR, DFR_DEINTERLACE_IMPOSSIBLE_MSG_ID, MOD_NAME "Cannot deinterlace, unsupported pixel format!\n"); + } } if (!s->nodelay) {