App hangs when using custom UI with video

Description
I’m using the custom UI feature on the latest macOS SDK. I have a component which is very similar to the ZMSDKThumbnailView component from the sample application. It has an arrow button feature to scroll through the video thumbnails of participants in my zoom meeting. I have a severe issue where in some cases when I scroll through the video thumbnails, my app will hang and become unresponsive with no errors until I force quit. Feels like some kind of deadlock symptom and the entire NSApplication hangs with no indication of what is failing.

I was able to reproduce this exact symptom on the MacOS sample application. To reproduce, I did the following:

  1. Ran the MacOS sample application on XCode 10
  2. Selected custom UI option and joined my personal meeting room
  3. Had 3 other devices join the meeting for a total of 4 participants
  4. Opened the Thumbnail video panel on the sample app, had arrows enabled since there were more than 3 participants
  5. Repeatedly scroll through thumbnail videos using bottom arrow -> top arrow -> bottom arrow -> top arrow -> etc… and so on until the app is no longer responsive

Here is a screen capture of the above procedure on the macOS sample app:

As you can see on the video, reproducing takes some repetition but clicking becomes unresponsive at about the ~38 second mark, and the sample app hangs. I’m unable to scroll through participants using the arrow keys nor can I click any of the buttons. The video stays active, but nothing else is functional. For some reason the video does not capture this, but the mouse pointer becomes a rainbow spinning wheel as further indication of a problem. The app/xcode logs do not show any error or feedback as to what is failing.

Which version?
Latest macOS SDK: https://github.com/zoom/zoom-sdk-macos/releases/tag/v4.6.21666.0427

To Reproduce(If applicable)
See above

Screenshots
Screen capture: https://drive.google.com/file/d/1PlJ8J6hRlR-ys5Lr45-rUlgi_9VIojK0/view?usp=sharing

Smartphone (please complete the following information):

  • XCode 10

Additional context
Although it takes a bit of repetition to reproduce, I anticipate users of my app encountering this issue frequently because the component I use is the primary video display of the application so I expect frequent scrolling.

Hi @nraj,

Thank you very much for the post, the details, and the screenshots. We are able to identify an issue with our demo app, but this should not affect the SDK integration in your own app. Are you experiencing the same issue in your own app?

Hi @Carson_Chen,

Yes I experience the same symptoms in my own app. The component I created in my app is very similar to parts of the demo app, so I think it’s possible that whatever issue you all found in your demo app is the same issue I have with mine.

Could you share some further details on what issue you found with the sample app and how to fix/workaround?

Thanks,
Nitin

Hi @Carson_Chen - just wanted to see if I could gather any further details from you on this issue?

Maybe related

Hi @nraj,

Thanks for the reply. We are having an SDK release very soon. Please have a try with the newer release and see if the issue persists.

Thanks!

Thanks for the update @Carson_Chen! I know it’s difficult to say for sure, but any high level idea when we can expect the next release? We’re waiting on a few key fixes - this issue in particular has significant impact on our application so we would like to close the loop on it asap.

Thanks,
Nitin

Hi Nitin,

Thanks for the reply. We are targeting to have a release around 06/30. Please follow our Github repo for any updates.

Thanks!

Hi @Carson_Chen thanks for the update!

Thanks,
Nitin

Hi @Carson_Chen,

I’ve updated to the latest SDK v5 released tonight (https://github.com/zoom/zoom-sdk-macos/releases/tag/v5.0.24433.0616), and unfortunately I reproduced my application hang with custom video on this release as well. Using the latest macOS demo application bundled with the v5.0.24433.0616 SDK I was able to reproduce the application deadlock on the demo app pretty easily when custom UI is enabled, using the same procedure as described in my initial post on this topic. So it appears this issue has not been fixed with the latest SDK release :cry:

You mentioned in your first reply on this topic that this issue should not affect SDK integration with our app and that there was an issue with the demo app itself. Could you please elaborate? The impact of this issue is significant enough that we’re looking for help on any kind of workaround/fix in the immediate term.

Thanks,
Nitin

Hi @nraj,

BEWARE
This workaround is very dangerous and need to be used with great caution.
Tested with v4.6.21666.0427.

@implementation NSOpenGLView(Swizzling)

+ (void)initialize {
    [self swizzle_lock];
    [self swizzle_unlock];
}

+ (void)swizzle_lock {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = NSClassFromString(@"ZPVideoOpenGLView");
        
        SEL originalSelector = @selector(lockVideo);
        SEL swizzledSelector = @selector(xxx_lockVideo);
        
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        
        BOOL didAddMethod =
        class_addMethod(class,
                        originalSelector,
                        method_getImplementation(swizzledMethod),
                        method_getTypeEncoding(swizzledMethod));
        
        if (didAddMethod) {
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

+ (void)swizzle_unlock {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = NSClassFromString(@"ZPVideoOpenGLView");
        
        SEL originalSelector = @selector(unlockVideo);
        SEL swizzledSelector = @selector(xxx_unlockVideo);
        
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        
        BOOL didAddMethod =
        class_addMethod(class,
                        originalSelector,
                        method_getImplementation(swizzledMethod),
                        method_getTypeEncoding(swizzledMethod));
        
        if (didAddMethod) {
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

- (void)xxx_lockVideo {
    //[self xxx_lockVideo];
}

- (void)xxx_unlockVideo {
    //[self xxx_unlockVideo];
}

@end