You are providing packet desc on the output side (which you would do
if you were encoding - in that case you just provide enough space for
that number of packet descs, and the converter fills it out).
Bill
On 16/03/2007, at 5:45 AM, Edward Hervey wrote:
> Hi all,
>
> I'm writing a core audio decoders wrapper plugin for GStreamer. This
> involves allowing to use the existing QT decoders within a GStreamer
> pipeline.
> I currently have it working with mp3 and somewhat with QDM2, but
> it's failing miserably with AAC.
> The first time I call AudioConverterFillComplexBuffer() it returns
> '!pkd' (kAudioConverterErr_RequiresPacketDescriptionsError). The
> problem is that I am giving that function a table of
> AudioStreamPacketDescription, so I can't figure out what's wrong here.
> I have been looking for documentation on what that error really means
> (apart from the obvious "you haven't given a packet description) but
> couldn't find any documentation whatsoever.
>
> Below follows the relevant part of my plugin so you can see how I'm
> using AudioConverter.
>
> Since this is a GStreamer plugin, we get the data (in this case AAC
> packets) without having any knowledge of where it comes from, so
> there's no way to use the QuickTime API that requires giving a file.
> This reduces drastically the number of examples I can base myself on
> (well ... basically no examples).
>
> I would appreciate any hints as to why ACFCB would return that error
> code, or any hints on what would be wrong in that code.
>
> Thanks in advance
>
>
>
> 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.mFormatID = kAudioFormatMPEG4AAC;
> macosx->indesc.mBytesPerPacket = 1024;
> }
>
> static gboolean
> open_decoder (MacOSXAudioDecoder * macosx, GstCaps * caps, GstCaps
> ** othercaps)
> {
>
> switch (oclass->componentSubType) {
> case QT_MAKE_FOURCC_LE ('.', 'm', 'p', '3'):
> fill_indesc_mp3 (macosx, oclass->componentSubType, rate,
> channels);
> break;
> case QT_MAKE_FOURCC_LE ('m', 'p', '4', 'a'):
> fill_indesc_aac (macosx, oclass->componentSubType, rate,
> channels);
> break;
> default:
> fill_indesc_generic (macosx, oclass->componentSubType, rate,
> channels);
> break;
> }
>
> macosx->samplerate = rate;
>
> /* 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 =
> (AudioBufferList *) calloc (1,
> sizeof (AudioBufferList) + channels * sizeof (AudioBuffer));
> macosx->bufferlist->mNumberBuffers = 1;
> macosx->bufferlist->mBuffers[0].mNumberChannels = channels;
>
> for (i = channels; i; i--) {
> /* 50 ms */
> macosx->bufferlist->mBuffers[i-1].mDataByteSize = rate *
> channels * 4 / 20;
> macosx->bufferlist->mBuffers[i-1].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;
> }
>
> chain() {
> 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)) {
> if (status < 0)
> GST_WARNING_OBJECT (macosx,
> "Error in AudioConverterFillComplexBuffer() : %d", status);
> else
> GST_WARNING_OBJECT (macosx,
> "Error in AudioConverterFillComplexBuffer() : %"
> GST_FOURCC_FORMAT,
> QT_FOURCC_ARGS (status));
> ret = GST_FLOW_ERROR;
> goto beach;
> }
>
> realbytes = macosx->bufferlist->mBuffers[0].mDataByteSize;
>
> GST_LOG_OBJECT (macosx, "We now have %d samples [%d bytes]",
> outsamples, realbytes);
>
> macosx->bufferlist->mBuffers[0].mDataByteSize = savedbytes;
>
> if (!outsamples)
> break;
>
> /* 4. Create buffer and copy data in it */
> ret = gst_pad_alloc_buffer (macosx->srcpad, macosx->cur_offset,
> realbytes, GST_PAD_CAPS (macosx->srcpad), &outbuf);
> if (ret != GST_FLOW_OK)
> goto beach;
>
> /* copy data from bufferlist to output buffer */
> g_memmove (GST_BUFFER_DATA (outbuf),
> macosx->bufferlist->mBuffers[0].mData, realbytes);
> }
>
> --
> Edward Hervey
> Multimedia editing developer / Fluendo S.A.
> http://www.pitivi.org/
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Coreaudio-api mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
--
mailto:email@hidden
tel: +1 408 974 4056
________________________________________________________________________
__
"Much human ingenuity has gone into finding the ultimate Before.
The current state of knowledge can be summarized thus:
In the beginning, there was nothing, which exploded" - Terry Pratchett
________________________________________________________________________
__