diff --git a/vhook/imlib2.c b/vhook/imlib2.c index 5103f880cc..331359db63 100644 --- a/vhook/imlib2.c +++ b/vhook/imlib2.c @@ -46,6 +46,7 @@ */ #include "framehook.h" +#include "swscale.h" #include #include @@ -59,6 +60,8 @@ #include #include +static int sws_flags = SWS_BICUBIC; + typedef struct { int dummy; Imlib_Font fn; @@ -68,6 +71,11 @@ typedef struct { int x; int y; struct _CachedImage *cache; + + // This vhook first converts frame to RGB ... + struct SwsContext *toRGB_convert_ctx; + // ... and then converts back frame from RGB to initial format + struct SwsContext *fromRGB_convert_ctx; } ContextInfo; typedef struct _CachedImage { @@ -87,8 +95,11 @@ void Release(void *ctx) imlib_free_image(); av_free(ci->cache); } - if (ctx) + if (ctx) { + sws_freeContext(ci->toRGB_convert_ctx); + sws_freeContext(ci->fromRGB_convert_ctx); av_free(ctx); + } } int Configure(void **ctxp, int argc, char *argv[]) @@ -218,15 +229,24 @@ void Process(void *ctx, AVPicture *picture, enum PixelFormat pix_fmt, int width, data = imlib_image_get_data(); avpicture_fill(&picture1, (uint8_t *) data, PIX_FMT_RGBA32, width, height); - if (pix_fmt != PIX_FMT_RGBA32) { - if (img_convert(&picture1, PIX_FMT_RGBA32, - picture, pix_fmt, width, height) < 0) { - goto done; - } - } else { - img_copy(&picture1, picture, PIX_FMT_RGBA32, width, height); + + // if we already got a SWS context, let's realloc if is not re-useable + ci->toRGB_convert_ctx = sws_getCachedContext(ci->toRGB_convert_ctx, + width, height, pix_fmt, + width, height, PIX_FMT_RGBA32, + sws_flags, NULL, NULL, NULL); + if (ci->toRGB_convert_ctx == NULL) { + av_log(NULL, AV_LOG_ERROR, + "Cannot initialize the toRGB conversion context\n"); + exit(1); } +// img_convert parameters are 2 first destination, then 4 source +// sws_scale parameters are context, 4 first source, then 2 destination + sws_scale(ci->toRGB_convert_ctx, + picture->data, picture->linesize, 0, height, + picture1.data, picture1.linesize); + imlib_image_set_has_alpha(0); { @@ -271,15 +291,20 @@ void Process(void *ctx, AVPicture *picture, enum PixelFormat pix_fmt, int width, } } - if (pix_fmt != PIX_FMT_RGBA32) { - if (img_convert(picture, pix_fmt, - &picture1, PIX_FMT_RGBA32, width, height) < 0) { - } - } else { - img_copy(picture, &picture1, PIX_FMT_RGBA32, width, height); + ci->fromRGB_convert_ctx = sws_getCachedContext(ci->fromRGB_convert_ctx, + width, height, PIX_FMT_RGBA32, + width, height, pix_fmt, + sws_flags, NULL, NULL, NULL); + if (ci->fromRGB_convert_ctx == NULL) { + av_log(NULL, AV_LOG_ERROR, + "Cannot initialize the fromRGB conversion context\n"); + exit(1); } +// img_convert parameters are 2 first destination, then 4 source +// sws_scale parameters are context, 4 first source, then 2 destination + sws_scale(ci->fromRGB_convert_ctx, + picture1.data, picture1.linesize, 0, height, + picture->data, picture->linesize); -done: - ; }