2222static const NSUInteger MAX_FPS = 60 ;
2323static NSString *const SERVER_NAME = @" WDA MJPEG Server" ;
2424static const char *QUEUE_NAME = " JPEG Screenshots Provider Queue" ;
25+ static const CGFloat COMPRESSION_QUALITY = 0.8 ;
26+ static const CGFloat SCREENSHOT_MAX_WIDTH = 450.0 ;
27+ static const uint64_t SCREENSHOT_INTERVAL = (uint64_t )(0.2 * NSEC_PER_SEC);
2528
2629@interface FBMjpegServer ()
2730
2831@property (nonatomic , readonly ) dispatch_queue_t backgroundQueue;
2932@property (nonatomic , readonly ) NSMutableArray <GCDAsyncSocket *> *listeningClients;
3033@property (nonatomic , readonly ) mach_timebase_info_data_t timebaseInfo;
3134@property (nonatomic , readonly ) CBXScreenshooter *screenshooter;
35+ @property (nonatomic , readonly ) CGSize scaledSize;
36+
3237@end
3338
3439@implementation FBMjpegServer
@@ -49,10 +54,17 @@ - (instancetype)init
4954 compression: 1 .0f
5055 typeIdentifier: @" JPEG" // (__bridge id)kUTTypeJPEG
5156 ];
57+
58+ UIImage *image = [UIImage imageWithData: [_screenshooter getScreenshotData ]];
59+ CGFloat screenWidth = image.size .width ;
60+ CGFloat screenHeight = image.size .height ;
61+ CGFloat scalingFactor = (screenWidth > SCREENSHOT_MAX_WIDTH) ? SCREENSHOT_MAX_WIDTH / screenWidth : 1.0 ;
62+ _scaledSize = CGSizeMake (screenWidth * scalingFactor, screenHeight * scalingFactor);
5263 }
5364 return self;
5465}
5566
67+
5668- (void )scheduleNextScreenshotWithInterval : (uint64_t )timerInterval timeStarted : (uint64_t )timeStarted
5769{
5870 uint64_t timeElapsed = mach_absolute_time () - timeStarted;
@@ -71,27 +83,19 @@ - (void)scheduleNextScreenshotWithInterval:(uint64_t)timerInterval timeStarted:(
7183
7284- (void )streamScreenshot
7385{
74- NSUInteger framerate = FBMjpegServerFramerate;
75- uint64_t timerInterval = (uint64_t )(1.0 / ((0 == framerate || framerate > MAX_FPS) ? MAX_FPS : framerate) * NSEC_PER_SEC);
7686 uint64_t timeStarted = mach_absolute_time ();
7787 @synchronized (self.listeningClients ) {
7888 if (0 == self.listeningClients .count ) {
79- [self scheduleNextScreenshotWithInterval: timerInterval timeStarted: timeStarted];
89+ [self scheduleNextScreenshotWithInterval: SCREENSHOT_INTERVAL timeStarted: timeStarted];
8090 return ;
8191 }
8292 }
8393
8494 @try {
85- NSData *screenShotData = [_screenshooter getScreenshotData ];
86- CGFloat scalingFactor = 50 / 100.0 ;
87- CGFloat compressionQuality = 0.8 ;
88-
89- UIImage *image = [UIImage imageWithData: screenShotData];
90- CGSize scaledSize = CGSizeMake (image.size .width * scalingFactor, image.size .height * scalingFactor);
91-
95+ UIImage *image = [UIImage imageWithData: [_screenshooter getScreenshotData ]];
9296 dispatch_semaphore_t semaphore = dispatch_semaphore_create (0 );
9397 __block UIImage *scaledImage = nil ;
94- [image prepareThumbnailOfSize: scaledSize completionHandler: ^(UIImage * _Nullable thumbnail) {
98+ [image prepareThumbnailOfSize: self . scaledSize completionHandler: ^(UIImage * _Nullable thumbnail) {
9599 scaledImage = thumbnail;
96100 dispatch_semaphore_signal (semaphore);
97101 }];
@@ -100,7 +104,7 @@ - (void)streamScreenshot
100104 if (nil == scaledImage) {
101105 NSLog (@" Screenshot exception: Failed to scale image using prepareThumbnailOfSize" );
102106 } else {
103- NSData *scaledImageData = UIImageJPEGRepresentation (scaledImage, compressionQuality );
107+ NSData *scaledImageData = UIImageJPEGRepresentation (scaledImage, COMPRESSION_QUALITY );
104108 if (nil == scaledImageData) {
105109 NSLog (@" Screenshot exception: Failed to scale image using UIImageJPEGRepresentation" );
106110 } else {
@@ -111,7 +115,7 @@ - (void)streamScreenshot
111115 NSLog (@" Screenshot exception: %@ , %@ " , exception.name , exception.reason );
112116 }
113117
114- [self scheduleNextScreenshotWithInterval: timerInterval timeStarted: timeStarted];
118+ [self scheduleNextScreenshotWithInterval: SCREENSHOT_INTERVAL timeStarted: timeStarted];
115119}
116120
117121- (void )sendScreenshot : (NSData *)screenshotData {
0 commit comments