Beispiel #1
0
void test_encode(void)
{
	RFX_CONTEXT* context;
	STREAM* enc_stream;
	int y_size, cb_size, cr_size;
	int i;
	BYTE decode_buffer[4096 * 3];

	rgb_data = (BYTE *) malloc(64 * 64 * 3);
	for (i = 0; i < 64; i++)
		memcpy(rgb_data + i * 64 * 3, rgb_scanline_data, 64 * 3);
	//freerdp_hexdump(rgb_data, 64 * 64 * 3);

	enc_stream = stream_new(65536);
	stream_clear(enc_stream);

	context = rfx_context_new();
	context->mode = RLGR3;
	rfx_context_set_pixel_format(context, RDP_PIXEL_FORMAT_R8G8B8);

	rfx_encode_rgb(context, rgb_data, 64, 64, 64 * 3,
		test_quantization_values, test_quantization_values, test_quantization_values,
		enc_stream, &y_size, &cb_size, &cr_size);
	//dump_buffer(context->priv->cb_g_buffer, 4096);

	/*printf("*** Y ***\n");
	freerdp_hexdump(stream_get_head(enc_stream), y_size);
	printf("*** Cb ***\n");
	freerdp_hexdump(stream_get_head(enc_stream) + y_size, cb_size);
	printf("*** Cr ***\n");
	freerdp_hexdump(stream_get_head(enc_stream) + y_size + cb_size, cr_size);*/

	stream_set_pos(enc_stream, 0);
	rfx_decode_rgb(context, enc_stream,
		y_size, test_quantization_values,
		cb_size, test_quantization_values,
		cr_size, test_quantization_values,
		decode_buffer);
	dump_ppm_image(decode_buffer);

	rfx_context_free(context);
	stream_free(enc_stream);
	free(rgb_data);
}
Beispiel #2
0
static void rfx_compose_message_tile(RFX_CONTEXT* context, STREAM* s,
	BYTE* tile_data, int tile_width, int tile_height, int rowstride,
	const UINT32* quantVals, int quantIdxY, int quantIdxCb, int quantIdxCr,
	int xIdx, int yIdx)
{
	int YLen = 0;
	int CbLen = 0;
	int CrLen = 0;
	int start_pos, end_pos;

	stream_check_size(s, 19);
	start_pos = stream_get_pos(s);

	stream_write_UINT16(s, CBT_TILE); /* BlockT.blockType */
	stream_seek_UINT32(s); /* set BlockT.blockLen later */
	stream_write_BYTE(s, quantIdxY);
	stream_write_BYTE(s, quantIdxCb);
	stream_write_BYTE(s, quantIdxCr);
	stream_write_UINT16(s, xIdx);
	stream_write_UINT16(s, yIdx);

	stream_seek(s, 6); /* YLen, CbLen, CrLen */

	rfx_encode_rgb(context, tile_data, tile_width, tile_height, rowstride,
		quantVals + quantIdxY * 10, quantVals + quantIdxCb * 10, quantVals + quantIdxCr * 10,
		s, &YLen, &CbLen, &CrLen);

	DEBUG_RFX("xIdx=%d yIdx=%d width=%d height=%d YLen=%d CbLen=%d CrLen=%d",
		xIdx, yIdx, tile_width, tile_height, YLen, CbLen, CrLen);

	end_pos = stream_get_pos(s);

	stream_set_pos(s, start_pos + 2);
	stream_write_UINT32(s, 19 + YLen + CbLen + CrLen); /* BlockT.blockLen */
	stream_set_pos(s, start_pos + 13);
	stream_write_UINT16(s, YLen);
	stream_write_UINT16(s, CbLen);
	stream_write_UINT16(s, CrLen);

	stream_set_pos(s, end_pos);
}
Beispiel #3
0
static void rfx_compose_message_tile(RFX_CONTEXT* context, wStream* s,
	BYTE* tile_data, int tile_width, int tile_height, int rowstride,
	const UINT32* quantVals, int quantIdxY, int quantIdxCb, int quantIdxCr,
	int xIdx, int yIdx)
{
	int YLen = 0;
	int CbLen = 0;
	int CrLen = 0;
	int start_pos, end_pos;

	Stream_EnsureRemainingCapacity(s, 19);
	start_pos = Stream_GetPosition(s);

	Stream_Write_UINT16(s, CBT_TILE); /* BlockT.blockType */
	Stream_Seek_UINT32(s); /* set BlockT.blockLen later */
	Stream_Write_UINT8(s, quantIdxY);
	Stream_Write_UINT8(s, quantIdxCb);
	Stream_Write_UINT8(s, quantIdxCr);
	Stream_Write_UINT16(s, xIdx);
	Stream_Write_UINT16(s, yIdx);

	Stream_Seek(s, 6); /* YLen, CbLen, CrLen */

	rfx_encode_rgb(context, tile_data, tile_width, tile_height, rowstride,
		quantVals + quantIdxY * 10, quantVals + quantIdxCb * 10, quantVals + quantIdxCr * 10,
		s, &YLen, &CbLen, &CrLen);

	DEBUG_RFX("xIdx=%d yIdx=%d width=%d height=%d YLen=%d CbLen=%d CrLen=%d",
		xIdx, yIdx, tile_width, tile_height, YLen, CbLen, CrLen);

	end_pos = Stream_GetPosition(s);

	Stream_SetPosition(s, start_pos + 2);
	Stream_Write_UINT32(s, 19 + YLen + CbLen + CrLen); /* BlockT.blockLen */
	Stream_SetPosition(s, start_pos + 13);
	Stream_Write_UINT16(s, YLen);
	Stream_Write_UINT16(s, CbLen);
	Stream_Write_UINT16(s, CrLen);

	Stream_SetPosition(s, end_pos);
}
Beispiel #4
0
void
test_encode(void)
{
	RFX_CONTEXT * context;
	uint8 ycbcr_buffer[1024000];
	int y_size, cb_size, cr_size;
	int i;
	uint8 decode_buffer[4096 * 3];

	rgb_data = (uint8 *) malloc(64 * 64 * 3);
	for (i = 0; i < 64; i++)
		memcpy(rgb_data + i * 64 * 3, rgb_scanline_data, 64 * 3);
	//hexdump(rgb_data, 64 * 64 * 3);

	context = rfx_context_new();
	context->mode = RLGR3;
	rfx_context_set_pixel_format(context, RFX_PIXEL_FORMAT_RGB);

	rfx_encode_rgb(context, rgb_data, 64, 64, 64 * 3,
		test_quantization_values, test_quantization_values, test_quantization_values,
		ycbcr_buffer, sizeof(ycbcr_buffer), &y_size, &cb_size, &cr_size);
	//dump_buffer(context->cb_g_buffer, 4096);

	/*printf("*** Y ***\n");
	hexdump(ycbcr_buffer, y_size);
	printf("*** Cb ***\n");
	hexdump(ycbcr_buffer + y_size, cb_size);
	printf("*** Cr ***\n");
	hexdump(ycbcr_buffer + y_size + cb_size, cr_size);*/

	rfx_decode_rgb(context,
		ycbcr_buffer, y_size, test_quantization_values,
		ycbcr_buffer + y_size, cb_size, test_quantization_values,
		ycbcr_buffer + y_size + cb_size, cr_size, test_quantization_values,
		decode_buffer);
	dump_ppm_image(decode_buffer);

	rfx_context_free(context);
	free(rgb_data);
}
Beispiel #5
0
RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int numRects,
		BYTE* data, int width, int height, int scanline)
{
	int i, maxNbTiles, maxTilesX, maxTilesY;
	int xIdx, yIdx, regionNbRects;
	int gridRelX, gridRelY, ax, ay, bytesPerPixel;
	RFX_TILE* tile;
	RFX_RECT* rfxRect;
	RFX_MESSAGE* message = NULL;
	PTP_WORK* workObject = NULL;
	RFX_TILE_COMPOSE_WORK_PARAM *workParam = NULL;
	BOOL success = FALSE;

	REGION16 rectsRegion, tilesRegion;
	RECTANGLE_16 currentTileRect;
	const RECTANGLE_16 *regionRect;
	const RECTANGLE_16 *extents;

	assert(data);
	assert(rects);
	assert(numRects > 0);
	assert(width > 0);
	assert(height > 0);
	assert(scanline > 0);

	if (!(message = (RFX_MESSAGE*)calloc(1, sizeof(RFX_MESSAGE))))
		return NULL;

	region16_init(&tilesRegion);
	region16_init(&rectsRegion);

	if (context->state == RFX_STATE_SEND_HEADERS)
		rfx_update_context_properties(context);

	message->frameIdx = context->frameIdx++;

	if (!context->numQuant)
	{
		if (!(context->quants = (UINT32*) malloc(sizeof(rfx_default_quantization_values))))
			goto skip_encoding_loop;

		CopyMemory(context->quants, &rfx_default_quantization_values, sizeof(rfx_default_quantization_values));
		context->numQuant = 1;
		context->quantIdxY = 0;
		context->quantIdxCb = 0;
		context->quantIdxCr = 0;
	}

	message->numQuant = context->numQuant;
	message->quantVals = context->quants;

	bytesPerPixel = (context->bits_per_pixel / 8);

	if (!computeRegion(rects, numRects, &rectsRegion, width, height))
		goto skip_encoding_loop;

	extents = region16_extents(&rectsRegion);
	assert(extents->right - extents->left > 0);
	assert(extents->bottom - extents->top > 0);

	maxTilesX = 1 + TILE_NO(extents->right - 1) - TILE_NO(extents->left);
	maxTilesY = 1 + TILE_NO(extents->bottom - 1) - TILE_NO(extents->top);
	maxNbTiles = maxTilesX * maxTilesY;

	if (!(message->tiles = calloc(maxNbTiles, sizeof(RFX_TILE*))))
		goto skip_encoding_loop;

	if (!setupWorkers(context, maxNbTiles))
		goto skip_encoding_loop;

	if (context->priv->UseThreads)
	{
		workObject = context->priv->workObjects;
		workParam = context->priv->tileWorkParams;
	}

	regionRect = region16_rects(&rectsRegion, &regionNbRects);

	if (!(message->rects = calloc(regionNbRects, sizeof(RFX_RECT))))
		goto skip_encoding_loop;

	message->numRects = regionNbRects;

	for (i = 0, rfxRect = message->rects; i < regionNbRects; i++, regionRect++, rfxRect++)
	{
		int startTileX = regionRect->left / 64;
		int endTileX = (regionRect->right - 1) / 64;

		int startTileY = regionRect->top / 64;
		int endTileY = (regionRect->bottom - 1) / 64;

		rfxRect->x = regionRect->left;
		rfxRect->y = regionRect->top;
		rfxRect->width = (regionRect->right - regionRect->left);
		rfxRect->height = (regionRect->bottom - regionRect->top);


		for (yIdx = startTileY, gridRelY = startTileY * 64; yIdx <= endTileY; yIdx++, gridRelY += 64 )
		{
			int tileHeight = 64;

			if ((yIdx == endTileY) && (gridRelY + 64 > height))
				tileHeight = height - gridRelY;

			currentTileRect.top = gridRelY;
			currentTileRect.bottom = gridRelY + tileHeight;

			for (xIdx = startTileX, gridRelX = startTileX * 64; xIdx <= endTileX; xIdx++, gridRelX += 64)
			{
				int tileWidth = 64;

				if ((xIdx == endTileX) && (gridRelX + 64 > width))
					tileWidth = width - gridRelX;

				currentTileRect.left = gridRelX;
				currentTileRect.right = gridRelX + tileWidth;

				/* checks if this tile is already treated */
				if (region16_intersects_rect(&tilesRegion, &currentTileRect))
					continue;

				if (!(tile = (RFX_TILE*) ObjectPool_Take(context->priv->TilePool)))
					goto skip_encoding_loop;

				tile->xIdx = xIdx;
				tile->yIdx = yIdx;
				tile->x = gridRelX;
				tile->y = gridRelY;
				tile->scanline = scanline;
				tile->width = tileWidth;
				tile->height = tileHeight;

				ax = gridRelX;
				ay = gridRelY;

				if (tile->data && tile->allocated)
				{
					free(tile->data);
					tile->allocated = FALSE;
				}
				tile->data = &data[(ay * scanline) + (ax * bytesPerPixel)];

				tile->quantIdxY = context->quantIdxY;
				tile->quantIdxCb = context->quantIdxCb;
				tile->quantIdxCr = context->quantIdxCr;

				tile->YLen = tile->CbLen = tile->CrLen = 0;

				if (!(tile->YCbCrData = (BYTE *)BufferPool_Take(context->priv->BufferPool, -1)))
					goto skip_encoding_loop;

				tile->YData = (BYTE*) &(tile->YCbCrData[((8192 + 32) * 0) + 16]);
				tile->CbData = (BYTE*) &(tile->YCbCrData[((8192 + 32) * 1) + 16]);
				tile->CrData = (BYTE*) &(tile->YCbCrData[((8192 + 32) * 2) + 16]);

				message->tiles[message->numTiles] = tile;
				message->numTiles++;

				if (context->priv->UseThreads)
				{
					workParam->context = context;
					workParam->tile = tile;

					if (!(*workObject = CreateThreadpoolWork(
							(PTP_WORK_CALLBACK)rfx_compose_message_tile_work_callback,
							(void*) workParam,
							&context->priv->ThreadPoolEnv)))
					{
						goto skip_encoding_loop;
					}

					SubmitThreadpoolWork(*workObject);

					workObject++;
					workParam++;
				}
				else
				{
					rfx_encode_rgb(context, tile);
				}

				if (!region16_union_rect(&tilesRegion, &tilesRegion, &currentTileRect))
					goto skip_encoding_loop;
			} /* xIdx */
		}  /* yIdx */
	}  /* rects */

	success = TRUE;

skip_encoding_loop:

	if (success && message->numTiles != maxNbTiles)
	{
		void* pmem = realloc((void*) message->tiles, sizeof(RFX_TILE*) * message->numTiles);

		if (pmem)
			message->tiles = (RFX_TILE**) pmem;
		else
			success = FALSE;
	}

	/* when using threads ensure all computations are done */
	message->tilesDataSize = 0;
	workObject = context->priv->workObjects;

	for (i = 0; i < message->numTiles; i++)
	{
		tile = message->tiles[i];
		if (context->priv->UseThreads)
		{
			if (*workObject)
			{
				WaitForThreadpoolWorkCallbacks(*workObject, FALSE);
				CloseThreadpoolWork(*workObject);
			}
			workObject++;
		}

		message->tilesDataSize += rfx_tile_length(tile);
	}

	region16_uninit(&tilesRegion);
	region16_uninit(&rectsRegion);

	if (success)
		return message;

	WLog_ERR(TAG, "%s: failed", __FUNCTION__);

	message->freeRects = TRUE;
	rfx_message_free(context, message);
	return NULL;
}
Beispiel #6
0
void CALLBACK rfx_compose_message_tile_work_callback(PTP_CALLBACK_INSTANCE instance, void* context, PTP_WORK work)
{
	RFX_TILE_COMPOSE_WORK_PARAM* param = (RFX_TILE_COMPOSE_WORK_PARAM*) context;
	rfx_encode_rgb(param->context, param->tile);
}