ISBX / apprtc-ios

A native iOS video chat app based on WebRTC
BSD 3-Clause "New" or "Revised" License
1.34k stars 411 forks source link

High CPU usage in iphone5 #8

Open pochuang opened 9 years ago

pochuang commented 9 years ago

Thanks for your kindly sharing, it really saves me hours; however, I found that the library runs with very high CPU usage under iphone 5 models. The phone will become very hot after some minutes with 140% CPU usage. It there any way to improve this? By the way, I can not get the webrtc codes compiled by myself. Is there any guides to correctly build webrtc in mac?

Reedyuk commented 9 years ago

I'm in the same boat as you, i have tried several guides and they all seem to not build correctly. Apparently the webrtc code runs hot on lower end devices, you should check out the google code forum about it.

pochuang commented 9 years ago

Originally, I doubt the high fps (up to 44 or higher) can be the reason. Finally I feel disappointed when I try to lower the frame rate using the codes below. The CPU usage still goes to 120% or even higher!

However, there is some evidence that the renderer can be the cause due to the following site:

https://perch.co/blog/perchrtc-custom-webrtc-rendering/

I would give a try if there is any progress and share with you guys.

Reedyuk commented 9 years ago

i have decided to use opentok, their library works perfect for webrtc, but you have to go through them.

kos9kus commented 9 years ago

pochuang, You mean that the webRtc lib ignores an initialization of mandatoryConstraints ?

pochuang commented 8 years ago

Finally, I found that the AVCaptureSession could be the reason why my iphone is burning! Before this adjustment, the cpu usage is always 120% or higher, but after this it drops down to 70%! This is a very huge change although it's not a very great solution. The magic is to set sessionPreset to low like this:

if !TARGET_IPHONE_SIMULATOR && TARGET_OS_IPHONE

RTCMediaConstraints *mediaConstraints = [self defaultMediaStreamConstraints];
RTCAVFoundationVideoSource *source =
[[RTCAVFoundationVideoSource alloc] initWithFactory:_factory
                                        constraints:mediaConstraints];
if ([source.captureSession canSetSessionPreset:AVCaptureSessionPresetLow]) {  
    source.captureSession.sessionPreset = AVCaptureSessionPresetLow;
}

endif

I am still working on this for a better solution. If you have any idea here, please let me know.

kos9kus commented 8 years ago

Please make a pull request for more details, what are values your self.maxHeight, self.minWidth etc..? The values is important and affect on a performance of CPU. And does it make sense to use a "dispatch_once" ? I would like to contribute towards it, because I look into this problem.

pochuang commented 8 years ago

The accepted values are listed below:

#define DEFAULT_MAX_HEIGHT 960
#define DEFAULT_MAX_WIDTH 720
#define DEFAULT_MIN_FRAME_RATE 5
#define DEFAULT_MAX_FRAME_RATE 12
#define ENABLE_BOOST_PERFORMANCE YES

The minWidth and minHeight do not work, so I modified it like this:

- (RTCMediaConstraints *)defaultMediaStreamConstraints {
    NSArray *mandatoryConstraints = @[
                                      [[RTCPair alloc] initWithKey:@"maxHeight" value:[NSString stringWithFormat:@"%d",self.maxHeight]],
                                      [[RTCPair alloc] initWithKey:@"maxWidth" value:[NSString stringWithFormat:@"%d",self.maxWidth]],
                                      [[RTCPair alloc] initWithKey:@"maxFrameRate" value:[NSString stringWithFormat:@"%d",self.maxFrameRate]],
                                      [[RTCPair alloc] initWithKey:@"minFrameRate" value:[NSString stringWithFormat:@"%d",self.minFrameRate]]
                                      ];

    NSArray *optionalConstraints = @[];

    RTCMediaConstraints* theConstraints =
    [[RTCMediaConstraints alloc]
     initWithMandatoryConstraints:mandatoryConstraints
     optionalConstraints:optionalConstraints];
    return theConstraints;
}

And the sessionPreset part like this:

#if !TARGET_IPHONE_SIMULATOR && TARGET_OS_IPHONE
    RTCMediaConstraints *mediaConstraints = [self defaultMediaStreamConstraints];
    RTCAVFoundationVideoSource *source =
    [[RTCAVFoundationVideoSource alloc] initWithFactory:_factory
                                            constraints:mediaConstraints];
    if(ENABLE_BOOST_PERFORMANCE){
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{            
            if ([source.captureSession canSetSessionPreset:AVCaptureSessionPresetLow]) {
                [source.captureSession stopRunning];
                source.captureSession.sessionPreset = AVCaptureSessionPresetLow;
                [source.captureSession startRunning];
            }
        });
    }
    videoTrack =
    [[RTCVideoTrack alloc] initWithFactory:_factory
                                    source:source
                                   trackId:@"ARDAMSv0"];
#endif

WebRTC will change sessionPreset due to your device's resolution at first. That will make your video more clear but become heavy to CPU. You may take a look at the source code downloaded from google.

The video resolution and frame rate you received from others will also affect CPU in iPhone. For me, I reduce it to 640x480.

Now the CPU usage is down to 58% or a little higher than 60%. Not pretty satisfying compared to Android's (the CPU usage is 30% only!) but is workable for now.

By the way, It will take a long time to change sessionPresent when your captureSession is already running. For my situation, I need to stop it temporarily and start it latter after making changes.

allenzyq commented 8 years ago

hi all. how can you fixup the video card problem?

hengtelin commented 8 years ago

is this problem fixed in the newest version? Or do we still need to make changes manually?