我AVAssetWriterInput
在 iPhone 3GS 和 iPhone 4 等单核设备上遇到了一个奇怪的性能问题。基本上,我有一个带有两个 AVAssetWriterInputs 的 AVAssetWriter,一个用于视频,一个用于音频。粗略地说,它看起来像:
AVAssetWriter * assetWriter = [[AVAssetWriter alloc] initWithURL:videoURL
fileType:AVFileTypeMPEG4
error:&error];
videoWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings];
videoWriterInput.expectsMediaDataInRealTime = YES;
NSDictionary * audioSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatMPEG4AAC], AVFormatIDKey,
[NSNumber numberWithInt:64000], AVEncoderBitRateKey,
[NSNumber numberWithInt:2], AVNumberOfChannelsKey,
[NSNumber numberWithInt:44100], AVSampleRateKey,
currentChannelLayoutData, AVChannelLayoutKey,
nil];
audioWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio
outputSettings:audioSettings];
audioWriterInput.expectsMediaDataInRealTime = YES;
[assetWriter addInput:videoWriterInput];
[assetWriter addInput:audioWriterInput];
里面也有一个AVAssetWriterInputPixelBufferAdaptor
,但为了简洁起见,我把它省略了。我创建了一个用于视频和音频写入的串行调度队列。当我得到一个新的视频帧时,我将作业分派到那个串行队列,当我得到新的音频字节时,我把那个作业分派到同一个串行队列。这样,大部分音频编写代码都不会发生在音频回调线程上(否则会减慢高优先级音频线程的速度)。
我能够成功编写带音频的视频,并且在双核设备上表现良好。但是,在单核设备上,我发现设备的显示屏大约每 500-700 毫秒就会出现明显的卡顿。我已经追查到以下罪魁祸首:
if ([audioWriterInput isReadyForMoreMediaData])
{
if (![audioWriterInput appendSampleBuffer:sampleBuffer])
{
NSLog(@"Couldn't append audio sample buffer: %d", numAudioCallbacks_);
}
}
appendSampleBuffer
如果我为注释掉audioWriterInput
,那么显然没有音频被写入,但实际显示中也没有口吃。这很奇怪,因为所有这些都发生在主线程之外。每帧的 CPU/GPU 时间约为 4-5 毫秒,因此 CPU/GPU 不会出现瓶颈。
另一个线索/好奇心:当我写音频缓冲区时,我得到一个锯齿状的内存图,如下所示:
在我看来,audioWriterInput 正在排队一些缓冲区,然后写入/释放它们。
最后一个提示是,当我录制为单声道而不是立体声时,口吃似乎不那么严重。不幸的是,进来的声音是立体声的,所以当我这样做时,声音是错误的。无论哪种方式,口吃都不会完全消失,因此它不是一个真正有效的解决方案,但可能暗示立体声占用更多资源来处理这一事实。
有没有人知道为什么要编写音频AVAssetInputWriter
导致整个应用程序结结巴巴?这些设备显然只有一个核心,因此所有线程都将在其上运行,但当 CPU 负载如此低时,主线程会卡顿似乎很奇怪。