2011-08-09 5 views
1

J'essaye de faire une application qui joue le flux audio en utilisant ffmpeg, libmms.
Je peux ouvrir le serveur mms, obtenir le flux et décoder la trame audio en trame brute en utilisant un codec approprié.
Cependant, je ne sais pas comment faire ensuite.
Je pense que je dois utiliser AudioToolbox/AudioToolbox.h et faire audioqueue.
mais cependant quand je donne la mémoire et la lecture du tampon de décodage audioqueuebuffer, seulement joue le bruit blanc.
Voici mon code.Iphone Streaming et jouer le problème audio

Que manque-t-il?
Tout commentaire et indice est très apprécié.
Merci beaucoup.

while(av_read_frame(pFormatCtx, &pkt)>=0) 
{ 
    int pkt_decoded_len = 0; 
    int frame_decoded_len; 
    int decode_buff_remain=AVCODEC_MAX_AUDIO_FRAME_SIZE * 5; 
    if(pkt.stream_index==audiostream) 
    { 
     frame_decoded_len=decode_buff_remain; 
     int16_t *decode_buff_ptr = decode_buffer; 
     int decoded_tot_len=0; 
     pkt_decoded_len = avcodec_decode_audio2(pCodecCtx, decode_buff_ptr, &frame_decoded_len, 
               pkt.data, pkt.size); 
     if (pkt_decoded_len <0) break; 
     AudioQueueAllocateBuffer(audioQueue, kBufferSize, &buffers[i]); 
     AQOutputCallback(self, audioQueue, buffers[i], pkt_decoded_len); 

     if(i == 1){ 
      AudioQueueSetParameter(audioQueue, kAudioQueueParam_Volume, 1.0); 
      AudioQueueStart(audioQueue, NULL); 
     } 
     i++; 
    } 
} 


void AQOutputCallback(void *inData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, int copySize) 
{ 
    mmsDemoViewController *staticApp = (mmsDemoViewController *)inData; 
    [staticApp handleBufferCompleteForQueue:inAQ buffer:inBuffer size:copySize]; 
} 

- (void)handleBufferCompleteForQueue:(AudioQueueRef)inAQ 
          buffer:(AudioQueueBufferRef)inBuffer 
          size:(int)copySize 
{ 
    inBuffer->mAudioDataByteSize = inBuffer->mAudioDataBytesCapacity; 
    memcpy((char*)inBuffer->mAudioData, (const char*)decode_buffer, copySize); 

    AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL); 
} 

Répondre

1

Vous avez appelé AQOutputCallback à tort. Vous n'avez pas besoin d'appeler nécessairement cette méthode.
Cette méthode sera appelée automatiquement lorsque des tampons audio sont utilisés par la file d'attente audio. Et le prototype de AQOutputCallback était faux.
Selon votre code Cette méthode ne sera pas appelée automatiquement je pense.
Vous pouvez remplacer

typedef void (*AudioQueueOutputCallback) (
    void     *inUserData, 
    AudioQueueRef  inAQ, 
    AudioQueueBufferRef inBuffer 
); 

comme celui-ci

void AudioQueueCallback(void* inUserData, AudioQueueRef inAQ, AudioQueueBufferRef 
         inBuffer); 

Et vous devez définir la session audio Lorsque votre application démarre.
Les références importantes sont here.

Cependant, quelle est l'extension de l'audio que vous êtes prêt à décoder?
AudioStreamPacketDescription est important si l'audio est une trame variable par paquet.
Sinon, si une trame par un paquet, AudioStreamPacketDescription n'est pas significative. Ce que vous faites ensuite est
Pour Définir la session audio, Pour Obtenir une trame audio brute à l'aide du décodeur, Pour placer la trame dans le tampon audio. A la place de vous, faites en sorte que le système remplisse le tampon vide.

+0

Merci j'ai eu une solution après l'utilisation du prototype correct – KayKay