static void clear_AudioStreamBasicDescription (AudioStreamBasicDescription *desc) { desc->mSampleRate = 0; desc->mFormatID = 0; desc->mFormatFlags = 0; desc->mBytesPerPacket = 0; desc->mFramesPerPacket = 0; desc->mBytesPerFrame = 0; desc->mChannelsPerFrame = 0; desc->mBitsPerChannel = 0; } static void fill_indesc_aac (MacOSXAudioDecoder * macosx, guint32 fourcc, gint rate, gint channels) { clear_AudioStreamBasicDescription (&macosx->indesc); /* aac always has 1024 bytes per packet */ macosx->indesc.mSampleRate = rate; macosx->indesc.mFormatID = kAudioFormatMPEG4AAC; macosx->indesc.mBytesPerPacket = 1024; macosx->indesc.mChannelsPerFrame = channels; } setup() { ... /* Setup the output format description */ macosx->outdesc.mSampleRate = rate; macosx->outdesc.mFormatID = kAudioFormatLinearPCM; macosx->outdesc.mFormatFlags = kAudioFormatFlagIsFloat; #if G_BYTE_ORDER == G_BIG_ENDIAN macosx->outdesc.mFormatFlags |= kAudioFormatFlagIsBigEndian ; #endif macosx->outdesc.mBytesPerPacket = channels * 4; /* ?? */ macosx->outdesc.mFramesPerPacket = 1; macosx->outdesc.mBytesPerFrame = channels * 4;/* channels * bytes-per-samples*/ macosx->outdesc.mChannelsPerFrame = channels; macosx->outdesc.mBitsPerChannel = 32; /* Create an AudioConverter */ status = AudioConverterNew (&macosx->indesc, &macosx->outdesc, &macosx->aconv); if (status != noErr) { GST_WARNING_OBJECT (macosx, "Error when calling AudioConverterNew() : %"GST_FOURCC_FORMAT, QT_FOURCC_ARGS (status)); goto beach; } /* if we have codec_data, give it to the converter ! */ if (codec_data) { oserr = AudioConverterSetProperty(macosx->aconv, kAudioConverterDecompressionMagicCookie, GST_BUFFER_SIZE (codec_data), GST_BUFFER_DATA (codec_data)); if (oserr != noErr) { GST_WARNING_OBJECT (macosx, "Error setting extra codec data !"); goto beach; } } /* Create output bufferlist */ macosx->bufferlist.mNumberBuffers = 1; macosx->bufferlist.mBuffers[0].mNumberChannels = channels; /* 50 ms */ macosx->bufferlist.mBuffers[0].mDataByteSize = rate * channels * 4 / 20; macosx->bufferlist.mBuffers[0].mData = g_malloc0(rate * channels * 4 / 20); ... } static OSStatus process_buffer_cb (AudioConverterRef inAudioConverter, UInt32 * ioNumberDataPackets, AudioBufferList * ioData, AudioStreamPacketDescription ** outDataPacketDescription, MacOSXAudioDecoder *macosx) { gint len; GST_LOG_OBJECT (macosx, "ioNumberDataPackets:%lu, iodata:%p, outDataPacketDescription:%p", *ioNumberDataPackets, ioData, outDataPacketDescription); ioData->mBuffers[0].mData = NULL; ioData->mBuffers[0].mDataByteSize = 0; if (macosx->prevdata) g_free (macosx->prevdata); len = gst_adapter_available (macosx->adapter); if (len) { ioData->mBuffers[0].mData = gst_adapter_take (macosx->adapter, len); macosx->prevdata = ioData->mBuffers[0].mData; } else { macosx->prevdata = NULL; } ioData->mBuffers[0].mDataByteSize = len; *outDataPacketDescription = NULL; GST_LOG_OBJECT (macosx, "returning %d bytes at %p", len, ioData->mBuffers[0].mData); if (!len) return 42; return noErr; } /* decoding phase */ while (gst_adapter_available(macosx->adapter) > 128) { GstBuffer *outbuf; OSErr oserr; OSStatus status; guint32 outsamples = macosx->bufferlist.mBuffers[0].mDataByteSize / 8; guint32 savedbytes = macosx->bufferlist.mBuffers[0].mDataByteSize; guint32 realbytes; AudioStreamPacketDescription *aspd; GST_LOG_OBJECT (macosx, "Calling FillBuffer(outsamples:%d , outdata:%p)", outsamples, macosx->bufferlist.mBuffers[0].mData); aspd = g_new0 (AudioStreamPacketDescription, outsamples); /* Ask AudioConverter to give us data ! */ status = AudioConverterFillComplexBuffer (macosx->aconv, (AudioConverterComplexInputDataProc) process_buffer_cb, macosx, &outsamples, &macosx->bufferlist, aspd); g_free (aspd); if ((status != noErr) && (status != 42)) { GST_WARNING_OBJECT (macosx, "Error in AudioConverterFillBuffer() : %"GST_FOURCC_FORMAT, QT_FOURCC_ARGS (status)); ret = GST_FLOW_ERROR; goto beach; }