我在iPhone 3GS和iPhone 4等单核设备上遇到AVAssetWriterInput
的奇怪性能问题。基本上,我有一个带有两个AVAssetWriterInput的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
,那么显然没有写入音频,但实际显示中也没有断断续续的声音。这很奇怪,因为所有这一切都发生在主线程的 off 。每帧的CPU / GPU时间大约为4-5毫秒,因此它不像CPU / GPU瓶颈。
另一条线索/好奇心:当我写下音频缓冲区时,我得到了一个如下所示的锯齿形内存图:
在我看来,audioWriterInput正在排队一些缓冲区,然后写入/释放它们。
最后一个提示是,当我录制为单声道而不是立体声时,口吃似乎不那么严重。不幸的是,进来的声音是立体声,所以当我这样做时,声音是错误的。无论哪种方式,口吃都不会完全消失,所以它不是真正有效的解决方案,但可能暗示立体声需要更多资源来处理。
有没有人对为什么用AVAssetInputWriter
编写音频会导致整个应用程序断断续续?这些设备显然只有一个核心,因此所有线程都可以在其上运行,但是当CPU负载过低时,主线程应该断言似乎很奇怪。