summaryrefslogtreecommitdiffstats
path: root/sys/qtwrapper/qtutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/qtwrapper/qtutils.c')
-rw-r--r--sys/qtwrapper/qtutils.c477
1 files changed, 477 insertions, 0 deletions
diff --git a/sys/qtwrapper/qtutils.c b/sys/qtwrapper/qtutils.c
new file mode 100644
index 00000000..441a87d2
--- /dev/null
+++ b/sys/qtwrapper/qtutils.c
@@ -0,0 +1,477 @@
+/*
+ * GStreamer QuickTime codec mapping
+ * Copyright <2006, 2007> Fluendo <gstreamer@fluendo.com>
+ * Copyright <2006, 2007> Pioneers of the Inevitable <songbird@songbirdnest.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
+ * which case the following provisions apply instead of the ones
+ * mentioned above:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "qtutils.h"
+
+gboolean
+get_name_info_from_component (Component componentID,
+ ComponentDescription * desc, gchar ** name, gchar ** info)
+{
+ gchar *tmp1 = NULL;
+ gchar *tmp2 = NULL;
+ gchar *tmpname;
+ gchar *tmpinfo;
+ OSErr result;
+
+ result = GetComponentInfo (componentID, desc, &tmp1, &tmp2, NULL);
+ if (result != noErr)
+ return FALSE;
+
+#if DEBUG_DUMP
+ GST_LOG ("ComponentDescription dump");
+ gst_util_dump_mem ((const guchar *) desc, sizeof (ComponentDescription));
+#endif
+
+ if (tmp1 && name) {
+ gsize read, written;
+
+ tmpname = g_strndup (tmp1 + 1, (guint8) * tmp1);
+ *name = g_convert_with_fallback (tmpname, -1, "ASCII", "MAC",
+ " ", &read, &written, NULL);
+ if (!*name)
+ GST_WARNING ("read:%" G_GSIZE_FORMAT ", written:%" G_GSIZE_FORMAT, read,
+ written);
+ g_free (tmpname);
+ }
+
+ if (tmp2 && info) {
+ tmpinfo = g_strndup (tmp2 + 1, (guint8) * tmp2);
+ *info = g_convert_with_fallback (tmpinfo, -1, "ASCII", "MAC",
+ " ", NULL, NULL, NULL);
+ g_free (tmpinfo);
+ }
+
+ return TRUE;
+}
+
+/*
+struct CodecDecompressParams {
+ ImageSequence sequenceID;
+ ImageDescriptionHandle imageDescription;
+ Ptr data;
+ long bufferSize;
+ long frameNumber;
+ long startLine;
+ long stopLine;
+ long conditionFlags;
+ CodecFlags callerFlags;
+ CodecCapabilities * capabilities;
+ ICMProgressProcRecord progressProcRecord;
+ ICMCompletionProcRecord completionProcRecord;
+ ICMDataProcRecord dataProcRecord;
+ CGrafPtr port;
+ PixMap dstPixMap;
+ BitMapPtr maskBits;
+ PixMapPtr mattePixMap;
+ Rect srcRect;
+ MatrixRecord * matrix;
+ CodecQ accuracy;
+ short transferMode;
+ ICMFrameTimePtr frameTime;
+ long reserved[1];
+ SInt8 matrixFlags;
+ SInt8 matrixType;
+ Rect dstRect;
+ UInt16 majorSourceChangeSeed;
+ UInt16 minorSourceChangeSeed;
+ CDSequenceDataSourcePtr sourceData;
+ RgnHandle maskRegion;
+ OSType ** wantedDestinationPixelTypes;
+ long screenFloodMethod;
+ long screenFloodValue;
+ short preferredOffscreenPixelSize;
+ ICMFrameTimeInfoPtr syncFrameTime;
+ Boolean needUpdateOnTimeChange;
+ Boolean enableBlackLining;
+ Boolean needUpdateOnSourceChange;
+ Boolean pad;
+ long unused;
+ CGrafPtr finalDestinationPort;
+ long requestedBufferWidth;
+ long requestedBufferHeight;
+ Rect displayableAreaOfRequestedBuffer;
+ Boolean requestedSingleField;
+ Boolean needUpdateOnNextIdle;
+ Boolean pad2[2];
+ fixed bufferGammaLevel;
+ UInt32 taskWeight;
+ OSType taskName;
+};
+ */
+
+/* struct ImageDescription { */
+/* long idSize; /\* total size of this structure *\/ */
+/* 4 CodecType cType; /\* compressor creator type *\/ */
+/* 8 long resvd1; /\* reserved--must be set to 0 *\/ */
+/* 12 short resvd2; /\* reserved--must be set to 0 *\/ */
+/* 14 short dataRefIndex; /\* reserved--must be set to 0 *\/ */
+/* 16 short version; /\* version of compressed data *\/ */
+/* 18 short revisionLevel; /\* compressor that created data *\/ */
+/* 20 long vendor; /\* compressor developer that created data *\/ */
+/* 24 CodecQ temporalQuality; */
+/* /\* degree of temporal compression *\/ */
+/* 28 CodecQ spatialQuality; */
+/* /\* degree of spatial compression *\/ */
+/* 32 short width; /\* width of source image in pixels *\/ */
+/* 34 short height; /\* height of source image in pixels *\/ */
+/* 36 Fixed hRes; /\* horizontal resolution of source image *\/ */
+/* 40 Fixed vRes; /\* vertical resolution of source image *\/ */
+/* 44 long dataSize; /\* size in bytes of compressed data *\/ */
+/* 48 short frameCount; /\* number of frames in image data *\/ */
+/* 50 Str31 name; /\* name of compression algorithm *\/ */
+/* 82 short depth; /\* pixel depth of source image *\/ */
+/* 84 short clutID; /\* ID number of the color table for image *\/ */
+/* }; */
+
+
+gboolean
+get_output_info_from_component (Component componentID)
+{
+ gboolean ret = FALSE;
+ ComponentInstance instance;
+ ImageSubCodecDecompressCapabilities caps;
+ CodecInfo info;
+
+ GST_LOG ("Creating an instance");
+
+ /* 1. Create an instance */
+ if (!(instance = OpenComponent (componentID))) {
+ GST_WARNING ("Couldn't open component");
+ return FALSE;
+ }
+
+ /* 2. initialize */
+ memset (&caps, 0, sizeof (ImageSubCodecDecompressCapabilities));
+ if (ImageCodecInitialize (instance, &caps) != noErr) {
+ GST_WARNING ("ImageCodecInitialize() failed");
+ goto beach;
+ }
+#if DEBUG_DUMP
+ GST_LOG ("ImageSubCodecDecompressCapabilities");
+ gst_util_dump_mem ((const guchar *) &caps,
+ sizeof (ImageSubCodecDecompressCapabilities));
+#endif
+
+ GST_LOG ("recordSize:%ld", caps.recordSize);
+ GST_LOG ("decompressRecordSize:%ld", caps.decompressRecordSize);
+ GST_LOG ("canAsync:%d", caps.canAsync);
+
+ /* 3. Get codec info */
+ memset (&info, 0, sizeof (CodecInfo));
+ if (ImageCodecGetCodecInfo (instance, &info) != noErr) {
+ GST_WARNING ("ImageCodecInfo() failed");
+ goto beach;
+ };
+
+#if DEBUG_DUMP
+ GST_LOG ("CodecInfo");
+ gst_util_dump_mem ((const guchar *) &info, sizeof (CodecInfo));
+#endif
+
+ GST_LOG ("version:%d", info.version);
+ GST_LOG ("revisionLevel:%d", info.revisionLevel);
+ GST_LOG ("vendor:%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (info.vendor));
+
+ /* Compression flags */
+ /* Contains flags (see below) that specify the decompression capabilities of
+ * the component. Typically, these flags are of interest only to developers of
+ * image decompressors. */
+ GST_LOG ("decompressFlags:%lx", info.decompressFlags);
+ if (info.decompressFlags & codecInfoDoes1)
+ GST_LOG ("Depth 1 OK");
+ if (info.decompressFlags & codecInfoDoes2)
+ GST_LOG ("Depth 2 OK");
+ if (info.decompressFlags & codecInfoDoes4)
+ GST_LOG ("Depth 4 OK");
+ if (info.decompressFlags & codecInfoDoes8)
+ GST_LOG ("Depth 8 OK");
+ if (info.decompressFlags & codecInfoDoes16)
+ GST_LOG ("Depth 16 OK");
+ if (info.decompressFlags & codecInfoDoes32)
+ GST_LOG ("Depth 32 OK");
+ GST_LOG ("compressFlags:%lx", info.compressFlags);
+
+ /* Format FLAGS */
+ /* Contains flags (see below) that describe the possible format for compressed
+ * data produced by this component and the format of compressed files that the
+ * component can handle during decompression. Typically, these flags are of
+ * interest only to developers of compressor components.
+ */
+ GST_LOG ("formatFlags:%lx", info.formatFlags);
+ if (info.formatFlags & codecInfoDepth1)
+ GST_LOG ("Depth 1 OK");
+ if (info.formatFlags & codecInfoDepth2)
+ GST_LOG ("Depth 2 OK");
+ if (info.formatFlags & codecInfoDepth4)
+ GST_LOG ("Depth 4 OK");
+ if (info.formatFlags & codecInfoDepth8)
+ GST_LOG ("Depth 8 OK");
+ if (info.formatFlags & codecInfoDepth16)
+ GST_LOG ("Depth 16 OK");
+ if (info.formatFlags & codecInfoDepth24)
+ GST_LOG ("Depth 24 OK");
+ if (info.formatFlags & codecInfoDepth32)
+ GST_LOG ("Depth 32 OK");
+ if (info.formatFlags & codecInfoDepth33)
+ GST_LOG ("Depth 33 OK");
+ if (info.formatFlags & codecInfoDepth34)
+ GST_LOG ("Depth 34 OK");
+ if (info.formatFlags & codecInfoDepth36)
+ GST_LOG ("Depth 36 OK");
+ if (info.formatFlags & codecInfoDepth40)
+ GST_LOG ("Depth 40 OK");
+ if (info.formatFlags & codecInfoStoresClut)
+ GST_LOG ("StoresClut OK");
+ if (info.formatFlags & codecInfoDoesLossless)
+ GST_LOG ("Lossless OK");
+ if (info.formatFlags & codecInfoSequenceSensitive)
+ GST_LOG ("SequenceSentitive OK");
+
+
+ GST_LOG ("compressionAccuracy:%u", info.compressionAccuracy);
+ GST_LOG ("decompressionAccuracy:%u", info.decompressionAccuracy);
+ GST_LOG ("compressionSpeed:%d", info.compressionSpeed);
+ GST_LOG ("decompressionSpeed:%d", info.decompressionSpeed);
+ GST_LOG ("compressionLevel:%u", info.compressionLevel);
+ GST_LOG ("minimumHeight:%d", info.minimumHeight);
+ GST_LOG ("minimumWidth:%d", info.minimumWidth);
+
+/* /\* . Call ImageCodecPreDecompress *\/ */
+/* memset(&params, 0, sizeof(CodecDecompressParams)); */
+/* GST_LOG ("calling imagecodecpredecompress"); */
+/* if (ImageCodecPreDecompress (instance, &params) != noErr) { */
+/* GST_WARNING ("Error in ImageCodecPreDecompress"); */
+/* goto beach; */
+/* } */
+
+/* GST_INFO ("sequenceID : %d", params.sequenceID); */
+
+ ret = TRUE;
+
+beach:
+ /* Free instance */
+ CloseComponent (instance);
+ return TRUE;
+}
+
+void
+dump_avcc_atom (gpointer atom)
+{
+ /* first 8 bytes : length + atom */
+ GST_LOG ("version:0x%x", QT_UINT8 (atom + 8));
+ GST_LOG ("Profile:%d", QT_UINT8 (atom + 9));
+ GST_LOG ("Compatible profiles : 0x%x", QT_UINT8 (atom + 10));
+ GST_LOG ("Level:%d", QT_UINT8 (atom + 11));
+}
+
+void
+dump_image_description (ImageDescription * desc)
+{
+ GST_LOG ("Description %p , size:%" G_GSIZE_FORMAT, desc, desc->idSize);
+
+#if DEBUG_DUMP
+ gst_util_dump_mem ((const guchar *) desc, desc->idSize);
+#endif
+
+ GST_LOG ("cType : %" GST_FOURCC_FORMAT, QT_FOURCC_ARGS (desc->cType));
+ GST_LOG ("version:%d", desc->version);
+ GST_LOG ("revisionLevel:%d", desc->revisionLevel);
+ GST_LOG ("vendor:%" GST_FOURCC_FORMAT, QT_FOURCC_ARGS (desc->vendor));
+ GST_LOG ("temporalQuality:%lu", desc->temporalQuality);
+ GST_LOG ("spatialQuality:%lu", desc->spatialQuality);
+ GST_LOG ("width:%u", desc->width);
+ GST_LOG ("height:%u", desc->height);
+ GST_LOG ("hres:%f", desc->hRes / 65536.0);
+ GST_LOG ("vres:%f", desc->vRes / 65536.0);
+ GST_LOG ("dataSize:%" G_GSIZE_FORMAT, desc->dataSize);
+ GST_LOG ("frameCount:%d", desc->frameCount);
+ GST_LOG ("name:%.*s", desc->name[0], desc->name + 1);
+ GST_LOG ("depth:%d", desc->depth);
+ GST_LOG ("clutID:%d", desc->clutID);
+
+ if (desc->idSize > sizeof (ImageDescription)) {
+ gpointer extradata =
+ (gpointer) (gulong) desc + (gulong) sizeof (ImageDescription);
+ guint32 type = QT_READ_UINT32 (extradata + 4);
+
+ GST_LOG ("Extra Data size:%lu",
+ (gulong) desc->idSize - (gulong) sizeof (ImageDescription));
+#if DEBUG_DUMP
+ gst_util_dump_mem ((gulong) desc + (gulong) sizeof (ImageDescription),
+ (gulong) desc->idSize - (gulong) sizeof (ImageDescription));
+#endif
+ GST_LOG ("Extra Data Type : %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (type));
+ if (type == QT_MAKE_FOURCC ('a', 'v', 'c', 'C'))
+ dump_avcc_atom (extradata);
+ }
+}
+
+void
+dump_codec_decompress_params (CodecDecompressParams * params)
+{
+ GST_LOG ("params %p", params);
+
+#if DEBUG_DUMP
+ gst_util_dump_mem ((const guchar *) params, sizeof (CodecDecompressParams));
+#endif
+
+ GST_LOG ("SequenceID:%ld", params->sequenceID);
+ GST_LOG ("imageDescription:%p", params->imageDescription);
+ GST_LOG ("data:%p", params->data);
+ GST_LOG ("bufferSize:%ld", params->bufferSize);
+ GST_LOG ("frameNumber:%ld", params->frameNumber);
+ GST_LOG ("startLine:%ld , StopLine:%ld", params->startLine,
+ params->stopLine);
+ GST_LOG ("conditionFlags:0x%lx", params->conditionFlags);
+ GST_LOG ("callerFlags:0x%x", params->callerFlags);
+ GST_LOG ("capabilities:%p", params->capabilities);
+ GST_LOG ("port:%p", params->port);
+ GST_LOG ("dstPixMap");
+ gst_util_dump_mem ((const guchar *) &params->dstPixMap, sizeof (PixMap));
+
+ GST_LOG ("maskBits:%p", params->maskBits);
+ GST_LOG ("mattePixMap:%p", params->mattePixMap);
+ GST_LOG ("srcRect %d/%d/%d/%d",
+ params->srcRect.top, params->srcRect.bottom,
+ params->srcRect.left, params->srcRect.right);
+
+ GST_LOG ("matrix:%p", params->matrix);
+ GST_LOG ("accuracy:%ld", params->accuracy);
+ GST_LOG ("transferMode:%d", params->transferMode);
+ GST_LOG ("frameTime:%p", params->frameTime);
+ GST_LOG ("matrixFlags:%x", params->matrixFlags);
+
+ GST_LOG ("dstRect %d/%d/%d/%d",
+ params->dstRect.top, params->dstRect.bottom,
+ params->dstRect.left, params->dstRect.right);
+
+ GST_LOG ("sourceData:%p", params->sourceData);
+
+ if (params->wantedDestinationPixelTypes) {
+ OSType *tmp;
+
+ for (tmp = *params->wantedDestinationPixelTypes; *tmp; tmp++)
+ GST_LOG ("Destination pixel %" GST_FOURCC_FORMAT, QT_FOURCC_ARGS (*tmp));
+ }
+}
+
+void
+addSInt32ToDictionary (CFMutableDictionaryRef dictionary, CFStringRef key,
+ SInt32 numberSInt32)
+{
+ CFNumberRef number =
+ CFNumberCreate (NULL, kCFNumberSInt32Type, &numberSInt32);
+ if (!number)
+ return;
+ CFDictionaryAddValue (dictionary, key, number);
+ CFRelease (number);
+}
+
+void
+dump_cvpixel_buffer (CVPixelBufferRef pixbuf)
+{
+ gsize left, right, top, bottom;
+
+ GST_LOG ("buffer %p", pixbuf);
+ if (CVPixelBufferLockBaseAddress (pixbuf, 0)) {
+ GST_WARNING ("Couldn't lock base adress on pixel buffer !");
+ return;
+ }
+ GST_LOG ("Width:%" G_GSIZE_FORMAT " , Height:%" G_GSIZE_FORMAT,
+ CVPixelBufferGetWidth (pixbuf), CVPixelBufferGetHeight (pixbuf));
+ GST_LOG ("Format:%" GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (CVPixelBufferGetPixelFormatType (pixbuf)));
+ GST_LOG ("base address:%p", CVPixelBufferGetBaseAddress (pixbuf));
+ GST_LOG ("Bytes per row:%" G_GSIZE_FORMAT,
+ CVPixelBufferGetBytesPerRow (pixbuf));
+ GST_LOG ("Data Size:%" G_GSIZE_FORMAT, CVPixelBufferGetDataSize (pixbuf));
+ GST_LOG ("Plane count:%" G_GSIZE_FORMAT, CVPixelBufferGetPlaneCount (pixbuf));
+ CVPixelBufferGetExtendedPixels (pixbuf, &left, &right, &top, &bottom);
+ GST_LOG ("Extended pixels. left/right/top/bottom : %" G_GSIZE_FORMAT
+ "/%" G_GSIZE_FORMAT "/%" G_GSIZE_FORMAT "/%" G_GSIZE_FORMAT,
+ left, right, top, bottom);
+ CVPixelBufferUnlockBaseAddress (pixbuf, 0);
+}
+
+
+// Convenience function to dispose of our audio buffers
+void
+DestroyAudioBufferList (AudioBufferList * list)
+{
+ UInt32 i;
+
+ if (list) {
+ for (i = 0; i < list->mNumberBuffers; i++) {
+ if (list->mBuffers[i].mData)
+ free (list->mBuffers[i].mData);
+ }
+ free (list);
+ }
+}
+
+// Convenience function to allocate our audio buffers
+AudioBufferList *
+AllocateAudioBufferList (UInt32 numChannels, UInt32 size)
+{
+ AudioBufferList *list;
+ UInt32 i;
+
+ list =
+ (AudioBufferList *) calloc (1,
+ sizeof (AudioBufferList) + sizeof (AudioBuffer));
+ if (list == NULL)
+ return NULL;
+
+ list->mNumberBuffers = 1;
+ for (i = 0; i < 1; ++i) {
+ list->mBuffers[i].mNumberChannels = numChannels;
+ list->mBuffers[i].mDataByteSize = size;
+ list->mBuffers[i].mData = malloc (size);
+ if (list->mBuffers[i].mData == NULL) {
+ DestroyAudioBufferList (list);
+ return NULL;
+ }
+ }
+ return list;
+}