Re: AAC and AudioConverter error : '!pkd'
Re: AAC and AudioConverter error : '!pkd'
- Subject: Re: AAC and AudioConverter error : '!pkd'
- From: William Stewart <email@hidden>
- Date: Mon, 19 Mar 2007 15:28:51 -0700
You have to know these - they are described in the files that is
storing the AAC data and there are APIs (AudioFileReadPackets for
instance) where you get the packet descriptions when you read the file
Bill
On 17/03/2007, at 1:23 AM, Edward Hervey wrote:
Hi,
On 3/17/07, William Stewart <email@hidden> wrote:
The packet descriptions have to be on the side that has the
compressed data - so if you are decoding, the input proc has to
provide packet descs for VBR. So, in the input proc you have to
provide these based on where they are in the AAC stream you are
getting.
Thanks for the info, so the missing packet description is indeed in
my input proc. As I explained, I can't request the information to fill
in those structures from quicktime/CA.
Supposing I only have framed AAC coming in, where could I find some
documentation about what I need to put in the packet description
depending on the buffer I am returning ?
Thanks again,
Edward
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:
40apple.com
>
> 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
_____________________________________________________________________
___
__
--
Edward Hervey
Multimedia editing developer / Fluendo S.A.
http://www.pitivi.org/
--
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
________________________________________________________________________
__
_______________________________________________
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