2012-12-10 4 views
2

J'ai un tampon contenant des paquets lus par ffmpeg à partir d'un fichier vidéo encodé en H264/AAC Selon le document d'Apple, flux audio encodé au format AAC peut être décoder avec support matériel,Comment utiliser le décodage matériel pour l'audio?

comment décoder le flux audio support matériel? MISE À JOUR: J'utilise Audio Queue Service pour sortir l'audio. En ce moment, je décode le paquet AAC en utilisant ffmpeg et envoie l'audio LPCM à AQS. Selon le document Apple, je peux envoyer directement de l'audio AAC à AQ et il s'occupera de la tâche de décodage. Décode-t-il avec du matériel? Ai-je besoin et comment définir le paramètre Audio Queue pour activer le décodage matériel audio?

Répondre

4

Vous pouvez indiquer au système de ne pas utiliser le décodage matériel, mais probablement pas l'inverse. Constante pour déterminer quels codecs matériels peuvent être utilisés.

enum { 
    kAudioFormatProperty_HardwareCodecCapabilities = 'hwcc', 
}; 

Constantes kAudioFormatProperty_HardwareCodecCapabilities Une valeur UInt32 indiquant le nombre de codecs de la liste spécifiée qui peuvent être utilisés, si la demande devait commencer à les utiliser dans l'ordre spécifié. Définissez le paramètre inSpecifier sur un tableau de structures AudioClassDescription qui décrit un ensemble d'un ou de plusieurs codecs audio. Si la valeur de la propriété est la même que la taille du tableau dans le paramètre inSpecifier, tous les codecs spécifiés peuvent être utilisés. Disponible dans iOS 3.0 et versions ultérieures. Déclaré dans AudioFormat.h. Discussion Utilisez cette propriété pour déterminer si un ensemble de codecs souhaité peut être instancié simultanément.

Les codecs matériels peuvent être utilisés uniquement lors de la lecture ou de l'enregistrement à l'aide de services de file d'attente audio ou à l'aide d'interfaces, telles que AV Foundation, qui utilisent les services de file d'attente audio. En particulier, vous ne pouvez pas utiliser de codecs audio matériels avec OpenAL ou lorsque vous utilisez l'unité audio E/S. Lors de la description de la présence d'un codec matériel, le système ne tient pas compte de la catégorie de session audio en cours. Certaines catégories interdisent l'utilisation de codecs matériels. Un ensemble de codecs matériels est considéré comme disponible, par cette constante, basé uniquement sur le fait que le matériel prend en charge la combinaison spécifiée de codecs.

Certains codecs peuvent être disponibles dans les implémentations matérielles et logicielles. Utilisez les constantes kAudioFormatProperty_Encoders et kAudioFormatProperty_Decoders pour déterminer si un codec donné est présent et s'il s'agit d'un matériel ou d'un logiciel.

Les codecs logiciels peuvent toujours être instanciés, il n'est donc pas nécessaire d'utiliser cette constante lors de l'utilisation du codage ou du décodage logiciel.

L'exemple de code suivant illustre comment vérifier si oui ou non un codeur AAC matériel et un décodeur AAC matériel sont disponibles, dans cet ordre de priorité:

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

Vous avez sans doute mieux à l'aide audioUnits cependant plutôt que la file d'attente audio

+0

Merci pour la réponse, dans le code des liens fournis est vraiment utile. Dans le code, les tampons d'AQ sont remplis de données LPCM, cela signifie que les échantillons audio doivent être décodés avant d'être envoyés à AQS. Mais je veux envoyer un paquet audio AAC directement à l'AQS. – jAckOdE

+1

ok, si vous avez la source aac vous avez raison, vous pouvez décoder la source compressée en utilisant https://github.com/mooncatventures-group/iFrameExtractor/tree/master/Classes –

+0

J'ai testé sur ip4/ios6, il n'y a pas de son . La vidéo est codée comme H264 BaselineL1.3/AAC LC. Il y a peut-être quelque chose qui cloche dans la description du flux audio. – jAckOdE

1

Vous pouvez, bien que, comme d'habitude avec Core Audio, il existe diverses mises en garde et cas de bords à surveiller.

Définissez la propriété kExtAudioFileProperty_CodecManufacturer sur kAppleHardwareAudioCodecManufacturer. Faites-le avant de définir le format de données client.

Quelques docs dans ExtendedAudioFile.h

+0

merci, mais pouvez-vous s'il vous plaît plus précis sur la façon de le faire? J'ai une file d'attente de paquet audio ffmpeg (codé en AAC). À l'heure actuelle, j'utilise ffmpeg pour décoder le flux audio et transmettre l'audio de décodage (LPCM) au service de file d'attente audio. Y at-il de toute façon à dire à Audio Queue Service d'utiliser du matériel pour décoder le flux AAC? – jAckOdE

+0

La réponse courte est que le système décodera avec le décodeur matériel chaque fois qu'il le peut, c'est-à-dire, si vous décodez seulement un flux AAC stéréo à la fois. Si le système n'utilise pas le décodeur matériel parce qu'il est occupé, il n'y a aucun moyen de le forcer. –

0

plutôt que de faire ce calcul juste forcer une très grande taille de tampon ici.

status = AudioQueueAllocateBufferWithPacketDescriptions (audioQueue_, _audioCodecContext-> bit_rate * kAudioBufferSeconds/8, _audioCodecContext-> sample_rate * kAudioBufferSeconds/ _audioCodecContext-> frame_size + 1, & audioQueueBuffer_ [i]);

Questions connexes