All pastes #396481 Raw Edit

Unnamed

public text v1 · immutable
·published 2007-03-15 20:06 UTC
rendered paste body
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;
    }