如何利用硬件解码音频?

问题描述:

我有包含使用H264/AAC 根据苹果文档编码的视频文件通过的ffmpeg读取数据包缓冲区,在AAC编码音频流可以通过硬件支持来进行解码,如何利用硬件解码音频?

如何将音频流与解码硬件支持?

更新:我使用音频队列服务来输出音频。现在我使用ffmpeg解码AAC数据包并将LPCM音频发送到AQS。根据苹果公司的文件,我可以直接将AAC音频发送给AQ,它将负责解码任务。它是否用硬件解码?我是否需要,以及如何设置音频队列的参数以启用音频硬件解码?

一些文档你可以告诉系统无法使用硬件解码,但是可能不是相反。

不断确定可以使用哪些硬件编解码器。

enum { 
    kAudioFormatProperty_HardwareCodecCapabilities = 'hwcc', 
}; 

常量 kAudioFormatProperty_HardwareCodecCapabilities 甲UInt32的值指示从指定列表的编解码器可以使用的,如果应用程序是开始以指定的顺序使用它们的数量。将inSpecifier参数设置为描述一组一个或多个音频编解码器的一组AudioClassDescription结构。如果属性值与参数inSpecifier中的数组大小相同,则可以使用所有指定的编解码器。 Available in iOS 3.0及更高。 在AudioFormat.h中声明。 讨论 使用此属性可确定是否可以同时实例化所需的一组编解码器。

仅当使用音频队列服务或使用接口(如使用音频队列服务的AV Foundation)进行播放或录制时,才能使用基于硬件的编解码器。特别是,您不能在OpenAL或使用I/O音频单元时使用基于硬件的音频编解码器。

当描述硬件编解码器的存在时,系统不考虑当前的音频会话类别。有些类别不允许使用硬件编解码器。通过这个常数,一组硬件编解码器被认为是可用的,仅基于硬件是否支持指定的编解码器组合。

某些编解码器可能在硬件和软件实现中都可用。使用kAudioFormatProperty_EncoderskAudioFormatProperty_Decoders常数来确定给定编解码器是否存在,以及它是基于硬件还是基于软件。

总是可以实例化基于软件的编解码器,因此在使用软件编码或解码时不需要使用此常量。

下面的代码示例说明了如何检查硬件AAC编码器和硬件AAC解码器是否是可用的,在优先顺序:

AudioClassDescription requestedCodecs[2] = { 
    { 
     kAudioEncoderComponentType, 
     kAudioFormatAAC, 
     kAppleHardwareAudioCodecManufacturer 
    }, 
    { 
     kAudioDecoderComponentType, 
     kAudioFormatAAC, 
     kAppleHardwareAudioCodecManufacturer 
    } 
}; 

UInt32 successfulCodecs = 0; 
size = sizeof (successfulCodecs); 
OSStatus result = AudioFormatGetProperty (
         kAudioFormatProperty_HardwareCodecCapabilities, 
         requestedCodecs, 
         sizeof (requestedCodecs), 
         &size, 
         &successfulCodecs 
        ); 
switch (successfulCodecs) { 
    case 0: 
     // aac hardware encoder is unavailable. aac hardware decoder availability 
     // is unknown; could ask again for only aac hardware decoding 
    case 1: 
     // aac hardware encoder is available but, while using it, no hardware 
     // decoder is available. 
    case 2: 
     // hardware encoder and decoder are available simultaneously 
} 

https://github.com/mooncatventures-group/sampleDecoder

你可能会更好过使用然而audioUnits而不是音频队列

+0

感谢您的回答,在提供的链接代码中真的很有帮助。在代码中,AQ的缓冲区填充了LPCM数据,这意味着音频样本必须在发送到AQS之前解码。但我想直接发送AAC音频数据包到AQS。 – jAckOdE

+1

好吧,如果你有aac源你是正确的,你可以使用aq解码压缩的源https://github.com/mooncatventures-group/iFrameExtractor/tree/master/Classes –

+0

我在ip4/ios6上测试过,没有声音。视频编码为H264 BaselineL1.3/AAC LC。音频流描述可能有问题。 – jAckOdE

虽然像往常一样使用Core Audio,但您仍可以注意各种注意事项和边缘情况。

将财产kExtAudioFileProperty_CodecManufacturer设置为kAppleHardwareAudioCodecManufacturer。在设置客户端数据格式之前执行此操作。

ExtendedAudioFile.h

+0

谢谢,但你可以请具体谈谈如何做到这一点?我有一个ffmpeg音频数据包的队列(以AAC编码)。现在我使用ffmpeg来解码音频流并将解码音频(LPCM)提供给音频队列服务。无论如何告诉音频队列服务使用硬件解码AAC流? – jAckOdE

+0

简而言之,系统会在任何时候用硬件解码器进行解码 - 即,如果您一次只解码一个立体声AAC流。如果系统因为占用而不使用硬件解码器,则无法强制执行。 –

,而不是做这种计算只是强迫一个非常大的缓冲区大小在这里。

状态= AudioQueueAllocateBufferWithPacketDescriptions(audioQueue_, _audioCodecContext-> BIT_RATE * kAudioBufferSeconds/8, _audioCodecContext-> SAMPLE_RATE * kAudioBufferSeconds/ _audioCodecContext-> frame_size + 1, & audioQueueBuffer_ [I]);

发现这个宝石:

https://developer.apple.com/library/ios/qa/qa1663/_index.html

由于AudioFormatGetProperty不会经常工作。以上介绍了如何使用AudioFormatGetPropetyInfo编码器或解码器,并检测哪些出现在hw或sw中。