appium-webdriveragent 16.9.3 → 16.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [16.9.4](https://github.com/appium/WebDriverAgent/compare/v16.9.3...v16.9.4) (2026-08-29)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* drop MJPEG frames for clients that stop draining their socket ([#1227](https://github.com/appium/WebDriverAgent/issues/1227)) ([00cb6b6](https://github.com/appium/WebDriverAgent/commit/00cb6b612a5a1a1d00a386e23de01c4eca811df8))
|
|
6
|
+
|
|
1
7
|
## [16.9.3](https://github.com/appium/WebDriverAgent/compare/v16.9.2...v16.9.3) (2026-08-29)
|
|
2
8
|
|
|
3
9
|
### Bug Fixes
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
<key>CFBundlePackageType</key>
|
|
16
16
|
<string>FMWK</string>
|
|
17
17
|
<key>CFBundleShortVersionString</key>
|
|
18
|
-
<string>16.9.
|
|
18
|
+
<string>16.9.4</string>
|
|
19
19
|
<key>CFBundleSignature</key>
|
|
20
20
|
<string>????</string>
|
|
21
21
|
<key>CFBundleVersion</key>
|
|
22
|
-
<string>16.9.
|
|
22
|
+
<string>16.9.4</string>
|
|
23
23
|
<key>NSPrincipalClass</key>
|
|
24
24
|
<string/>
|
|
25
25
|
</dict>
|
|
@@ -22,6 +22,9 @@
|
|
|
22
22
|
|
|
23
23
|
static const NSUInteger MAX_FPS = 60;
|
|
24
24
|
static const NSTimeInterval FRAME_TIMEOUT = 1.;
|
|
25
|
+
// nw_connection_send buffers without backpressure, so a client that stops reading would retain
|
|
26
|
+
// every generated frame. Frames past this cap are dropped instead of queued.
|
|
27
|
+
static const NSUInteger MAX_PENDING_FRAMES_PER_CLIENT = 4;
|
|
25
28
|
static const NSTimeInterval FAILURE_BACKOFF_MIN = 1.0;
|
|
26
29
|
static const NSTimeInterval FAILURE_BACKOFF_MAX = 10.0;
|
|
27
30
|
|
|
@@ -44,6 +47,9 @@ static NSUInteger FBNormalizedMjpegFramerate(NSUInteger framerate)
|
|
|
44
47
|
@property (atomic, assign) BOOL isStreaming;
|
|
45
48
|
@property (nonatomic, assign) NSUInteger sentFramesCount;
|
|
46
49
|
@property (nonatomic, assign) NSUInteger sentBytesCount;
|
|
50
|
+
@property (nonatomic, assign) NSUInteger droppedFramesCount;
|
|
51
|
+
// Frames submitted but not sent yet, per client. Guarded by @synchronized (self.listeningClients).
|
|
52
|
+
@property (nonatomic, readonly) NSMapTable<id, NSNumber *> *pendingFrameCounts;
|
|
47
53
|
|
|
48
54
|
@end
|
|
49
55
|
|
|
@@ -58,6 +64,8 @@ static NSUInteger FBNormalizedMjpegFramerate(NSUInteger framerate)
|
|
|
58
64
|
_sentFramesCount = 0;
|
|
59
65
|
_sentBytesCount = 0;
|
|
60
66
|
_listeningClients = [NSMutableArray array];
|
|
67
|
+
_pendingFrameCounts = [NSMapTable mapTableWithKeyOptions:(NSPointerFunctionsOptions)(NSMapTableObjectPointerPersonality | NSMapTableStrongMemory)
|
|
68
|
+
valueOptions:(NSPointerFunctionsOptions)NSMapTableStrongMemory];
|
|
61
69
|
_imageProcessor = [[FBImageProcessor alloc] init];
|
|
62
70
|
_mainScreenID = [XCUIScreen.mainScreen displayID];
|
|
63
71
|
dispatch_queue_attr_t queueAttributes = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_UTILITY, 0);
|
|
@@ -149,17 +157,38 @@ static NSUInteger FBNormalizedMjpegFramerate(NSUInteger framerate)
|
|
|
149
157
|
return;
|
|
150
158
|
}
|
|
151
159
|
NSUInteger clientCount = self.listeningClients.count;
|
|
160
|
+
__weak typeof(self) weakSelf = self;
|
|
152
161
|
for (nw_connection_t client in self.listeningClients) {
|
|
153
|
-
[self.
|
|
162
|
+
NSUInteger pendingFrames = [self.pendingFrameCounts objectForKey:client].unsignedIntegerValue;
|
|
163
|
+
if (pendingFrames >= MAX_PENDING_FRAMES_PER_CLIENT) {
|
|
164
|
+
self.droppedFramesCount++;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
[self.pendingFrameCounts setObject:@(pendingFrames + 1) forKey:client];
|
|
168
|
+
[self.socket writeData:chunk toClient:client completion:^{
|
|
169
|
+
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
170
|
+
if (nil == strongSelf) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
@synchronized (strongSelf.listeningClients) {
|
|
174
|
+
NSUInteger stillPending = [strongSelf.pendingFrameCounts objectForKey:client].unsignedIntegerValue;
|
|
175
|
+
if (stillPending > 1) {
|
|
176
|
+
[strongSelf.pendingFrameCounts setObject:@(stillPending - 1) forKey:client];
|
|
177
|
+
} else {
|
|
178
|
+
[strongSelf.pendingFrameCounts removeObjectForKey:client];
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}];
|
|
154
182
|
}
|
|
155
183
|
self.sentFramesCount++;
|
|
156
184
|
self.sentBytesCount += chunk.length * clientCount;
|
|
157
185
|
NSUInteger framerate = FBNormalizedMjpegFramerate(FBConfiguration.sharedInstance.mjpegServerFramerate);
|
|
158
186
|
if (0 == self.sentFramesCount % framerate) {
|
|
159
|
-
[FBLogger verboseLog:[NSString stringWithFormat:@"MJPEG stats: clients=%@ sentFrames=%@ sentBytes=%@",
|
|
187
|
+
[FBLogger verboseLog:[NSString stringWithFormat:@"MJPEG stats: clients=%@ sentFrames=%@ sentBytes=%@ droppedFrames=%@",
|
|
160
188
|
@(clientCount),
|
|
161
189
|
@(self.sentFramesCount),
|
|
162
|
-
@(self.sentBytesCount)
|
|
190
|
+
@(self.sentBytesCount),
|
|
191
|
+
@(self.droppedFramesCount)]];
|
|
163
192
|
}
|
|
164
193
|
}
|
|
165
194
|
}
|
|
@@ -190,6 +219,7 @@ static NSUInteger FBNormalizedMjpegFramerate(NSUInteger framerate)
|
|
|
190
219
|
{
|
|
191
220
|
@synchronized (self.listeningClients) {
|
|
192
221
|
[self.listeningClients removeObject:client];
|
|
222
|
+
[self.pendingFrameCounts removeObjectForKey:client];
|
|
193
223
|
}
|
|
194
224
|
[FBLogger log:@"Disconnected a client from screenshots broadcast"];
|
|
195
225
|
}
|
|
@@ -200,6 +230,7 @@ static NSUInteger FBNormalizedMjpegFramerate(NSUInteger framerate)
|
|
|
200
230
|
@synchronized (self.listeningClients) {
|
|
201
231
|
NSArray<nw_connection_t> *clients = self.listeningClients.copy;
|
|
202
232
|
[self.listeningClients removeAllObjects];
|
|
233
|
+
[self.pendingFrameCounts removeAllObjects];
|
|
203
234
|
for (nw_connection_t client in clients) {
|
|
204
235
|
nw_connection_cancel(client);
|
|
205
236
|
}
|