3

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 负载如此低时,主线程会卡顿似乎很奇怪。

4

0 回答 0