如何利用硬件解码音频?
我有包含使用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_Encoders
和kAudioFormatProperty_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而不是音频队列
虽然像往常一样使用Core Audio,但您仍可以注意各种注意事项和边缘情况。
将财产kExtAudioFileProperty_CodecManufacturer
设置为kAppleHardwareAudioCodecManufacturer
。在设置客户端数据格式之前执行此操作。
在ExtendedAudioFile.h
谢谢,但你可以请具体谈谈如何做到这一点?我有一个ffmpeg音频数据包的队列(以AAC编码)。现在我使用ffmpeg来解码音频流并将解码音频(LPCM)提供给音频队列服务。无论如何告诉音频队列服务使用硬件解码AAC流? – jAckOdE
简而言之,系统会在任何时候用硬件解码器进行解码 - 即,如果您一次只解码一个立体声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中。
感谢您的回答,在提供的链接代码中真的很有帮助。在代码中,AQ的缓冲区填充了LPCM数据,这意味着音频样本必须在发送到AQS之前解码。但我想直接发送AAC音频数据包到AQS。 – jAckOdE
好吧,如果你有aac源你是正确的,你可以使用aq解码压缩的源https://github.com/mooncatventures-group/iFrameExtractor/tree/master/Classes –
我在ip4/ios6上测试过,没有声音。视频编码为H264 BaselineL1.3/AAC LC。音频流描述可能有问题。 – jAckOdE