libfreerdp-codec: refactor NSCodec
This commit is contained in:
parent
af858e8f2a
commit
8123a1d9b8
@ -31,17 +31,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* NSCODEC_BITMAP_STREAM */
|
||||
struct _NSC_STREAM
|
||||
{
|
||||
UINT32 PlaneByteCount[4];
|
||||
BYTE ColorLossLevel;
|
||||
BYTE ChromaSubSamplingLevel;
|
||||
UINT16 Reserved;
|
||||
BYTE* Planes;
|
||||
};
|
||||
typedef struct _NSC_STREAM NSC_STREAM;
|
||||
|
||||
struct _NSC_MESSAGE
|
||||
{
|
||||
int x;
|
||||
@ -54,7 +43,13 @@ struct _NSC_MESSAGE
|
||||
UINT32 MaxPlaneSize;
|
||||
BYTE* PlaneBuffers[5];
|
||||
UINT32 OrgByteCount[4];
|
||||
UINT32 PlaneByteCount[4];
|
||||
|
||||
UINT32 LumaPlaneByteCount;
|
||||
UINT32 OrangeChromaPlaneByteCount;
|
||||
UINT32 GreenChromaPlaneByteCount;
|
||||
UINT32 AlphaPlaneByteCount;
|
||||
UINT32 ColorLossLevel;
|
||||
UINT32 ChromaSubsamplingLevel;
|
||||
};
|
||||
typedef struct _NSC_MESSAGE NSC_MESSAGE;
|
||||
|
||||
@ -64,15 +59,20 @@ typedef struct _NSC_CONTEXT NSC_CONTEXT;
|
||||
|
||||
struct _NSC_CONTEXT
|
||||
{
|
||||
UINT32 OrgByteCount[4]; /* original byte length of luma, chroma orange, chroma green, alpha variable in order */
|
||||
NSC_STREAM nsc_stream;
|
||||
UINT32 OrgByteCount[4];
|
||||
UINT16 bpp;
|
||||
UINT16 width;
|
||||
UINT16 height;
|
||||
BYTE* BitmapData; /* final argb values in little endian order */
|
||||
UINT32 BitmapDataLength; /* the maximum length of the buffer that bmpdata points to */
|
||||
BYTE* BitmapData;
|
||||
UINT32 BitmapDataLength;
|
||||
RDP_PIXEL_FORMAT pixel_format;
|
||||
|
||||
BYTE* Planes;
|
||||
UINT32 PlaneByteCount[4];
|
||||
UINT32 ColorLossLevel;
|
||||
UINT32 ChromaSubsamplingLevel;
|
||||
BOOL DynamicColorFidelity;
|
||||
|
||||
/* color palette allocated by the application */
|
||||
const BYTE* palette;
|
||||
|
||||
|
@ -63,14 +63,14 @@ static void nsc_decode(NSC_CONTEXT* context)
|
||||
|
||||
bmpdata = context->BitmapData;
|
||||
rw = ROUND_UP_TO(context->width, 8);
|
||||
shift = context->nsc_stream.ColorLossLevel - 1; /* colorloss recovery + YCoCg shift */
|
||||
shift = context->ColorLossLevel - 1; /* colorloss recovery + YCoCg shift */
|
||||
|
||||
WLog_Print(context->priv->log, WLOG_DEBUG, "NscDecode: width: %d height: %d ChromaSubSamplingLevel: %d",
|
||||
context->width, context->height, context->nsc_stream.ChromaSubSamplingLevel);
|
||||
WLog_Print(context->priv->log, WLOG_DEBUG, "NscDecode: width: %d height: %d ChromaSubsamplingLevel: %d",
|
||||
context->width, context->height, context->ChromaSubsamplingLevel);
|
||||
|
||||
for (y = 0; y < context->height; y++)
|
||||
{
|
||||
if (context->nsc_stream.ChromaSubSamplingLevel > 0)
|
||||
if (context->ChromaSubsamplingLevel)
|
||||
{
|
||||
yplane = context->priv->PlaneBuffers[0] + y * rw; /* Y */
|
||||
coplane = context->priv->PlaneBuffers[1] + (y >> 1) * (rw >> 1); /* Co, supersampled */
|
||||
@ -98,8 +98,8 @@ static void nsc_decode(NSC_CONTEXT* context)
|
||||
*bmpdata++ = MINMAX(r_val, 0, 0xFF);
|
||||
*bmpdata++ = *aplane;
|
||||
yplane++;
|
||||
coplane += (context->nsc_stream.ChromaSubSamplingLevel > 0 ? x % 2 : 1);
|
||||
cgplane += (context->nsc_stream.ChromaSubSamplingLevel > 0 ? x % 2 : 1);
|
||||
coplane += (context->ChromaSubsamplingLevel ? x % 2 : 1);
|
||||
cgplane += (context->ChromaSubsamplingLevel ? x % 2 : 1);
|
||||
aplane++;
|
||||
}
|
||||
}
|
||||
@ -159,12 +159,12 @@ static void nsc_rle_decompress_data(NSC_CONTEXT* context)
|
||||
UINT32 planeSize;
|
||||
UINT32 originalSize;
|
||||
|
||||
rle = context->nsc_stream.Planes;
|
||||
rle = context->Planes;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
originalSize = context->OrgByteCount[i];
|
||||
planeSize = context->nsc_stream.PlaneByteCount[i];
|
||||
planeSize = context->PlaneByteCount[i];
|
||||
|
||||
if (planeSize == 0)
|
||||
FillMemory(context->priv->PlaneBuffers[i], originalSize, 0xFF);
|
||||
@ -182,13 +182,13 @@ static void nsc_stream_initialize(NSC_CONTEXT* context, wStream* s)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
Stream_Read_UINT32(s, context->nsc_stream.PlaneByteCount[i]);
|
||||
Stream_Read_UINT32(s, context->PlaneByteCount[i]);
|
||||
|
||||
Stream_Read_UINT8(s, context->nsc_stream.ColorLossLevel);
|
||||
Stream_Read_UINT8(s, context->nsc_stream.ChromaSubSamplingLevel);
|
||||
Stream_Seek(s, 2);
|
||||
Stream_Read_UINT8(s, context->ColorLossLevel); /* ColorLossLevel (1 byte) */
|
||||
Stream_Read_UINT8(s, context->ChromaSubsamplingLevel); /* ChromaSubsamplingLevel (1 byte) */
|
||||
Stream_Seek(s, 2); /* Reserved (2 bytes) */
|
||||
|
||||
context->nsc_stream.Planes = Stream_Pointer(s);
|
||||
context->Planes = Stream_Pointer(s);
|
||||
}
|
||||
|
||||
static void nsc_context_initialize(NSC_CONTEXT* context, wStream* s)
|
||||
@ -232,7 +232,7 @@ static void nsc_context_initialize(NSC_CONTEXT* context, wStream* s)
|
||||
context->OrgByteCount[i] = context->width * context->height;
|
||||
}
|
||||
|
||||
if (context->nsc_stream.ChromaSubSamplingLevel > 0) /* [MS-RDPNSC] 2.2 */
|
||||
if (context->ChromaSubsamplingLevel)
|
||||
{
|
||||
context->OrgByteCount[0] = tempWidth * context->height;
|
||||
context->OrgByteCount[1] = (tempWidth >> 1) * (tempHeight >> 1);
|
||||
@ -288,8 +288,8 @@ NSC_CONTEXT* nsc_context_new(void)
|
||||
PROFILER_CREATE(context->priv->prof_nsc_encode, "nsc_encode");
|
||||
|
||||
/* Default encoding parameters */
|
||||
context->nsc_stream.ColorLossLevel = 3;
|
||||
context->nsc_stream.ChromaSubSamplingLevel = 1;
|
||||
context->ColorLossLevel = 3;
|
||||
context->ChromaSubsamplingLevel = 1;
|
||||
|
||||
/* init optimized methods */
|
||||
NSC_INIT_SIMD(context);
|
||||
|
@ -57,7 +57,7 @@ static void nsc_context_initialize_encode(NSC_CONTEXT* context)
|
||||
context->priv->PlaneBuffersLength = length;
|
||||
}
|
||||
|
||||
if (context->nsc_stream.ChromaSubSamplingLevel > 0)
|
||||
if (context->ChromaSubsamplingLevel)
|
||||
{
|
||||
context->OrgByteCount[0] = tempWidth * context->height;
|
||||
context->OrgByteCount[1] = tempWidth * tempHeight / 4;
|
||||
@ -93,8 +93,8 @@ static void nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, BYTE* data, int scan
|
||||
|
||||
tempWidth = ROUND_UP_TO(context->width, 8);
|
||||
tempHeight = ROUND_UP_TO(context->height, 2);
|
||||
rw = (context->nsc_stream.ChromaSubSamplingLevel > 0 ? tempWidth : context->width);
|
||||
ccl = context->nsc_stream.ColorLossLevel;
|
||||
rw = (context->ChromaSubsamplingLevel ? tempWidth : context->width);
|
||||
ccl = context->ColorLossLevel;
|
||||
yplane = context->priv->PlaneBuffers[0];
|
||||
coplane = context->priv->PlaneBuffers[1];
|
||||
cgplane = context->priv->PlaneBuffers[2];
|
||||
@ -201,7 +201,7 @@ static void nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, BYTE* data, int scan
|
||||
*aplane++ = a_val;
|
||||
}
|
||||
|
||||
if (context->nsc_stream.ChromaSubSamplingLevel > 0 && (x % 2) == 1)
|
||||
if (context->ChromaSubsamplingLevel && (x % 2) == 1)
|
||||
{
|
||||
*yplane = *(yplane - 1);
|
||||
*coplane = *(coplane - 1);
|
||||
@ -209,7 +209,7 @@ static void nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, BYTE* data, int scan
|
||||
}
|
||||
}
|
||||
|
||||
if (context->nsc_stream.ChromaSubSamplingLevel > 0 && (y % 2) == 1)
|
||||
if (context->ChromaSubsamplingLevel && (y % 2) == 1)
|
||||
{
|
||||
CopyMemory(yplane + rw, yplane, rw);
|
||||
CopyMemory(coplane + rw, coplane, rw);
|
||||
@ -260,7 +260,7 @@ void nsc_encode(NSC_CONTEXT* context, BYTE* bmpdata, int rowstride)
|
||||
{
|
||||
nsc_encode_argb_to_aycocg(context, bmpdata, rowstride);
|
||||
|
||||
if (context->nsc_stream.ChromaSubSamplingLevel > 0)
|
||||
if (context->ChromaSubsamplingLevel)
|
||||
{
|
||||
nsc_encode_subsampling(context);
|
||||
}
|
||||
@ -344,7 +344,7 @@ static void nsc_rle_compress_data(NSC_CONTEXT* context)
|
||||
planeSize = originalSize;
|
||||
}
|
||||
|
||||
context->nsc_stream.PlaneByteCount[i] = planeSize;
|
||||
context->PlaneByteCount[i] = planeSize;
|
||||
}
|
||||
}
|
||||
|
||||
@ -359,7 +359,7 @@ UINT32 nsc_compute_byte_count(NSC_CONTEXT* context, UINT32* ByteCount, UINT32 wi
|
||||
|
||||
maxPlaneSize = tempWidth * tempHeight + 16;
|
||||
|
||||
if (context->nsc_stream.ChromaSubSamplingLevel > 0)
|
||||
if (context->ChromaSubsamplingLevel)
|
||||
{
|
||||
ByteCount[0] = tempWidth * height;
|
||||
ByteCount[1] = tempWidth * tempHeight / 4;
|
||||
@ -469,10 +469,12 @@ NSC_MESSAGE* nsc_encode_messages(NSC_CONTEXT* context, BYTE* data, int x, int y,
|
||||
nsc_rle_compress_data(context);
|
||||
PROFILER_EXIT(context->priv->prof_nsc_rle_compress_data);
|
||||
|
||||
messages[i].PlaneByteCount[0] = context->nsc_stream.PlaneByteCount[0];
|
||||
messages[i].PlaneByteCount[1] = context->nsc_stream.PlaneByteCount[1];
|
||||
messages[i].PlaneByteCount[2] = context->nsc_stream.PlaneByteCount[2];
|
||||
messages[i].PlaneByteCount[3] = context->nsc_stream.PlaneByteCount[3];
|
||||
messages[i].LumaPlaneByteCount = context->PlaneByteCount[0];
|
||||
messages[i].OrangeChromaPlaneByteCount = context->PlaneByteCount[1];
|
||||
messages[i].GreenChromaPlaneByteCount = context->PlaneByteCount[2];
|
||||
messages[i].AlphaPlaneByteCount = context->PlaneByteCount[3];
|
||||
messages[i].ColorLossLevel = context->ColorLossLevel;
|
||||
messages[i].ChromaSubsamplingLevel = context->ChromaSubsamplingLevel;
|
||||
}
|
||||
|
||||
context->priv->PlaneBuffers[0] = NULL;
|
||||
@ -486,25 +488,31 @@ NSC_MESSAGE* nsc_encode_messages(NSC_CONTEXT* context, BYTE* data, int x, int y,
|
||||
|
||||
int nsc_write_message(NSC_CONTEXT* context, wStream* s, NSC_MESSAGE* message)
|
||||
{
|
||||
int i;
|
||||
UINT32 totalPlaneByteCount;
|
||||
|
||||
Stream_EnsureRemainingCapacity(s, 20);
|
||||
Stream_Write_UINT32(s, message->PlaneByteCount[0]); /* LumaPlaneByteCount (4 bytes) */
|
||||
Stream_Write_UINT32(s, message->PlaneByteCount[1]); /* OrangeChromaPlaneByteCount (4 bytes) */
|
||||
Stream_Write_UINT32(s, message->PlaneByteCount[2]); /* GreenChromaPlaneByteCount (4 bytes) */
|
||||
Stream_Write_UINT32(s, message->PlaneByteCount[3]); /* AlphaPlaneByteCount (4 bytes) */
|
||||
Stream_Write_UINT8(s, context->nsc_stream.ColorLossLevel); /* ColorLossLevel (1 byte) */
|
||||
Stream_Write_UINT8(s, context->nsc_stream.ChromaSubSamplingLevel); /* ChromaSubsamplingLevel (1 byte) */
|
||||
totalPlaneByteCount = message->LumaPlaneByteCount + message->OrangeChromaPlaneByteCount +
|
||||
message->GreenChromaPlaneByteCount + message->AlphaPlaneByteCount;
|
||||
|
||||
Stream_EnsureRemainingCapacity(s, 20 + totalPlaneByteCount);
|
||||
Stream_Write_UINT32(s, message->LumaPlaneByteCount); /* LumaPlaneByteCount (4 bytes) */
|
||||
Stream_Write_UINT32(s, message->OrangeChromaPlaneByteCount); /* OrangeChromaPlaneByteCount (4 bytes) */
|
||||
Stream_Write_UINT32(s, message->GreenChromaPlaneByteCount); /* GreenChromaPlaneByteCount (4 bytes) */
|
||||
Stream_Write_UINT32(s, message->AlphaPlaneByteCount); /* AlphaPlaneByteCount (4 bytes) */
|
||||
Stream_Write_UINT8(s, message->ColorLossLevel); /* ColorLossLevel (1 byte) */
|
||||
Stream_Write_UINT8(s, message->ChromaSubsamplingLevel); /* ChromaSubsamplingLevel (1 byte) */
|
||||
Stream_Write_UINT16(s, 0); /* Reserved (2 bytes) */
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (message->PlaneByteCount[i] > 0)
|
||||
{
|
||||
Stream_EnsureRemainingCapacity(s, (int) message->PlaneByteCount[i]);
|
||||
Stream_Write(s, message->PlaneBuffers[i], message->PlaneByteCount[i]);
|
||||
}
|
||||
}
|
||||
if (message->LumaPlaneByteCount)
|
||||
Stream_Write(s, message->PlaneBuffers[0], message->LumaPlaneByteCount); /* LumaPlane */
|
||||
|
||||
if (message->OrangeChromaPlaneByteCount)
|
||||
Stream_Write(s, message->PlaneBuffers[1], message->OrangeChromaPlaneByteCount); /* OrangeChromaPlane */
|
||||
|
||||
if (message->GreenChromaPlaneByteCount)
|
||||
Stream_Write(s, message->PlaneBuffers[2], message->GreenChromaPlaneByteCount); /* GreenChromaPlane */
|
||||
|
||||
if (message->AlphaPlaneByteCount)
|
||||
Stream_Write(s, message->PlaneBuffers[3], message->AlphaPlaneByteCount); /* AlphaPlane */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -517,7 +525,8 @@ int nsc_message_free(NSC_CONTEXT* context, NSC_MESSAGE* message)
|
||||
|
||||
void nsc_compose_message(NSC_CONTEXT* context, wStream* s, BYTE* data, int width, int height, int scanline)
|
||||
{
|
||||
int i;
|
||||
NSC_MESSAGE s_message = { 0 };
|
||||
NSC_MESSAGE* message = &s_message;
|
||||
|
||||
context->width = width;
|
||||
context->height = height;
|
||||
@ -533,22 +542,17 @@ void nsc_compose_message(NSC_CONTEXT* context, wStream* s, BYTE* data, int width
|
||||
nsc_rle_compress_data(context);
|
||||
PROFILER_EXIT(context->priv->prof_nsc_rle_compress_data);
|
||||
|
||||
/* Assemble the NSCodec message into stream */
|
||||
Stream_EnsureRemainingCapacity(s, 20);
|
||||
Stream_Write_UINT32(s, context->nsc_stream.PlaneByteCount[0]); /* LumaPlaneByteCount (4 bytes) */
|
||||
Stream_Write_UINT32(s, context->nsc_stream.PlaneByteCount[1]); /* OrangeChromaPlaneByteCount (4 bytes) */
|
||||
Stream_Write_UINT32(s, context->nsc_stream.PlaneByteCount[2]); /* GreenChromaPlaneByteCount (4 bytes) */
|
||||
Stream_Write_UINT32(s, context->nsc_stream.PlaneByteCount[3]); /* AlphaPlaneByteCount (4 bytes) */
|
||||
Stream_Write_UINT8(s, context->nsc_stream.ColorLossLevel); /* ColorLossLevel (1 byte) */
|
||||
Stream_Write_UINT8(s, context->nsc_stream.ChromaSubSamplingLevel); /* ChromaSubsamplingLevel (1 byte) */
|
||||
Stream_Write_UINT16(s, 0); /* Reserved (2 bytes) */
|
||||
message->PlaneBuffers[0] = context->priv->PlaneBuffers[0];
|
||||
message->PlaneBuffers[1] = context->priv->PlaneBuffers[1];
|
||||
message->PlaneBuffers[2] = context->priv->PlaneBuffers[2];
|
||||
message->PlaneBuffers[3] = context->priv->PlaneBuffers[3];
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (context->nsc_stream.PlaneByteCount[i] > 0)
|
||||
{
|
||||
Stream_EnsureRemainingCapacity(s, (int) context->nsc_stream.PlaneByteCount[i]);
|
||||
Stream_Write(s, context->priv->PlaneBuffers[i], context->nsc_stream.PlaneByteCount[i]);
|
||||
}
|
||||
}
|
||||
message->LumaPlaneByteCount = context->PlaneByteCount[0];
|
||||
message->OrangeChromaPlaneByteCount = context->PlaneByteCount[1];
|
||||
message->GreenChromaPlaneByteCount = context->PlaneByteCount[2];
|
||||
message->AlphaPlaneByteCount = context->PlaneByteCount[3];
|
||||
message->ColorLossLevel = context->ColorLossLevel;
|
||||
message->ChromaSubsamplingLevel = context->ChromaSubsamplingLevel;
|
||||
|
||||
nsc_write_message(context, s, message);
|
||||
}
|
||||
|
@ -56,8 +56,8 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* data, int
|
||||
|
||||
tempWidth = ROUND_UP_TO(context->width, 8);
|
||||
tempHeight = ROUND_UP_TO(context->height, 2);
|
||||
rw = (context->nsc_stream.ChromaSubSamplingLevel > 0 ? tempWidth : context->width);
|
||||
ccl = context->nsc_stream.ColorLossLevel;
|
||||
rw = (context->ChromaSubsamplingLevel > 0 ? tempWidth : context->width);
|
||||
ccl = context->ColorLossLevel;
|
||||
yplane = context->priv->PlaneBuffers[0];
|
||||
coplane = context->priv->PlaneBuffers[1];
|
||||
cgplane = context->priv->PlaneBuffers[2];
|
||||
@ -278,7 +278,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* data, int
|
||||
aplane += 8;
|
||||
}
|
||||
|
||||
if (context->nsc_stream.ChromaSubSamplingLevel > 0 && (context->width % 2) == 1)
|
||||
if (context->ChromaSubsamplingLevel > 0 && (context->width % 2) == 1)
|
||||
{
|
||||
context->priv->PlaneBuffers[0][y * rw + context->width] = context->priv->PlaneBuffers[0][y * rw + context->width - 1];
|
||||
context->priv->PlaneBuffers[1][y * rw + context->width] = context->priv->PlaneBuffers[1][y * rw + context->width - 1];
|
||||
@ -286,7 +286,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* data, int
|
||||
}
|
||||
}
|
||||
|
||||
if (context->nsc_stream.ChromaSubSamplingLevel > 0 && (y % 2) == 1)
|
||||
if (context->ChromaSubsamplingLevel > 0 && (y % 2) == 1)
|
||||
{
|
||||
CopyMemory(yplane + rw, yplane, rw);
|
||||
CopyMemory(coplane + rw, coplane, rw);
|
||||
@ -351,7 +351,7 @@ static void nsc_encode_sse2(NSC_CONTEXT* context, BYTE* data, int scanline)
|
||||
{
|
||||
nsc_encode_argb_to_aycocg_sse2(context, data, scanline);
|
||||
|
||||
if (context->nsc_stream.ChromaSubSamplingLevel > 0)
|
||||
if (context->ChromaSubsamplingLevel > 0)
|
||||
{
|
||||
nsc_encode_subsampling_sse2(context);
|
||||
}
|
||||
|
@ -142,6 +142,9 @@ int shadow_encoder_init_rfx(rdpShadowEncoder* encoder)
|
||||
|
||||
int shadow_encoder_init_nsc(rdpShadowEncoder* encoder)
|
||||
{
|
||||
rdpContext* context = (rdpContext*) encoder->client;
|
||||
rdpSettings* settings = context->settings;
|
||||
|
||||
if (!encoder->nsc)
|
||||
encoder->nsc = nsc_context_new();
|
||||
|
||||
@ -159,6 +162,10 @@ int shadow_encoder_init_nsc(rdpShadowEncoder* encoder)
|
||||
encoder->frameList = ListDictionary_New(TRUE);
|
||||
}
|
||||
|
||||
encoder->nsc->ColorLossLevel = settings->NSCodecColorLossLevel;
|
||||
encoder->nsc->ChromaSubsamplingLevel = settings->NSCodecAllowSubsampling ? 1 : 0;
|
||||
encoder->nsc->DynamicColorFidelity = settings->NSCodecAllowDynamicColorFidelity;
|
||||
|
||||
encoder->codecs |= FREERDP_CODEC_NSCODEC;
|
||||
|
||||
return 1;
|
||||
|
Loading…
Reference in New Issue
Block a user