Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
tianguanghui committed Sep 8, 2021
1 parent 5fb960f commit d2ccfc1
Showing 1 changed file with 41 additions and 67 deletions.
108 changes: 41 additions & 67 deletions LFLiveKit-ReplayKit/coder/LFHardwareAudioEncoder.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//

#define DebugInfoKey @"DebugInfoKey" //一般调试信息
#define AppGroupName @"group.group.com.lancoo.LGTeachingAssistantTest"
#define DarwinNotifyCenter CFNotificationCenterGetDarwinNotifyCenter()
#define DegugInfoNotifyName CFSTR("DegugInfoNotifyName")
#import "LFHardwareAudioEncoder.h"

@interface LFHardwareAudioEncoder (){
Expand Down Expand Up @@ -55,60 +58,33 @@ - (void)setDelegate:(id<LFAudioEncodingDelegate>)delegate {
_aacDeleage = delegate;
}

- (void)encodeAudioData:(nullable NSData*)audioData timeStamp:(uint64_t)timeStamp {
if (![self createAudioConvert]) {
- (void)encodeAudioData:(CMSampleBufferRef*)audioBuff timeStamp:(uint64_t)timeStamp {
if (![self createAudioConvert:audioBuff]) {
return;
}

if(leftLength + audioData.length >= self.configuration.bufferLength){
///<  发送
NSInteger totalSize = leftLength + audioData.length;
NSInteger encodeCount = totalSize/self.configuration.bufferLength;
char *totalBuf = malloc(totalSize);
char *p = totalBuf;

memset(totalBuf, (int)totalSize, 0);
memcpy(totalBuf, leftBuf, leftLength);
memcpy(totalBuf + leftLength, audioData.bytes, audioData.length);

for(NSInteger index = 0;index < encodeCount;index++){
[self encodeBuffer:p timeStamp:timeStamp];
p += self.configuration.bufferLength;
}

leftLength = totalSize%self.configuration.bufferLength;
memset(leftBuf, 0, self.configuration.bufferLength);
memcpy(leftBuf, totalBuf + (totalSize -leftLength), leftLength);

free(totalBuf);

}else{
///< 积累
memcpy(leftBuf+leftLength, audioData.bytes, audioData.length);
leftLength = leftLength + audioData.length;
}
[self encodeBuffer:audioBuff timeStamp:timeStamp];
}

- (void)encodeBuffer:(char*)buf timeStamp:(uint64_t)timeStamp{

AudioBuffer inBuffer;
inBuffer.mNumberChannels = 1;
inBuffer.mData = buf;
inBuffer.mDataByteSize = (UInt32)self.configuration.bufferLength;

AudioBufferList buffers;
buffers.mNumberBuffers = 1;
buffers.mBuffers[0] = inBuffer;


- (void)encodeBuffer:(CMSampleBufferRef)buf timeStamp:(uint64_t)timeStamp{
OSStatus status = noErr;
CMBlockBufferRef blockBuffer = nil;
AudioBufferList inBufferList;
status = CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(buf, NULL, &inBufferList, sizeof(inBufferList), NULL, NULL, 0, &blockBuffer);
if (status != noErr)
{
[self logExtensionDebugInfo:[NSString stringWithFormat:@"输入音频缓冲列表创建失败:%d",status]];
return;
}
// 初始化一个输出缓冲列表
AudioBufferList outBufferList;
outBufferList.mNumberBuffers = 1;
outBufferList.mBuffers[0].mNumberChannels = inBuffer.mNumberChannels;
outBufferList.mBuffers[0].mDataByteSize = inBuffer.mDataByteSize; // 设置缓冲区大小
outBufferList.mBuffers[0].mNumberChannels = 1;
outBufferList.mBuffers[0].mDataByteSize = (UInt32)self.configuration.bufferLength; // 设置缓冲区大小
outBufferList.mBuffers[0].mData = aacBuf; // 设置AAC缓冲区
UInt32 outputDataPacketSize = 1;
if (AudioConverterFillComplexBuffer(m_converter, inputDataProc, &buffers, &outputDataPacketSize, &outBufferList, NULL) != noErr) {
status = AudioConverterFillComplexBuffer(m_converter, inputDataProc, &inBufferList, &outputDataPacketSize, &outBufferList, NULL);
if (status != noErr) {
[self logExtensionDebugInfo:[NSString stringWithFormat:@"音频编码失败:%d",status]];
return;
}

Expand All @@ -121,45 +97,44 @@ - (void)encodeBuffer:(char*)buf timeStamp:(uint64_t)timeStamp{
exeData[1] = _configuration.asc[1];
audioFrame.audioInfo = [NSData dataWithBytes:exeData length:2];
if (self.aacDeleage && [self.aacDeleage respondsToSelector:@selector(audioEncoder:audioFrame:)]) {
// [self logExtensionDebugInfo:@"音频编码成功"];
[self.aacDeleage audioEncoder:self audioFrame:audioFrame];
}

if (self->enabledWriteVideoFile) {
NSData *adts = [self adtsData:_configuration.numberOfChannels rawDataLength:audioFrame.data.length];
fwrite(adts.bytes, 1, adts.length, self->fp);
fwrite(audioFrame.data.bytes, 1, audioFrame.data.length, self->fp);
CFRelease(blockBuffer);
}
- (void)logExtensionDebugInfo:(NSString *)info {
#ifdef DEBUG
if (!info.length) {
return;
}

}
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:AppGroupName];
[defaults setValue:info forKey:DebugInfoKey];
[defaults synchronize];

CFNotificationCenterPostNotification(DarwinNotifyCenter, DegugInfoNotifyName, NULL, NULL, kCFNotificationDeliverImmediately);
#endif
}
- (void)stopEncoder {

}

#pragma mark -- CustomMethod
- (BOOL)createAudioConvert { //根据输入样本初始化一个编码转换器
- (BOOL)createAudioConvert:(CMSampleBufferRef)sampleBuffer { //根据输入样本初始化一个编码转换器
if (m_converter != nil) {
return TRUE;
}

AudioStreamBasicDescription inputFormat = {0};
inputFormat.mSampleRate = _configuration.audioSampleRate;
inputFormat.mFormatID = kAudioFormatLinearPCM;
inputFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
inputFormat.mChannelsPerFrame = (UInt32)_configuration.numberOfChannels;
inputFormat.mFramesPerPacket = 1;
inputFormat.mBitsPerChannel = 16;
inputFormat.mBytesPerFrame = inputFormat.mBitsPerChannel / 8 * inputFormat.mChannelsPerFrame;
inputFormat.mBytesPerPacket = inputFormat.mBytesPerFrame * inputFormat.mFramesPerPacket;
AudioStreamBasicDescription inputFormat = *CMAudioFormatDescriptionGetStreamBasicDescription((CMAudioFormatDescriptionRef)CMSampleBufferGetFormatDescription(sampleBuffer));

AudioStreamBasicDescription outputFormat; // 这里开始是输出音频格式
memset(&outputFormat, 0, sizeof(outputFormat));
outputFormat.mSampleRate = inputFormat.mSampleRate; // 采样率保持一致
outputFormat.mFormatID = kAudioFormatMPEG4AAC; // AAC编码 kAudioFormatMPEG4AAC kAudioFormatMPEG4AAC_HE_V2
outputFormat.mChannelsPerFrame = (UInt32)_configuration.numberOfChannels;;
outputFormat.mChannelsPerFrame = (UInt32)_configuration.numberOfChannels;
outputFormat.mFramesPerPacket = 1024; // AAC一帧是1024个字节

outputFormat.mFormatFlags = kMPEG4Object_AAC_LC; // 无损编码 ,0表示没有
const OSType subtype = kAudioFormatMPEG4AAC;

AudioClassDescription requestedCodecs[2] = {
{
kAudioEncoderComponentType,
Expand All @@ -184,10 +159,9 @@ - (BOOL)createAudioConvert { //根据输入样本初始化一个编码转换器

return YES;
}


#pragma mark -- AudioCallBack
OSStatus inputDataProc(AudioConverterRef inConverter, UInt32 *ioNumberDataPackets, AudioBufferList *ioData, AudioStreamPacketDescription * *outDataPacketDescription, void *inUserData) { //<span style="font-family: Arial, Helvetica, sans-serif;">AudioConverterFillComplexBuffer 编码过程中,会要求这个函数来填充输入数据,也就是原始PCM数据</span>
ioData->mNumberBuffers = 1;
AudioBufferList bufferList = *(AudioBufferList *)inUserData;
ioData->mBuffers[0].mNumberChannels = 1;
ioData->mBuffers[0].mData = bufferList.mBuffers[0].mData;
Expand Down

0 comments on commit d2ccfc1

Please sign in to comment.