iOS AudioConverter exceeds maximum packet size (2048) for input format

105 views Asked by At

I'm trying to decode aac to pcm data, my goal is to decode the acc data received by tcp into pcm data. Currently I want to convert local aac files to pcm data first, and I encounter a problem:

[AudioConverter] CompositeAudioConverter.cpp:1063 Packet description 0 of 1 (size 1009664) exceeds maximum packet size (2048) for input format

I first convert all the aac files to data, and then directly feed it to the decoder, and get the above error.

Below is my decoder code:

- (void)setupDecoder{
    AudioStreamBasicDescription outputAudioDes;
    memset(&outputAudioDes, 0, sizeof(outputAudioDes));
    
    outputAudioDes.mSampleRate = (Float64)_config.sampleRate;    outputAudioDes.mChannelsPerFrame = (UInt32)_config.channelCount;
    outputAudioDes.mFormatID = kAudioFormatLinearPCM; 
    outputAudioDes.mFormatFlags = (kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked);
    outputAudioDes.mFramesPerPacket = 1;
    outputAudioDes.mBitsPerChannel = 16; 
    outputAudioDes.mBytesPerFrame = outputAudioDes.mBitsPerChannel / 8 * outputAudioDes.mChannelsPerFrame;
    outputAudioDes.mBytesPerPacket = outputAudioDes.mBytesPerFrame * outputAudioDes.mFramesPerPacket;
    outputAudioDes.mReserved = 0;
    
    
    AudioStreamBasicDescription inputAudioDes;
    memset(&inputAudioDes, 0, sizeof(inputAudioDes));
    
    inputAudioDes.mSampleRate = (Float64)_config.sampleRate;
    inputAudioDes.mFormatID = kAudioFormatMPEG4AAC;
    inputAudioDes.mFormatFlags = kMPEG4Object_AAC_LC;
    inputAudioDes.mFramesPerPacket = 1024;
    inputAudioDes.mChannelsPerFrame = (UInt32)_config.channelCount;
    
    
    UInt32 inDesSize = sizeof(inputAudioDes);
    AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &inDesSize, &inputAudioDes);
    
    
    AudioClassDescription *audioClassDesc = [self getAudioClassDescriptionWithType:outputAudioDes.mFormatID fromManufacture:kAppleHardwareAudioCodecManufacturer];
    
   
    OSStatus status = AudioConverterNewSpecific(&inputAudioDes,
                                                &outputAudioDes,
                                                1,
                                                audioClassDesc,
                                                &_audioConverter);
    if (status != noErr){
        NSLog(@"Error!: status = %d",(int)status);
        return;
    }
}

- (AudioClassDescription *)getAudioClassDescriptionWithType:(AudioFormatID)type fromManufacture:(uint32_t)manufacture{
    static AudioClassDescription desc;
    UInt32 decoderSpecific = type;
    
   
    UInt32 size;
    OSStatus status = AudioFormatGetPropertyInfo(kAudioFormatProperty_Decoders, sizeof(decoderSpecific), &decoderSpecific, &size);
    if (status != noErr){
        NSLog(@"Error!:  status = %d",(int)status);
        return nil;
    }
    
    unsigned int count = size / sizeof(AudioClassDescription);
    AudioClassDescription description[count];
    status = AudioFormatGetProperty(kAudioFormatProperty_Encoders, sizeof(decoderSpecific), &decoderSpecific, &size, &description);
    if (status != noErr){
        NSLog(@"Error!: status = %d",(int)status);
        return nil;
    }
    for (unsigned int i = 0; i < count; i++) {
        if (type == description[i].mSubType &&
            manufacture == description[i].mManufacturer){
            desc = description[i];
            return &desc;
        }
    }
    return nil;
}

- (void)decodeAudioAACData:(NSData *)aacData{
    if (!_audioConverter){
        return;
    }
    __weak typeof(self) weakSelf = self;
    dispatch_async(_decoderQueue, ^{
        SRAudioUserData userData = {0};
        userData.channelCount = (UInt32)weakSelf.config.channelCount;
        userData.data = (char *)[aacData bytes];
        userData.size = (UInt32)aacData.length;
        userData.packetDesc.mDataByteSize = (UInt32)aacData.length;
        userData.packetDesc.mStartOffset = 0;
        userData.packetDesc.mVariableFramesInPacket = 0;
        
     
        const uint32_t MAX_AUDIO_FRAMES = 2048;
        UInt32 pcmBufferSize = (UInt32)(MAX_AUDIO_FRAMES * self->_config.channelCount);
        UInt32 pcmDataPacketSize = 1;
        
       
        uint8_t *pcmBuffer = malloc(pcmBufferSize);
        memset(pcmBuffer, 0, pcmBufferSize);
        
        
        AudioBufferList outAudioBufferList = {0};
        outAudioBufferList.mNumberBuffers = 1;
        outAudioBufferList.mBuffers[0].mNumberChannels = (uint32_t)self->_config.channelCount;
        outAudioBufferList.mBuffers[0].mDataByteSize = (UInt32)pcmBufferSize;
        outAudioBufferList.mBuffers[0].mData = pcmBuffer;
        
        
        AudioStreamPacketDescription outputPacketDesc;
        memset(&outputPacketDesc, 0, sizeof(AudioStreamPacketDescription));
        outputPacketDesc.mDataByteSize = MAX_AUDIO_FRAMES;
        outputPacketDesc.mStartOffset = 0;
        outputPacketDesc.mVariableFramesInPacket = 0;
        
        
        OSStatus status = AudioConverterFillComplexBuffer(self->_audioConverter,
                                                          &AudioDecoderConverterComplexInputDataProc,
                                                          &userData,
                                                          &pcmDataPacketSize,
                                                          &outAudioBufferList,
                                                          &outputPacketDesc);
        if (status != noErr){
            NSLog(@"Error: AAC Decoder error, status = %d",(int)status);
            return;
        }
        
        if (outAudioBufferList.mBuffers[0].mDataByteSize > 0){
            NSData *rawData = [NSData dataWithBytes:outAudioBufferList.mBuffers[0].mData length:outAudioBufferList.mBuffers[0].mDataByteSize];
            NSLog(@"rawData %ld", rawData.length);
            dispatch_async(weakSelf.callbackQueue, ^{
                [weakSelf.delegate audioDecoderCallback:rawData];
            });
        }
        free(pcmBuffer);
    });
}

- (void)dealloc{
    if (_audioConverter){
        AudioConverterDispose(_audioConverter);
        _audioConverter = NULL;
    }
}


static OSStatus AudioDecoderConverterComplexInputDataProc(AudioConverterRef inAudioConverter,
                                                          UInt32 *ioNumberDataPackets,
                                                          AudioBufferList *ioData,
                                                          AudioStreamPacketDescription **outDataPacketDescription,
                                                          void *inUserData){
    SRAudioUserData *audioDecoder = (SRAudioUserData *)(inUserData);
    if (audioDecoder->size <= 0){
        ioNumberDataPackets = 0;
        return -1;
    }
    
    
    if (outDataPacketDescription){
        *outDataPacketDescription = &audioDecoder->packetDesc;
        (*outDataPacketDescription)[0].mStartOffset = 0;
        (*outDataPacketDescription)[0].mDataByteSize = audioDecoder->size;
        (*outDataPacketDescription)[0].mVariableFramesInPacket = 0;
    }
    
    ioData->mBuffers[0].mData = audioDecoder->data;
    ioData->mBuffers[0].mDataByteSize = audioDecoder->size;
    ioData->mBuffers[0].mNumberChannels = audioDecoder->channelCount;
    
    return noErr;
}


Below are the default property values for my _config:

self.bitrate = 6400;
self.channelCount = 2;
self.sampleSize = 16;
self.sampleRate = 44100;

This is my code to convert aac file to data:

if let audioPath = Bundle.main.path(forResource: "hello.aac", ofType: nil),
   let stream = InputStream(fileAtPath: audioPath){
   let audioDecoder = SRAudioDecoder(config: nil)
                            
   if let streamData = try? Data(reading: stream){
       audioDecoder.decodeAudioAACData(streamData)
   }
}

// Data Extension
init(reading input: InputStream) throws {
    self.init()
    input.open()
    defer {
        input.close()
    }

    let bufferSize = 1024
    let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
    defer {
        buffer.deallocate()
    }
    while input.hasBytesAvailable {
        let read = input.read(buffer, maxLength: bufferSize)
        if read < 0 {
            //Stream error occured
            throw input.streamError!
        } else if read == 0 {
            //EOF
            break
        }
        self.append(buffer, count: read)
    }
}

I try to split the data into 1024 for the decoder, but there is still an error:

Error: AAC Decoder error, status = 1650549857
AACDecoder.cpp:200    Unmatched number of channel elements in payload
AACDecoder.cpp:228    Error deserializing packet
ACMP4AACBaseDecoder.cpp:1438  (0x108811840) Error decoding packet 141: err = -1, packet length: 1024

Any suggestions are greatly appreciated.

0

There are 0 answers