int shadow_encoder_reset(rdpShadowEncoder* encoder) { int status; UINT32 codecs = encoder->codecs; rdpContext* context = (rdpContext*) encoder->client; rdpSettings* settings = context->settings; status = shadow_encoder_uninit(encoder); if (status < 0) return -1; status = shadow_encoder_init(encoder); if (status < 0) return -1; status = shadow_encoder_prepare(encoder, codecs); if (status < 0) return -1; encoder->fps = 16; encoder->maxFps = 32; encoder->frameId = 0; encoder->lastAckframeId = 0; encoder->frameAck = settings->SurfaceFrameMarkerEnabled; return 1; }
int shadow_encoder_reset(rdpShadowEncoder* encoder) { int status; UINT32 codecs = encoder->codecs; status = shadow_encoder_uninit(encoder); if (status < 0) return -1; status = shadow_encoder_init(encoder); if (status < 0) return -1; status = shadow_encoder_prepare(encoder, codecs); if (status < 0) return -1; return 1; }
int shadow_client_send_bitmap_update(rdpShadowClient* client, rdpShadowSurface* surface, int nXSrc, int nYSrc, int nWidth, int nHeight) { BYTE* data; BYTE* buffer; int yIdx, xIdx, k; int rows, cols; int nSrcStep; BYTE* pSrcData; UINT32 DstSize; UINT32 SrcFormat; BITMAP_DATA* bitmap; rdpUpdate* update; rdpContext* context; rdpSettings* settings; UINT32 maxUpdateSize; UINT32 totalBitmapSize; UINT32 updateSizeEstimate; BITMAP_DATA* bitmapData; BITMAP_UPDATE bitmapUpdate; rdpShadowServer* server; rdpShadowEncoder* encoder; context = (rdpContext*) client; update = context->update; settings = context->settings; server = client->server; encoder = client->encoder; maxUpdateSize = settings->MultifragMaxRequestSize; if (settings->ColorDepth < 32) shadow_encoder_prepare(encoder, FREERDP_CODEC_INTERLEAVED); else shadow_encoder_prepare(encoder, FREERDP_CODEC_PLANAR); pSrcData = surface->data; nSrcStep = surface->scanline; SrcFormat = PIXEL_FORMAT_RGB32; if (server->shareSubRect) { int subX, subY; int subWidth, subHeight; subX = server->subRect.left; subY = server->subRect.top; subWidth = server->subRect.right - server->subRect.left; subHeight = server->subRect.bottom - server->subRect.top; nXSrc -= subX; nYSrc -= subY; pSrcData = &pSrcData[(subY * nSrcStep) + (subX * 4)]; } if ((nXSrc % 4) != 0) { nWidth += (nXSrc % 4); nXSrc -= (nXSrc % 4); } if ((nYSrc % 4) != 0) { nHeight += (nYSrc % 4); nYSrc -= (nYSrc % 4); } rows = (nHeight / 64) + ((nHeight % 64) ? 1 : 0); cols = (nWidth / 64) + ((nWidth % 64) ? 1 : 0); k = 0; totalBitmapSize = 0; bitmapUpdate.count = bitmapUpdate.number = rows * cols; if (!(bitmapData = (BITMAP_DATA*) malloc(sizeof(BITMAP_DATA) * bitmapUpdate.number))) return -1; bitmapUpdate.rectangles = bitmapData; if ((nWidth % 4) != 0) { nWidth += (4 - (nWidth % 4)); } if ((nHeight % 4) != 0) { nHeight += (4 - (nHeight % 4)); } for (yIdx = 0; yIdx < rows; yIdx++) { for (xIdx = 0; xIdx < cols; xIdx++) { bitmap = &bitmapData[k]; bitmap->width = 64; bitmap->height = 64; bitmap->destLeft = nXSrc + (xIdx * 64); bitmap->destTop = nYSrc + (yIdx * 64); if ((bitmap->destLeft + bitmap->width) > (nXSrc + nWidth)) bitmap->width = (nXSrc + nWidth) - bitmap->destLeft; if ((bitmap->destTop + bitmap->height) > (nYSrc + nHeight)) bitmap->height = (nYSrc + nHeight) - bitmap->destTop; bitmap->destRight = bitmap->destLeft + bitmap->width - 1; bitmap->destBottom = bitmap->destTop + bitmap->height - 1; bitmap->compressed = TRUE; if ((bitmap->width < 4) || (bitmap->height < 4)) continue; if (settings->ColorDepth < 32) { int bitsPerPixel = settings->ColorDepth; int bytesPerPixel = (bitsPerPixel + 7) / 8; DstSize = 64 * 64 * 4; buffer = encoder->grid[k]; interleaved_compress(encoder->interleaved, buffer, &DstSize, bitmap->width, bitmap->height, pSrcData, SrcFormat, nSrcStep, bitmap->destLeft, bitmap->destTop, NULL, bitsPerPixel); bitmap->bitmapDataStream = buffer; bitmap->bitmapLength = DstSize; bitmap->bitsPerPixel = bitsPerPixel; bitmap->cbScanWidth = bitmap->width * bytesPerPixel; bitmap->cbUncompressedSize = bitmap->width * bitmap->height * bytesPerPixel; } else { int dstSize; buffer = encoder->grid[k]; data = &pSrcData[(bitmap->destTop * nSrcStep) + (bitmap->destLeft * 4)]; buffer = freerdp_bitmap_compress_planar(encoder->planar, data, SrcFormat, bitmap->width, bitmap->height, nSrcStep, buffer, &dstSize); bitmap->bitmapDataStream = buffer; bitmap->bitmapLength = dstSize; bitmap->bitsPerPixel = 32; bitmap->cbScanWidth = bitmap->width * 4; bitmap->cbUncompressedSize = bitmap->width * bitmap->height * 4; } bitmap->cbCompFirstRowSize = 0; bitmap->cbCompMainBodySize = bitmap->bitmapLength; totalBitmapSize += bitmap->bitmapLength; k++; } } bitmapUpdate.count = bitmapUpdate.number = k; updateSizeEstimate = totalBitmapSize + (k * bitmapUpdate.count) + 16; if (updateSizeEstimate > maxUpdateSize) { UINT32 i, j; UINT32 updateSize; UINT32 newUpdateSize; BITMAP_DATA* fragBitmapData = NULL; if (k > 0) fragBitmapData = (BITMAP_DATA*) malloc(sizeof(BITMAP_DATA) * k); if (!fragBitmapData) { free(bitmapData); return -1; } bitmapUpdate.rectangles = fragBitmapData; i = j = 0; updateSize = 1024; while (i < k) { newUpdateSize = updateSize + (bitmapData[i].bitmapLength + 16); if ((newUpdateSize < maxUpdateSize) && ((i + 1) < k)) { CopyMemory(&fragBitmapData[j++], &bitmapData[i++], sizeof(BITMAP_DATA)); updateSize = newUpdateSize; } else { if ((i + 1) >= k) { CopyMemory(&fragBitmapData[j++], &bitmapData[i++], sizeof(BITMAP_DATA)); updateSize = newUpdateSize; } bitmapUpdate.count = bitmapUpdate.number = j; IFCALL(update->BitmapUpdate, context, &bitmapUpdate); updateSize = 1024; j = 0; } } free(fragBitmapData); } else { IFCALL(update->BitmapUpdate, context, &bitmapUpdate); } free(bitmapData); return 1; }
int shadow_client_send_surface_bits(rdpShadowClient* client, rdpShadowSurface* surface, int nXSrc, int nYSrc, int nWidth, int nHeight) { int i; BOOL first; BOOL last; wStream* s; int nSrcStep; BYTE* pSrcData; int numMessages; UINT32 frameId = 0; rdpUpdate* update; rdpContext* context; rdpSettings* settings; rdpShadowServer* server; rdpShadowEncoder* encoder; SURFACE_BITS_COMMAND cmd; context = (rdpContext*) client; update = context->update; settings = context->settings; server = client->server; encoder = client->encoder; pSrcData = surface->data; nSrcStep = surface->scanline; if (server->shareSubRect) { int subX, subY; int subWidth, subHeight; subX = server->subRect.left; subY = server->subRect.top; subWidth = server->subRect.right - server->subRect.left; subHeight = server->subRect.bottom - server->subRect.top; nXSrc -= subX; nYSrc -= subY; pSrcData = &pSrcData[(subY * nSrcStep) + (subX * 4)]; } if (encoder->frameAck) frameId = shadow_encoder_create_frame_id(encoder); if (settings->RemoteFxCodec) { RFX_RECT rect; RFX_MESSAGE* messages; RFX_RECT *messageRects = NULL; shadow_encoder_prepare(encoder, FREERDP_CODEC_REMOTEFX); s = encoder->bs; rect.x = nXSrc; rect.y = nYSrc; rect.width = nWidth; rect.height = nHeight; if (!(messages = rfx_encode_messages(encoder->rfx, &rect, 1, pSrcData, settings->DesktopWidth, settings->DesktopHeight, nSrcStep, &numMessages, settings->MultifragMaxRequestSize))) { return 0; } cmd.codecID = settings->RemoteFxCodecId; cmd.destLeft = 0; cmd.destTop = 0; cmd.destRight = settings->DesktopWidth; cmd.destBottom = settings->DesktopHeight; cmd.bpp = 32; cmd.width = settings->DesktopWidth; cmd.height = settings->DesktopHeight; cmd.skipCompression = TRUE; if (numMessages > 0) messageRects = messages[0].rects; for (i = 0; i < numMessages; i++) { Stream_SetPosition(s, 0); if (!rfx_write_message(encoder->rfx, s, &messages[i])) { while (i < numMessages) { rfx_message_free(encoder->rfx, &messages[i++]); } break; } rfx_message_free(encoder->rfx, &messages[i]); cmd.bitmapDataLength = Stream_GetPosition(s); cmd.bitmapData = Stream_Buffer(s); first = (i == 0) ? TRUE : FALSE; last = ((i + 1) == numMessages) ? TRUE : FALSE; if (!encoder->frameAck) IFCALL(update->SurfaceBits, update->context, &cmd); else IFCALL(update->SurfaceFrameBits, update->context, &cmd, first, last, frameId); } free(messageRects); free(messages); } else if (settings->NSCodec) { shadow_encoder_prepare(encoder, FREERDP_CODEC_NSCODEC); s = encoder->bs; Stream_SetPosition(s, 0); pSrcData = &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)]; nsc_compose_message(encoder->nsc, s, pSrcData, nWidth, nHeight, nSrcStep); cmd.bpp = 32; cmd.codecID = settings->NSCodecId; cmd.destLeft = nXSrc; cmd.destTop = nYSrc; cmd.destRight = cmd.destLeft + nWidth; cmd.destBottom = cmd.destTop + nHeight; cmd.width = nWidth; cmd.height = nHeight; cmd.bitmapDataLength = Stream_GetPosition(s); cmd.bitmapData = Stream_Buffer(s); first = TRUE; last = TRUE; if (!encoder->frameAck) IFCALL(update->SurfaceBits, update->context, &cmd); else IFCALL(update->SurfaceFrameBits, update->context, &cmd, first, last, frameId); } return 1; }
/** * Function description * * @return TRUE on success */ static BOOL shadow_client_send_surface_bits(rdpShadowClient* client, BYTE* pSrcData, int nSrcStep, int nXSrc, int nYSrc, int nWidth, int nHeight) { BOOL ret = TRUE; int i; BOOL first; BOOL last; wStream* s; int numMessages; UINT32 frameId = 0; rdpUpdate* update; rdpContext* context; rdpSettings* settings; rdpShadowServer* server; rdpShadowEncoder* encoder; SURFACE_BITS_COMMAND cmd; context = (rdpContext*) client; update = context->update; settings = context->settings; server = client->server; encoder = client->encoder; if (encoder->frameAck) frameId = shadow_encoder_create_frame_id(encoder); if (settings->RemoteFxCodec) { RFX_RECT rect; RFX_MESSAGE* messages; RFX_RECT *messageRects = NULL; if (shadow_encoder_prepare(encoder, FREERDP_CODEC_REMOTEFX) < 0) { WLog_ERR(TAG, "Failed to prepare encoder FREERDP_CODEC_REMOTEFX"); return FALSE; } s = encoder->bs; rect.x = nXSrc; rect.y = nYSrc; rect.width = nWidth; rect.height = nHeight; if (!(messages = rfx_encode_messages(encoder->rfx, &rect, 1, pSrcData, settings->DesktopWidth, settings->DesktopHeight, nSrcStep, &numMessages, settings->MultifragMaxRequestSize))) { WLog_ERR(TAG, "rfx_encode_messages failed"); return FALSE; } cmd.codecID = settings->RemoteFxCodecId; cmd.destLeft = 0; cmd.destTop = 0; cmd.destRight = settings->DesktopWidth; cmd.destBottom = settings->DesktopHeight; cmd.bpp = 32; cmd.width = settings->DesktopWidth; cmd.height = settings->DesktopHeight; cmd.skipCompression = TRUE; if (numMessages > 0) messageRects = messages[0].rects; for (i = 0; i < numMessages; i++) { Stream_SetPosition(s, 0); if (!rfx_write_message(encoder->rfx, s, &messages[i])) { while (i < numMessages) { rfx_message_free(encoder->rfx, &messages[i++]); } WLog_ERR(TAG, "rfx_write_message failed"); ret = FALSE; break; } rfx_message_free(encoder->rfx, &messages[i]); cmd.bitmapDataLength = Stream_GetPosition(s); cmd.bitmapData = Stream_Buffer(s); first = (i == 0) ? TRUE : FALSE; last = ((i + 1) == numMessages) ? TRUE : FALSE; if (!encoder->frameAck) IFCALLRET(update->SurfaceBits, ret, update->context, &cmd); else IFCALLRET(update->SurfaceFrameBits, ret, update->context, &cmd, first, last, frameId); if (!ret) { WLog_ERR(TAG, "Send surface bits(RemoteFxCodec) failed"); break; } } free(messageRects); free(messages); } else if (settings->NSCodec) { if (shadow_encoder_prepare(encoder, FREERDP_CODEC_NSCODEC) < 0) { WLog_ERR(TAG, "Failed to prepare encoder FREERDP_CODEC_NSCODEC"); return FALSE; } s = encoder->bs; Stream_SetPosition(s, 0); pSrcData = &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)]; nsc_compose_message(encoder->nsc, s, pSrcData, nWidth, nHeight, nSrcStep); cmd.bpp = 32; cmd.codecID = settings->NSCodecId; cmd.destLeft = nXSrc; cmd.destTop = nYSrc; cmd.destRight = cmd.destLeft + nWidth; cmd.destBottom = cmd.destTop + nHeight; cmd.width = nWidth; cmd.height = nHeight; cmd.bitmapDataLength = Stream_GetPosition(s); cmd.bitmapData = Stream_Buffer(s); first = TRUE; last = TRUE; if (!encoder->frameAck) IFCALLRET(update->SurfaceBits, ret, update->context, &cmd); else IFCALLRET(update->SurfaceFrameBits, ret, update->context, &cmd, first, last, frameId); if (!ret) { WLog_ERR(TAG, "Send surface bits(NSCodec) failed"); } } return ret; }
/** * Function description * * @return TRUE on success */ static BOOL shadow_client_send_surface_gfx(rdpShadowClient* client, BYTE* pSrcData, int nSrcStep, int nXSrc, int nYSrc, int nWidth, int nHeight) { UINT error = CHANNEL_RC_OK; rdpUpdate* update; rdpContext* context; rdpSettings* settings; rdpShadowServer* server; rdpShadowEncoder* encoder; RDPGFX_SURFACE_COMMAND cmd; RDPGFX_START_FRAME_PDU cmdstart; RDPGFX_END_FRAME_PDU cmdend; SYSTEMTIME sTime; context = (rdpContext*) client; update = context->update; settings = context->settings; server = client->server; encoder = client->encoder; cmdstart.frameId = shadow_encoder_create_frame_id(encoder); GetSystemTime(&sTime); cmdstart.timestamp = sTime.wHour << 22 | sTime.wMinute << 16 | sTime.wSecond << 10 | sTime.wMilliseconds; cmdend.frameId = cmdstart.frameId; cmd.surfaceId = 0; cmd.contextId = 0; cmd.format = PIXEL_FORMAT_XRGB_8888; cmd.left = nXSrc; cmd.top = nYSrc; cmd.right = cmd.left + nWidth; cmd.bottom = cmd.top + nHeight; cmd.width = nWidth; cmd.height = nHeight; if (settings->GfxH264) { RDPGFX_AVC420_BITMAP_STREAM avc420; RECTANGLE_16 regionRect; RDPGFX_H264_QUANT_QUALITY quantQualityVal; if (shadow_encoder_prepare(encoder, FREERDP_CODEC_AVC420) < 0) { WLog_ERR(TAG, "Failed to prepare encoder FREERDP_CODEC_AVC420"); return FALSE; } avc420_compress(encoder->h264, pSrcData, PIXEL_FORMAT_RGB32, nSrcStep, nWidth, nHeight, &avc420.data, &avc420.length); cmd.codecId = RDPGFX_CODECID_AVC420; cmd.extra = (void *)&avc420; regionRect.left = cmd.left; regionRect.top = cmd.top; regionRect.right = cmd.right; regionRect.bottom = cmd.bottom; quantQualityVal.qp = encoder->h264->QP; quantQualityVal.r = 0; quantQualityVal.p = 0; quantQualityVal.qualityVal = 100 - quantQualityVal.qp; avc420.meta.numRegionRects = 1; avc420.meta.regionRects = ®ionRect; avc420.meta.quantQualityVals = &quantQualityVal; IFCALLRET(client->rdpgfx->SurfaceFrameCommand, error, client->rdpgfx, &cmd, &cmdstart, &cmdend); if (error) { WLog_ERR(TAG, "SurfaceFrameCommand failed with error %lu", error); return FALSE; } } return TRUE; }