Remove unported and obsolete qtwrapper plugin code

QuickTime is deprecated, we want new plugins based
on avfoundation (osx) or dxva/mediafoundation (windows).
This commit is contained in:
Tim-Philipp Müller 2014-11-26 14:36:42 +00:00
parent 1d7c4f4344
commit a964491735
13 changed files with 3 additions and 3283 deletions

View file

@ -422,7 +422,7 @@ GST_PLUGINS_NONPORTED=" cdxaparse \
gsettings \
musepack nas sdl timidity \
directdraw acm wininet \
xvid lv2 teletextdec sndio osx_video quicktime libvisual"
xvid lv2 teletextdec sndio osx_video libvisual"
AC_SUBST(GST_PLUGINS_NONPORTED)
dnl these are all the gst plug-ins, compilable without additional libs
@ -1710,13 +1710,6 @@ case "$host" in
;;
esac
dnl check for QuickTime
translit(dnm, m, l) AM_CONDITIONAL(USE_QUICKTIME, true)
AG_GST_CHECK_FEATURE(QUICKTIME, [QuickTime wrapper], qtwrapper, [
AC_CHECK_TYPE([SampleReferenceRecord], HAVE_QUICKTIME="yes", HAVE_QUICKTIME="no",
[#include <Quicktime/Quicktime.h>])
])
dnl check for shm_open (for shm plugin)
translit(dnm, m, l) AM_CONDITIONAL(USE_SHM, true)
AG_GST_CHECK_FEATURE(SHM, [POSIX shared memory source and sink], shm, [
@ -3291,7 +3284,6 @@ sys/fbdev/Makefile
sys/linsys/Makefile
sys/opensles/Makefile
sys/osxvideo/Makefile
sys/qtwrapper/Makefile
sys/shm/Makefile
sys/uvch264/Makefile
sys/vcd/Makefile

View file

@ -124,12 +124,6 @@ endif
# QCAM_DIR=
# endif
if USE_QUICKTIME
QT_DIR=qtwrapper
else
QT_DIR=
endif
if USE_WININET
WININET_DIR=wininet
else
@ -160,9 +154,9 @@ else
UVCH264_DIR=
endif
SUBDIRS = $(ACM_DIR) $(ANDROID_MEDIA_DIR) $(APPLE_MEDIA_DIR) $(AVC_DIR) $(BLUEZ_DIR) $(D3DVIDEOSINK_DIR) $(DECKLINK_DIR) $(DIRECTDRAW_DIR) $(DIRECTSOUND_DIR) $(WINKS_DIR) $(DVB_DIR) $(FBDEV_DIR) $(LINSYS_DIR) $(OPENSLES_DIR) $(OSX_VIDEO_DIR) $(PVR_DIR) $(QT_DIR) $(SHM_DIR) $(UVCH264_DIR) $(VCD_DIR) $(VDPAU_DIR) $(WININET_DIR) $(WINSCREENCAP_DIR) $(WASAPI_DIR)
SUBDIRS = $(ACM_DIR) $(ANDROID_MEDIA_DIR) $(APPLE_MEDIA_DIR) $(AVC_DIR) $(BLUEZ_DIR) $(D3DVIDEOSINK_DIR) $(DECKLINK_DIR) $(DIRECTDRAW_DIR) $(DIRECTSOUND_DIR) $(WINKS_DIR) $(DVB_DIR) $(FBDEV_DIR) $(LINSYS_DIR) $(OPENSLES_DIR) $(OSX_VIDEO_DIR) $(PVR_DIR) $(SHM_DIR) $(UVCH264_DIR) $(VCD_DIR) $(VDPAU_DIR) $(WININET_DIR) $(WINSCREENCAP_DIR) $(WASAPI_DIR)
DIST_SUBDIRS = acmenc acmmp3dec androidmedia applemedia applemedia-nonpublic avc bluez d3dvideosink decklink directdraw directsound dvb linsys fbdev dshowdecwrapper dshowsrcwrapper dshowvideosink \
opensles osxvideo pvr2d qtwrapper shm uvch264 vcd vdpau wasapi wininet winks winscreencap
opensles osxvideo pvr2d shm uvch264 vcd vdpau wasapi wininet winks winscreencap
include $(top_srcdir)/common/parallel-subdirs.mak

View file

@ -1,24 +0,0 @@
plugin_LTLIBRARIES = libgstqtwrapper.la
# sources used to compile this plug-in
libgstqtwrapper_la_SOURCES = \
qtwrapper.c \
qtutils.c \
codecmapping.c \
audiodecoders.c \
videodecoders.c \
imagedescription.c
# flags used to compile this plugin
# add other _CFLAGS and _LIBS as needed
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 = $(GST_PLUGIN_LIBTOOLFLAGS)
# headers we need but don't want installed
noinst_HEADERS = \
codecmapping.h \
qtwrapper.h \
qtutils.h \
imagedescription.h

File diff suppressed because it is too large Load diff

View file

@ -1,157 +0,0 @@
/*
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "qtwrapper.h"
#include "codecmapping.h"
#include "qtutils.h"
static GstCaps *
audio_caps_from_string (const gchar * str)
{
GstCaps *res;
res = gst_caps_from_string (str);
gst_caps_set_simple (res,
"rate", GST_TYPE_INT_RANGE, 8000, 96000,
"channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
return res;
}
GstCaps *
fourcc_to_caps (guint32 fourcc)
{
GstCaps *caps = NULL;
GST_DEBUG ("%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc));
switch (fourcc) {
/* VIDEO */
case QT_MAKE_FOURCC_LE ('S', 'V', 'Q', '1'):
caps = gst_caps_new_simple ("video/x-svq",
"svqversion", G_TYPE_INT, 1, NULL);
break;
case QT_MAKE_FOURCC_LE ('S', 'V', 'Q', '3'):
caps = gst_caps_new_simple ("video/x-svq",
"svqversion", G_TYPE_INT, 3, NULL);
break;
case QT_MAKE_FOURCC_LE ('a', 'v', 'c', '1'):
caps = gst_caps_from_string ("video/x-h264");
break;
case QT_MAKE_FOURCC_LE ('m', 'p', '4', 'v'):
caps =
gst_caps_from_string
("video/mpeg,mpegversion=4,systemstream=(boolean)false");
break;
case QT_MAKE_FOURCC_LE ('m', 'p', 'e', 'g'):
caps = gst_caps_from_string ("video/mpeg, "
"systemstream = (boolean) false, " "mpegversion = (int) 1");
break;
case QT_MAKE_FOURCC_LE ('h', '2', '6', '3'):
case QT_MAKE_FOURCC_LE ('H', '2', '6', '3'):
case QT_MAKE_FOURCC_LE ('s', '2', '6', '3'):
case QT_MAKE_FOURCC_LE ('U', '2', '6', '3'):
caps = gst_caps_from_string ("video/x-h263");
break;
case QT_MAKE_FOURCC_LE ('c', 'v', 'i', 'd'):
caps = gst_caps_from_string ("video/x-cinepak");
break;
case QT_MAKE_FOURCC_LE ('d', 'v', 'c', 'p'):
case QT_MAKE_FOURCC_LE ('d', 'v', 'c', ' '):
case QT_MAKE_FOURCC_LE ('d', 'v', 's', 'd'):
case QT_MAKE_FOURCC_LE ('D', 'V', 'S', 'D'):
case QT_MAKE_FOURCC_LE ('d', 'v', 'c', 's'):
case QT_MAKE_FOURCC_LE ('D', 'V', 'C', 'S'):
case QT_MAKE_FOURCC_LE ('d', 'v', '2', '5'):
case QT_MAKE_FOURCC_LE ('d', 'v', 'p', 'p'):
caps = gst_caps_from_string ("video/x-dv, systemstream=(boolean)false");
break;
/* AUDIO */
case QT_MAKE_FOURCC_LE ('.', 'm', 'p', '3'):
caps =
audio_caps_from_string
("audio/mpeg,mpegversion=1,layer=3,parsed=(boolean)true");
break;
case QT_MAKE_FOURCC_LE ('Q', 'D', 'M', '2'):
caps = audio_caps_from_string ("audio/x-qdm2");
break;
case QT_MAKE_FOURCC_LE ('a', 'g', 's', 'm'):
caps = audio_caps_from_string ("audio/x-gsm");
break;
case QT_MAKE_FOURCC_LE ('a', 'l', 'a', 'c'):
caps = audio_caps_from_string ("audio/x-alac");
break;
case QT_MAKE_FOURCC_LE ('a', 'l', 'a', 'w'):
caps = audio_caps_from_string ("audio/x-alaw");
break;
case QT_MAKE_FOURCC_LE ('m', 'p', '4', 'a'):
case QT_MAKE_FOURCC_LE ('a', 'a', 'c', ' '):
caps = audio_caps_from_string ("audio/mpeg,mpegversion=4");
break;
case QT_MAKE_FOURCC_LE ('s', 'a', 'm', 'r'):
caps = audio_caps_from_string ("audio/AMR");
break;
case QT_MAKE_FOURCC_LE ('u', 'l', 'a', 'w'):
caps = audio_caps_from_string ("audio/x-mulaw");
break;
case QT_MAKE_FOURCC_LE ('A', 'V', 'd', 'n'):
caps = audio_caps_from_string ("video/x-dnxhd");
break;
case QT_MAKE_FOURCC_LE ('i', 'c', 'o', 'd'):
caps = audio_caps_from_string ("video/x-apple-intermediate-codec");
break;
/* TO FILL !! */
case QT_MAKE_FOURCC_LE ('M', 'A', 'C', '3'):
case QT_MAKE_FOURCC_LE ('M', 'A', 'C', '6'):
case QT_MAKE_FOURCC_LE ('Q', 'D', 'M', 'C'):
case QT_MAKE_FOURCC_LE ('Q', 'c', 'l', 'p'):
case QT_MAKE_FOURCC_LE ('Q', 'c', 'l', 'q'):
case QT_MAKE_FOURCC_LE ('d', 'v', 'c', 'a'):
default:
break;
}
return caps;
}

View file

@ -1,61 +0,0 @@
/*
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <gst/gst.h>
#include "qtwrapper.h"
#ifdef G_OS_WIN32
#include <ImageCodec.h>
#else
#include <QuickTime/ImageCodec.h>
#endif
/*
* fourcc_to_caps:
*
* Return the caps for a given fourcc.
*/
GstCaps *fourcc_to_caps (guint32 fourcc);

View file

@ -1,213 +0,0 @@
/*
* GStreamer QuickTime video decoder codecs wrapper
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <string.h>
#include "imagedescription.h"
static ImageDescription *
image_description_for_avc1 (GstBuffer * buf)
{
ImageDescription *desc = NULL;
guint8 *pos;
desc = g_malloc0 (sizeof (ImageDescription) + GST_BUFFER_SIZE (buf) + 8);
pos = (guint8 *) desc + sizeof (ImageDescription);
desc->idSize = sizeof (ImageDescription) + GST_BUFFER_SIZE (buf) + 8;
/* write size in Big-Endian */
GST_WRITE_UINT32_BE (pos, GST_BUFFER_SIZE (buf) + 8);
GST_WRITE_UINT32_LE (pos + 4, QT_MAKE_FOURCC_BE ('a', 'v', 'c', 'C'));
memmove (pos + 8, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
return desc;
}
/* image_description_for_mp4v
*
* mpeg4 video has an 'esds' atom as extension for the ImageDescription.
* It is meant to contain the ES Description.
* We here create a fake one.
*/
static ImageDescription *
image_description_for_mp4v (GstBuffer * buf)
{
ImageDescription *desc = NULL;
guint32 offset = sizeof (ImageDescription);
guint8 *location;
GST_LOG ("buf %p , size:%d", buf, GST_BUFFER_SIZE (buf));
/* this image description contains:
* ImageDescription sizeof(ImageDescription)
* esds atom 34 bytes
* buffer GST_BUFFER_SIZE (buf)
* ending 3 bytes
*/
desc = g_malloc0 (offset + 37 + GST_BUFFER_SIZE (buf));
desc->idSize = offset + 37 + GST_BUFFER_SIZE (buf);
location = (guint8 *) desc + offset;
/* Fill in ESDS */
/* size */
GST_WRITE_UINT32_BE (location, 37 + GST_BUFFER_SIZE (buf));
/* atom */
GST_WRITE_UINT32_LE (location + 4, GST_MAKE_FOURCC ('e', 's', 'd', 's'));
/* version + flags */
QT_WRITE_UINT32 (location + 8, 0);
/* tag */
QT_WRITE_UINT8 (location + 12, 0x3);
/* size (buffsize + 23) */
QT_WRITE_UINT8 (location + 13, GST_BUFFER_SIZE (buf) + 23);
/* ESID */
QT_WRITE_UINT16 (location + 14, 0);
/* priority */
QT_WRITE_UINT8 (location + 16, 0);
/* tag */
QT_WRITE_UINT8 (location + 17, 0x4);
/* size (buffsize + 8) */
QT_WRITE_UINT8 (location + 18, GST_BUFFER_SIZE (buf) + 15);
/* object type */
QT_WRITE_UINT8 (location + 19, 0x20);
/* stream type */
QT_WRITE_UINT8 (location + 20, 0x11);
/* buffersize db */
QT_WRITE_UINT24 (location + 21, 13640);
/* max bitrate */
QT_WRITE_UINT32 (location + 24, 1849648);
/* avg bitrate */
QT_WRITE_UINT32 (location + 28, 918191);
/* tag */
QT_WRITE_UINT8 (location + 32, 0x05);
/* size */
QT_WRITE_UINT8 (location + 33, GST_BUFFER_SIZE (buf));
/* codec data */
memmove (location + 34, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
/* end */
QT_WRITE_UINT8 (location + 34 + GST_BUFFER_SIZE (buf), 0x06);
QT_WRITE_UINT8 (location + 34 + GST_BUFFER_SIZE (buf) + 1, 0x01);
QT_WRITE_UINT8 (location + 34 + GST_BUFFER_SIZE (buf) + 2, 0x02);
return desc;
}
static ImageDescription *
image_description_from_stsd_buffer (GstBuffer * buf)
{
ImageDescription *desc = NULL;
guint8 *content;
guint size;
gint imds;
GST_LOG ("buffer %p, size:%u", buf, GST_BUFFER_SIZE (buf));
/* The buffer contains a full atom, we only need the contents */
/* This buffer has data in big-endian, we need to read it as such.
* except for the fourcc which are ALWAYS big-endian. */
content = GST_BUFFER_DATA (buf) + 16;
size = GST_BUFFER_SIZE (buf) - 16;
#if DEBUG_DUMP
GST_LOG ("incoming data in big-endian");
gst_util_dump_mem (content, size);
#endif
desc = g_malloc0 (size);
desc->idSize = size;
desc->cType = GST_READ_UINT32_BE (content + 4);
desc->version = QT_UINT16 (content + 16);
desc->revisionLevel = QT_UINT16 (content + 18);
desc->vendor = GST_READ_UINT32_BE (content + 20);
desc->temporalQuality = QT_UINT32 (content + 24);
desc->spatialQuality = QT_UINT32 (content + 24);
desc->dataSize = QT_UINT32 (content + 44);
desc->frameCount = QT_UINT16 (content + 48);
desc->depth = QT_UINT16 (content + 82);
desc->clutID = QT_UINT16 (content + 84);
imds = 86; /* sizeof (ImageDescription); */
if (desc->idSize > imds) {
GST_LOG ("Copying %d bytes from %p to %p",
size - imds, content + imds, desc + imds);
memcpy ((guint8 *) desc + imds, (guint8 *) content + imds, size - imds);
}
#if DEBUG_DUMP
GST_LOG ("outgoing data in machine-endian");
dump_image_description (desc);
#endif
return desc;
}
ImageDescription *
image_description_from_codec_data (GstBuffer * buf, guint32 codectype)
{
ImageDescription *desc = NULL;
GST_LOG ("codectype:%" GST_FOURCC_FORMAT " buf:%p",
GST_FOURCC_ARGS (codectype), buf);
if ((GST_BUFFER_SIZE (buf) == GST_READ_UINT32_BE (GST_BUFFER_DATA (buf))) &&
(QT_MAKE_FOURCC_LE ('s', 't', 's',
'd') == GST_READ_UINT32_BE (GST_BUFFER_DATA (buf) + 4))) {
/* We have the full stsd (ImageDescription) in our codec_data */
desc = image_description_from_stsd_buffer (buf);
} else {
switch (codectype) {
case QT_MAKE_FOURCC_LE ('m', 'p', '4', 'v'):
desc = image_description_for_mp4v (buf);
break;
case QT_MAKE_FOURCC_LE ('a', 'v', 'c', '1'):
desc = image_description_for_avc1 (buf);
break;
default:
GST_WARNING ("Format not handled !");
}
}
return desc;
}

View file

@ -1,53 +0,0 @@
/*
* GStreamer QuickTime video decoder codecs wrapper
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "qtwrapper.h"
#include "qtutils.h"
ImageDescription *image_description_from_codec_data (GstBuffer * buf,
guint32 codec);

View file

@ -1,493 +0,0 @@
/*
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <glib.h>
#include "qtutils.h"
gboolean
get_name_info_from_component (Component componentID,
ComponentDescription * desc, gchar ** name, gchar ** info)
{
Handle nameHandle = NewHandle (200);
Handle infoHandle = NewHandle (200);
gchar *tmpname;
gchar *tmpinfo;
OSErr result;
gboolean ret = TRUE;
result = GetComponentInfo (componentID, desc, nameHandle, infoHandle, NULL);
if (result != noErr) {
ret = FALSE;
goto done;
}
#if DEBUG_DUMP
GST_LOG ("ComponentDescription dump");
gst_util_dump_mem ((const guchar *) desc, sizeof (ComponentDescription));
gst_util_dump_mem ((gpointer) * nameHandle, 200);
gst_util_dump_mem ((gpointer) * infoHandle, 200);
GST_LOG ("0x%x 0x%x", **((guint8 **) nameHandle), **((guint8 **) infoHandle));
#endif
if (*nameHandle && name) {
gsize read, written;
tmpname = g_strndup ((*(char **) nameHandle) + 1,
**((guint8 **) nameHandle));
*name = g_convert_with_fallback (tmpname, -1, "ASCII", "MAC",
(gchar *) " ", &read, &written, NULL);
if (!*name)
GST_WARNING ("read:%" G_GSIZE_FORMAT ", written:%" G_GSIZE_FORMAT, read,
written);
g_free (tmpname);
}
if (*infoHandle && info) {
tmpinfo =
g_strndup ((*(char **) infoHandle) + 1, **((guint8 **) infoHandle));
*info =
g_convert_with_fallback (tmpinfo, -1, "ASCII", "MAC", (gchar *) " ",
NULL, NULL, NULL);
g_free (tmpinfo);
}
done:
DisposeHandle (nameHandle);
DisposeHandle (infoHandle);
return ret;
}
/*
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 (guint8 * 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)) {
guint8 *extradata = (guint8 *) desc + 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 ((gpointer) (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");
#if DEBUG_DUMP
gst_util_dump_mem ((const guchar *) &params->dstPixMap, sizeof (PixMap));
#endif
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;
list = (AudioBufferList *) calloc (1, sizeof (AudioBufferList));
if (list == NULL)
return NULL;
list->mNumberBuffers = 1;
list->mBuffers[0].mNumberChannels = numChannels;
list->mBuffers[0].mDataByteSize = size;
list->mBuffers[0].mData = malloc (size);
if (list->mBuffers[0].mData == NULL) {
DestroyAudioBufferList (list);
return NULL;
}
return list;
}

View file

@ -1,136 +0,0 @@
/*
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifdef G_OS_WIN32
#include <ImageCodec.h>
#else
#include <QuickTime/ImageCodec.h>
#endif
#include <gst/gst.h>
#include "qtwrapper.h"
#ifndef __QTUTILS_H__
#define __QTUTILS_H__
#define QT_UINT32(a) (GST_READ_UINT32_BE(a))
#define QT_UINT24(a) (GST_READ_UINT32_BE(a) >> 8)
#define QT_UINT16(a) (GST_READ_UINT16_BE(a))
#define QT_UINT8(a) (GST_READ_UINT8(a))
#define QT_FP32(a) ((GST_READ_UINT32_BE(a))/65536.0)
#define QT_FP16(a) ((GST_READ_UINT16_BE(a))/256.0)
#define QT_FOURCC(a) (GST_READ_UINT32_LE(a))
#define QT_UINT64(a) ((((guint64)QT_UINT32(a))<<32)|QT_UINT32(((guint8 *)a)+4))
#define QT_FOURCC_ARGS(fourcc) \
((gchar) (((fourcc)>>24)&0xff)), \
((gchar) (((fourcc)>>16)&0xff)), \
((gchar) (((fourcc)>>8 )&0xff)), \
((gchar) ((fourcc) &0xff))
#define QT_WRITE_UINT8(data, num) GST_WRITE_UINT8(data, num)
#define QT_MAKE_FOURCC_BE(a,b,c,d) (guint32)((a)|(b)<<8|(c)<<16|(d)<<24)
#define QT_MAKE_FOURCC_LE(a,b,c,d) QT_MAKE_FOURCC_BE(d,c,b,a)
#define _QT_PUT(__data, __idx, __size, __shift, __num) \
(((guint8 *) (__data))[__idx] = (((guint##__size) __num) >> __shift) & 0xff)
/* endianness-dependent macros */
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
#define QT_MAKE_FOURCC(a,b,c,d) QT_MAKE_FOURCC_LE(a,b,c,d)
#define QT_WRITE_UINT16(data, num) GST_WRITE_UINT16_LE(data, num)
#define QT_WRITE_UINT24(data, num) do { \
_QT_PUT (data, 0, 32, 0, num); \
_QT_PUT (data, 1, 32, 8, num); \
_QT_PUT (data, 2, 32, 16, num); \
} while (0)
#define QT_WRITE_UINT32(data, num) GST_WRITE_UINT32_LE(data, num)
#define QT_READ_UINT16(data) GST_READ_UINT16_LE(data)
#define QT_READ_UINT32(data) GST_READ_UINT32_LE(data)
#else
#define QT_MAKE_FOURCC(a,b,c,d) QT_MAKE_FOURCC_BE(a,b,c,d)
#define QT_WRITE_UINT16(data, num) GST_WRITE_UINT16_BE(data, num)
#define QT_WRITE_UINT24(data, num) do { \
_QT_PUT (data, 0, 32, 16, num); \
_QT_PUT (data, 1, 32, 8, num); \
_QT_PUT (data, 2, 32, 0, num); \
} while (0)
#define QT_WRITE_UINT32(data, num) GST_WRITE_UINT32_BE(data, num)
#define QT_READ_UINT16(data) GST_READ_UINT16_BE(data)
#define QT_READ_UINT32(data) GST_READ_UINT32_BE(data)
#endif
/*
* get_name_info_from_component:
*
* Fills name and info with the name and description from a Component
*/
gboolean
get_name_info_from_component (Component component, ComponentDescription * desc,
gchar ** name, gchar ** info);
gboolean get_output_info_from_component (Component component);
void dump_image_description (ImageDescription * desc);
void dump_codec_decompress_params (CodecDecompressParams * params);
guint32 destination_pixel_types_to_fourcc (OSType ** types);
void
addSInt32ToDictionary (CFMutableDictionaryRef dictionary, CFStringRef key,
SInt32 numberSInt32);
void dump_cvpixel_buffer (CVPixelBufferRef pixbuf);
void dump_avcc_atom (guint8 * atom);
AudioBufferList *AllocateAudioBufferList(UInt32 numChannels, UInt32 size);
void DestroyAudioBufferList(AudioBufferList* list);
#endif /* __QTUTILS_H__ */

View file

@ -1,87 +0,0 @@
/*
* GStreamer QuickTime codecs wrapper
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "qtwrapper.h"
#include <stdio.h>
GST_DEBUG_CATEGORY (qtwrapper_debug);
static gboolean
plugin_init (GstPlugin * plugin)
{
gboolean res;
OSErr status;
GST_DEBUG_CATEGORY_INIT (qtwrapper_debug, "qtwrapper",
0, "QuickTime codecs wrappers");
/* Initialize quicktime environment */
#ifdef G_OS_WIN32
/* Only required on win32 */
InitializeQTML (0);
#endif
status = EnterMovies ();
if (status) {
GST_ERROR ("Error initializing QuickTime environment: %d", status);
return FALSE;
}
GST_INFO ("Registering video decoders");
res = qtwrapper_video_decoders_register (plugin);
GST_INFO ("Registering audio decoders");
res &= qtwrapper_audio_decoders_register (plugin);
return res;
}
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
qtwrapper,
"QuickTime codecs wrapper",
plugin_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/")

View file

@ -1,69 +0,0 @@
/*
* GStreamer QuickTime codecs wrapper
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __GST_QTWRAPPER_H__
#define __GST_QTWRAPPER_H__
#include <gst/gst.h>
#ifdef G_OS_WIN32
#include <Movies.h>
#include <QTML.h>
#else
#include <QuickTime/Movies.h>
#endif
/* Set following to 1 if you want to have extra debug in form of
* memory dumps */
#define DEBUG_DUMP 0
GST_DEBUG_CATEGORY_EXTERN (qtwrapper_debug);
#define GST_CAT_DEFAULT qtwrapper_debug
G_BEGIN_DECLS
extern gboolean qtwrapper_video_decoders_register (GstPlugin *);
extern gboolean qtwrapper_audio_decoders_register (GstPlugin *);
G_END_DECLS
#endif /* __GST_QTWRAPPER_H__ */

View file

@ -1,872 +0,0 @@
/*
* GStreamer QuickTime video decoder codecs wrapper
* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include "qtwrapper.h"
#include "codecmapping.h"
#include "qtutils.h"
#include "imagedescription.h"
#define QTWRAPPER_VDEC_PARAMS_QDATA g_quark_from_static_string("qtwrapper-vdec-params")
static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw-yuv"));
typedef struct _QTWrapperVideoDecoder QTWrapperVideoDecoder;
typedef struct _QTWrapperVideoDecoderClass QTWrapperVideoDecoderClass;
#define MAC_LOCK(qtwrapper) g_mutex_lock (qtwrapper->lock)
#define MAC_UNLOCK(qtwrapper) g_mutex_unlock (qtwrapper->lock)
struct _QTWrapperVideoDecoder
{
GstElement parent;
GstPad *sinkpad;
GstPad *srcpad;
GMutex *lock;
ComponentInstance instance;
CodecInfo codecinfo;
ImageDescriptionHandle idesc;
CodecDecompressParams *dparams;
CodecCapabilities codeccaps;
guint64 frameNumber;
ICMDecompressionSessionRef decsession;
GstFlowReturn lastret;
guint64 outsize;
guint width, height;
GstClockTime last_ts;
GstClockTime last_duration;
GstBuffer *prevbuf;
gboolean flushing;
gboolean framebuffering;
/* width/height of output buffer */
Rect rect;
};
struct _QTWrapperVideoDecoderClass
{
GstElementClass parent_class;
Component component;
guint32 componentType;
guint32 componentSubType;
GstPadTemplate *sinktempl;
};
typedef struct _QTWrapperVideoDecoderParams QTWrapperVideoDecoderParams;
struct _QTWrapperVideoDecoderParams
{
Component component;
GstCaps *sinkcaps;
};
static GstElementClass *parent_class = NULL;
static gboolean
qtwrapper_video_decoder_sink_setcaps (GstPad * pad, GstCaps * caps);
static GstFlowReturn qtwrapper_video_decoder_chain (GstPad * pad,
GstBuffer * buf);
static gboolean qtwrapper_video_decoder_sink_event (GstPad * pad,
GstEvent * event);
static void qtwrapper_video_decoder_finalize (GObject * object);
static void decompressCb (void *decompressionTrackingRefCon,
OSStatus result,
ICMDecompressionTrackingFlags decompressionTrackingFlags,
CVPixelBufferRef pixelBuffer,
TimeValue64 displayTime,
TimeValue64 displayDuration,
ICMValidTimeFlags validTimeFlags, void *reserved, void *sourceFrameRefCon);
/*
* Class setup
*/
static void
qtwrapper_video_decoder_base_init (QTWrapperVideoDecoderClass * klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gchar *name = NULL;
gchar *info = NULL;
char *longname, *description;
ComponentDescription desc;
QTWrapperVideoDecoderParams *params;
params = (QTWrapperVideoDecoderParams *)
g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
QTWRAPPER_VDEC_PARAMS_QDATA);
g_assert (params);
get_name_info_from_component (params->component, &desc, &name, &info);
/* Fill in details */
longname =
g_strdup_printf ("QTWrapper Video Decoder : %s", GST_STR_NULL (name));
description =
g_strdup_printf ("QTWrapper SCAudio wrapper for decoder: %s",
GST_STR_NULL (info));
gst_element_class_set_metadata (element_class, longname,
"Codec/Decoder/Video", description,
"Fluendo <gstreamer@fluendo.com>, "
"Pioneers of the Inevitable <songbird@songbirdnest.com>");
g_free (longname);
g_free (description);
g_free (name);
g_free (info);
klass->sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
GST_PAD_ALWAYS, params->sinkcaps);
gst_element_class_add_pad_template (element_class, klass->sinktempl);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_templ));
/* Store class-global values */
klass->component = params->component;
klass->componentType = desc.componentType;
klass->componentSubType = desc.componentSubType;
}
static void
qtwrapper_video_decoder_class_init (QTWrapperVideoDecoderClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
gobject_class->finalize =
GST_DEBUG_FUNCPTR (qtwrapper_video_decoder_finalize);
}
static void
qtwrapper_video_decoder_init (QTWrapperVideoDecoder * qtwrapper)
{
QTWrapperVideoDecoderClass *oclass;
ImageSubCodecDecompressCapabilities capabs;
GST_LOG ("...");
oclass = (QTWrapperVideoDecoderClass *) (G_OBJECT_GET_CLASS (qtwrapper));
/* 1. Create a ocmponent instance */
if (!(qtwrapper->instance = OpenComponent (oclass->component))) {
GST_ERROR_OBJECT (qtwrapper, "Couldn't create a component instance !");
return;
}
/* 2. Initialize decoder */
memset (&capabs, 0, sizeof (ImageSubCodecDecompressCapabilities));
if (ImageCodecInitialize (qtwrapper->instance, &capabs) != noErr) {
GST_ERROR_OBJECT (qtwrapper, "Couldn't initialize the QT component !");
return;
}
/* 3. Get codec info */
memset (&qtwrapper->codecinfo, 0, sizeof (CodecInfo));
if (ImageCodecGetCodecInfo (qtwrapper->instance,
&qtwrapper->codecinfo) != noErr) {
GST_ERROR_OBJECT (qtwrapper, "Couldn't get Codec Information !");
return;
}
/* sink pad */
qtwrapper->sinkpad = gst_pad_new_from_template (oclass->sinktempl, "sink");
gst_pad_set_setcaps_function (qtwrapper->sinkpad,
GST_DEBUG_FUNCPTR (qtwrapper_video_decoder_sink_setcaps));
gst_pad_set_chain_function (qtwrapper->sinkpad,
GST_DEBUG_FUNCPTR (qtwrapper_video_decoder_chain));
gst_pad_set_event_function (qtwrapper->sinkpad,
GST_DEBUG_FUNCPTR (qtwrapper_video_decoder_sink_event));
gst_element_add_pad (GST_ELEMENT (qtwrapper), qtwrapper->sinkpad);
/* src pad */
qtwrapper->srcpad = gst_pad_new_from_static_template (&src_templ, "src");
gst_element_add_pad (GST_ELEMENT (qtwrapper), qtwrapper->srcpad);
qtwrapper->lock = g_mutex_new ();
}
static void
qtwrapper_video_decoder_finalize (GObject * object)
{
QTWrapperVideoDecoder *qtwrapper;
qtwrapper = (QTWrapperVideoDecoder *) object;
if (qtwrapper->lock)
g_mutex_free (qtwrapper->lock);
if (G_OBJECT_CLASS (parent_class)->finalize)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
/* fill_image_description
* Fills an ImageDescription with codec-specific values
*
* Doesn't fill in the idSize, width and height.
*/
static void
fill_image_description (QTWrapperVideoDecoder * qtwrapper,
ImageDescription * desc)
{
QTWrapperVideoDecoderClass *oclass;
oclass = (QTWrapperVideoDecoderClass *) (G_OBJECT_GET_CLASS (qtwrapper));
desc->cType = oclass->componentSubType;
desc->version = qtwrapper->codecinfo.version;
desc->revisionLevel = qtwrapper->codecinfo.revisionLevel;
desc->vendor = qtwrapper->codecinfo.vendor;
desc->temporalQuality = codecMaxQuality;
desc->spatialQuality = codecNormalQuality;
desc->hRes = Long2Fix (72);
desc->vRes = Long2Fix (72);
desc->frameCount = 1;
/* The following is a pure empiric calculation ... so there's are chances it
* might not work. To be fixed when we can figure out what the exact value should
* be. */
desc->depth = 24;
/* no color table */
desc->clutID = -1;
}
/* new_image_description
*
* Create an ImageDescription for the given 'codec_data' buffer.
*/
static ImageDescription *
new_image_description (QTWrapperVideoDecoder * qtwrapper, GstBuffer * buf,
guint width, guint height)
{
QTWrapperVideoDecoderClass *oclass;
ImageDescription *desc = NULL;
oclass = (QTWrapperVideoDecoderClass *) (G_OBJECT_GET_CLASS (qtwrapper));
if (buf) {
GST_LOG ("buf %p , size:%d", buf, GST_BUFFER_SIZE (buf));
#if DEBUG_DUMP
gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
#endif
}
if (!buf) {
/* standard case, no codec data */
desc = g_new0 (ImageDescription, 1);
desc->idSize = sizeof (ImageDescription);
fill_image_description (qtwrapper, desc);
} else {
if ((desc =
image_description_from_codec_data (buf, oclass->componentSubType)))
fill_image_description (qtwrapper, desc);
else
goto beach;
}
/* Fix up values */
desc->width = width;
desc->height = height;
desc->hRes = Long2Fix (72);
desc->vRes = Long2Fix (72);
/* if we have h264, we need frame buffering */
if ((oclass->componentSubType == QT_MAKE_FOURCC_LE ('a', 'v', 'c', '1')))
qtwrapper->framebuffering = TRUE;
else
qtwrapper->framebuffering = FALSE;
beach:
return desc;
}
/* close_decoder
*
* Close and free decoder
*/
#if 0
static void
close_decoder (QTWrapperVideoDecoder * qtwrapper)
{
if (qtwrapper->idesc) {
DisposeHandle ((Handle) qtwrapper->idesc);
qtwrapper->idesc = NULL;
}
if (qtwrapper->prevbuf) {
gst_buffer_unref (qtwrapper->prevbuf);
qtwrapper->prevbuf = NULL;
}
if (qtwrapper->dparams) {
g_free (qtwrapper->dparams);
qtwrapper->dparams = NULL;
}
}
#endif
/* open_decoder
*
* Attempt to initialize the ImageDecompressorComponent with the given
* caps.
*
* Returns TRUE and fills *outcaps if the decoder was properly initialized
* Returns FALSE if something went wrong.
*/
static gboolean
open_decoder (QTWrapperVideoDecoder * qtwrapper, GstCaps * caps,
GstCaps ** outcaps)
{
ImageDescription *desc;
gint width, height;
GstStructure *s;
const GValue *par = NULL;
const GValue *rate = NULL;
const GValue *cdata = NULL;
OSStatus status;
gboolean res = FALSE;
guint32 outformat;
ICMDecompressionSessionOptionsRef sessionoptions = NULL;
ICMDecompressionTrackingCallbackRecord cbrecord;
CFMutableDictionaryRef pixelBufferAttributes = NULL;
s = gst_caps_get_structure (caps, 0);
/* 1. Extract information from incoming caps */
if ((!gst_structure_get_int (s, "width", &width)) ||
(!gst_structure_get_int (s, "height", &height)) ||
(!(rate = gst_structure_get_value (s, "framerate"))))
goto beach;
par = gst_structure_get_value (s, "pixel-aspect-ratio");
cdata = gst_structure_get_value (s, "codec_data");
/* 2. Create ImageDescription */
if (cdata) {
GstBuffer *cdatabuf;
cdatabuf = gst_value_get_buffer (cdata);
desc = new_image_description (qtwrapper, cdatabuf, width, height);
} else {
desc = new_image_description (qtwrapper, NULL, width, height);
}
#if DEBUG_DUMP
dump_image_description (desc);
#endif
/* 3.a. Create a handle to receive the ImageDescription */
GST_LOG_OBJECT (qtwrapper,
"Creating a new ImageDescriptionHandle of %" G_GSIZE_FORMAT " bytes",
desc->idSize);
qtwrapper->idesc = (ImageDescriptionHandle) NewHandleClear (desc->idSize);
if (G_UNLIKELY (qtwrapper->idesc == NULL)) {
GST_WARNING_OBJECT (qtwrapper,
"Failed to create an ImageDescriptionHandle of size %" G_GSIZE_FORMAT,
desc->idSize);
g_free (desc);
goto beach;
}
/* 3.b. Copy the ImageDescription to the handle */
GST_LOG_OBJECT (qtwrapper,
"Copying %" G_GSIZE_FORMAT
" bytes from desc [%p] to *qtwrapper->video [%p]", desc->idSize, desc,
*qtwrapper->idesc);
memcpy (*qtwrapper->idesc, desc, desc->idSize);
g_free (desc);
#if G_BYTE_ORDER == G_BIG_ENDIAN
outformat = kYUVSPixelFormat;
#else
outformat = k2vuyPixelFormat;
#endif
/* 4. Put output pixel info in dictionnnary */
pixelBufferAttributes =
CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
addSInt32ToDictionary (pixelBufferAttributes, kCVPixelBufferWidthKey, width);
addSInt32ToDictionary (pixelBufferAttributes, kCVPixelBufferHeightKey,
height);
addSInt32ToDictionary (pixelBufferAttributes,
kCVPixelBufferPixelFormatTypeKey, outformat);
/* 5. fill in callback structure */
cbrecord.decompressionTrackingCallback = decompressCb;
cbrecord.decompressionTrackingRefCon = qtwrapper;
/* 6. create decompressionsession */
status = ICMDecompressionSessionCreate (NULL,
qtwrapper->idesc,
sessionoptions, pixelBufferAttributes, &cbrecord, &qtwrapper->decsession);
qtwrapper->outsize = width * height * 2;
qtwrapper->width = width;
qtwrapper->height = height;
if (status) {
GST_DEBUG_OBJECT (qtwrapper,
"Error when Calling ICMDecompressionSessionCreate : %ld", status);
goto beach;
}
#if G_BYTE_ORDER == G_BIG_ENDIAN
outformat = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
#else
outformat = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
#endif
/* 9. Create output caps */
*outcaps = gst_caps_new_simple ("video/x-raw-yuv",
"format", GST_TYPE_FOURCC, outformat,
"width", G_TYPE_INT, width,
"height", G_TYPE_INT, height,
"framerate", GST_TYPE_FRACTION,
gst_value_get_fraction_numerator (rate),
gst_value_get_fraction_denominator (rate), NULL);
if (par)
gst_structure_set_value (gst_caps_get_structure (*outcaps, 0),
"pixel-aspect-ratio", par);
res = TRUE;
beach:
return res;
}
static gboolean
qtwrapper_video_decoder_sink_setcaps (GstPad * pad, GstCaps * caps)
{
QTWrapperVideoDecoder *qtwrapper;
gboolean ret = FALSE;
GstCaps *othercaps = NULL;
qtwrapper = (QTWrapperVideoDecoder *) gst_pad_get_parent (pad);
GST_LOG_OBJECT (qtwrapper, "caps:%" GST_PTR_FORMAT, caps);
/* Setup the decoder with the given input caps */
if (!(open_decoder (qtwrapper, caps, &othercaps))) {
goto beach;
}
ret = gst_pad_set_caps (qtwrapper->srcpad, othercaps);
if (!ret)
goto beach;
beach:
if (othercaps)
gst_caps_unref (othercaps);
gst_object_unref (qtwrapper);
return ret;
}
static void
decompressCb (void *decompressionTrackingRefCon,
OSStatus result,
ICMDecompressionTrackingFlags decompressionTrackingFlags,
CVPixelBufferRef pixelBuffer,
TimeValue64 displayTime,
TimeValue64 displayDuration,
ICMValidTimeFlags validTimeFlags, void *reserved, void *sourceFrameRefCon)
{
QTWrapperVideoDecoder *qtwrapper;
GstBuffer *origbuf = (GstBuffer *) sourceFrameRefCon;
qtwrapper = (QTWrapperVideoDecoder *) decompressionTrackingRefCon;
GST_LOG_OBJECT (qtwrapper,
"result:%d, flags:0x%x, pixelBuffer:%p, displayTime:%lld, displayDuration:%lld",
(guint32) result, (guint32) decompressionTrackingFlags, pixelBuffer,
displayTime, displayDuration);
GST_LOG_OBJECT (qtwrapper,
"validTimeFlags:0x%x, reserved:%p, sourceFrameRefCon:%p",
(guint32) validTimeFlags, reserved, sourceFrameRefCon);
if (decompressionTrackingFlags & kICMDecompressionTracking_ReleaseSourceData) {
GST_LOG ("removing previous buffer : %p", origbuf);
gst_buffer_unref (origbuf);
}
if (decompressionTrackingFlags & kICMDecompressionTracking_EmittingFrame)
GST_LOG ("EMITTING FRAME");
if (decompressionTrackingFlags & kICMDecompressionTracking_FrameDecoded)
GST_LOG ("FRAME DECODED");
if (decompressionTrackingFlags & kICMDecompressionTracking_FrameDropped)
GST_LOG ("FRAME DROPPED");
if (decompressionTrackingFlags &
kICMDecompressionTracking_FrameNeedsRequeueing)
GST_LOG ("FRAME NEEDS REQUEUING");
if ((decompressionTrackingFlags & kICMDecompressionTracking_EmittingFrame)
&& pixelBuffer) {
guint8 *addr;
GstBuffer *outbuf;
size_t size;
GstClockTime outtime;
size = CVPixelBufferGetDataSize (pixelBuffer);
outtime = gst_util_uint64_scale (displayTime, GST_SECOND, 600);
GST_LOG ("Got a buffer ready outtime : %" GST_TIME_FORMAT,
GST_TIME_ARGS (outtime));
if (qtwrapper->flushing) {
CVPixelBufferRelease (pixelBuffer);
goto beach;
}
dump_cvpixel_buffer (pixelBuffer);
CVPixelBufferRetain (pixelBuffer);
if (CVPixelBufferLockBaseAddress (pixelBuffer, 0))
GST_WARNING ("Couldn't lock base adress on pixel buffer !");
addr = CVPixelBufferGetBaseAddress (pixelBuffer);
/* allocate buffer */
qtwrapper->lastret =
gst_pad_alloc_buffer (qtwrapper->srcpad, GST_BUFFER_OFFSET_NONE,
(gint) qtwrapper->outsize, GST_PAD_CAPS (qtwrapper->srcpad), &outbuf);
if (G_UNLIKELY (qtwrapper->lastret != GST_FLOW_OK)) {
GST_LOG ("gst_pad_alloc_buffer() returned %s",
gst_flow_get_name (qtwrapper->lastret));
goto beach;
}
/* copy data */
GST_LOG ("copying data in buffer from %p to %p",
addr, GST_BUFFER_DATA (outbuf));
if (G_UNLIKELY ((qtwrapper->width * 2) !=
CVPixelBufferGetBytesPerRow (pixelBuffer))) {
guint i;
gulong realpixels;
size_t stride;
stride = CVPixelBufferGetBytesPerRow (pixelBuffer);
realpixels = qtwrapper->width * 2;
/* special copy for stride handling */
for (i = 0; i < qtwrapper->height; i++)
memmove (GST_BUFFER_DATA (outbuf) + realpixels * i,
addr + stride * i, realpixels);
} else
memmove (GST_BUFFER_DATA (outbuf), addr, (int) qtwrapper->outsize);
/* Release CVPixelBuffer */
CVPixelBufferUnlockBaseAddress (pixelBuffer, 0);
CVPixelBufferRelease (pixelBuffer);
/* Set proper timestamp ! */
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (qtwrapper->srcpad));
GST_BUFFER_TIMESTAMP (outbuf) = qtwrapper->last_ts;
GST_BUFFER_DURATION (outbuf) = qtwrapper->last_duration;
GST_BUFFER_SIZE (outbuf) = (int) qtwrapper->outsize;
/* See if we push buffer downstream */
if (G_LIKELY (!qtwrapper->framebuffering)) {
GST_LOG ("No buffering needed, pushing buffer downstream");
MAC_UNLOCK (qtwrapper);
qtwrapper->lastret = gst_pad_push (qtwrapper->srcpad, outbuf);
MAC_LOCK (qtwrapper);
} else {
/* Check if we push the current buffer or the stored buffer */
if (!qtwrapper->prevbuf) {
GST_LOG ("Storing buffer");
qtwrapper->prevbuf = outbuf;
qtwrapper->lastret = GST_FLOW_OK;
} else if (GST_BUFFER_TIMESTAMP (qtwrapper->prevbuf) >
GST_BUFFER_TIMESTAMP (outbuf)) {
GST_LOG ("Newly decoded buffer is earliest, pushing that one !");
MAC_UNLOCK (qtwrapper);
qtwrapper->lastret = gst_pad_push (qtwrapper->srcpad, outbuf);
MAC_LOCK (qtwrapper);
} else {
GstBuffer *tmp;
tmp = qtwrapper->prevbuf;
qtwrapper->prevbuf = outbuf;
GST_LOG ("Stored buffer is earliest, pushing that one !");
MAC_UNLOCK (qtwrapper);
qtwrapper->lastret = gst_pad_push (qtwrapper->srcpad, tmp);
MAC_LOCK (qtwrapper);
}
}
} else {
qtwrapper->lastret = GST_FLOW_OK;
}
beach:
return;
}
/* _chain
*
* Here we feed the data to the decoder and ask to decode frames.
*
* Known issues/questions are:
* * How can we be guaranteed that one frame in automatically gives one output
* frame ?
* * PTS/DTS timestamp issues. With mpeg-derivate formats, the incoming order is
* different from the output order.
*/
static GstFlowReturn
qtwrapper_video_decoder_chain (GstPad * pad, GstBuffer * buf)
{
QTWrapperVideoDecoder *qtwrapper;
GstFlowReturn ret = GST_FLOW_OK;
ICMFrameTimeRecord frameTime = { {0} };
OSStatus status;
guint64 intime;
qtwrapper = (QTWrapperVideoDecoder *) gst_pad_get_parent (pad);
intime = gst_util_uint64_scale (GST_BUFFER_TIMESTAMP (buf), 600, GST_SECOND);
GST_DEBUG_OBJECT (qtwrapper,
"buffer:%p timestamp:%" GST_TIME_FORMAT " intime:%llu Size:%d", buf,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), intime,
GST_BUFFER_SIZE (buf));
frameTime.recordSize = sizeof (ICMFrameTimeRecord);
/* *(TimeValue64 *)&frameTime.value = intime; */
frameTime.value.lo = (guint32) (intime & 0xffffffff);
frameTime.value.hi = (guint32) (intime >> 32);
frameTime.base = 0;
frameTime.scale = 600;
frameTime.rate = fixed1;
frameTime.duration = 1;
frameTime.flags = icmFrameTimeDecodeImmediately;
/* frameTime.flags = icmFrameTimeIsNonScheduledDisplayTime; */
frameTime.frameNumber = (long) (++qtwrapper->frameNumber);
MAC_LOCK (qtwrapper);
qtwrapper->last_ts = GST_BUFFER_TIMESTAMP (buf);
qtwrapper->last_duration = GST_BUFFER_DURATION (buf);
status = ICMDecompressionSessionDecodeFrame (qtwrapper->decsession,
GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf), NULL, &frameTime, buf);
MAC_UNLOCK (qtwrapper);
if (status) {
GST_WARNING_OBJECT (qtwrapper, "Error when Calling DecodeFrame() : %ld",
status);
ret = GST_FLOW_ERROR;
goto beach;
}
beach:
gst_object_unref (qtwrapper);
return qtwrapper->lastret;
}
static gboolean
qtwrapper_video_decoder_sink_event (GstPad * pad, GstEvent * event)
{
gboolean res;
QTWrapperVideoDecoder *qtwrapper;
qtwrapper = (QTWrapperVideoDecoder *) gst_pad_get_parent (pad);
GST_LOG_OBJECT (pad, "event : %s", GST_EVENT_TYPE_NAME (event));
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_START:
MAC_LOCK (qtwrapper);
qtwrapper->flushing = TRUE;
if (qtwrapper->prevbuf) {
GST_LOG ("About to unref buffer %p", qtwrapper->prevbuf);
gst_buffer_unref (qtwrapper->prevbuf);
qtwrapper->prevbuf = NULL;
}
ICMDecompressionSessionFlush (qtwrapper->decsession);
MAC_UNLOCK (qtwrapper);
break;
case GST_EVENT_FLUSH_STOP:
MAC_LOCK (qtwrapper);
qtwrapper->flushing = FALSE;
qtwrapper->prevbuf = NULL;
MAC_UNLOCK (qtwrapper);
break;
default:
break;
}
res = gst_pad_push_event (qtwrapper->srcpad, event);
gst_object_unref (qtwrapper);
return res;
}
/* _register
*
* Scan through all available Image Decompressor components to find the ones we
* can handle and wrap in this plugin.
*/
gboolean
qtwrapper_video_decoders_register (GstPlugin * plugin)
{
gboolean res = TRUE;
Component componentID = NULL;
ComponentDescription desc = {
'imdc', 0, 0, 0, 0
};
GTypeInfo typeinfo = {
sizeof (QTWrapperVideoDecoderClass),
(GBaseInitFunc) qtwrapper_video_decoder_base_init,
NULL,
(GClassInitFunc) qtwrapper_video_decoder_class_init,
NULL,
NULL,
sizeof (QTWrapperVideoDecoder),
0,
(GInstanceInitFunc) qtwrapper_video_decoder_init,
};
/* Find all ImageDecoders ! */
GST_DEBUG ("There are %ld decompressors available", CountComponents (&desc));
/* loop over ImageDecoders */
do {
componentID = FindNextComponent (componentID, &desc);
GST_LOG ("componentID : %p", componentID);
if (componentID) {
ComponentDescription thisdesc;
gchar *name = NULL, *info = NULL;
GstCaps *caps = NULL;
gchar *type_name = NULL;
GType type;
QTWrapperVideoDecoderParams *params = NULL;
if (!(get_name_info_from_component (componentID, &thisdesc, &name,
&info)))
goto next;
if (!get_output_info_from_component (componentID)) {
GST_WARNING ("Couldn't get output info from component");
goto next;
}
GST_LOG (" name:%s", GST_STR_NULL (name));
GST_LOG (" info:%s", GST_STR_NULL (info));
GST_LOG (" type:%" GST_FOURCC_FORMAT,
QT_FOURCC_ARGS (thisdesc.componentType));
GST_LOG (" subtype:%" GST_FOURCC_FORMAT,
QT_FOURCC_ARGS (thisdesc.componentSubType));
GST_LOG (" manufacturer:%" GST_FOURCC_FORMAT,
QT_FOURCC_ARGS (thisdesc.componentManufacturer));
if (!(caps = fourcc_to_caps (thisdesc.componentSubType))) {
GST_LOG
("We can't find caps for this component, switching to the next one !");
goto next;
}
type_name = g_strdup_printf ("qtwrappervideodec_%" GST_FOURCC_FORMAT,
QT_FOURCC_ARGS (thisdesc.componentSubType));
g_strdelimit (type_name, " ", '_');
if (g_type_from_name (type_name)) {
GST_WARNING ("We already have a registered plugin for %s", type_name);
goto next;
}
params = g_new0 (QTWrapperVideoDecoderParams, 1);
params->component = componentID;
params->sinkcaps = gst_caps_ref (caps);
GST_INFO ("Registering g_type for type_name: %s", type_name);
type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
/* Store params in type qdata */
g_type_set_qdata (type, QTWRAPPER_VDEC_PARAMS_QDATA, (gpointer) params);
/* register type */
if (!gst_element_register (plugin, type_name, GST_RANK_MARGINAL, type)) {
g_warning ("Failed to register %s", type_name);;
g_type_set_qdata (type, QTWRAPPER_VDEC_PARAMS_QDATA, NULL);
g_free (params);
res = FALSE;
goto next;
} else {
GST_LOG ("Reigstered video plugin %s", type_name);
}
next:
if (name)
g_free (name);
if (info)
g_free (info);
if (type_name)
g_free (type_name);
if (caps)
gst_caps_unref (caps);
}
} while (componentID && res);
return res;
}