2 * FreeRDP: A Remote Desktop Protocol Implementation
4 * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
25 #include "shadow_encoder.h"
27 int shadow_encoder_create_frame_id(rdpShadowEncoder* encoder)
33 inFlightFrames = ListDictionary_Count(encoder->frameList);
35 if (inFlightFrames > encoder->frameAck)
37 encoder->fps = (100 / (inFlightFrames + 1) * encoder->maxFps) / 100;
43 if (encoder->fps > encoder->maxFps)
44 encoder->fps = encoder->maxFps;
50 frame = (SURFACE_FRAME*) malloc(sizeof(SURFACE_FRAME));
55 frameId = frame->frameId = ++encoder->frameId;
56 ListDictionary_Add(encoder->frameList, (void*) (size_t) frame->frameId, frame);
58 return (int) frame->frameId;
61 int shadow_encoder_init_grid(rdpShadowEncoder* encoder)
67 encoder->gridWidth = ((encoder->width + (encoder->maxTileWidth - 1)) / encoder->maxTileWidth);
68 encoder->gridHeight = ((encoder->height + (encoder->maxTileHeight - 1)) / encoder->maxTileHeight);
70 tileSize = encoder->maxTileWidth * encoder->maxTileHeight * 4;
71 tileCount = encoder->gridWidth * encoder->gridHeight;
73 encoder->gridBuffer = (BYTE*) malloc(tileSize * tileCount);
75 if (!encoder->gridBuffer)
78 encoder->grid = (BYTE**) malloc(tileCount * sizeof(BYTE*));
83 for (i = 0; i < encoder->gridHeight; i++)
85 for (j = 0; j < encoder->gridWidth; j++)
87 k = (i * encoder->gridHeight) + j;
88 encoder->grid[k] = &(encoder->gridBuffer[k * tileSize]);
95 int shadow_encoder_uninit_grid(rdpShadowEncoder* encoder)
97 if (encoder->gridBuffer)
99 free(encoder->gridBuffer);
100 encoder->gridBuffer = NULL;
106 encoder->grid = NULL;
109 encoder->gridWidth = 0;
110 encoder->gridHeight = 0;
115 int shadow_encoder_init_rfx(rdpShadowEncoder* encoder)
118 encoder->rfx = rfx_context_new(TRUE);
123 encoder->rfx->mode = RLGR3;
124 encoder->rfx->width = encoder->width;
125 encoder->rfx->height = encoder->height;
127 rfx_context_set_pixel_format(encoder->rfx, RDP_PIXEL_FORMAT_B8G8R8A8);
129 if (!encoder->frameList)
132 encoder->maxFps = 32;
133 encoder->frameId = 0;
134 encoder->frameAck = TRUE;
135 encoder->frameList = ListDictionary_New(TRUE);
138 encoder->codecs |= SHADOW_CODEC_REMOTEFX;
143 int shadow_encoder_init_nsc(rdpShadowEncoder* encoder)
146 encoder->nsc = nsc_context_new();
151 nsc_context_set_pixel_format(encoder->nsc, RDP_PIXEL_FORMAT_B8G8R8A8);
153 if (!encoder->frameList)
156 encoder->maxFps = 32;
157 encoder->frameId = 0;
158 encoder->frameAck = TRUE;
159 encoder->frameList = ListDictionary_New(TRUE);
162 encoder->codecs |= SHADOW_CODEC_NSCODEC;
167 int shadow_encoder_init_bitmap(rdpShadowEncoder* encoder)
171 planarFlags = PLANAR_FORMAT_HEADER_NA;
172 planarFlags |= PLANAR_FORMAT_HEADER_RLE;
174 if (!encoder->planar)
176 encoder->planar = freerdp_bitmap_planar_context_new(planarFlags,
177 encoder->maxTileWidth, encoder->maxTileHeight);
180 if (!encoder->planar)
184 encoder->bts = Stream_New(NULL, encoder->maxTileWidth * encoder->maxTileHeight * 4);
189 encoder->codecs |= SHADOW_CODEC_BITMAP;
194 int shadow_encoder_init(rdpShadowEncoder* encoder)
196 encoder->maxTileWidth = 64;
197 encoder->maxTileHeight = 64;
199 shadow_encoder_init_grid(encoder);
202 encoder->bs = Stream_New(NULL, encoder->maxTileWidth * encoder->maxTileHeight * 4);
210 int shadow_encoder_uninit_rfx(rdpShadowEncoder* encoder)
214 rfx_context_free(encoder->rfx);
218 if (encoder->frameList)
220 ListDictionary_Free(encoder->frameList);
221 encoder->frameList = NULL;
224 encoder->codecs &= ~SHADOW_CODEC_REMOTEFX;
229 int shadow_encoder_uninit_nsc(rdpShadowEncoder* encoder)
233 nsc_context_free(encoder->nsc);
237 if (encoder->frameList)
239 ListDictionary_Free(encoder->frameList);
240 encoder->frameList = NULL;
243 encoder->codecs &= ~SHADOW_CODEC_NSCODEC;
248 int shadow_encoder_uninit_bitmap(rdpShadowEncoder* encoder)
252 freerdp_bitmap_planar_context_free(encoder->planar);
253 encoder->planar = NULL;
258 Stream_Free(encoder->bts, TRUE);
262 encoder->codecs &= ~SHADOW_CODEC_BITMAP;
267 int shadow_encoder_uninit(rdpShadowEncoder* encoder)
269 shadow_encoder_uninit_grid(encoder);
273 Stream_Free(encoder->bs, TRUE);
277 if (encoder->codecs & SHADOW_CODEC_REMOTEFX)
279 shadow_encoder_uninit_rfx(encoder);
282 if (encoder->codecs & SHADOW_CODEC_NSCODEC)
284 shadow_encoder_uninit_nsc(encoder);
287 if (encoder->codecs & SHADOW_CODEC_BITMAP)
289 shadow_encoder_uninit_bitmap(encoder);
295 int shadow_encoder_reset(rdpShadowEncoder* encoder)
298 UINT32 codecs = encoder->codecs;
300 status = shadow_encoder_uninit(encoder);
305 status = shadow_encoder_init(encoder);
310 status = shadow_encoder_prepare(encoder, codecs);
318 int shadow_encoder_prepare(rdpShadowEncoder* encoder, UINT32 codecs)
322 if ((codecs & SHADOW_CODEC_REMOTEFX) && !(encoder->codecs & SHADOW_CODEC_REMOTEFX))
324 status = shadow_encoder_init_rfx(encoder);
330 if ((codecs & SHADOW_CODEC_NSCODEC) && !(encoder->codecs & SHADOW_CODEC_NSCODEC))
332 status = shadow_encoder_init_nsc(encoder);
338 if ((codecs & SHADOW_CODEC_BITMAP) && !(encoder->codecs & SHADOW_CODEC_BITMAP))
340 status = shadow_encoder_init_bitmap(encoder);
349 rdpShadowEncoder* shadow_encoder_new(rdpShadowServer* server)
351 rdpShadowEncoder* encoder;
353 encoder = (rdpShadowEncoder*) calloc(1, sizeof(rdpShadowEncoder));
358 encoder->server = server;
361 encoder->maxFps = 32;
363 encoder->width = server->screen->width;
364 encoder->height = server->screen->height;
366 if (shadow_encoder_init(encoder) < 0)
372 void shadow_encoder_free(rdpShadowEncoder* encoder)
377 shadow_encoder_uninit(encoder);