banshee r4780 - in trunk/banshee: . build/osx/targets
- From: eoinh svn gnome org
- To: svn-commits-list gnome org
- Subject: banshee r4780 - in trunk/banshee: . build/osx/targets
- Date: Thu, 6 Nov 2008 07:30:56 +0000 (UTC)
Author: eoinh
Date: Thu Nov 6 07:30:56 2008
New Revision: 4780
URL: http://svn.gnome.org/viewvc/banshee?rev=4780&view=rev
Log:
2008-11-05 Eoin Hennessy <eoin randomrules org>
* build/osx/targets/gst-plugins-bad-qtwrapper-fixes.patch:
Added a patch containing a number of fixes for qtwrapper issues in
gst-plugins-bad 0.10.9 backported from current cvs. Makes playback on
OSX considerably more stable.
Added:
trunk/banshee/build/osx/targets/gst-plugins-bad-qtwrapper-fixes.patch
Modified:
trunk/banshee/ChangeLog
Added: trunk/banshee/build/osx/targets/gst-plugins-bad-qtwrapper-fixes.patch
==============================================================================
--- (empty file)
+++ trunk/banshee/build/osx/targets/gst-plugins-bad-qtwrapper-fixes.patch Thu Nov 6 07:30:56 2008
@@ -0,0 +1,417 @@
+diff --git sys/qtwrapper/Makefile.am sys/qtwrapper/Makefile.am
+index db08647..35a8337 100644
+--- sys/qtwrapper/Makefile.am
++++ sys/qtwrapper/Makefile.am
+@@ -14,7 +14,7 @@ libgstqtwrapper_la_SOURCES = \
+ libgstqtwrapper_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS)
+ libgstqtwrapper_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS)
+ libgstqtwrapper_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -Wl,-framework,CoreAudio,-framework,AudioToolbox,-framework,Carbon,-framework,QuickTime,-framework,QuartzCore
+-
++libgstqtwrapper_la_LIBTOOLFLAGS = --tag=disable-static
+
+ # headers we need but don't want installed
+ noinst_HEADERS = \
+diff --git sys/qtwrapper/audiodecoders.c sys/qtwrapper/audiodecoders.c
+index ed5c69c..1816a02 100644
+--- sys/qtwrapper/audiodecoders.c
++++ sys/qtwrapper/audiodecoders.c
+@@ -210,6 +210,49 @@ fill_indesc_generic (QTWrapperAudioDecoder * qtwrapper, guint32 fourcc,
+ qtwrapper->indesc.mChannelsPerFrame = channels;
+ }
+
++static void
++fill_indesc_alac (QTWrapperAudioDecoder * qtwrapper, guint32 fourcc,
++ gint rate, gint channels)
++{
++ clear_AudioStreamBasicDescription (&qtwrapper->indesc);
++ qtwrapper->indesc.mSampleRate = rate;
++ qtwrapper->indesc.mFormatID = fourcc;
++ qtwrapper->indesc.mChannelsPerFrame = channels;
++
++ // This has to be set, but the particular value doesn't seem to matter much
++ qtwrapper->indesc.mFramesPerPacket = 4096;
++}
++
++static gpointer
++make_alac_magic_cookie (GstBuffer * codec_data, gsize * len)
++{
++ guint8 *res;
++
++ if (GST_BUFFER_SIZE (codec_data) < 4)
++ return NULL;
++
++ *len = 20 + GST_BUFFER_SIZE (codec_data);
++ res = g_malloc0 (*len);
++
++ /* 12 first bytes are 'frma' (format) atom with 'alac' value */
++ GST_WRITE_UINT32_BE (res, 0xc); /* Atom length: 12 bytes */
++ GST_WRITE_UINT32_LE (res + 4, QT_MAKE_FOURCC_BE ('f', 'r', 'm', 'a'));
++ GST_WRITE_UINT32_LE (res + 8, QT_MAKE_FOURCC_BE ('a', 'l', 'a', 'c'));
++
++ /* Write the codec_data, but with the first four bytes reversed (different
++ endianness). This is the 'alac' atom. */
++ GST_WRITE_UINT32_BE (res + 12,
++ GST_READ_UINT32_LE (GST_BUFFER_DATA (codec_data)));
++ memcpy (res + 16, GST_BUFFER_DATA (codec_data) + 4,
++ GST_BUFFER_SIZE (codec_data) - 4);
++
++ /* Terminator atom */
++ GST_WRITE_UINT32_BE (res + 12 + GST_BUFFER_SIZE (codec_data), 8);
++ GST_WRITE_UINT32_BE (res + 12 + GST_BUFFER_SIZE (codec_data) + 4, 0);
++
++ return res;
++}
++
+ static gpointer
+ make_samr_magic_cookie (GstBuffer * codec_data, gsize * len)
+ {
+@@ -234,7 +277,7 @@ make_samr_magic_cookie (GstBuffer * codec_data, gsize * len)
+ /* yes... we need to replace 'damr' by 'samr'. Blame Apple ! */
+ GST_WRITE_UINT8 (res + 26, 's');
+
+- /* padding 8 bytes */
++ /* Terminator atom */
+ GST_WRITE_UINT32_BE (res + 40, 8);
+
+ #if DEBUG_DUMP
+@@ -259,6 +302,27 @@ write_len (guint8 * buf, int val)
+ return 4;
+ }
+
++static void
++aac_parse_codec_data (GstBuffer * codec_data, guint * channels)
++{
++ guint8 *data = GST_BUFFER_DATA (codec_data);
++ int codec_channels;
++
++ if (GST_BUFFER_SIZE (codec_data) < 2) {
++ GST_WARNING ("Cannot parse codec_data for channel count");
++ return;
++ }
++
++ codec_channels = (data[1] & 0x7f) >> 3;
++
++ if (*channels != codec_channels) {
++ GST_INFO ("Overwriting channels %d with %d", *channels, codec_channels);
++ *channels = codec_channels;
++ } else {
++ GST_INFO ("Retaining channel count %d", codec_channels);
++ }
++}
++
+ /* The AAC decoder requires the entire mpeg4 audio elementary stream
+ * descriptor, which is the body (except the 4-byte version field) of
+ * the quicktime 'esds' atom. However, qtdemux only passes through the
+@@ -360,6 +424,16 @@ open_decoder (QTWrapperAudioDecoder * qtwrapper, GstCaps * caps,
+ codec_data = GST_BUFFER_CAST (gst_value_get_mini_object (value));
+ }
+
++ oclass = (QTWrapperAudioDecoderClass *) (G_OBJECT_GET_CLASS (qtwrapper));
++
++ if (codec_data
++ && oclass->componentSubType == QT_MAKE_FOURCC_LE ('m', 'p', '4', 'a')) {
++ /* QuickTime/iTunes creates AAC files with the wrong channel count in the header,
++ so parse that out of the codec data if we can.
++ */
++ aac_parse_codec_data (codec_data, (guint *) & channels);
++ }
++
+ /* If the quicktime demuxer gives us a full esds atom, use that instead of
+ * the codec_data */
+ if ((value = gst_structure_get_value (s, "quicktime_esds"))) {
+@@ -375,7 +449,6 @@ open_decoder (QTWrapperAudioDecoder * qtwrapper, GstCaps * caps,
+
+ GST_INFO_OBJECT (qtwrapper, "rate:%d, channels:%d", rate, channels);
+
+- oclass = (QTWrapperAudioDecoderClass *) (G_OBJECT_GET_CLASS (qtwrapper));
+ GST_INFO_OBJECT (qtwrapper, "componentSubType is %" GST_FOURCC_FORMAT,
+ QT_FOURCC_ARGS (oclass->componentSubType));
+
+@@ -391,6 +464,9 @@ open_decoder (QTWrapperAudioDecoder * qtwrapper, GstCaps * caps,
+ fill_indesc_samr (qtwrapper, oclass->componentSubType, channels);
+ rate = 8000;
+ break;
++ case QT_MAKE_FOURCC_LE ('a', 'l', 'a', 'c'):
++ fill_indesc_alac (qtwrapper, oclass->componentSubType, rate, channels);
++ break;
+ default:
+ fill_indesc_generic (qtwrapper, oclass->componentSubType, rate, channels);
+ break;
+@@ -433,6 +509,10 @@ open_decoder (QTWrapperAudioDecoder * qtwrapper, GstCaps * caps,
+ if (status) {
+ GST_WARNING_OBJECT (qtwrapper,
+ "Error setting input description on SCAudio: %ld", status);
++
++ GST_ELEMENT_ERROR (qtwrapper, STREAM, NOT_IMPLEMENTED,
++ ("A QuickTime error occurred trying to decode this stream"),
++ ("QuickTime returned error status %lx", status));
+ goto beach;
+ }
+
+@@ -450,6 +530,9 @@ open_decoder (QTWrapperAudioDecoder * qtwrapper, GstCaps * caps,
+ case QT_MAKE_FOURCC_LE ('s', 'a', 'm', 'r'):
+ magiccookie = make_samr_magic_cookie (codec_data, &len);
+ break;
++ case QT_MAKE_FOURCC_LE ('a', 'l', 'a', 'c'):
++ magiccookie = make_alac_magic_cookie (codec_data, &len);
++ break;
+ case QT_MAKE_FOURCC_LE ('m', 'p', '4', 'a'):
+ if (!have_esds) {
+ magiccookie = make_aac_magic_cookie (codec_data, &len);
+@@ -462,19 +545,22 @@ open_decoder (QTWrapperAudioDecoder * qtwrapper, GstCaps * caps,
+ break;
+ }
+
+- GST_LOG_OBJECT (qtwrapper, "Setting magic cookie %p of size %"
+- G_GSIZE_FORMAT, magiccookie, len);
++ if (magiccookie) {
++ GST_LOG_OBJECT (qtwrapper, "Setting magic cookie %p of size %"
++ G_GSIZE_FORMAT, magiccookie, len);
+
+ #if DEBUG_DUMP
+- gst_util_dump_mem (magiccookie, len);
++ gst_util_dump_mem (magiccookie, len);
+ #endif
+
+- status = QTSetComponentProperty (qtwrapper->adec, kQTPropertyClass_SCAudio,
+- kQTSCAudioPropertyID_InputMagicCookie, len, magiccookie);
+- if (status) {
+- GST_WARNING_OBJECT (qtwrapper, "Error setting extra codec data: %ld",
+- status);
+- goto beach;
++ status =
++ QTSetComponentProperty (qtwrapper->adec, kQTPropertyClass_SCAudio,
++ kQTSCAudioPropertyID_InputMagicCookie, len, magiccookie);
++ if (status) {
++ GST_WARNING_OBJECT (qtwrapper, "Error setting extra codec data: %ld",
++ status);
++ goto beach;
++ }
+ }
+ }
+
+@@ -507,6 +593,25 @@ open_decoder (QTWrapperAudioDecoder * qtwrapper, GstCaps * caps,
+ }
+ }
+
++ qtwrapper->outdesc.mSampleRate = 0; /* Use recommended; we read this out later */
++ qtwrapper->outdesc.mFormatID = kAudioFormatLinearPCM;
++ qtwrapper->outdesc.mFormatFlags = kAudioFormatFlagIsFloat;
++ qtwrapper->outdesc.mBytesPerPacket = 0;
++ qtwrapper->outdesc.mFramesPerPacket = 0;
++ qtwrapper->outdesc.mBytesPerFrame = 4 * channels;
++ qtwrapper->outdesc.mChannelsPerFrame = channels;
++ qtwrapper->outdesc.mBitsPerChannel = 32;
++ qtwrapper->outdesc.mReserved = 0;
++
++ status = QTSetComponentProperty (qtwrapper->adec, kQTPropertyClass_SCAudio,
++ kQTSCAudioPropertyID_BasicDescription,
++ sizeof (qtwrapper->outdesc), &qtwrapper->outdesc);
++ if (status) {
++ GST_WARNING_OBJECT (qtwrapper, "Error setting output description: %ld",
++ status);
++ goto beach;
++ }
++
+ status = QTGetComponentProperty (qtwrapper->adec, kQTPropertyClass_SCAudio,
+ kQTSCAudioPropertyID_BasicDescription,
+ sizeof (qtwrapper->outdesc), &qtwrapper->outdesc, NULL);
+@@ -518,9 +623,9 @@ open_decoder (QTWrapperAudioDecoder * qtwrapper, GstCaps * caps,
+ goto beach;
+ }
+
+- if (qtwrapper->outdesc.mFormatID != kAudioFormatLinearPCM ||
+- (qtwrapper->outdesc.mFormatFlags & kAudioFormatFlagIsFloat) !=
+- kAudioFormatFlagIsFloat) {
++ if (qtwrapper->outdesc.mFormatID != kAudioFormatLinearPCM /*||
++ (qtwrapper->outdesc.mFormatFlags & kAudioFormatFlagIsFloat) !=
++ kAudioFormatFlagIsFloat */ ) {
+ GST_WARNING_OBJECT (qtwrapper, "Output is not floating point PCM");
+ ret = FALSE;
+ goto beach;
+@@ -531,21 +636,21 @@ open_decoder (QTWrapperAudioDecoder * qtwrapper, GstCaps * caps,
+ GST_DEBUG_OBJECT (qtwrapper, "Output is %d Hz, %d channels",
+ qtwrapper->samplerate, qtwrapper->channels);
+
+- /* Create output bufferlist, big enough for 50ms of audio */
++ /* Create output bufferlist, big enough for 200ms of audio */
+ GST_DEBUG_OBJECT (qtwrapper, "Allocating bufferlist for %d channels",
+ channels);
+ qtwrapper->bufferlist =
+ AllocateAudioBufferList (channels,
+- qtwrapper->samplerate * qtwrapper->channels * 4 / 20);
++ qtwrapper->samplerate / 5 * qtwrapper->channels * 4);
+
+- /* TODO: Figure out how the output format is determined, can we pick this? */
+- /* Create output caps */
++ /* Create output caps matching the format the component is giving us */
+ *othercaps = gst_caps_new_simple ("audio/x-raw-float",
+ "endianness", G_TYPE_INT, G_BYTE_ORDER,
+ "signed", G_TYPE_BOOLEAN, TRUE,
+ "width", G_TYPE_INT, 32,
+ "depth", G_TYPE_INT, 32,
+- "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, channels, NULL);
++ "rate", G_TYPE_INT, qtwrapper->samplerate, "channels", G_TYPE_INT,
++ qtwrapper->channels, NULL);
+
+ ret = TRUE;
+
+@@ -671,70 +776,76 @@ qtwrapper_audio_decoder_chain (GstPad * pad, GstBuffer * buf)
+
+ qtwrapper->input_buffer = buf;
+
+- GST_LOG_OBJECT (qtwrapper, "Calling FillBuffer(outsamples:%d , outdata:%p)",
+- outsamples, qtwrapper->bufferlist->mBuffers[0].mData);
+-
+- /* Ask SCAudio to give us data ! */
+- status = SCAudioFillBuffer (qtwrapper->adec,
+- (SCAudioInputDataProc) process_buffer_cb,
+- qtwrapper, (UInt32 *) & outsamples, qtwrapper->bufferlist, NULL);
+-
+- /* TODO: What's this '42' crap?? It does seem to be needed, though. */
+- if ((status != noErr) && (status != 42)) {
+- if (status < 0)
+- GST_WARNING_OBJECT (qtwrapper,
+- "Error in SCAudioFillBuffer() : %d", (gint32) status);
+- else
+- GST_WARNING_OBJECT (qtwrapper,
+- "Error in SCAudioFillBuffer() : %" GST_FOURCC_FORMAT,
+- QT_FOURCC_ARGS (status));
+- ret = GST_FLOW_ERROR;
+- goto beach;
+- }
++ do {
++ GST_LOG_OBJECT (qtwrapper,
++ "Calling SCAudioFillBuffer(outsamples:%d , outdata:%p)", outsamples,
++ qtwrapper->bufferlist->mBuffers[0].mData);
++
++ /* Ask SCAudio to give us data ! */
++ status = SCAudioFillBuffer (qtwrapper->adec,
++ (SCAudioInputDataProc) process_buffer_cb,
++ qtwrapper, (UInt32 *) & outsamples, qtwrapper->bufferlist, NULL);
++
++ /* TODO: What's this '42' crap?? It does seem to be needed, though. */
++ if ((status != noErr) && (status != 42)) {
++ if (status < 0)
++ GST_WARNING_OBJECT (qtwrapper,
++ "Error in SCAudioFillBuffer() : %d", (gint32) status);
++ else
++ GST_WARNING_OBJECT (qtwrapper,
++ "Error in SCAudioFillBuffer() : %" GST_FOURCC_FORMAT,
++ QT_FOURCC_ARGS (status));
++ ret = GST_FLOW_ERROR;
++ goto beach;
++ }
+
+- realbytes = qtwrapper->bufferlist->mBuffers[0].mDataByteSize;
++ realbytes = qtwrapper->bufferlist->mBuffers[0].mDataByteSize;
+
+- GST_LOG_OBJECT (qtwrapper, "We now have %d samples [%d bytes]",
+- outsamples, realbytes);
++ GST_LOG_OBJECT (qtwrapper, "We now have %d samples [%d bytes]",
++ outsamples, realbytes);
+
+- qtwrapper->bufferlist->mBuffers[0].mDataByteSize = savedbytes;
++ qtwrapper->bufferlist->mBuffers[0].mDataByteSize = savedbytes;
+
+- if (!outsamples)
+- goto beach;
++ if (!outsamples)
++ goto beach;
+
+- /* 4. Create buffer and copy data in it */
+- ret = gst_pad_alloc_buffer (qtwrapper->srcpad, qtwrapper->cur_offset,
+- realbytes, GST_PAD_CAPS (qtwrapper->srcpad), &outbuf);
+- if (ret != GST_FLOW_OK)
+- goto beach;
++ /* 4. Create buffer and copy data in it */
++ ret = gst_pad_alloc_buffer (qtwrapper->srcpad, qtwrapper->cur_offset,
++ realbytes, GST_PAD_CAPS (qtwrapper->srcpad), &outbuf);
++ if (ret != GST_FLOW_OK)
++ goto beach;
+
+- /* copy data from bufferlist to output buffer */
+- g_memmove (GST_BUFFER_DATA (outbuf),
+- qtwrapper->bufferlist->mBuffers[0].mData, realbytes);
++ /* copy data from bufferlist to output buffer */
++ g_memmove (GST_BUFFER_DATA (outbuf),
++ qtwrapper->bufferlist->mBuffers[0].mData, realbytes);
+
+- /* 5. calculate timestamp and duration */
+- GST_BUFFER_TIMESTAMP (outbuf) =
+- qtwrapper->initial_time + gst_util_uint64_scale_int (GST_SECOND,
+- (gint) qtwrapper->cur_offset, qtwrapper->samplerate);
+- GST_BUFFER_SIZE (outbuf) = realbytes;
+- GST_BUFFER_DURATION (outbuf) =
+- gst_util_uint64_scale_int (GST_SECOND,
+- realbytes / (qtwrapper->channels * 4), qtwrapper->samplerate);
++ /* 5. calculate timestamp and duration */
++ GST_BUFFER_TIMESTAMP (outbuf) =
++ qtwrapper->initial_time + gst_util_uint64_scale_int (GST_SECOND,
++ (gint) qtwrapper->cur_offset, qtwrapper->samplerate);
++ GST_BUFFER_SIZE (outbuf) = realbytes;
++ GST_BUFFER_DURATION (outbuf) =
++ gst_util_uint64_scale_int (GST_SECOND,
++ realbytes / (qtwrapper->channels * 4), qtwrapper->samplerate);
+
+- GST_LOG_OBJECT (qtwrapper,
+- "timestamp:%" GST_TIME_FORMAT ", duration:%" GST_TIME_FORMAT
+- "offset:%lld, offset_end:%lld",
+- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
+- GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)),
+- GST_BUFFER_OFFSET (outbuf), GST_BUFFER_OFFSET_END (outbuf));
++ GST_LOG_OBJECT (qtwrapper,
++ "timestamp:%" GST_TIME_FORMAT ", duration:%" GST_TIME_FORMAT
++ "offset:%lld, offset_end:%lld",
++ GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
++ GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)),
++ GST_BUFFER_OFFSET (outbuf), GST_BUFFER_OFFSET_END (outbuf));
+
+- qtwrapper->cur_offset += outsamples;
++ qtwrapper->cur_offset += outsamples;
+
+- /* 6. push buffer downstream */
++ /* 6. push buffer downstream */
+
+- ret = gst_pad_push (qtwrapper->srcpad, outbuf);
+- if (ret != GST_FLOW_OK)
+- goto beach;
++ ret = gst_pad_push (qtwrapper->srcpad, outbuf);
++ if (ret != GST_FLOW_OK)
++ goto beach;
++
++ GST_DEBUG_OBJECT (qtwrapper,
++ "Read %d bytes, could have read up to %d bytes", realbytes, savedbytes);
++ } while (realbytes == savedbytes);
+
+ beach:
+ gst_buffer_unref (buf);
+@@ -875,8 +986,6 @@ qtwrapper_audio_decoders_register (GstPlugin * plugin)
+ };
+
+ /* Find all SoundDecompressors ! */
+- fprintf (stderr, "There are %ld decompressors available\n",
+- CountComponents (&desc));
+ GST_DEBUG ("There are %ld decompressors available", CountComponents (&desc));
+
+ /* loop over SoundDecompressors */
+diff --git sys/qtwrapper/qtutils.c sys/qtwrapper/qtutils.c
+index b698dc8..9b71bd0 100644
+--- sys/qtwrapper/qtutils.c
++++ sys/qtwrapper/qtutils.c
+@@ -42,7 +42,12 @@
+ * Boston, MA 02111-1307, USA.
+ */
+
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
+ #include <string.h>
++#include <glib.h>
+
+ #include "qtutils.h"
+
+--
+1.5.4
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]