When SGPlayer is used to play the panoramic live stream, the video source can be normally played by VLC player or MKPlayer on PC MAC. However, on iOS mobile phones, the video will sometimes crash or not crash after loading.
At the breakdown
- Details displayed on Xcode
Domain: IDEDebugSessionErrorDomain
Code: 10
Failure Reason: Message from debugger: Terminated due to memory issue
Copy the code
There is a memory problem
- After loading the SGPlog log data into the VR stream, it is obvious that there is no initialization of videoToolbox_vld
2022-03-09 14:35:28.050460+0800 PanoramicLive[40398:12015087] SGFFLog: Format VideoToolbox_vLD chosen by get_format().
2022-03-09 14:35:28.050516+0800 PanoramicLive[40398:12015087] SGFFLog: Format videotoolbox_vld requires hwaccel initialisation.
**2022-03-09 14:32:50.774550+0800 PanoramicLive[40379:12013560] SGFFLog: format: start_time: 1386865.197 duration: -9223372036854.775 bitRate =0 KB /s** **2022-03-09 14:32:50.778570+0800 PanoramicLive[40379:12013560] SGFFLog: After avformat_find_stream_info() pos: 2399171 bytes Read :2399171 Opens :0 frames:120** **2022-03-09 14:32:50.972442+0800 PanoramicLive[40379:12013407] Metal GPU Frame Capture Enabled** **2022-03-09 14:32:50.973027+0800 PanoramicLive[40379:12013407] Metal API Validation Enabled** **2022-03-09 14:32:51.068288+0800 PanoramicLive[40379:12013560] VR ** Stream loaded **2022-03-09 14:32:51.073546+0800 PanoramicLive[40379:12013786] SGFFLog : Detected 6 Logical Cores ** **2022-03-09 14:32:51.073783+0800 PanoramicLive[40379:12013786] SGFFLog: nal_unit_type: 7(SPS), Nal_ref_IDC :3 ** **2022-03-09 14:32:51.073866+0800 PanoramicLive[40379:12013786] SGFFLog: nal_unit_type: 8(PPS), nal_ref_idc: 3** **(lldb)**Copy the code
- The crash log on Bugly looks like this
SGAudioFrame frameWithDescriptor:numberOfSamples:] -[SGAudioDecoder clipFrames:timeRange:] + 972
-[SGAudioDecoder processPacket:] + 292
-[SGAudioDecoder decode:] + 1460
-[SGDecodeContext decode:unlock:] + 1796
-[SGDecodeLoop runningThread] + 764
SGAudioDecoder is abnormal when it gets Frame from Packet when decoding. So we can see a very important parameter numberOfSamples, the sample rate, where does that come from?
- Xcode exception crash breakpoint screenshot
Looking again at the crash of the previous step, you can see that numberOfSamples is obtained using this method
**int** nb_samples = (**int**)CMTimeConvertScale(duration, ad.sampleRate, kCMTimeRoundingMethod_RoundTowardZero).value;
Copy the code
CMTimeConvertScale Converts the source time to the new time scale using the specified rounding method.
func CMTimeConvertScale(_ time: CMTime , timescale newTimescale: Int32, method: CMTimeRoundingMethod -> CMTime
Copy the code
So I used long long int to receive data, and then I printed data, and I found that sometimes long long int and int return different data, so I looked at the range of int,
32bit: unsigned int 0 ~ 4294967295 int-2147483648 ~ 2147483647 Unsigned long The same as int long the same as int long The maximum value of long: 9223372036854775807 Minimum value of long long: -9223372036854775808 Maximum value of unsigned long long: 1844674407370955161 __int64 Maximum value of long: 9223372036854775807 __int64 minimum value: -9223372036854775808 Unsigned __int64 maximum value: 18446744073709551615 64bit Unsigned int 0 ~ 4294967295 int-2147483648 ~ 2147483647 Unsigned long The same as unsigned long long -9223372036854775807 minimum value of long: -9223372036854775808 Maximum value of unsigned long: 1844674407370955161 maximum value of __int64:9223372036854775807 Minimum value of __int64: -9223372036854775808 Maximum value of unsigned __int64: 18446744073709551615Copy the code
The solution
At this point, we have determined that the crash was caused by a data overflow; We have two sets of solutions:
-
- Replace all ints with long long ints. However, the underlying FFmpeg methods are all ints. Engineers currently use FFmpeg
-
- There are only some abnormal data, so it is ok to filter out the data
So I also choose this method, before the transformation of clipFrames method CMTimeConvertScale, filter out abnormal data, there should be other better methods, you can add oh
long long int nb_samplesLong = ( long long int)CMTimeConvertScale(duration, ad.sampleRate, kCMTimeRoundingMethod_RoundTowardZero).value;
if(nb_samplesLong >=2147483647) {
break;
}
Copy the code
The end!