마이크에서 오디오를 캡처하는 동안 오디오의 메모리 누수 또는 과도한 정적 사이에 끼어 있습니다.

Ozguronur

마이크에서 오디오를 캡처하여 AAC 형식의 스트리밍 서버로 스트리밍해야하는 iPhone 앱을 작성 중입니다. 그래서 먼저 오디오를 캡처 한 다음

AudioConverterFillComplexBuffer

오디오를 AAC로 변환하는 방법.

아래는 코드입니다

- (void) captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{

   NSArray *audioChannels = connection.audioChannels;
   if (audioChannels == nil || [audioChannels count]==0) { 
        // NSLog(@"We have Video Frame");      
        [_encoder encodeFrame:sampleBuffer];
   }else{
        // NSLog(@"We have Audio Frame");
        if (hasAudio) {
            CMTime prestime =          CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
        double dPTS = (double)(prestime.value) / prestime.timescale;         

        [self getAudioBufferDataFromCMSampleBufferRef:sampleBuffer];      

        // describe output data buffers into which we can receive data.
        AudioBufferList outputBufferList;
        outputBufferList.mNumberBuffers = 1;
        outputBufferList.mBuffers[0].mNumberChannels = _aacASBD.mChannelsPerFrame;
        outputBufferList.mBuffers[0].mDataByteSize = _aacBufferSize;
        outputBufferList.mBuffers[0].mData = _aacBuffer;

        OSStatus st = AudioConverterFillComplexBuffer(_converter,   &putPcmSamplesInBufferList, (__bridge void *) self, &_numOutputPackets, &outputBufferList, NULL);

        if (0 == st) {             
            [_rtsp onAudioData:_aacBuffer :outputBufferList.mBuffers[0].mDataByteSize :dPTS];
        }else{
            NSLog(@"Error converting Buffer");
            NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:st userInfo:nil];
            NSLog([self OSStatusToStr :st] );
            char * str = new char[3];
            FormatError(str, st);

        } 

        if (_blockBuffer) // Double check that what you are releasing actually exists!
        {
            CFRelease(_blockBuffer);
        }          
  }


}

getAudioBufferDataFromCMSampleBufferRef의 코드는 다음과 같습니다.

- (AudioBuffer) getAudioBufferDataFromCMSampleBufferRef: (CMSampleBufferRef)audioSampleBuffer{

     AudioBufferList audioBufferList;  

     OSStatus err =      CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(audioSampleBuffer, NULL, &audioBufferList, sizeof(audioBufferList), NULL, NULL, 0, &_blockBuffer);
     AudioBuffer audioBuffer ;

     if (!err && _blockBuffer && audioBufferList.mBuffers[0].mData && (audioBufferList.mBuffers[0].mDataByteSize > 0))
     {
         for( int y=0; y<audioBufferList.mNumberBuffers; y++ )
         {
             audioBuffer = audioBufferList.mBuffers[y];           
             break;
         }
     }

    inputBuffer.mData=audioBuffer.mData;
    inputBuffer.mDataByteSize=audioBuffer.mDataByteSize;
    inputBuffer.mNumberChannels=1;

    return audioBuffer;
}

위 버전의 코드에서 BAD_ACCESS 오류가 발생합니다. 대신 blockBuffer를 해제하는 코드를 제거하면 메모리 누수가 발생하고 결국 메모리 부족으로 인해 앱이 종료됩니다.

blockBuffer를 유지하지 않고 코드를 작성하면

 getAudioBufferDataFromCMSampleBufferRef

아래와 같이 다르게

- (AudioBuffer) getAudioBufferDataFromCMSampleBufferRef: (CMSampleBufferRef)audioSampleBuffer
{
    _blockBuffer = CMSampleBufferGetDataBuffer(audioSampleBuffer);
    int audioBufferByteSize =    CMSampleBufferGetTotalSampleSize(audioSampleBuffer);                   

CMBlockBufferCopyDataBytes(_blockBuffer,0,audioBufferByteSize,inputBuffer.mData);
    inputBuffer.mDataByteSize=audioBuffer.mDataByteSize;
    inputBuffer.mNumberChannels=1;
}

이 버전에서는 블록 버퍼가 유지되지 않으므로 해제 할 필요가 없습니다. 그러나 이제 나는 오디오에서 끔찍한 정적을 얻습니다.

이 문제를 해결하는 방법에 대한 아이디어가 있습니까?

고마워, Ozgur

hotpaw2

한 가지 방법은 일반적으로 보유되지 않은 버퍼의 모든 오디오 샘플 데이터를 자체 (사전 할당 및 보유, 잠금없는) 원형 fifo 버퍼로 복사하는 것입니다. 그런 다음 어느 시점에서 해제되므로 보유되지 않은 버퍼를 무시하십시오. 자신의 원형 버퍼에서 오디오 데이터를 사용하십시오.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관