int TestBufferPool(int argc, char* argv[]) { DWORD PoolSize; int BufferSize; wBufferPool* pool; BYTE* Buffers[10]; DWORD DefaultSize = 1234; pool = BufferPool_New(TRUE, -1, 16); if (!pool) return -1; Buffers[0] = BufferPool_Take(pool, DefaultSize); Buffers[1] = BufferPool_Take(pool, DefaultSize); Buffers[2] = BufferPool_Take(pool, 2048); if (!Buffers[0] || !Buffers[1] || !Buffers[2]) return -1; BufferSize = BufferPool_GetBufferSize(pool, Buffers[0]); if (BufferSize != DefaultSize) { printf("BufferPool_GetBufferSize failure: Actual: %d Expected: %"PRIu32"\n", BufferSize, DefaultSize); return -1; } BufferSize = BufferPool_GetBufferSize(pool, Buffers[1]); if (BufferSize != DefaultSize) { printf("BufferPool_GetBufferSize failure: Actual: %d Expected: %"PRIu32"\n", BufferSize, DefaultSize); return -1; } BufferSize = BufferPool_GetBufferSize(pool, Buffers[2]); if (BufferSize != 2048) { printf("BufferPool_GetBufferSize failure: Actual: %d Expected: 2048\n", BufferSize); return -1; } BufferPool_Return(pool, Buffers[1]); PoolSize = BufferPool_GetPoolSize(pool); if (PoolSize != 2) { printf("BufferPool_GetPoolSize failure: Actual: %"PRIu32" Expected: 2\n", PoolSize); return -1; } BufferPool_Clear(pool); BufferPool_Free(pool); return 0; }
PROGRESSIVE_CONTEXT* progressive_context_new(BOOL Compressor) { PROGRESSIVE_CONTEXT* progressive; progressive = (PROGRESSIVE_CONTEXT*) calloc(1, sizeof(PROGRESSIVE_CONTEXT)); if (progressive) { progressive->Compressor = Compressor; progressive->bufferPool = BufferPool_New(TRUE, (8192 + 32) * 3, 16); progressive->cRects = 64; progressive->rects = (RFX_RECT*) malloc(progressive->cRects * sizeof(RFX_RECT)); if (!progressive->rects) return NULL; progressive->cTiles = 64; progressive->tiles = (RFX_PROGRESSIVE_TILE*) malloc(progressive->cTiles * sizeof(RFX_PROGRESSIVE_TILE)); if (!progressive->tiles) return NULL; progressive->cQuant = 8; progressive->quantVals = (RFX_COMPONENT_CODEC_QUANT*) malloc(progressive->cQuant * sizeof(RFX_COMPONENT_CODEC_QUANT)); if (!progressive->quantVals) return NULL; progressive->cProgQuant = 8; progressive->quantProgVals = (RFX_PROGRESSIVE_CODEC_QUANT*) malloc(progressive->cProgQuant * sizeof(RFX_PROGRESSIVE_CODEC_QUANT)); if (!progressive->quantProgVals) return NULL; ZeroMemory(&(progressive->quantProgValFull), sizeof(RFX_PROGRESSIVE_CODEC_QUANT)); progressive->quantProgValFull.quality = 100; progressive_context_reset(progressive); } return progressive; }
VideoClientContextPriv *VideoClientContextPriv_new(VideoClientContext *video) { VideoClientContextPriv *ret = calloc(1, sizeof(*ret)); if (!ret) return NULL; ret->frames = Queue_New(TRUE, 10, 2); if (!ret->frames) { WLog_ERR(TAG, "unable to allocate frames queue"); goto error_frames; } ret->surfacePool = BufferPool_New(FALSE, 0, 16); if (!ret->surfacePool) { WLog_ERR(TAG, "unable to create surface pool"); goto error_surfacePool; } if (!InitializeCriticalSectionAndSpinCount(&ret->framesLock, 4 * 1000)) { WLog_ERR(TAG, "unable to initialize frames lock"); goto error_spinlock; } ret->video = video; /* don't set to unlimited so that we have the chance to send a feedback in * the first second (for servers that want feedback directly) */ ret->lastSentRate = 30; return ret; error_spinlock: BufferPool_Free(ret->surfacePool); error_surfacePool: Queue_Free(ret->frames); error_frames: free(ret); return NULL; }
RFX_CONTEXT* rfx_context_new(void) { HKEY hKey; LONG status; DWORD dwType; DWORD dwSize; DWORD dwValue; SYSTEM_INFO sysinfo; RFX_CONTEXT* context; context = (RFX_CONTEXT*) malloc(sizeof(RFX_CONTEXT)); ZeroMemory(context, sizeof(RFX_CONTEXT)); context->priv = (RFX_CONTEXT_PRIV*) malloc(sizeof(RFX_CONTEXT_PRIV)); ZeroMemory(context->priv, sizeof(RFX_CONTEXT_PRIV)); context->priv->TilePool = Queue_New(TRUE, -1, -1); context->priv->TileQueue = Queue_New(TRUE, -1, -1); /* * align buffers to 16 byte boundary (needed for SSE/NEON instructions) * * y_r_buffer, cb_g_buffer, cr_b_buffer: 64 * 64 * 4 = 16384 (0x4000) * dwt_buffer: 32 * 32 * 2 * 2 * 4 = 16384, maximum sub-band width is 32 */ context->priv->BufferPool = BufferPool_New(TRUE, 16384, 16); #ifdef _WIN32 { BOOL isVistaOrLater; OSVERSIONINFOA verinfo; ZeroMemory(&verinfo, sizeof(OSVERSIONINFOA)); verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); GetVersionExA(&verinfo); isVistaOrLater = ((verinfo.dwMajorVersion >= 6) && (verinfo.dwMinorVersion >= 0)) ? TRUE : FALSE; context->priv->UseThreads = isVistaOrLater; } #else context->priv->UseThreads = TRUE; #endif GetNativeSystemInfo(&sysinfo); context->priv->MinThreadCount = sysinfo.dwNumberOfProcessors; context->priv->MaxThreadCount = 0; status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\RemoteFX"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); if (status == ERROR_SUCCESS) { if (RegQueryValueEx(hKey, _T("UseThreads"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) context->priv->UseThreads = dwValue ? 1 : 0; if (RegQueryValueEx(hKey, _T("MinThreadCount"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) context->priv->MinThreadCount = dwValue; if (RegQueryValueEx(hKey, _T("MaxThreadCount"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) context->priv->MaxThreadCount = dwValue; RegCloseKey(hKey); } if (context->priv->UseThreads) { /* Call primitives_get here in order to avoid race conditions when using primitives_get */ /* from multiple threads. This call will initialize all function pointers correctly */ /* before any decoding threads are started */ primitives_get(); context->priv->ThreadPool = CreateThreadpool(NULL); InitializeThreadpoolEnvironment(&context->priv->ThreadPoolEnv); SetThreadpoolCallbackPool(&context->priv->ThreadPoolEnv, context->priv->ThreadPool); if (context->priv->MinThreadCount) SetThreadpoolThreadMinimum(context->priv->ThreadPool, context->priv->MinThreadCount); if (context->priv->MaxThreadCount) SetThreadpoolThreadMaximum(context->priv->ThreadPool, context->priv->MaxThreadCount); } /* initialize the default pixel format */ rfx_context_set_pixel_format(context, RDP_PIXEL_FORMAT_B8G8R8A8); /* create profilers for default decoding routines */ rfx_profiler_create(context); /* set up default routines */ context->quantization_decode = rfx_quantization_decode; context->quantization_encode = rfx_quantization_encode; context->dwt_2d_decode = rfx_dwt_2d_decode; context->dwt_2d_encode = rfx_dwt_2d_encode; RFX_INIT_SIMD(context); return context; }
RFX_CONTEXT* rfx_context_new(BOOL encoder) { HKEY hKey; LONG status; DWORD dwType; DWORD dwSize; DWORD dwValue; SYSTEM_INFO sysinfo; RFX_CONTEXT* context; wObject *pool; RFX_CONTEXT_PRIV *priv; context = (RFX_CONTEXT*)calloc(1, sizeof(RFX_CONTEXT)); if (!context) return NULL; context->encoder = encoder; context->priv = priv = (RFX_CONTEXT_PRIV *)calloc(1, sizeof(RFX_CONTEXT_PRIV) ); if (!priv) goto error_priv; WLog_Init(); priv->log = WLog_Get("com.freerdp.codec.rfx"); WLog_OpenAppender(priv->log); #ifdef WITH_DEBUG_RFX WLog_SetLogLevel(priv->log, WLOG_DEBUG); #endif priv->TilePool = ObjectPool_New(TRUE); if (!priv->TilePool) goto error_tilePool; pool = ObjectPool_Object(priv->TilePool); pool->fnObjectInit = (OBJECT_INIT_FN) rfx_tile_init; if (context->encoder) { pool->fnObjectNew = (OBJECT_NEW_FN) rfx_encoder_tile_new; pool->fnObjectFree = (OBJECT_FREE_FN) rfx_encoder_tile_free; } else { pool->fnObjectNew = (OBJECT_NEW_FN) rfx_decoder_tile_new; pool->fnObjectFree = (OBJECT_FREE_FN) rfx_decoder_tile_free; } /* * align buffers to 16 byte boundary (needed for SSE/NEON instructions) * * y_r_buffer, cb_g_buffer, cr_b_buffer: 64 * 64 * sizeof(INT16) = 8192 (0x2000) * dwt_buffer: 32 * 32 * 2 * 2 * sizeof(INT16) = 8192, maximum sub-band width is 32 * * Additionally we add 32 bytes (16 in front and 16 at the back of the buffer) * in order to allow optimized functions (SEE, NEON) to read from positions * that are actually in front/beyond the buffer. Offset calculations are * performed at the BufferPool_Take function calls in rfx_encode/decode.c. * * We then multiply by 3 to use a single, partioned buffer for all 3 channels. */ priv->BufferPool = BufferPool_New(TRUE, (8192 + 32) * 3, 16); if (!priv->BufferPool) goto error_BufferPool; #ifdef _WIN32 { BOOL isVistaOrLater; OSVERSIONINFOA verinfo; ZeroMemory(&verinfo, sizeof(OSVERSIONINFOA)); verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); GetVersionExA(&verinfo); isVistaOrLater = ((verinfo.dwMajorVersion >= 6) && (verinfo.dwMinorVersion >= 0)) ? TRUE : FALSE; priv->UseThreads = isVistaOrLater; } #else priv->UseThreads = TRUE; #endif GetNativeSystemInfo(&sysinfo); priv->MinThreadCount = sysinfo.dwNumberOfProcessors; priv->MaxThreadCount = 0; status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\RemoteFX"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); if (status == ERROR_SUCCESS) { dwSize = sizeof(dwValue); if (RegQueryValueEx(hKey, _T("UseThreads"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) priv->UseThreads = dwValue ? 1 : 0; if (RegQueryValueEx(hKey, _T("MinThreadCount"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) priv->MinThreadCount = dwValue; if (RegQueryValueEx(hKey, _T("MaxThreadCount"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) priv->MaxThreadCount = dwValue; RegCloseKey(hKey); } if (priv->UseThreads) { /* Call primitives_get here in order to avoid race conditions when using primitives_get */ /* from multiple threads. This call will initialize all function pointers correctly */ /* before any decoding threads are started */ primitives_get(); priv->ThreadPool = CreateThreadpool(NULL); if (!priv->ThreadPool) goto error_threadPool; InitializeThreadpoolEnvironment(&priv->ThreadPoolEnv); SetThreadpoolCallbackPool(&priv->ThreadPoolEnv, priv->ThreadPool); if (priv->MinThreadCount) if (!SetThreadpoolThreadMinimum(priv->ThreadPool, priv->MinThreadCount)) goto error_threadPool_minimum; if (priv->MaxThreadCount) SetThreadpoolThreadMaximum(priv->ThreadPool, priv->MaxThreadCount); } /* initialize the default pixel format */ rfx_context_set_pixel_format(context, RDP_PIXEL_FORMAT_B8G8R8A8); /* create profilers for default decoding routines */ rfx_profiler_create(context); /* set up default routines */ context->quantization_decode = rfx_quantization_decode; context->quantization_encode = rfx_quantization_encode; context->dwt_2d_decode = rfx_dwt_2d_decode; context->dwt_2d_encode = rfx_dwt_2d_encode; RFX_INIT_SIMD(context); context->state = RFX_STATE_SEND_HEADERS; return context; error_threadPool_minimum: CloseThreadpool(priv->ThreadPool); error_threadPool: BufferPool_Free(priv->BufferPool); error_BufferPool: ObjectPool_Free(priv->TilePool); error_tilePool: free(priv); error_priv: free(context); return NULL; }
int TestBufferPool(int argc, char* argv[]) { int PoolSize; int BufferSize; int DefaultSize; wBufferPool* pool; BYTE* Buffers[10]; DefaultSize = 1234; pool = BufferPool_New(TRUE, DefaultSize, 16); Buffers[0] = BufferPool_Take(pool, -1); Buffers[1] = BufferPool_Take(pool, 0); Buffers[2] = BufferPool_Take(pool, 2048); PoolSize = BufferPool_GetPoolSize(pool); if (PoolSize != 3) { printf("BufferPool_GetPoolSize failure: Actual: %d Expected: %d\n", PoolSize, 3); return -1; } BufferSize = BufferPool_GetBufferSize(pool, Buffers[0]); if (BufferSize != DefaultSize) { printf("BufferPool_GetBufferSize failure: Actual: %d Expected: %d\n", BufferSize, DefaultSize); return -1; } BufferSize = BufferPool_GetBufferSize(pool, Buffers[1]); if (BufferSize != DefaultSize) { printf("BufferPool_GetBufferSize failure: Actual: %d Expected: %d\n", BufferSize, DefaultSize); return -1; } BufferSize = BufferPool_GetBufferSize(pool, Buffers[2]); if (BufferSize != 2048) { printf("BufferPool_GetBufferSize failure: Actual: %d Expected: %d\n", BufferSize, 2048); return -1; } BufferPool_Return(pool, Buffers[1]); PoolSize = BufferPool_GetPoolSize(pool); if (PoolSize != 2) { printf("BufferPool_GetPoolSize failure: Actual: %d Expected: %d\n", PoolSize, 2); return -1; } BufferPool_Clear(pool); PoolSize = BufferPool_GetPoolSize(pool); if (PoolSize != 0) { printf("BufferPool_GetPoolSize failure: Actual: %d Expected: %d\n", PoolSize, 0); return -1; } BufferPool_Free(pool); return 0; }