codecs: added --jpeg command line, moved jpeg hack to bitmap cache v3, added bcv3 xxx setting
This commit is contained in:
parent
c74cae4209
commit
238cf848c2
@ -25,6 +25,7 @@
|
||||
#endif
|
||||
|
||||
#include <freerdp/codec/bitmap.h>
|
||||
#include <freerdp/codec/rfx.h>
|
||||
#include <freerdp/codec/jpeg.h>
|
||||
|
||||
#include "xf_graphics.h"
|
||||
@ -106,9 +107,14 @@ void xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
|
||||
}
|
||||
|
||||
void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
|
||||
uint8* data, int width, int height, int bpp, int length, boolean compressed)
|
||||
uint8* data, int width, int height, int bpp, int length, int compressed)
|
||||
{
|
||||
uint16 size;
|
||||
RFX_MESSAGE* msg;
|
||||
uint8* src;
|
||||
uint8* dst;
|
||||
int yindex;
|
||||
int xindex;
|
||||
|
||||
size = width * height * (bpp + 7) / 8;
|
||||
|
||||
@ -117,22 +123,52 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
|
||||
else
|
||||
bitmap->data = (uint8*) xrealloc(bitmap->data, size);
|
||||
|
||||
if (compressed == 2)
|
||||
if (compressed == 4)
|
||||
{
|
||||
printf("xf_Bitmap_Decompress: nsc not done\n");
|
||||
}
|
||||
else if (compressed == 3)
|
||||
{
|
||||
xfInfo* xfi = ((xfContext*)context)->xfi;
|
||||
rfx_context_set_pixel_format(xfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
|
||||
msg = rfx_process_message(xfi->rfx_context, data, length);
|
||||
if (msg == NULL)
|
||||
{
|
||||
printf("xf_Bitmap_Decompress: rfx Decompression Failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (yindex = 0; yindex < height; yindex++)
|
||||
{
|
||||
src = msg->tiles[0]->data + yindex * 64 * 4;
|
||||
dst = bitmap->data + yindex * width * 3;
|
||||
for (xindex = 0; xindex < width; xindex++)
|
||||
{
|
||||
*(dst++) = *(src++);
|
||||
*(dst++) = *(src++);
|
||||
*(dst++) = *(src++);
|
||||
src++;
|
||||
}
|
||||
}
|
||||
rfx_message_free(xfi->rfx_context, msg);
|
||||
}
|
||||
}
|
||||
else if (compressed == 2)
|
||||
{
|
||||
if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp))
|
||||
{
|
||||
printf("jpeg Decompression Failed\n");
|
||||
printf("xf_Bitmap_Decompress: jpeg Decompression Failed\n");
|
||||
}
|
||||
}
|
||||
else if (compressed)
|
||||
else if (compressed == 1)
|
||||
{
|
||||
boolean status;
|
||||
|
||||
status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp);
|
||||
|
||||
if (status != true)
|
||||
if (status == false)
|
||||
{
|
||||
printf("Bitmap Decompression Failed\n");
|
||||
printf("xf_Bitmap_Decompress: Bitmap Decompression Failed\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -27,6 +27,7 @@ enum RDP_CODEC_ID
|
||||
{
|
||||
CODEC_ID_NONE = 0x00,
|
||||
CODEC_ID_NSCODEC = 0x01,
|
||||
CODEC_ID_JPEG = 0x02,
|
||||
CODEC_ID_REMOTEFX = 0x03
|
||||
};
|
||||
|
||||
|
@ -35,7 +35,7 @@ typedef void (*pBitmap_New)(rdpContext* context, rdpBitmap* bitmap);
|
||||
typedef void (*pBitmap_Free)(rdpContext* context, rdpBitmap* bitmap);
|
||||
typedef void (*pBitmap_Paint)(rdpContext* context, rdpBitmap* bitmap);
|
||||
typedef void (*pBitmap_Decompress)(rdpContext* context, rdpBitmap* bitmap,
|
||||
uint8* data, int width, int height, int bpp, int length, boolean compressed);
|
||||
uint8* data, int width, int height, int bpp, int length, int compressed);
|
||||
typedef void (*pBitmap_SetSurface)(rdpContext* context, rdpBitmap* bitmap, boolean primary);
|
||||
|
||||
struct rdp_bitmap
|
||||
|
@ -388,7 +388,11 @@ struct rdp_settings
|
||||
ALIGN64 uint32 ns_codec_id; /* 283 */
|
||||
ALIGN64 uint32 rfx_codec_mode; /* 284 */
|
||||
ALIGN64 boolean frame_acknowledge; /* 285 */
|
||||
ALIGN64 uint64 paddingM[296 - 286]; /* 286 */
|
||||
ALIGN64 boolean jpeg_codec; /* 286 */
|
||||
ALIGN64 uint32 jpeg_codec_id; /* 287 */
|
||||
ALIGN64 uint32 jpeg_quality; /* 288 */
|
||||
ALIGN64 uint32 preferred_codec_id; /* 289 */
|
||||
ALIGN64 uint64 paddingM[296 - 290]; /* 290 */
|
||||
|
||||
/* Recording */
|
||||
ALIGN64 boolean dump_rfx; /* 296 */
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
@ -125,6 +126,54 @@ void update_gdi_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cach
|
||||
bitmap_cache_put(cache->bitmap, cache_bitmap_v2->cacheId, cache_bitmap_v2->cacheIndex, bitmap);
|
||||
}
|
||||
|
||||
void update_gdi_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3)
|
||||
{
|
||||
rdpBitmap* bitmap;
|
||||
rdpBitmap* prevBitmap;
|
||||
rdpCache* cache = context->cache;
|
||||
BITMAP_DATA_EX* bitmapData = &cache_bitmap_v3->bitmapData;
|
||||
boolean compression;
|
||||
|
||||
bitmap = Bitmap_Alloc(context);
|
||||
|
||||
Bitmap_SetDimensions(context, bitmap, bitmapData->width, bitmapData->height);
|
||||
|
||||
if (cache_bitmap_v3->bitmapData.bpp == 0)
|
||||
{
|
||||
/* Workaround for Windows 8 bug where bitmapBpp is not set */
|
||||
cache_bitmap_v3->bitmapData.bpp = context->instance->settings->color_depth;
|
||||
}
|
||||
|
||||
switch (bitmapData->codecID)
|
||||
{
|
||||
case CODEC_ID_JPEG:
|
||||
compression = 2;
|
||||
break;
|
||||
case CODEC_ID_REMOTEFX:
|
||||
compression = 3;
|
||||
break;
|
||||
case CODEC_ID_NSCODEC:
|
||||
compression = 4;
|
||||
break;
|
||||
default:
|
||||
compression = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
bitmap->Decompress(context, bitmap,
|
||||
bitmapData->data, bitmap->width, bitmap->height,
|
||||
bitmapData->bpp, bitmapData->length, compression);
|
||||
|
||||
bitmap->New(context, bitmap);
|
||||
|
||||
prevBitmap = bitmap_cache_get(cache->bitmap, cache_bitmap_v3->cacheId, cache_bitmap_v3->cacheIndex);
|
||||
|
||||
if (prevBitmap != NULL)
|
||||
Bitmap_Free(context, prevBitmap);
|
||||
|
||||
bitmap_cache_put(cache->bitmap, cache_bitmap_v3->cacheId, cache_bitmap_v3->cacheIndex, bitmap);
|
||||
}
|
||||
|
||||
void update_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap_update)
|
||||
{
|
||||
int i;
|
||||
@ -229,6 +278,7 @@ void bitmap_cache_register_callbacks(rdpUpdate* update)
|
||||
|
||||
update->secondary->CacheBitmap = update_gdi_cache_bitmap;
|
||||
update->secondary->CacheBitmapV2 = update_gdi_cache_bitmap_v2;
|
||||
update->secondary->CacheBitmapV3 = update_gdi_cache_bitmap_v3;
|
||||
|
||||
update->BitmapUpdate = update_gdi_bitmap_update;
|
||||
}
|
||||
|
@ -62,6 +62,9 @@ static const char* const CAPSET_TYPE_STRINGS[] =
|
||||
/* CODEC_GUID_NSCODEC 0xCA8D1BB9000F154F589FAE2D1A87E2D6 */
|
||||
#define CODEC_GUID_NSCODEC "\xb9\x1b\x8d\xca\x0f\x00\x4f\x15\x58\x9f\xae\x2d\x1a\x87\xe2\xd6"
|
||||
|
||||
/* CODEC_GUID_JPEG 0x430C9EED1BAF4CE6869ACB8B37B66237*/
|
||||
#define CODEC_GUID_JPEG "\xE6\x4C\xAF\x1B\xED\x9E\x0C\x43\x86\x9A\xCB\x8B\x37\xB6\x62\x37"
|
||||
|
||||
void rdp_read_capability_set_header(STREAM* s, uint16* length, uint16* type)
|
||||
{
|
||||
stream_read_uint16(s, *type); /* capabilitySetType */
|
||||
@ -1014,7 +1017,6 @@ void rdp_write_bitmap_cache_v2_capability_set(STREAM* s, rdpSettings* settings)
|
||||
header = rdp_capability_set_start(s);
|
||||
|
||||
cacheFlags = ALLOW_CACHE_WAITING_LIST_FLAG;
|
||||
cacheFlags |= 0x80; /* jpeg hack */
|
||||
|
||||
if (settings->persistent_bitmap_cache)
|
||||
cacheFlags |= PERSISTENT_KEYS_EXPECTED_FLAG;
|
||||
@ -1529,6 +1531,12 @@ void rdp_write_nsc_client_capability_container(STREAM* s, rdpSettings* settings)
|
||||
stream_write_uint8(s, 3); /* colorLossLevel */
|
||||
}
|
||||
|
||||
void rdp_write_jpeg_client_capability_container(STREAM* s, rdpSettings* settings)
|
||||
{
|
||||
stream_write_uint16(s, 1); /* codecPropertiesLength */
|
||||
stream_write_uint8(s, settings->jpeg_quality);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write RemoteFX Server Capability Container.\n
|
||||
* @param s stream
|
||||
@ -1540,6 +1548,12 @@ void rdp_write_rfx_server_capability_container(STREAM* s, rdpSettings* settings)
|
||||
stream_write_uint32(s, 0); /* reserved */
|
||||
}
|
||||
|
||||
void rdp_write_jpeg_server_capability_container(STREAM* s, rdpSettings* settings)
|
||||
{
|
||||
stream_write_uint16(s, 1); /* codecPropertiesLength */
|
||||
stream_write_uint8(s, 75);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write NSCODEC Server Capability Container.\n
|
||||
* @param s stream
|
||||
@ -1571,6 +1585,8 @@ void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings)
|
||||
bitmapCodecCount++;
|
||||
if (settings->ns_codec)
|
||||
bitmapCodecCount++;
|
||||
if (settings->jpeg_codec)
|
||||
bitmapCodecCount++;
|
||||
|
||||
stream_write_uint8(s, bitmapCodecCount);
|
||||
|
||||
@ -1603,6 +1619,20 @@ void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings)
|
||||
rdp_write_nsc_client_capability_container(s, settings);
|
||||
}
|
||||
}
|
||||
if (settings->jpeg_codec)
|
||||
{
|
||||
stream_write(s, CODEC_GUID_JPEG, 16);
|
||||
if (settings->server_mode)
|
||||
{
|
||||
stream_write_uint8(s, 0); /* codecID is defined by the client */
|
||||
rdp_write_jpeg_server_capability_container(s, settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream_write_uint8(s, CODEC_ID_JPEG); /* codecID */
|
||||
rdp_write_jpeg_client_capability_container(s, settings);
|
||||
}
|
||||
}
|
||||
rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS);
|
||||
}
|
||||
|
||||
@ -2098,4 +2128,3 @@ boolean rdp_send_confirm_active(rdpRdp* rdp)
|
||||
|
||||
return rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->user_id);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <freerdp/gdi/region.h>
|
||||
#include <freerdp/gdi/bitmap.h>
|
||||
#include <freerdp/codec/jpeg.h>
|
||||
#include <freerdp/codec/rfx.h>
|
||||
#include <freerdp/gdi/drawing.h>
|
||||
#include <freerdp/gdi/clipping.h>
|
||||
#include <freerdp/codec/color.h>
|
||||
@ -88,9 +89,14 @@ void gdi_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
|
||||
}
|
||||
|
||||
void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
|
||||
uint8* data, int width, int height, int bpp, int length, boolean compressed)
|
||||
uint8* data, int width, int height, int bpp, int length, int compressed)
|
||||
{
|
||||
uint16 size;
|
||||
RFX_MESSAGE* msg;
|
||||
uint8* src;
|
||||
uint8* dst;
|
||||
int yindex;
|
||||
int xindex;
|
||||
|
||||
size = width * height * (bpp + 7) / 8;
|
||||
|
||||
@ -99,11 +105,41 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
|
||||
else
|
||||
bitmap->data = (uint8*) xrealloc(bitmap->data, size);
|
||||
|
||||
if (compressed == 2)
|
||||
if (compressed == 4)
|
||||
{
|
||||
printf("gdi_Bitmap_Decompress: nsc not done\n");
|
||||
}
|
||||
else if (compressed == 3)
|
||||
{
|
||||
rdpGdi* gdi = context->gdi;
|
||||
rfx_context_set_pixel_format(gdi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
|
||||
msg = rfx_process_message(gdi->rfx_context, data, length);
|
||||
if (msg == NULL)
|
||||
{
|
||||
printf("gdi_Bitmap_Decompress: rfx Decompression Failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (yindex = 0; yindex < height; yindex++)
|
||||
{
|
||||
src = msg->tiles[0]->data + yindex * 64 * 4;
|
||||
dst = bitmap->data + yindex * width * 3;
|
||||
for (xindex = 0; xindex < width; xindex++)
|
||||
{
|
||||
*(dst++) = *(src++);
|
||||
*(dst++) = *(src++);
|
||||
*(dst++) = *(src++);
|
||||
src++;
|
||||
}
|
||||
}
|
||||
rfx_message_free(gdi->rfx_context, msg);
|
||||
}
|
||||
}
|
||||
else if (compressed == 2)
|
||||
{
|
||||
if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp))
|
||||
{
|
||||
printf("jpeg Decompression Failed\n");
|
||||
printf("gdi_Bitmap_Decompress: jpeg Decompression Failed\n");
|
||||
}
|
||||
}
|
||||
else if (compressed)
|
||||
@ -112,9 +148,9 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
|
||||
|
||||
status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp);
|
||||
|
||||
if (status != true)
|
||||
if (status == false)
|
||||
{
|
||||
printf("Bitmap Decompression Failed\n");
|
||||
printf("gdi_Bitmap_Decompress: Bitmap Decompression Failed\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -244,4 +280,3 @@ void gdi_register_graphics(rdpGraphics* graphics)
|
||||
graphics_register_glyph(graphics, glyph);
|
||||
xfree(glyph);
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ HGDI_BITMAP gdi_create_bitmap(rdpGdi* gdi, int width, int height, int bpp, uint8
|
||||
void gdi_Bitmap_New(rdpContext* context, rdpBitmap* bitmap);
|
||||
void gdi_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap);
|
||||
void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
|
||||
uint8* data, int width, int height, int bpp, int length, boolean compressed);
|
||||
uint8* data, int width, int height, int bpp, int length, int compressed);
|
||||
void gdi_register_graphics(rdpGraphics* graphics);
|
||||
|
||||
#endif /* __GDI_GRAPHICS_H */
|
||||
|
@ -86,10 +86,13 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
|
||||
" --gdi: graphics rendering (hw, sw)\n"
|
||||
" --no-osb: disable offscreen bitmaps\n"
|
||||
" --no-bmp-cache: disable bitmap cache\n"
|
||||
" --bcv3: codec for bitmap cache v3 (rfx, nsc, jpeg)\n"
|
||||
" --plugin: load a virtual channel plugin\n"
|
||||
" --rfx: enable RemoteFX\n"
|
||||
" --rfx-mode: RemoteFX operational flags (v[ideo], i[mage]), default is video\n"
|
||||
" --nsc: enable NSCodec (experimental)\n"
|
||||
" --jpeg: enable jpeg codec, uses 75 quality\n"
|
||||
" --jpegex: enable jpeg and set quality(1..99)\n"
|
||||
" --disable-wallpaper: disables wallpaper\n"
|
||||
" --composition: enable desktop composition\n"
|
||||
" --disable-full-window-drag: disables full window drag\n"
|
||||
@ -346,6 +349,47 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
|
||||
return FREERDP_ARGS_PARSE_FAILURE;
|
||||
}
|
||||
}
|
||||
else if (strcmp("--bcv3", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing codec name\n");
|
||||
return FREERDP_ARGS_PARSE_FAILURE;
|
||||
}
|
||||
settings->bitmap_cache_v3 = true;
|
||||
if (strcmp("rfx", argv[index]) == 0)
|
||||
{
|
||||
printf("setting rfx\n");
|
||||
settings->preferred_codec_id = 3; /* CODEC_ID_REMOTEFX */
|
||||
}
|
||||
else if (strcmp("nsc", argv[index]) == 0)
|
||||
{
|
||||
printf("setting codec nsc\n");
|
||||
settings->preferred_codec_id = 1; /* CODEC_ID_NSCODEC */
|
||||
}
|
||||
else if (strcmp("jpeg", argv[index]) == 0)
|
||||
{
|
||||
printf("setting codec jpeg\n");
|
||||
settings->preferred_codec_id = 2;
|
||||
}
|
||||
}
|
||||
else if (strcmp("--jpeg", argv[index]) == 0)
|
||||
{
|
||||
settings->jpeg_codec = true;
|
||||
settings->jpeg_quality = 75;
|
||||
}
|
||||
else if (strcmp("--jpegex", argv[index]) == 0)
|
||||
{
|
||||
index++;
|
||||
if (index == argc)
|
||||
{
|
||||
printf("missing codec name\n");
|
||||
return FREERDP_ARGS_PARSE_FAILURE;
|
||||
}
|
||||
settings->jpeg_codec = true;
|
||||
settings->jpeg_quality = atoi(argv[index]);
|
||||
}
|
||||
else if (strcmp("--rfx", argv[index]) == 0)
|
||||
{
|
||||
settings->rfx_codec = true;
|
||||
|
Loading…
Reference in New Issue
Block a user