FreeRDP
Loading...
Searching...
No Matches
wf_update.c
1
21#include <freerdp/config.h>
22
23#include <stdio.h>
24
25#include <winpr/windows.h>
26
27#include <freerdp/freerdp.h>
28#include <freerdp/listener.h>
29
30#include "wf_peer.h"
31#include "wf_info.h"
32#include "wf_mirage.h"
33
34#include "wf_update.h"
35
36#include <freerdp/log.h>
37#define TAG SERVER_TAG("windows")
38
39DWORD WINAPI wf_update_thread(LPVOID lpParam)
40{
41 DWORD fps;
42 wfInfo* wfi;
43 DWORD beg, end;
44 DWORD diff, rate;
45 wfi = (wfInfo*)lpParam;
46 fps = wfi->framesPerSecond;
47 rate = 1000 / fps;
48
49 while (1)
50 {
51 beg = GetTickCount();
52
53 if (wf_info_lock(wfi) > 0)
54 {
55 if (wfi->activePeerCount > 0)
56 {
57 wf_info_update_changes(wfi);
58
59 if (wf_info_have_updates(wfi))
60 {
61 wf_update_encode(wfi);
62 // WLog_DBG(TAG, "Start of parallel sending");
63 int index = 0;
64
65 for (int peerindex = 0; peerindex < wfi->peerCount; peerindex++)
66 {
67 for (; index < FREERDP_SERVER_WIN_INFO_MAXPEERS; index++)
68 {
69 if (wfi->peers[index] && wfi->peers[index]->activated)
70 {
71 // WLog_DBG(TAG, "Setting event for %d of %d", index + 1,
72 // wfi->activePeerCount);
73 (void)SetEvent(
74 ((wfPeerContext*)wfi->peers[index]->context)->updateEvent);
75 }
76 }
77 }
78
79 for (int index = 0; index < wfi->activePeerCount; index++)
80 {
81 // WLog_DBG(TAG, "Waiting for %d of %d", index + 1, wfi->activePeerCount);
82 // WaitForSingleObject(wfi->updateSemaphore, INFINITE);
83 (void)WaitForSingleObject(wfi->updateSemaphore, 1000);
84 }
85
86 // WLog_DBG(TAG, "End of parallel sending");
87 wf_info_clear_invalid_region(wfi);
88 }
89 }
90
91 wf_info_unlock(wfi);
92 }
93
94 end = GetTickCount();
95 diff = end - beg;
96
97 if (diff < rate)
98 {
99 Sleep(rate - diff);
100 }
101 }
102
103 // WLog_DBG(TAG, "Exiting Update Thread");
104 return 0;
105}
106
107void wf_update_encode(wfInfo* wfi)
108{
109 RFX_RECT rect;
110 long height, width;
111 BYTE* pDataBits = NULL;
112 int stride;
114 wf_info_find_invalid_region(wfi);
115 cmd = &wfi->cmd;
116 Stream_SetPosition(wfi->s, 0);
117 wf_info_getScreenData(wfi, &width, &height, &pDataBits, &stride);
118 rect.x = 0;
119 rect.y = 0;
120 rect.width = (UINT16)width;
121 rect.height = (UINT16)height;
122 // WLog_DBG(TAG, "x:%"PRId32" y:%"PRId32" w:%ld h:%ld", wfi->invalid.left, wfi->invalid.top,
123 // width, height);
124 Stream_Clear(wfi->s);
125
126 if (!(rfx_compose_message(wfi->rfx_context, wfi->s, &rect, 1, pDataBits, width, height,
127 stride)))
128 {
129 return;
130 }
131
132 wfi->frame_idx = rfx_context_get_frame_idx(wfi->rfx_context);
133 cmd->destLeft = wfi->invalid.left;
134 cmd->destTop = wfi->invalid.top;
135 cmd->destRight = wfi->invalid.left + width;
136 cmd->destBottom = wfi->invalid.top + height;
137 cmd->bmp.bpp = 32;
138 cmd->bmp.codecID = 3;
139 cmd->bmp.width = width;
140 cmd->bmp.height = height;
141 cmd->bmp.bitmapDataLength = Stream_GetPosition(wfi->s);
142 cmd->bmp.bitmapData = Stream_Buffer(wfi->s);
143}
144
145void wf_update_peer_send(wfInfo* wfi, wfPeerContext* context)
146{
147 freerdp_peer* client;
148
149 WINPR_ASSERT(wfi);
150 WINPR_ASSERT(context);
151
152 client = ((rdpContext*)context)->peer;
153 WINPR_ASSERT(client);
154
155 /* This happens when the RemoteFX encoder state is reset */
156
157 if (wfi->frame_idx == 1)
158 context->frame_idx = 0;
159
160 /*
161 * When a new client connects, it is possible that old frames from
162 * from a previous encoding state remain. Those frames should be discarded
163 * as they will cause an error condition in mstsc.
164 */
165
166 if ((context->frame_idx + 1) != wfi->frame_idx)
167 {
168 /* This frame is meant to be discarded */
169 if (context->frame_idx == 0)
170 return;
171
172 /* This is an unexpected error condition */
173 WLog_DBG(TAG, "Unexpected Frame Index: Actual: %d Expected: %d", wfi->frame_idx,
174 context->frame_idx + 1);
175 }
176
177 WINPR_ASSERT(client->context);
178 WINPR_ASSERT(client->context->settings);
179 WINPR_ASSERT(client->context->update);
180 WINPR_ASSERT(client->context->update->SurfaceBits);
181
182 wfi->cmd.bmp.codecID =
183 freerdp_settings_get_uint32(client->context->settings, FreeRDP_RemoteFxCodecId);
184 client->context->update->SurfaceBits(client->context, &wfi->cmd);
185 context->frame_idx++;
186}
187
188void wf_update_encoder_reset(wfInfo* wfi)
189{
190 if (wf_info_lock(wfi) > 0)
191 {
192 WLog_DBG(TAG, "Resetting encoder");
193
194 if (wfi->rfx_context)
195 {
196 rfx_context_reset(wfi->rfx_context, wfi->servscreen_width, wfi->servscreen_height);
197 }
198 else
199 {
200 /* TODO: pass ThreadingFlags somehow */
201 wfi->rfx_context = rfx_context_new(TRUE);
202 rfx_context_set_mode(wfi->rfx_context, RLGR3);
203 rfx_context_reset(wfi->rfx_context, wfi->servscreen_width, wfi->servscreen_height);
204 rfx_context_set_pixel_format(wfi->rfx_context, PIXEL_FORMAT_BGRA32);
205 wfi->s = Stream_New(NULL, 0xFFFF);
206 }
207
208 wf_info_invalidate_full_screen(wfi);
209 wf_info_unlock(wfi);
210 }
211}
212
213void wf_update_peer_activate(wfInfo* wfi, wfPeerContext* context)
214{
215 if (wf_info_lock(wfi) > 0)
216 {
217 if (wfi->activePeerCount < 1)
218 {
219#ifndef WITH_DXGI_1_2
220 wf_mirror_driver_activate(wfi);
221#endif
222 ResumeThread(wfi->updateThread);
223 }
224
225 wf_update_encoder_reset(wfi);
226 wfi->activePeerCount++;
227 WLog_DBG(TAG, "Activating Peer Updates: %d", wfi->activePeerCount);
228 wf_info_unlock(wfi);
229 }
230}
231
232void wf_update_peer_deactivate(wfInfo* wfi, wfPeerContext* context)
233{
234 if (wf_info_lock(wfi) > 0)
235 {
236 freerdp_peer* client = ((rdpContext*)context)->peer;
237
238 if (client->activated)
239 {
240 if (wfi->activePeerCount <= 1)
241 {
242 wf_mirror_driver_deactivate(wfi);
243 }
244
245 client->activated = FALSE;
246 wfi->activePeerCount--;
247 WLog_DBG(TAG, "Deactivating Peer Updates: %d", wfi->activePeerCount);
248 }
249
250 wf_info_unlock(wfi);
251 }
252}
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
Definition rfx.h:44