From 841960b670c7ed9324b0437b1cd2865b57fc3ad9 Mon Sep 17 00:00:00 2001 From: Maryla Date: Wed, 30 Mar 2022 11:37:32 +0200 Subject: [PATCH] Make libsharpyuv self-contained by removing dependency on cpu.c Change-Id: I2edac1afa38bfddf2a91e7829e38425bd3519feb --- sharpyuv/sharpyuv.c | 28 +++++++++++++++++++++++----- sharpyuv/sharpyuv_dsp.c | 8 ++++---- sharpyuv/sharpyuv_dsp.h | 2 +- src/dsp/cpu.c | 2 +- src/enc/picture_csp_enc.c | 21 +++++++++++++++++++++ 5 files changed, 50 insertions(+), 11 deletions(-) diff --git a/sharpyuv/sharpyuv.c b/sharpyuv/sharpyuv.c index ce671f57..bdd0c3f3 100644 --- a/sharpyuv/sharpyuv.c +++ b/sharpyuv/sharpyuv.c @@ -62,9 +62,8 @@ static uint32_t kLinearToGammaTabS[kGammaTabSize + 2]; #define GAMMA_TO_LINEAR_BITS 14 static uint32_t kGammaToLinearTabS[MAX_Y_T + 1]; // size scales with Y_FIX static volatile int kGammaTablesSOk = 0; -static void InitGammaTablesS(void); -WEBP_DSP_INIT_FUNC(InitGammaTablesS) { +static void InitGammaTablesS(void) { assert(2 * GAMMA_TO_LINEAR_BITS < 32); // we use uint32_t intermediate values if (!kGammaTablesSOk) { int v; @@ -180,6 +179,7 @@ static void UpdateChroma(const fixed_y_t* src1, const fixed_y_t* src2, static void StoreGray(const fixed_y_t* rgb, fixed_y_t* y, int w) { int i; + assert(w > 0); for (i = 0; i < w; ++i) { y[i] = RGBToGray(rgb[0 * w + i], rgb[1 * w + i], rgb[2 * w + i]); } @@ -348,9 +348,6 @@ static int DoSharpArgbToYuv(const uint8_t* r_ptr, const uint8_t* g_ptr, goto End; } - InitGammaTablesS(); - InitSharpYuv(); - // Import RGB samples to W/RGB representation. for (j = 0; j < height; j += 2) { const int is_last_row = (j == height - 1); @@ -438,6 +435,26 @@ static int DoSharpArgbToYuv(const uint8_t* r_ptr, const uint8_t* g_ptr, } #undef SAFE_ALLOC +// Hidden exported init function. +// By default SharpYuvConvert calls it with NULL. If needed, users can declare +// it as extern and call it with a VP8CPUInfo function. +extern void SharpYuvInit(VP8CPUInfo cpu_info_func); +void SharpYuvInit(VP8CPUInfo cpu_info_func) { + static volatile VP8CPUInfo sharpyuv_last_cpuinfo_used = + (VP8CPUInfo)&sharpyuv_last_cpuinfo_used; + const int initialized = + (sharpyuv_last_cpuinfo_used != (VP8CPUInfo)&sharpyuv_last_cpuinfo_used); + if (cpu_info_func == NULL && initialized) return; + if (sharpyuv_last_cpuinfo_used == cpu_info_func) return; + + SharpYuvInitDsp(cpu_info_func); + if (!initialized) { + InitGammaTablesS(); + } + + sharpyuv_last_cpuinfo_used = cpu_info_func; +} + // In YUV_FIX fixed point precision. static const SharpYuvConversionMatrix kWebpYuvMatrix = { {16839, 33059, 6420, 16 << 16}, @@ -459,6 +476,7 @@ int SharpYuvConvert(const uint8_t* r_ptr, const uint8_t* g_ptr, height < kMinDimensionIterativeConversion) { return 0; } + SharpYuvInit(NULL); return DoSharpArgbToYuv(r_ptr, g_ptr, b_ptr, step, rgb_stride, dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v, dst_stride_v, width, height, yuv_matrix); diff --git a/sharpyuv/sharpyuv_dsp.c b/sharpyuv/sharpyuv_dsp.c index 15e88327..06825011 100644 --- a/sharpyuv/sharpyuv_dsp.c +++ b/sharpyuv/sharpyuv_dsp.c @@ -74,7 +74,8 @@ void (*SharpYUVFilterRow)(const int16_t* A, const int16_t* B, int len, extern void InitSharpYUVSSE2(void); extern void InitSharpYUVNEON(void); -WEBP_DSP_INIT_FUNC(InitSharpYuv) { +void SharpYuvInitDsp(VP8CPUInfo cpu_info_func) { + (void)cpu_info_func; #if !WEBP_NEON_OMIT_C_CODE SharpYUVUpdateY = SharpYUVUpdateY_C; @@ -83,14 +84,13 @@ WEBP_DSP_INIT_FUNC(InitSharpYuv) { #endif #if defined(WEBP_HAVE_SSE2) - if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSSE2)) { + if (cpu_info_func == NULL || cpu_info_func(kSSE2)) { InitSharpYUVSSE2(); } #endif // WEBP_HAVE_SSE2 #if defined(WEBP_HAVE_NEON) - if (WEBP_NEON_OMIT_C_CODE || - (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) { + if (WEBP_NEON_OMIT_C_CODE || cpu_info_func == NULL || cpu_info_func(kNEON)) { InitSharpYUVNEON(); } #endif // WEBP_HAVE_NEON diff --git a/sharpyuv/sharpyuv_dsp.h b/sharpyuv/sharpyuv_dsp.h index d4905f8e..474fbc44 100644 --- a/sharpyuv/sharpyuv_dsp.h +++ b/sharpyuv/sharpyuv_dsp.h @@ -23,6 +23,6 @@ extern void (*SharpYUVUpdateRGB)(const int16_t* src, const int16_t* ref, extern void (*SharpYUVFilterRow)(const int16_t* A, const int16_t* B, int len, const uint16_t* best_y, uint16_t* out); -void InitSharpYuv(void); +void SharpYuvInitDsp(VP8CPUInfo cpu_info_func); #endif // WEBP_SHARPYUV_DSP_H_ diff --git a/src/dsp/cpu.c b/src/dsp/cpu.c index 3145e190..a4ba7f2c 100644 --- a/src/dsp/cpu.c +++ b/src/dsp/cpu.c @@ -11,7 +11,7 @@ // // Author: Christian Duvivier (cduvivier@google.com) -#include "src/dsp/dsp.h" +#include "src/dsp/cpu.h" #if defined(WEBP_HAVE_NEON_RTCD) #include diff --git a/src/enc/picture_csp_enc.c b/src/enc/picture_csp_enc.c index cabee114..3aec3104 100644 --- a/src/enc/picture_csp_enc.c +++ b/src/enc/picture_csp_enc.c @@ -22,6 +22,11 @@ #include "src/dsp/dsp.h" #include "src/dsp/lossless.h" #include "src/dsp/yuv.h" +#include "src/dsp/cpu.h" + +#if defined(WEBP_USE_THREAD) && !defined(_WIN32) +#include +#endif // Uncomment to disable gamma-compression during RGB->U/V averaging #define USE_GAMMA_COMPRESSION @@ -174,6 +179,21 @@ typedef uint16_t fixed_y_t; // unsigned type with extra SFIX precision for W //------------------------------------------------------------------------------ // Main function +extern void SharpYuvInit(VP8CPUInfo cpu_info_func); + +static void SafeInitSharpYuv(void) { +#if defined(WEBP_USE_THREAD) && !defined(_WIN32) + static pthread_mutex_t initsharpyuv_lock = PTHREAD_MUTEX_INITIALIZER; + if (pthread_mutex_lock(&initsharpyuv_lock)) return; +#endif + + SharpYuvInit(VP8GetCPUInfo); + +#if defined(WEBP_USE_THREAD) && !defined(_WIN32) + (void)pthread_mutex_unlock(&initsharpyuv_lock); +#endif +} + static int PreprocessARGB(const uint8_t* r_ptr, const uint8_t* g_ptr, const uint8_t* b_ptr, @@ -495,6 +515,7 @@ static int ImportYUVAFromRGBA(const uint8_t* r_ptr, } if (use_iterative_conversion) { + SafeInitSharpYuv(); if (!PreprocessARGB(r_ptr, g_ptr, b_ptr, step, rgb_stride, picture)) { return 0; }