Skip to content

Commit ed44e5a

Browse files
committed
Apply stream quality changes to active encoders
1 parent 7b3f3c6 commit ed44e5a

13 files changed

Lines changed: 71 additions & 11 deletions

cli/XCWH264Encoder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ typedef void (^XCWH264EncoderOutputHandler)(NSData *sampleData,
1919

2020
- (void)encodePixelBuffer:(CVPixelBufferRef)pixelBuffer;
2121
- (void)requestKeyFrame;
22+
- (void)reconfigureForStreamQualityChange;
2223
- (NSDictionary *)statsRepresentation;
2324
- (void)invalidate;
2425

cli/XCWH264Encoder.m

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@
3434
static const uint64_t XCWLowLatencySoftwareMaximumFrameIntervalUs = 133333;
3535
static const uint64_t XCWLowLatencySoftwareFrameIntervalStepUs = 11111;
3636
static const NSUInteger XCWLowLatencySoftwareHealthyFrameWindow = 8;
37-
static const uint64_t XCWRealtimeHardwareInitialFrameIntervalUs = 33333;
38-
static const uint64_t XCWRealtimeHardwareMinimumFrameIntervalUs = 33333;
39-
static const uint64_t XCWRealtimeHardwareMaximumFrameIntervalUs = 66667;
4037
static const uint64_t XCWRealtimeHardwareFrameIntervalStepUs = 5556;
4138
static const NSUInteger XCWRealtimeHardwareHealthyFrameWindow = 6;
4239

@@ -308,7 +305,7 @@ static CGSize XCWScaledDimensionsForSourceSize(int32_t width, int32_t height, XC
308305
? XCWRealtimeMaximumEncodedDimension()
309306
: XCWMaximumEncodedDimension;
310307
if (mode == XCWVideoEncoderModeH264Software && lowLatencyMode) {
311-
maximumDimension = XCWMaximumLowLatencySoftwareEncodedDimension;
308+
maximumDimension = MIN(maximumDimension, XCWMaximumLowLatencySoftwareEncodedDimension);
312309
} else if (mode == XCWVideoEncoderModeH264Software && !realtimeStreamMode) {
313310
maximumDimension = XCWMaximumSoftwareEncodedDimension;
314311
}
@@ -492,7 +489,7 @@ - (instancetype)initWithOutputHandler:(XCWH264EncoderOutputHandler)outputHandler
492489
_realtimeStreamMode = XCWRealtimeStreamModeFromEnvironment() || _lowLatencyMode;
493490
_codecType = XCWVideoCodecTypeForMode(_encoderMode);
494491
_softwareFrameIntervalUs = [self initialSoftwareFrameIntervalUsLocked];
495-
_realtimeHardwareFrameIntervalUs = XCWRealtimeHardwareInitialFrameIntervalUs;
492+
_realtimeHardwareFrameIntervalUs = XCWRealtimeFrameIntervalUs();
496493
return self;
497494
}
498495

@@ -535,6 +532,19 @@ - (void)requestKeyFrame {
535532
});
536533
}
537534

535+
- (void)reconfigureForStreamQualityChange {
536+
dispatch_async(_queue, ^{
537+
[self invalidateCompressionSessionLocked];
538+
self->_needsKeyFrame = YES;
539+
self->_softwareFrameIntervalUs = [self initialSoftwareFrameIntervalUsLocked];
540+
self->_softwarePacedFrameCount = 0;
541+
self->_softwareHealthyFrameCount = 0;
542+
self->_realtimeHardwareFrameIntervalUs = XCWRealtimeFrameIntervalUs();
543+
self->_realtimeHardwarePacedFrameCount = 0;
544+
self->_realtimeHardwareHealthyFrameCount = 0;
545+
});
546+
}
547+
538548
- (NSDictionary *)statsRepresentation {
539549
__block NSUInteger inputFrameCount = 0;
540550
__block NSUInteger pendingReplacementCount = 0;
@@ -642,7 +652,7 @@ - (BOOL)shouldPaceRealtimeHardwareFrameAtTimeUs:(uint64_t)nowUs {
642652
return NO;
643653
}
644654
if (_realtimeHardwareFrameIntervalUs == 0) {
645-
_realtimeHardwareFrameIntervalUs = XCWRealtimeHardwareInitialFrameIntervalUs;
655+
_realtimeHardwareFrameIntervalUs = XCWRealtimeFrameIntervalUs();
646656
}
647657
if (_lastRealtimeHardwareSubmissionUs == 0) {
648658
return NO;
@@ -717,28 +727,30 @@ - (void)adaptRealtimeHardwarePacingForLatencyUs:(uint64_t)latencyUs {
717727
return;
718728
}
719729
if (_realtimeHardwareFrameIntervalUs == 0) {
720-
_realtimeHardwareFrameIntervalUs = XCWRealtimeHardwareInitialFrameIntervalUs;
730+
_realtimeHardwareFrameIntervalUs = XCWRealtimeFrameIntervalUs();
721731
}
722732

733+
uint64_t minimumIntervalUs = XCWRealtimeFrameIntervalUs();
734+
uint64_t maximumIntervalUs = XCWRealtimeMaximumFrameIntervalUs();
723735
if (latencyUs > _realtimeHardwareFrameIntervalUs) {
724736
uint64_t nextIntervalUs = _realtimeHardwareFrameIntervalUs + XCWRealtimeHardwareFrameIntervalStepUs;
725737
uint64_t latencyBoundIntervalUs = latencyUs + XCWRealtimeHardwareFrameIntervalStepUs;
726738
if (nextIntervalUs < latencyBoundIntervalUs) {
727739
nextIntervalUs = latencyBoundIntervalUs;
728740
}
729-
_realtimeHardwareFrameIntervalUs = MIN(nextIntervalUs, XCWRealtimeHardwareMaximumFrameIntervalUs);
741+
_realtimeHardwareFrameIntervalUs = MIN(nextIntervalUs, maximumIntervalUs);
730742
_realtimeHardwareHealthyFrameCount = 0;
731743
return;
732744
}
733745

734746
if (latencyUs < _realtimeHardwareFrameIntervalUs &&
735-
_realtimeHardwareFrameIntervalUs > XCWRealtimeHardwareMinimumFrameIntervalUs) {
747+
_realtimeHardwareFrameIntervalUs > minimumIntervalUs) {
736748
_realtimeHardwareHealthyFrameCount += 1;
737749
if (_realtimeHardwareHealthyFrameCount >= XCWRealtimeHardwareHealthyFrameWindow) {
738750
uint64_t nextIntervalUs = _realtimeHardwareFrameIntervalUs > XCWRealtimeHardwareFrameIntervalStepUs
739751
? _realtimeHardwareFrameIntervalUs - XCWRealtimeHardwareFrameIntervalStepUs
740-
: XCWRealtimeHardwareMinimumFrameIntervalUs;
741-
_realtimeHardwareFrameIntervalUs = MAX(nextIntervalUs, XCWRealtimeHardwareMinimumFrameIntervalUs);
752+
: minimumIntervalUs;
753+
_realtimeHardwareFrameIntervalUs = MAX(nextIntervalUs, minimumIntervalUs);
742754
_realtimeHardwareHealthyFrameCount = 0;
743755
}
744756
return;

cli/XCWPrivateSimulatorSession.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ typedef void (^XCWPrivateSimulatorEncodedFrameHandler)(NSData *sampleData,
2929
- (BOOL)waitForFirstEncodedFrameWithTimeout:(NSTimeInterval)timeout;
3030
- (void)requestKeyFrameRefresh;
3131
- (void)requestFrameRefresh;
32+
- (void)reconfigureVideoEncoder;
3233
- (id)addEncodedFrameListener:(XCWPrivateSimulatorEncodedFrameHandler)handler;
3334
- (void)removeEncodedFrameListener:(id)token;
3435

cli/XCWPrivateSimulatorSession.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ - (void)requestFrameRefresh {
171171
[self refreshCurrentFrame];
172172
}
173173

174+
- (void)reconfigureVideoEncoder {
175+
[_videoEncoder reconfigureForStreamQualityChange];
176+
[_videoEncoder requestKeyFrame];
177+
[self refreshCurrentFrame];
178+
}
179+
174180
- (id)addEncodedFrameListener:(XCWPrivateSimulatorEncodedFrameHandler)handler {
175181
if (handler == nil) {
176182
return [NSUUID UUID];

cli/native/XCWNativeBridge.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ void xcw_native_session_destroy(void * _Nullable handle);
7272
bool xcw_native_session_start(void * _Nonnull handle, char * _Nullable * _Nullable error_message);
7373
void xcw_native_session_request_refresh(void * _Nonnull handle);
7474
void xcw_native_session_request_keyframe(void * _Nonnull handle);
75+
void xcw_native_session_reconfigure_video_encoder(void * _Nonnull handle);
7576
bool xcw_native_session_send_touch(void * _Nonnull handle, double x, double y, const char * _Nonnull phase, char * _Nullable * _Nullable error_message);
7677
bool xcw_native_session_send_multitouch(void * _Nonnull handle, double x1, double y1, double x2, double y2, const char * _Nonnull phase, char * _Nullable * _Nullable error_message);
7778
bool xcw_native_session_send_key(void * _Nonnull handle, uint16_t key_code, uint32_t modifiers, char * _Nullable * _Nullable error_message);

cli/native/XCWNativeBridge.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,12 @@ void xcw_native_session_request_keyframe(void *handle) {
690690
}
691691
}
692692

693+
void xcw_native_session_reconfigure_video_encoder(void *handle) {
694+
@autoreleasepool {
695+
[XCWNativeSessionFromHandle(handle) reconfigureVideoEncoder];
696+
}
697+
}
698+
693699
bool xcw_native_session_send_touch(void *handle, double x, double y, const char *phase, char **error_message) {
694700
@autoreleasepool {
695701
NSError *error = nil;

cli/native/XCWNativeSession.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN
1414
- (BOOL)start:(NSError * _Nullable * _Nullable)error;
1515
- (void)requestRefresh;
1616
- (void)requestKeyFrame;
17+
- (void)reconfigureVideoEncoder;
1718
- (BOOL)sendTouchAtX:(double)x
1819
y:(double)y
1920
phase:(NSString *)phase

cli/native/XCWNativeSession.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ - (void)requestKeyFrame {
9898
[self.session requestKeyFrameRefresh];
9999
}
100100

101+
- (void)reconfigureVideoEncoder {
102+
[self.session reconfigureVideoEncoder];
103+
}
104+
101105
- (BOOL)sendTouchAtX:(double)x
102106
y:(double)y
103107
phase:(NSString *)phase

server/src/api/routes.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,7 @@ async fn stream_quality() -> Json<Value> {
569569
}
570570

571571
async fn set_stream_quality(
572+
State(state): State<AppState>,
572573
Json(payload): Json<StreamQualityPayload>,
573574
) -> Result<Json<Value>, AppError> {
574575
let profile = payload
@@ -612,6 +613,7 @@ async fn set_stream_quality(
612613
env::set_var("SIMDECK_STREAM_QUALITY_PROFILE", "custom");
613614
}
614615

616+
state.registry.reconfigure_video_encoders();
615617
Ok(json(json_value!(stream_quality_response())))
616618
}
617619

server/src/native/bridge.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,12 @@ impl NativeSession {
641641
}
642642
}
643643

644+
pub fn reconfigure_video_encoder(&self) {
645+
unsafe {
646+
ffi::xcw_native_session_reconfigure_video_encoder(self.handle);
647+
}
648+
}
649+
644650
pub unsafe fn set_frame_callback(
645651
&self,
646652
callback: Option<ffi::xcw_native_frame_callback>,

0 commit comments

Comments
 (0)