• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ios - 从麦克风捕获音频时,我陷入内存泄漏或音频中的过度静态之间

[复制链接]
菜鸟教程小白 发表于 2022-12-13 09:03:16 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我正在编写一个 iPhone 应用程序,我需要从麦克风捕获音频并将其以 AAC 格式流式传输到流媒体服务器。所以我先捕获音频,然后使用

AudioConverterFillComplexBuffer

将音频转换为 AAC 的方法。

下面是代码

- (void) captureOutputAVCaptureOutput *)captureOutput didOutputSampleBufferCMSampleBufferRef)sampleBuffer fromConnectionAVCaptureConnection *)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 utputBufferList.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;
}

在这个版本中, block 缓冲区没有被保留,所以不需要释放它。但是现在我在音频中得到了可怕的静电。

有人知道如何解决这个问题吗?

谢谢, 奥兹古尔



Best Answer-推荐答案


通常这样做的一种方法是将所有音频样本数据从未保留的缓冲区复制到您自己的(预分配和保留的、无锁的)循环 fifo 缓冲区中。然后忽略未保留的缓冲区,因为它会在某个时候被释放。使用您自己的循环缓冲区中的音频数据。

关于ios - 从麦克风捕获音频时,我陷入内存泄漏或音频中的过度静态之间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31433442/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap