AudioConverterFillComplexBuffer returns 1852797029 (kAudioCodecIllegalOperationError)

1.5k views Asked by At

I'm trying to decode aac data with AudioToolbox in iOS environment. I consulted this thread.

'AudioConverterNew' function call succeed but AudioConverterFillComplexBuffer returns error code 1852797029, kAudioCodecIllegalOperationError.

I'm trying to find my mistakes. Thank you for reading.

- (void)initAudioToolBox {
    HCAudioAsset* asset = [self.provider getAudioAsset];

    AudioStreamBasicDescription outFormat;
    memset(&outFormat, 0, sizeof(outFormat));
    outFormat.mSampleRate       = 44100;
    outFormat.mFormatID         = kAudioFormatLinearPCM;
    outFormat.mFormatFlags      = kLinearPCMFormatFlagIsSignedInteger;
    outFormat.mBytesPerPacket   = 2;
    outFormat.mFramesPerPacket  = 1;
    outFormat.mBytesPerFrame    = 2;
    outFormat.mChannelsPerFrame = 1;
    outFormat.mBitsPerChannel   = 16;
    outFormat.mReserved         = 0;

    AudioStreamBasicDescription inFormat;
    memset(&inFormat, 0, sizeof(inFormat));
    inFormat.mSampleRate        = [asset sampleRate];
    inFormat.mFormatID          = kAudioFormatMPEG4AAC;
    inFormat.mFormatFlags       = kMPEG4Object_AAC_LC;
    inFormat.mBytesPerPacket    = 0;
    inFormat.mFramesPerPacket   = (UInt32)[asset framePerPacket];
    inFormat.mBytesPerFrame     = 0;
    inFormat.mChannelsPerFrame  = (UInt32)[asset channelCount];
    inFormat.mBitsPerChannel    = 0;
    inFormat.mReserved          = 0;

    OSStatus status =  AudioConverterNew(&inFormat, &outFormat, &audioConverter);
    if (status != noErr) {
        NSLog(@"setup converter error, status: %i\n", (int)status);
    } else {
        NSLog(@"Audio Converter is initialized successfully.");
    }
}

typedef struct _PassthroughUserData PassthroughUserData;
struct _PassthroughUserData {
    UInt32 mChannels;
    UInt32 mDataSize;
    const void* mData;
    AudioStreamPacketDescription mPacket;
};

int inInputDataProc(AudioConverterRef aAudioConverter,
                    UInt32* aNumDataPackets,
                    AudioBufferList* aData,
                    AudioStreamPacketDescription** aPacketDesc,
                    void* aUserData)
{
    PassthroughUserData* userData = (PassthroughUserData*)aUserData;
    if (!userData->mDataSize) {
        *aNumDataPackets = 0;
        NSLog(@"inInputDataProc returns -1");
        return -1;
    }

    if (aPacketDesc) {
        userData->mPacket.mStartOffset = 0;
        userData->mPacket.mVariableFramesInPacket = 0;
        userData->mPacket.mDataByteSize = userData->mDataSize;
        NSLog(@"mDataSize:%d", userData->mDataSize);
        *aPacketDesc = &userData->mPacket;
    }

    aData->mBuffers[0].mNumberChannels = userData->mChannels;
    aData->mBuffers[0].mDataByteSize = userData->mDataSize;
    aData->mBuffers[0].mData = (void*)(userData->mData);
    NSLog(@"buffer[0] - channel:%d, byte size:%u, data:%p",
          aData->mBuffers[0].mNumberChannels,
          (unsigned int)aData->mBuffers[0].mDataByteSize,
          aData->mBuffers[0].mData);

    // No more data to provide following this run.
    userData->mDataSize = 0;

    NSLog(@"inInputDataProc returns 0");
    return 0;
}

- (void)decodeAudioFrame:(NSData *)frame withPts:(NSInteger)pts{
    if(!audioConverter){
        [self initAudioToolBox];
    }

    HCAudioAsset* asset = [self.provider getAudioAsset];

    PassthroughUserData userData = { (UInt32)[asset channelCount], (UInt32)frame.length, [frame bytes]};
    NSMutableData *decodedData = [NSMutableData new];

    const uint32_t MAX_AUDIO_FRAMES = 128;
    const uint32_t maxDecodedSamples = MAX_AUDIO_FRAMES * 1;

    do {
        uint8_t *buffer = (uint8_t *)malloc(maxDecodedSamples * sizeof(short int));
        AudioBufferList decBuffer;
        memset(&decBuffer, 0, sizeof(AudioBufferList));
        decBuffer.mNumberBuffers = 1;
        decBuffer.mBuffers[0].mNumberChannels = 2;
        decBuffer.mBuffers[0].mDataByteSize = maxDecodedSamples * sizeof(short int);
        decBuffer.mBuffers[0].mData = buffer;

        UInt32 numFrames = MAX_AUDIO_FRAMES;

        AudioStreamPacketDescription outPacketDescription;
        memset(&outPacketDescription, 0, sizeof(AudioStreamPacketDescription));
        outPacketDescription.mDataByteSize = MAX_AUDIO_FRAMES;
        outPacketDescription.mStartOffset = 0;
        outPacketDescription.mVariableFramesInPacket = 0;

        NSLog(@"frame - size:%lu, buffer:%p", [frame length], [frame bytes]);
        OSStatus rv = AudioConverterFillComplexBuffer(audioConverter,
                                                      inInputDataProc,
                                                      &userData,
                                                      &numFrames,
                                                      &decBuffer,
                                                      &outPacketDescription);

        NSLog(@"num frames:%d, dec buffer [0] channels:%d, dec buffer [0] data byte size:%d, rv:%d",
              numFrames, decBuffer.mBuffers[0].mNumberChannels,
              decBuffer.mBuffers[0].mDataByteSize, (int)rv);

        if (rv && rv != noErr) {
            NSLog(@"Error decoding audio stream: %d\n", rv);
            break;
        }

        if (numFrames) {
            [decodedData appendBytes:decBuffer.mBuffers[0].mData length:decBuffer.mBuffers[0].mDataByteSize];
        }

    } while (true);

    //void *pData = (void *)[decodedData bytes];
    //audioRenderer->Render(&pData, decodedData.length, pts);
}
0

There are 0 answers